1 /* Copyright (c) 2009 Arnaud Renevier, Inc, published under the modified BSD
5 * Fix canvas rendering engine race condition. See js/syp.js for more explanation.
7 OpenLayers.Renderer.Canvas.prototype = OpenLayers.Util.extend({
10 }, OpenLayers.Renderer.Canvas.prototype);
11 OpenLayers.Renderer.Canvas.prototype.oldRedraw = OpenLayers.Renderer.Canvas.prototype.redraw;
12 OpenLayers.Renderer.Canvas.prototype.redraw = function() {
13 if (this.imagesLoading > 0) {
14 this.needsRedraw = true;
17 OpenLayers.Renderer.Canvas.prototype.oldRedraw.apply(this, arguments);
19 OpenLayers.Renderer.Canvas.prototype.drawExternalGraphic = function(pt, style) {
20 var img = new Image();
21 img.src = style.externalGraphic;
23 if(style.graphicTitle) {
24 img.title=style.graphicTitle;
27 var width = style.graphicWidth || style.graphicHeight;
28 var height = style.graphicHeight || style.graphicWidth;
29 width = width ? width : style.pointRadius*2;
30 height = height ? height : style.pointRadius*2;
31 var xOffset = (style.graphicXOffset != undefined) ?
32 style.graphicXOffset : -(0.5 * width);
33 var yOffset = (style.graphicYOffset != undefined) ?
34 style.graphicYOffset : -(0.5 * height);
35 var opacity = style.graphicOpacity || style.fillOpacity;
37 var context = { img: img,
42 canvas: this.canvas };
46 img.onerror = function() {
48 if ((self.imagesLoading == 0) && (self.needsRedraw)) {
49 self.needsRedraw = false;
53 img.onload = OpenLayers.Function.bind( function() {
55 if ((self.imagesLoading == 0) && (self.needsRedraw)) {
56 self.needsRedraw = false;
59 this.canvas.drawImage(this.img, this.x,
60 this.y, this.width, this.height);
64 // drag feature with tolerance
65 OpenLayers.Control.SypDragFeature = OpenLayers.Class (OpenLayers.Control.DragFeature, {
71 downFeature: function(pixel) {
72 OpenLayers.Control.DragFeature.prototype.downFeature.apply(this, arguments);
73 this.dragStart = (new Date()).getTime();
74 this.startPixel = pixel;
77 doneDragging: function(pixel) {
78 OpenLayers.Control.DragFeature.prototype.doneDragging.apply(this, arguments);
80 var passesTimeTolerance =
81 (new Date()).getTime() > this.dragStart + this.timeTolerance;
83 var xDiff = this.startPixel.x - pixel.x;
84 var yDiff = this.startPixel.y - pixel.y;
86 var passesPixelTolerance =
87 Math.sqrt(Math.pow(xDiff,2) + Math.pow(yDiff,2)) > this.pixelTolerance;
89 if(passesTimeTolerance && passesPixelTolerance){
90 this.onComplete(this.feature, pixel);
92 var feature = this.feature;
93 var res = this.map.getResolution();
94 this.feature.geometry.move(res * (this.startPixel.x - this.lastPixel.x),
95 res * (this.lastPixel.y - this.startPixel.y));
96 this.layer.drawFeature(this.feature);
98 this.layer.drawFeature(this.feature, "select");
101 moveFeature: function(pixel) {
102 OpenLayers.Control.DragFeature.prototype.moveFeature.apply(this, arguments);
103 this.layer.drawFeature(this.feature, "temporary");
106 overFeature: function (feature) {
107 // can only drag and drop currently selected feature
108 if (feature != Admin.currentFeature) {
111 OpenLayers.Control.DragFeature.prototype.overFeature.apply(this, arguments);
114 CLASS_NAME: "OpenLayers.Control.SypDragFeature"
119 ICON: "media/marker-normal.png",
120 SELECT_ICON: "media/marker-selected.png",
121 TEMPORARY_ICON: "media/marker-temp.png",
128 selFeatureControl: null,
129 moveFeatureControl: null,
130 addFeatureControl: null,
132 currentFeature: null,
133 currentFeatureLocation: null,
136 this.map = new OpenLayers.Map ("map", {
138 new OpenLayers.Control.Navigation (),
139 new OpenLayers.Control.PanZoom ()
141 projection: new OpenLayers.Projection("EPSG:900913"),
142 displayProjection: new OpenLayers.Projection("EPSG:4326")
145 this.baseLayer = this.createBaseLayer ();
146 this.map.addLayer(this.baseLayer);
148 this.map.setCenter(new OpenLayers.LonLat(0, 0), 0);
149 if (sypSettings.loggedUser) {
150 this.dataLayer = this.createDataLayer (sypSettings.loggedUser);
151 this.map.addLayer(this.dataLayer);
157 this.addFeatureControl.deactivate();
158 this.moveFeatureControl.deactivate();
159 this.selFeatureControl.activate();
160 this.checkForFeatures();
161 $("#newfeature_button").show().val(SypStrings.AddItem);
162 $("#newfeature_button").unbind("click").click(function () {
163 Admin.addNewFeature();
167 createBaseLayer: function () {
168 return new OpenLayers.Layer.OSM("OSM");
171 createDataLayer: function (user) {
172 var styleMap = new OpenLayers.StyleMap (
174 externalGraphic: this.Markers.ICON,
175 graphicHeight: this.Markers.HEIGHT || 32
178 externalGraphic: this.Markers.TEMPORARY_ICON,
179 graphicHeight: this.Markers.HEIGHT || 32
182 externalGraphic: this.Markers.SELECT_ICON,
183 graphicHeight: this.Markers.HEIGHT || 32
186 var layer = new OpenLayers.Layer.GML("KML", "items.php?from_user=" + encodeURIComponent(user),
189 format: OpenLayers.Format.KML,
190 projection: this.map.displayProjection,
191 eventListeners: { scope: this,
192 loadend: this.dataLayerEndLoad
197 this.selFeatureControl = this.createSelectFeatureControl(layer)
198 this.map.addControl(this.selFeatureControl);
199 this.moveFeatureControl = this.createMoveFeatureControl(layer)
200 this.map.addControl(this.moveFeatureControl);
201 this.addFeatureControl = this.createNewfeatureControl();
202 this.map.addControl(this.addFeatureControl);
207 createMoveFeatureControl: function (layer) {
208 var control = new OpenLayers.Control.SypDragFeature(
214 createSelectFeatureControl: function (layer) {
215 var control = new OpenLayers.Control.SelectFeature(
217 onSelect: OpenLayers.Function.bind(this.onFeatureSelect, this)
222 createNewfeatureControl: function () {
223 var control = new OpenLayers.Control ();
224 var handler = new OpenLayers.Handler.Click(control, {
225 'click': OpenLayers.Function.bind(FeatureMgr.add, FeatureMgr)
227 control.handler = handler;
231 onFeatureSelect: function (feature) {
232 this.showEditor(feature);
234 this.selFeatureControl.deactivate();
235 this.moveFeatureControl.activate();
238 closeEditor: function() {
239 if ($("#editor").css("display") == "none") {
242 if (this.currentFeature && this.currentFeature.layer) {
243 this.selFeatureControl.unselect(this.currentFeature);
245 this.currentFeature = null;
246 this.currentFeatureLocation = null;
247 $("#img").removeAttr('src');
248 $("#img").parent().html($("#img").parent().html());
249 $("#img").parent().show();
250 $("#title, #description").val("");
252 // do it once before hidding and once after hidding to work in all cases
253 $("#title, #description").val("");
254 $("#image_file").parent().html($("#image_file").parent().html());
255 $(document).unbind("keydown");
256 this.checkForFeatures();
260 showEditor: function (feature) {
261 $("#newfeature_button").hide();
269 $(document).unbind("keydown").keydown(function(e) {
270 if (e.keyCode == 27) {
271 Admin.cancelCurrentFeature()
275 this.currentFeature = feature;
276 this.currentFeatureLocation = new OpenLayers.Pixel(feature.geometry.x, feature.geometry.y);
278 $("#instructions").text(SypStrings.DragDropHowto);
279 $("#title").val(feature.attributes.name);
280 var fullDesc = $(feature.attributes.description).parent();
281 $("#description").val(fullDesc.find('p').text());
282 var src = fullDesc.find('img').attr('src');
284 $("#img").parent().show();
285 $("#img").attr('src', src);
286 $("#image_file").parent().hide();
287 $("#image_delete").show();
289 $("#img").parent().hide();
290 $("#image_file").parent().show();
291 $("#image_delete").hide();
293 $("#title").select().focus();
296 dataLayerEndLoad: function() {
297 // only set zoom extent once
298 this.dataLayer.events.unregister('loadend', this, this.dataLayerEndLoad);
299 this.dataLayer.events.register('loadend', this, this.checkForFeatures);
301 if (!this.checkForFeatures()) {
306 var orig = this.Utils.mbr (this.dataLayer);
307 var centerBounds = new OpenLayers.Bounds();
309 var mapProj = map.getProjectionObject();
310 var sypOrigProj = new OpenLayers.Projection("EPSG:4326");
312 var bottomLeft = new OpenLayers.LonLat(orig[0],orig[1]);
313 bottomLeft = bottomLeft.transform(sypOrigProj, mapProj);
314 var topRight = new OpenLayers.LonLat(orig[2],orig[3])
315 topRight = topRight.transform(sypOrigProj, mapProj);
317 centerBounds.extend(bottomLeft);
318 centerBounds.extend(topRight);
319 map.zoomToExtent(centerBounds);
322 checkForFeatures: function () {
323 var features = this.dataLayer.features;
324 if (features.length != 0) {
325 $("#instructions").text(SypStrings.SelectHowto);
327 return !!features.length;
330 addNewFeature: function () {
333 $(document).unbind("keydown");
336 $(document).unbind("keydown").keydown(function(e) {
337 if (e.keyCode == 27) {
343 $("#newfeature_button").val(SypStrings.Cancel);
344 $("#newfeature_button").unbind("click").click(cancel);
346 $("#instructions").text(SypStrings.AddHowto);
347 this.selFeatureControl.deactivate();
348 this.addFeatureControl.activate();
352 cancelCurrentFeature: function() {
353 if (AjaxMgr.running) {
356 var feature = this.currentFeature;
359 FeatureMgr.move (feature, this.currentFeatureLocation);
361 this.dataLayer.removeFeatures([feature]);
368 reloadLayer: function (layer) {
369 layer.destroyFeatures();
370 layer.loaded = false;
375 /* minimum bounds rectangle containing all feature locations.
376 * FIXME: if two features are close, but separated by 180th meridian,
377 * their mbr will span the whole earth. Actually, 179° lon and -170°
378 * lon are considerated very near.
380 mbr: function (layer) {
384 var mapProj = map.getProjectionObject();
385 var sypOrigProj = new OpenLayers.Projection("EPSG:4326");
387 for (var i =0; i < layer.features.length; i++) {
388 if (layer.features[i].cluster) {
389 features = features.concat(layer.features[i].cluster);
391 features = features.concat(layer.features);
400 if (features.length == 0) {
401 // keep default values
402 } else if (features.length == 1) {
403 // in case there's only one feature, we show an area of at least
405 var pos = features[0].geometry.getBounds().getCenterLonLat().clone();
406 var lonlat = pos.transform(mapProj, sypOrigProj);
408 minlon = Math.max (lonlat.lon - 2, -180);
409 maxlon = Math.min (lonlat.lon + 2, 180);
410 minlat = Math.max (lonlat.lat - 2, -90);
411 maxlat = Math.min (lonlat.lat + 2, 90);
413 for (var i = 0; i < features.length; i++) {
414 var pos = features[i].geometry.getBounds().getCenterLonLat().clone();
415 var lonlat = pos.transform(mapProj, sypOrigProj);
416 minlon = Math.min (lonlat.lon, minlon);
417 minlat = Math.min (lonlat.lat, minlat);
418 maxlon = Math.max (lonlat.lon, maxlon);
419 maxlat = Math.max (lonlat.lat, maxlat);
423 return [minlon, minlat, maxlon, maxlat];
428 escapeHTML: function (str) {
433 replace(/&/gm, '&').
434 replace(/'/gm, ''').
435 replace(/"/gm, '"').
436 replace(/>/gm, '>').
437 replace(/</gm, '<');
440 startsWith: function (str, prefix) {
441 return (str.slice(0, prefix.length) == prefix);
444 indexOf: function (array, item) {
445 if (array.indexOf !== undefined) {
446 return array.indexOf(item);
448 return OpenLayers.Util.indexOf(array, item);
460 alert (SypStrings.DisabledForDemo);
461 $(document).unbind("keydown");
465 var pos = map.getLonLatFromViewPortPx(evt.xy);
466 feature = this.update (null, pos, "", "", "");
467 Admin.addFeatureControl.deactivate();
468 Admin.selFeatureControl.select(feature);
471 move: function (feature, aLocation) {
472 if (!feature || !aLocation) {
475 var curLoc = feature.geometry;
476 feature.geometry.move(aLocation.x - curLoc.x, aLocation.y - curLoc.y);
477 feature.layer.drawFeature(feature);
480 update: function(feature, lonlat, imgurl, title, description) {
481 var point = new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat);
483 feature = new OpenLayers.Feature.Vector(point);
484 Admin.dataLayer.addFeatures([feature]);
486 this.move (feature, point);
488 feature.attributes.name = title;
489 feature.attributes.description = "<p>" + Admin.Utils.escapeHTML(description) + "</p>"
490 + "<img src=\"" + imgurl + "\">"
494 del: function (feature) {
495 alert (SypStrings.DisabledForDemo);
497 var form = $("#feature_delete");
498 form.find('input[name="fid"]').val(feature.fid);
501 oncomplete: OpenLayers.Function.bind(this.ajaxReply, this),
502 throbberid: "editor_throbber"
506 save: function (feature) {
507 var x = feature.geometry.x;
508 var y = feature.geometry.y;
510 var mapProj = feature.layer.map.getProjectionObject();
511 var lonlat = new OpenLayers.LonLat(x, y).
513 new OpenLayers.Projection("EPSG:4326"));
514 var form = $("#feature_update");
515 form.find('input[name="lon"]').val(lonlat.lon);
516 form.find('input[name="lat"]').val(lonlat.lat);
517 form.find('input[name="fid"]').val(feature.fid);
518 form.find('input[name="keep_img"]').val(
519 $("#img").attr("src") ? "yes": "no"
523 form.find('input[name="request"]').val("update");
525 form.find('input[name="request"]').val("add");
529 oncomplete: OpenLayers.Function.bind(this.ajaxReply, this),
530 throbberid: "editor_throbber"
534 ajaxReply: function (data) {
536 this.commError(SypStrings.ServerError);
540 var xml = new OpenLayers.Format.XML().read(data);
541 if (!xml.documentElement) {
542 this.commError(SypStrings.UnconsistentError);
547 switch (xml.documentElement.nodeName.toLowerCase()) {
549 switch (xml.documentElement.getAttribute("reason")) {
552 $("#cookie_warning").show();
554 Admin.cancelCurrentFeature();
559 this.commError(SypStrings.ServerError);
563 this.commError(SypStrings.UnreferencedError);
564 Admin.reloadLayer(Admin.dataLayer);
568 this.commError(SypStrings.NochangeError);
572 this.commError(SypStrings.RequestError);
576 this.commError(SypStrings.ToobigError);
577 $("#image_file").parent().html($("#image_file").parent().html());
578 $("#image_file").focus();
581 this.commError(SypStrings.NotimageError);
582 $("#image_file").parent().html($("#image_file").parent().html());
583 $("#image_file").focus();
586 this.commError(SypStrings.UnconsistentError);
592 switch (xml.documentElement.getAttribute("request")) {
594 this.commSuccess(SypStrings.DelSucces);
595 var someFeature = false;
597 $.each($(xml).find("FEATURE,feature"), function () {
599 var id = parseFloat($(this).find("ID:first,id:first").text());
600 if ((id === null) || isNaN (id)) {
603 var features = Admin.dataLayer.features;
604 for (var idx = 0; idx < features.length; idx++) {
605 if (features[idx].fid == id) {
606 Admin.dataLayer.removeFeatures([features[idx]]);
610 if (someFeature == false) {
611 this.commError(SypStrings.UnconsistentError);
618 var someFeature = false;
620 $.each($(xml).find("FEATURE,feature"), function () {
622 var id = parseFloat($(this).find("ID:first,id:first").text());
623 if ((id === null) || isNaN (id)) {
627 var lon = parseFloat($(this).find("LON:first,lon:first").text());
628 if ((typeof (lon) != "number") || isNaN (lon) ||
629 (lon < -180) || (lon > 180)) {
633 var lat = parseFloat($(this).find("LAT:first,lat:first").text());
634 if ((typeof (lat) != "number") || isNaN (lat) ||
635 (lat < -90) || (lat > 90)) {
639 var mapProj = Admin.map.getProjectionObject();
640 var lonlat = new OpenLayers.LonLat (lon, lat).
641 transform( new OpenLayers.Projection("EPSG:4326"), mapProj);
643 var imgurl = $(this).find("IMGURL:first,imgurl:first").text();
644 var title = $(this).find("HEADING:first,heading:first").text();
645 var description = $(this).find("DESCRIPTION:first,description:first").text();
647 feature = self.update (Admin.currentFeature, lonlat, imgurl, title, description);
651 if (someFeature == false) {
652 this.commError(SypStrings.UnconsistentError);
654 this.commSuccess(SypStrings.UpdateSucces);
660 this.commError(SypStrings.UnconsistentError);
665 this.commError(SypStrings.UnconsistentError);
670 commSuccess: function (message) {
671 $("#server_comm").text(message);
672 $("#server_comm").removeClass("error success").addClass("success");
675 commError: function (message) {
676 $("#server_comm").text(message);
677 $("#server_comm").removeClass("error success").addClass("error");
681 /* maintains a queue of ajax queries, so I'm sure they all execute in the same
682 * order they were defined */
688 add: function(query) {
689 this._queue.push(query);
690 if (this._queue.length > 1) {
693 this._runQuery(query);
697 _runQuery: function(query) {
699 $('#api_frame').one("load", function() {
700 self.running = false;
702 if (query.throbberid) {
703 $("#" + query.throbberid).css("visibility", "hidden");
705 if (typeof (query.oncomplete) == "function") {
708 if (this.contentDocument) {
709 body = this.contentDocument.body;
710 } else if (this.contentWindow) {
711 body = this.contentWindow.document.body;
713 body = document.frames[this.id].document.body;
717 query.oncomplete(body.innerHTML);
719 query.oncomplete(null);
723 query.form.attr("action", "api.php");
724 query.form.attr("target", "api_frame");
725 query.form.attr("method", "post");
727 query.form.get(0).submit();
728 if (query.throbberid) {
729 $("#" + query.throbberid).css("visibility", "visible");
731 if (typeof (query.onsend) == "function") {
736 _reqEnd: function() {
738 if (this._queue.length > 0) {
739 this._reqEnd(this._queue[0]);
747 $("#login_form").submit(this.submit);
748 $("#user").focus().select();
753 $("#login_area").show();
754 $("#password").val("");
755 $("#user").val(sypSettings.loggedUser).focus().select();
758 submit: function () {
760 pwdMgr.commError("");
762 form: $("#login_form"),
763 throbberid: "pwd_throbber",
765 $("#login_error").hide();
767 // we need a timeout; otherwise those fields will not be submitted
768 window.setTimeout(function() {
769 // removes focus from #password before disabling it. Otherwise, opera
770 // prevents re-focusing it after re-enabling it.
771 $("#user, #password").blur();
772 $("#login_submit, #user, #password").attr("disabled", "disabled");
775 oncomplete: OpenLayers.Function.bind(pwdMgr.ajaxReply, pwdMgr)
782 ajaxReply: function (data) {
783 // here, we need a timeout because onsend timeout sometimes has not been triggered yet
784 window.setTimeout(function() {
785 $("#login_submit, #user, #password").removeAttr("disabled");
789 this.commError(SypStrings.ServerError);
790 $("#login_error").show();
791 window.setTimeout(function() {
792 $("#user").focus().select();
797 var xml = new OpenLayers.Format.XML().read(data);
798 if (!xml.documentElement) {
799 this.commError(SypStrings.UnconsistentError);
800 $("#login_error").show();
801 window.setTimeout(function() {
802 $("#user").focus().select();
806 switch (xml.documentElement.nodeName.toLowerCase()) {
808 switch (xml.documentElement.getAttribute("reason")) {
810 this.commError(SypStrings.ServerError);
813 this.commError(SypStrings.UnauthorizedError);
816 this.commError(SypStrings.RequestError);
819 this.commError(SypStrings.UnconsistentError);
822 $("#login_error").show();
823 window.setTimeout(function() {
824 $("#user").focus().select();
828 $("#login_area").hide();
830 user = $(xml).find("USER,user").text();
831 sypSettings.loggedUser = user;
833 if (sypSettings.loggedUser == "admin") {
837 if (Admin.selFeatureControl) {
838 Admin.selFeatureControl.destroy();
840 if (Admin.moveFeatureControl) {
841 Admin.moveFeatureControl.destroy();
843 if (Admin.addFeatureControl) {
844 Admin.addFeatureControl.destroy();
846 if (Admin.dataLayer) {
847 Admin.dataLayer.destroy();
850 Admin.dataLayer = Admin.createDataLayer(user);
851 Admin.map.addLayer(Admin.dataLayer);
856 this.commError(SypStrings.UnconsistentError);
861 commError: function (message) {
862 $("#login_error").text(message);
864 $("#login_error").show();
866 $("#login_error").hide();
872 _adduserDisplayed: false,
873 _changepassDisplayed: false,
876 $("#user_close").unbind("click").click(function () {
880 $("#change_pass").unbind("click").click(function() {
881 userMgr.toggleChangePass();
884 $("#changepass").unbind("submit").submit(function() {
886 userMgr.changepass();
891 if (sypSettings.loggedUser != "admin") {
895 $("#add_user").show();
896 $("#add_user").unbind("click").click(function () {
897 userMgr.toggleAddUser();
900 $("#newuser").unbind("submit").submit(function() {
909 disableForms: function() {
910 $("#newuser_name, #newuser_password, #newuser_password_confirm, #newuser_submit").attr("disabled", "disabled");
911 $("#pass_current, #pass_new, #pass_new_confirm, #pass_submit").attr("disabled", "disabled");
914 enableForms: function() {
915 $("#newuser_name, #newuser_password, #newuser_password_confirm, #newuser_submit").removeAttr("disabled");
916 $("#pass_current, #pass_new, #pass_new_confirm, #pass_submit").removeAttr("disabled");
919 resetForms: function() {
920 $("#newuser_name, #newuser_password, #newuser_password_confirm").val("");
921 $("#pass_current, #pass_new, #pass_new_confirm").val("");
926 $("#add_user").unbind("click");
927 $("#add_user").hide();
928 $("#change_pass").unbind("click");
929 $("#user_close").unbind("click");
930 $("#newuser").unbind("submit");
931 $("#changepass").unbind("submit");
935 this.closeChangePass();
939 toggleChangePass: function() {
940 if (this._changepassDisplayed) {
941 this.closeChangePass();
943 this.showChangePass();
947 showChangePass: function() {
948 if (!Admin.cancelCurrentFeature()) {
953 $(document).unbind("keydown").keydown(function(e) {
954 if (e.keyCode == 27) {
955 userMgr.closeChangePass()
962 $("#user_area, #changepass").show();
965 // XXX: setTimeout needed because otherwise, map becomes hidden in IE. Why ??
966 window.setTimeout(function() {
967 $("#pass_current").focus();
970 this._changepassDisplayed = true;
973 closeChangePass: function() {
974 if (!this._changepassDisplayed) {
977 $("#user_area, #changepass").hide();
978 $(document).unbind("keydown");
979 this._changepassDisplayed = false;
982 changepass: function() {
983 var newpass = $("#pass_new").val();
984 var newpass_confirm = $("#pass_new_confirm").val();
985 if (newpass != newpass_confirm) {
986 this.commError(SypStrings.userPasswordmatchError);
987 $("#pass_new").focus().select();
992 this.commError(SypStrings.emptyPasswordError);
993 $("#pass_new").focus().select();
997 var curpass = $("#pass_current").val();
998 if (newpass == curpass) {
999 this.commError(SypStrings.changeSamePass);
1000 $("#pass_new").focus().select();
1006 this.disableForms();
1007 alert (SypStrings.DisabledForDemo);
1011 form: $("#changepass"),
1012 oncomplete: OpenLayers.Function.bind(this.ajaxReply, this),
1013 throbberid: "user_throbber",
1014 onsend: function() {
1015 // we need a timeout; otherwise those fields will not be submitted
1016 window.setTimeout(function() {
1017 // removes focus from #password before disabling it. Otherwise, opera
1018 // prevents re-focusing it after re-enabling it.
1019 $("#pass_current, #pass_new, #pass_new_confirm").blur();
1020 userMgr.disableForms();
1026 toggleAddUser: function() {
1027 if (this._adduserDisplayed) {
1028 this.closeAddUser();
1034 showAddUser: function() {
1035 if (!Admin.cancelCurrentFeature()) {
1039 this.closeChangePass();
1041 $(document).unbind("keydown").keydown(function(e) {
1042 if (e.keyCode == 27) {
1043 userMgr.closeAddUser()
1048 $("#user_area, #newuser").show();
1053 // XXX: setTimeout needed because otherwise, map becomes hidden in IE. Why ??
1054 window.setTimeout(function() {
1055 $("#newuser_name").focus();
1058 this._adduserDisplayed = true;
1061 closeAddUser: function() {
1062 if (!this._adduserDisplayed) {
1065 $("#user_area, #newuser").hide();
1066 $(document).unbind("keydown");
1067 this._adduserDisplayed = false;
1071 var newuser_name = $("#newuser_name").val();
1072 if (!newuser_name) {
1073 this.commError(SypStrings.newUserNonameError);
1074 $("#newuser_name").focus();
1078 var newuser_pass = $("#newuser_password").val();
1079 var newuser_pass_confirm = $("#newuser_password_confirm").val();
1080 if (newuser_pass != newuser_pass_confirm) {
1081 this.commError(SypStrings.userPasswordmatchError);
1082 $("#newuser_password").focus().select();
1086 if (!newuser_pass) {
1087 this.commError(SypStrings.emptyPasswordError);
1088 $("#pass_new").focus().select();
1093 this.disableForms();
1094 alert (SypStrings.DisabledForDemo);
1098 form: $("#newuser"),
1099 oncomplete: OpenLayers.Function.bind(this.ajaxReply, this),
1100 throbberid: "user_throbber",
1101 onsend: function() {
1102 // we need a timeout; otherwise those fields will not be submitted
1103 window.setTimeout(function() {
1104 // removes focus from #password before disabling it. Otherwise, opera
1105 // prevents re-focusing it after re-enabling it.
1106 $("#newuser_name, #newuser_password, #newuser_password_confirm").blur();
1107 userMgr.disableForms();
1113 ajaxReply: function (data) {
1115 // here, we need a timeout because onsend timeout sometimes has not been triggered yet
1117 window.setTimeout(function() {
1120 this.commError(SypStrings.ServerError);
1124 var xml = new OpenLayers.Format.XML().read(data);
1125 if (!xml.documentElement) {
1126 // here, we need a timeout because onsend timeout sometimes has not been triggered yet
1128 window.setTimeout(function() {
1131 this.commError(SypStrings.UnconsistentError);
1135 var needFormEnabling = true;
1138 switch (xml.documentElement.nodeName.toLowerCase()) {
1140 switch (xml.documentElement.getAttribute("reason")) {
1141 case "unauthorized":
1143 $("#cookie_warning").show();
1148 this.commError(SypStrings.ServerError);
1149 if (this._adduserDisplayed) {
1150 focusEl = $("#newuser_name");
1151 } else if (this._changepassDisplayed) {
1152 focusEl = $("#pass_current");
1156 this.commError(SypStrings.RequestError);
1157 if (this._adduserDisplayed) {
1158 focusEl = $("#newuser_name");
1159 } else if (this._changepassDisplayed) {
1160 focusEl = $("#pass_current");
1164 this.commError(SypStrings.changePassBadPass);
1165 focusEl = $("#pass_current");
1167 case "newuser_exists":
1168 this.commError(SypStrings.newUserExistsError);
1169 focusEl = $("#newuser_name");
1172 this.commError(SypStrings.UnconsistentError);
1173 if (this._adduserDisplayed) {
1174 focusEl = $("#newuser_name");
1175 } else if (this._changepassDisplayed) {
1176 focusEl = $("#pass_current");
1182 switch (xml.documentElement.getAttribute("request")) {
1184 this.commSuccess(SypStrings.newUserSuccess);
1185 needFormEnabling = false;
1188 this.commSuccess(SypStrings.changePassSuccess);
1189 needFormEnabling = false;
1192 this.commError(SypStrings.UnconsistentError);
1193 focusEl = $("newuser_name");
1198 this.commError(SypStrings.UnconsistentError);
1199 focusEl = $("newuser_name");
1203 if (needFormEnabling) {
1204 // here, we need a timeout because onsend timeout sometimes has not been triggered yet
1206 window.setTimeout(function() {
1209 focusEl.select().focus();
1214 focusEl.focus().select();
1220 commSuccess: function (message) {
1221 $("#user_comm").text(message);
1222 $("#user_comm").removeClass("error success").addClass("success");
1225 commError: function (message) {
1226 $("#user_comm").text(message);
1227 $("#user_comm").removeClass("error success").addClass("error");
1231 $(window).load(function () {
1232 // if using .ready, ie triggers an error when trying to access
1233 // document.namespaces
1235 $("#newfeature_button").click(function () {
1236 Admin.addNewFeature();
1238 $("#editor_close").click(function () {
1239 Admin.cancelCurrentFeature()
1241 $("#feature_update").submit(function() {
1243 FeatureMgr.save(Admin.currentFeature);
1247 $("#feature_delete").submit(function() {
1249 FeatureMgr.del(Admin.currentFeature);
1253 $("#image_delete").click(function() {
1254 alert (SypStrings.DisabledForDemo);
1256 $("#img").removeAttr('src');
1257 // needs to rebuild element otherwise some browsers still
1259 $("#img").parent().html($("#img").parent().html());
1260 $("#img").parent().hide();
1261 $("#image_delete").hide();
1262 $("#image_file").parent().show();