]> dev.renevier.net Git - syp.git/blobdiff - js/admin.js
fixes CHANGES.txt
[syp.git] / js / admin.js
index 8101799156f8b7ec4c0fda46692df9459e08eb54..71daf2c7cc93ca4ecf6ad97dfa64ed98b9de34a8 100644 (file)
@@ -1,6 +1,66 @@
 /* Copyright (c) 2009 Arnaud Renevier, Inc, published under the modified BSD
  * license. */
 
+/*
+ * Fix canvas rendering engine race condition. See js/syp.js for more explanation.
+ */
+OpenLayers.Renderer.Canvas.prototype = OpenLayers.Util.extend({
+    needsRedraw: false,
+    imagesLoading: 0,
+}, OpenLayers.Renderer.Canvas.prototype);
+OpenLayers.Renderer.Canvas.prototype.oldRedraw = OpenLayers.Renderer.Canvas.prototype.redraw;
+OpenLayers.Renderer.Canvas.prototype.redraw = function() {
+    if (this.imagesLoading > 0) {
+        this.needsRedraw = true;
+        return;
+    }
+    OpenLayers.Renderer.Canvas.prototype.oldRedraw.apply(this, arguments);
+}
+OpenLayers.Renderer.Canvas.prototype.drawExternalGraphic = function(pt, style) {
+    var img = new Image();
+    img.src = style.externalGraphic;
+       
+    if(style.graphicTitle) {
+        img.title=style.graphicTitle;           
+    }
+
+    var width = style.graphicWidth || style.graphicHeight;
+    var height = style.graphicHeight || style.graphicWidth;
+    width = width ? width : style.pointRadius*2;
+    height = height ? height : style.pointRadius*2;
+    var xOffset = (style.graphicXOffset != undefined) ?
+        style.graphicXOffset : -(0.5 * width);
+   var yOffset = (style.graphicYOffset != undefined) ?
+       style.graphicYOffset : -(0.5 * height);
+   var opacity = style.graphicOpacity || style.fillOpacity;
+       
+   var context = { img: img, 
+                   x: (pt[0]+xOffset), 
+                   y: (pt[1]+yOffset), 
+                   width: width, 
+                   height: height, 
+                   canvas: this.canvas };
+
+   var self = this;
+   this.imagesLoading++;
+   img.onerror = function() {
+       self.imagesLoading--;
+       if ((self.imagesLoading == 0) && (self.needsRedraw)) {
+           self.needsRedraw = false;
+           self.redraw();
+       }
+   }
+   img.onload = OpenLayers.Function.bind( function() {
+       self.imagesLoading--;
+       if ((self.imagesLoading == 0) && (self.needsRedraw)) {
+           self.needsRedraw = false;
+           self.redraw();
+       } else {
+            this.canvas.drawImage(this.img, this.x, 
+                             this.y, this.width, this.height);
+       }
+   }, context);   
+}
 // drag feature with tolerance
 OpenLayers.Control.SypDragFeature = OpenLayers.Class (OpenLayers.Control.DragFeature, {
     startPixel: null,
@@ -199,7 +259,7 @@ var Admin = {
 
     showEditor: function (feature) {
         $("#newfeature_button").hide();
-        userMgr.closeAddUser();
+        userMgr.close();
 
         if (feature.fid) {
             $("#delete").show();
@@ -268,7 +328,7 @@ var Admin = {
     },
 
     addNewFeature: function () {
-        userMgr.closeAddUser();
+        userMgr.close();
 
         function cancel() {
             $(document).unbind("keydown");
@@ -281,7 +341,7 @@ var Admin = {
             }
         });
 
-        $("#newfeature_button").val("annuler");
+        $("#newfeature_button").val(SypStrings.Cancel);
         $("#newfeature_button").unbind("click").click(cancel);
 
         $("#instructions").text(SypStrings.AddHowto);
@@ -434,7 +494,7 @@ var FeatureMgr = {
         AjaxMgr.add({
             form: form,
             oncomplete: OpenLayers.Function.bind(this.ajaxReply, this),
-            onsend: function() { $("#editor_throbber").css("visibility", "visible"); }
+            throbberid: "editor_throbber"
         });
     },
 
@@ -462,18 +522,22 @@ var FeatureMgr = {
         AjaxMgr.add({
             form: form,
             oncomplete: OpenLayers.Function.bind(this.ajaxReply, this),
-            onsend: function() { $("#editor_throbber").css("visibility", "visible"); }
+            throbberid: "editor_throbber"
         });
     },
 
     ajaxReply: function (data) {
-        $("#editor_throbber").css("visibility", "hidden");
         if (!data) {
             this.commError(SypStrings.ServerError);
             return;
         }
 
         var xml = new OpenLayers.Format.XML().read(data);
+        if (!xml.documentElement) {
+            this.commError(SypStrings.UnconsistentError);
+            $("title").focus();
+            return;
+        }
 
         switch (xml.documentElement.nodeName.toLowerCase()) {
             case "error":
@@ -630,6 +694,9 @@ var AjaxMgr = {
         $('#api_frame').one("load", function() {
             self.running = false;
             self._reqEnd();
+            if (query.throbberid) {
+                $("#" + query.throbberid).css("visibility", "hidden");
+            }
             if (typeof (query.oncomplete) == "function") {
                 var body = null;
                 try {
@@ -653,6 +720,9 @@ var AjaxMgr = {
         query.form.attr("method", "post");
         this.running = true;
         query.form.get(0).submit();
+        if (query.throbberid) {
+            $("#" + query.throbberid).css("visibility", "visible");
+        }
         if (typeof (query.onsend) == "function") {
             query.onsend();
         }
@@ -685,8 +755,8 @@ var pwdMgr = {
             pwdMgr.commError("");
             var req = {
                 form:  $("#login_form"),
+                throbberid: "pwd_throbber",
                 onsend: function() {
-                    $("#pwd_throbber").css("visibility", "visible");
                     $("#login_error").hide();
 
                     // we need a timeout; otherwise those fields will not be submitted
@@ -705,7 +775,6 @@ var pwdMgr = {
     },
 
     ajaxReply: function (data) {
-        $("#pwd_throbber").css("visibility", "hidden");
         // here, we need a timeout because onsend timeout sometimes has not been triggered yet
         window.setTimeout(function() {
             $("#login_submit, #user, #password").removeAttr("disabled");
@@ -719,7 +788,15 @@ var pwdMgr = {
             }, 0);
             return;
         }
+
         var xml = new OpenLayers.Format.XML().read(data);
+        if (!xml.documentElement) {
+            this.commError(SypStrings.UnconsistentError);
+            $("#login_error").show();
+            window.setTimeout(function() {
+                    $("#user").focus().select();
+            }, 0);
+        }
 
         switch (xml.documentElement.nodeName.toLowerCase()) {
             case "error":
@@ -788,38 +865,153 @@ var pwdMgr = {
 
 var userMgr = {
     _adduserDisplayed: false,
-    _deluserDisplayed: false,
+    _changepassDisplayed: false,
 
     init: function() {
+        $("#user_close").unbind("click").click(function () {
+            userMgr.close()
+        });
+
+        $("#change_pass").unbind("click").click(function() {
+            userMgr.toggleChangePass();
+            return false;
+        });
+        $("#changepass").unbind("submit").submit(function() {
+            try {
+                userMgr.changepass();
+            } catch(e) {}
+            return false;
+        });
+
         if (sypSettings.loggedUser != "admin") {
             return;
         }
 
         $("#add_user").show();
-
-        $("#add_user").click(function () {
+        $("#add_user").unbind("click").click(function () {
             userMgr.toggleAddUser();
             return false;
         });
-        $("#newuser_close").click(function () {
-            userMgr.closeAddUser()
-        });
-        $("#newuser").submit(function() {
+        $("#newuser").unbind("submit").submit(function() {
             try {
                 userMgr.add();
             } catch(e) {}
             return false;
         });
+
+    },
+
+    disableForms: function() {
+        $("#newuser_name, #newuser_password, #newuser_password_confirm, #newuser_submit").attr("disabled", "disabled");
+        $("#pass_current, #pass_new, #pass_new_confirm, #pass_submit").attr("disabled", "disabled");
+    },
+
+    enableForms: function() {
+        $("#newuser_name, #newuser_password, #newuser_password_confirm, #newuser_submit").removeAttr("disabled");
+        $("#pass_current, #pass_new, #pass_new_confirm, #pass_submit").removeAttr("disabled");
+    },
+
+    resetForms: function() {
+        $("#newuser_name, #newuser_password, #newuser_password_confirm").val("");
+        $("#pass_current, #pass_new, #pass_new_confirm").val("");
     },
 
     uninit: function() {
-        if (this._adduserDisplayed) {
-            this.closeAddUser();
-        }
+        this.close();
         $("#add_user").unbind("click");
         $("#add_user").hide();
-        $("#newuser_close").unbind("click");
+        $("#change_pass").unbind("click");
+        $("#user_close").unbind("click");
         $("#newuser").unbind("submit");
+        $("#changepass").unbind("submit");
+    },
+
+    close: function() {
+        this.closeChangePass();
+        this.closeAddUser();
+    },
+
+    toggleChangePass: function() {
+        if (this._changepassDisplayed) {
+            this.closeChangePass();
+        } else {
+            this.showChangePass();
+        }
+    },
+
+    showChangePass: function() {
+        if (!Admin.cancelCurrentFeature()) {
+            return;
+        }
+        this.closeAddUser();
+
+        $(document).unbind("keydown").keydown(function(e) { 
+            if (e.keyCode == 27) {
+                userMgr.closeChangePass()
+                e.preventDefault();
+            }
+        });
+
+        this.resetForms();
+        this.enableForms();
+        $("#user_area, #changepass").show();
+        this.commError("");
+
+        // XXX: setTimeout needed because otherwise, map becomes hidden in IE. Why ??
+        window.setTimeout(function() { 
+            $("#pass_current").focus();
+        }, 0);
+
+        this._changepassDisplayed = true;
+    },
+
+    closeChangePass: function() {
+        if (!this._changepassDisplayed) {
+            return;
+        }
+        $("#user_area, #changepass").hide();
+        $(document).unbind("keydown");
+        this._changepassDisplayed = false;
+    },
+
+    changepass: function() {
+        var newpass = $("#pass_new").val();
+        var newpass_confirm = $("#pass_new_confirm").val();
+        if (newpass != newpass_confirm) {
+            this.commError(SypStrings.userPasswordmatchError);
+            $("#pass_new").focus().select();
+            return;
+        }
+
+        if (!newpass) {
+            this.commError(SypStrings.emptyPasswordError);
+            $("#pass_new").focus().select();
+            return;
+        }
+
+        var curpass = $("#pass_current").val();
+        if (newpass == curpass) {
+            this.commError(SypStrings.changeSamePass);
+            $("#pass_new").focus().select();
+            return;
+        }
+
+        this.commError("");
+
+        AjaxMgr.add({
+            form: $("#changepass"),
+            oncomplete: OpenLayers.Function.bind(this.ajaxReply, this),
+            throbberid: "user_throbber",
+            onsend: function() { 
+                // we need a timeout; otherwise those fields will not be submitted
+                window.setTimeout(function() {
+                    // removes focus from #password before disabling it. Otherwise, opera
+                    // prevents re-focusing it after re-enabling it.
+                    $("#pass_current, #pass_new, #pass_new_confirm").blur(); 
+                    userMgr.disableForms();
+                }, 0);
+            }
+        });
     },
 
     toggleAddUser: function() {
@@ -835,6 +1027,8 @@ var userMgr = {
             return;
         }
 
+        this.closeChangePass();
+
         $(document).unbind("keydown").keydown(function(e) { 
             if (e.keyCode == 27) {
                 userMgr.closeAddUser()
@@ -842,18 +1036,24 @@ var userMgr = {
             }
         });
 
-        Admin.reset();
-        $("#newuser_area").show();
-        $("#newuser_name, #newuser_password, #newuser_password_confirm").val("");
-        $("#newuser_name, #newuser_password, #newuser_password_confirm, #newuser_submit").removeAttr('disabled');
-        $("#newuser_name").focus();;
+        $("#user_area, #newuser").show();
+        this.resetForms();
+        this.enableForms();
         this.commError("");
 
+        // XXX: setTimeout needed because otherwise, map becomes hidden in IE. Why ??
+        window.setTimeout(function() { 
+            $("#newuser_name").focus();
+        }, 0);
+
         this._adduserDisplayed = true;
     },
 
     closeAddUser: function() {
-        $("#newuser_area").hide();
+        if (!this._adduserDisplayed) {
+            return;
+        }
+        $("#user_area, #newuser").hide();
         $(document).unbind("keydown");
         this._adduserDisplayed = false;
     },
@@ -869,28 +1069,60 @@ var userMgr = {
         var newuser_pass = $("#newuser_password").val();
         var newuser_pass_confirm = $("#newuser_password_confirm").val();
         if (newuser_pass != newuser_pass_confirm) {
-            this.commError(SypStrings.newUserPasswordmatchError);
+            this.commError(SypStrings.userPasswordmatchError);
             $("#newuser_password").focus().select();
             return;
         }
 
+        if (!newuser_pass) {
+            this.commError(SypStrings.emptyPasswordError);
+            $("#pass_new").focus().select();
+            return;
+        }
+
         this.commError("");
 
         AjaxMgr.add({
             form: $("#newuser"),
             oncomplete: OpenLayers.Function.bind(this.ajaxReply, this),
-            onsend: function() { $("#newuser_throbber").css("visibility", "visible"); }
+            throbberid: "user_throbber",
+            onsend: function() { 
+                // we need a timeout; otherwise those fields will not be submitted
+                window.setTimeout(function() {
+                    // removes focus from #password before disabling it. Otherwise, opera
+                    // prevents re-focusing it after re-enabling it.
+                    $("#newuser_name, #newuser_password, #newuser_password_confirm").blur(); 
+                    userMgr.disableForms();
+                }, 0);
+            }
         });
     },
 
     ajaxReply: function (data) {
-        $("#newuser_throbber").css("visibility", "hidden");
         if (!data) {
+            // here, we need a timeout because onsend timeout sometimes has not been triggered yet
+            var self = this;
+            window.setTimeout(function() {
+                self.enableForms();
+             }, 0);
             this.commError(SypStrings.ServerError);
             return;
         }
 
         var xml = new OpenLayers.Format.XML().read(data);
+        if (!xml.documentElement) {
+            // here, we need a timeout because onsend timeout sometimes has not been triggered yet
+            var self = this;
+            window.setTimeout(function() {
+                self.enableForms();
+             }, 0);
+            this.commError(SypStrings.UnconsistentError);
+            return;
+        }
+
+        var needFormEnabling = true;
+        var focusEl = null;
+
         switch (xml.documentElement.nodeName.toLowerCase()) {
             case "error":
                 switch (xml.documentElement.getAttribute("reason")) {
@@ -902,19 +1134,35 @@ var userMgr = {
                     break;
                     case "server":
                         this.commError(SypStrings.ServerError);
-                        $("#newuser_name").focus().select();
+                        if (this._adduserDisplayed) {
+                            focusEl = $("#newuser_name");
+                        } else if (this._changepassDisplayed) {
+                            focusEl = $("#pass_current");
+                        }
                     break;
                     case "request":
                         this.commError(SypStrings.RequestError);
-                        $("#newuser_name").focus().select();
+                        if (this._adduserDisplayed) {
+                            focusEl = $("#newuser_name");
+                        } else if (this._changepassDisplayed) {
+                            focusEl = $("#pass_current");
+                        }
+                    break;
+                    case "wrongpass":
+                        this.commError(SypStrings.changePassBadPass);
+                        focusEl = $("#pass_current");
                     break;
                     case "newuser_exists":
                         this.commError(SypStrings.newUserExistsError);
-                        $("#newuser_name").focus().select();
+                        focusEl = $("#newuser_name");
                     break;
                     default:
                         this.commError(SypStrings.UnconsistentError);
-                        $("#newuser_name").focus().select();
+                        if (this._adduserDisplayed) {
+                            focusEl = $("#newuser_name");
+                        } else if (this._changepassDisplayed) {
+                            focusEl = $("#pass_current");
+                        }
                     break;
                 }
             break;
@@ -922,29 +1170,49 @@ var userMgr = {
                 switch (xml.documentElement.getAttribute("request")) {
                     case "newuser":
                         this.commSuccess(SypStrings.newUserSuccess);
-                        $("#newuser_name, #newuser_password, #newuser_password_confirm, #newuser_submit").attr('disabled', 'disabled');
+                        needFormEnabling = false;
+                    break;
+                    case "changepass":
+                        this.commSuccess(SypStrings.changePassSuccess);
+                        needFormEnabling = false;
                     break;
                     default:
                         this.commError(SypStrings.UnconsistentError);
-                        $("newuser_name").focus().select();
+                        focusEl = $("newuser_name");
                     break;
                 }
             break;
             default:
                 this.commError(SypStrings.UnconsistentError);
-                $("newuser_name").focus().select();
+                focusEl = $("newuser_name");
             break;
         }
+
+        if (needFormEnabling) {
+            // here, we need a timeout because onsend timeout sometimes has not been triggered yet
+            var self = this;
+            window.setTimeout(function() {
+                self.enableForms();
+                if (focusEl) {
+                    focusEl.select().focus();
+                }
+             }, 0);
+        } else {
+            if (focusEl) {
+                focusEl.focus().select();
+            }
+        }
+
     },
 
     commSuccess: function (message) {
-        $("#newuser_comm").text(message);
-        $("#newuser_comm").removeClass("error success").addClass("success");
+        $("#user_comm").text(message);
+        $("#user_comm").removeClass("error success").addClass("success");
     },
 
     commError: function (message) {
-        $("#newuser_comm").text(message);
-        $("#newuser_comm").removeClass("error success").addClass("error");
+        $("#user_comm").text(message);
+        $("#user_comm").removeClass("error success").addClass("error");
     }
 }