X-Git-Url: https://dev.renevier.net/gitweb.cgi?p=syp.git;a=blobdiff_plain;f=js%2Fadmin.js;h=71daf2c7cc93ca4ecf6ad97dfa64ed98b9de34a8;hp=d950aeba91275e5055d3f0dda8f87508d8e3ea6b;hb=19730f2e2bbf61f389882c646f58349df3bcd848;hpb=3b38ca36fc18d34999073625a9c66dc2f05747a3 diff --git a/js/admin.js b/js/admin.js index d950aeb..71daf2c 100644 --- a/js/admin.js +++ b/js/admin.js @@ -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, @@ -176,6 +236,9 @@ var Admin = { }, closeEditor: function() { + if ($("#editor").css("display") == "none") { + return; + } if (this.currentFeature && this.currentFeature.layer) { this.selFeatureControl.unselect(this.currentFeature); } @@ -196,6 +259,8 @@ var Admin = { showEditor: function (feature) { $("#newfeature_button").hide(); + userMgr.close(); + if (feature.fid) { $("#delete").show(); } else { @@ -263,6 +328,8 @@ var Admin = { }, addNewFeature: function () { + userMgr.close(); + function cancel() { $(document).unbind("keydown"); Admin.reset() @@ -274,7 +341,7 @@ var Admin = { } }); - $("#newfeature_button").val("annuler"); + $("#newfeature_button").val(SypStrings.Cancel); $("#newfeature_button").unbind("click").click(cancel); $("#instructions").text(SypStrings.AddHowto); @@ -285,15 +352,18 @@ var Admin = { cancelCurrentFeature: function() { if (AjaxMgr.running) { - return; + return false; } var feature = this.currentFeature; - if (feature.fid) { - FeatureMgr.move (feature, this.currentFeatureLocation); - } else { - this.dataLayer.removeFeatures([feature]); + if (feature) { + if (feature.fid) { + FeatureMgr.move (feature, this.currentFeatureLocation); + } else { + this.dataLayer.removeFeatures([feature]); + } } this.closeEditor(); + return true; }, reloadLayer: function (layer) { @@ -424,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" }); }, @@ -452,30 +522,33 @@ 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": switch (xml.documentElement.getAttribute("reason")) { case "unauthorized": - $("#login_area").show(); - $("#password").val(""); - $("#user").val(sypSettings.loggedUser).focus().select(); + pwdMgr.reset(); $("#cookie_warning").show(); this.reset(); Admin.cancelCurrentFeature(); Admin.reset(); + userMgr.uninit(); break; case "server": this.commError(SypStrings.ServerError); @@ -505,7 +578,7 @@ var FeatureMgr = { $("#image_file").focus(); break; default: - this.commError(SypStrings.UnknownError); + this.commError(SypStrings.UnconsistentError); $("title").focus(); break; } @@ -591,12 +664,12 @@ var FeatureMgr = { commSuccess: function (message) { $("#server_comm").text(message); - $("#server_comm").removeClass().addClass("success"); + $("#server_comm").removeClass("error success").addClass("success"); }, commError: function (message) { $("#server_comm").text(message); - $("#server_comm").removeClass().addClass("error"); + $("#server_comm").removeClass("error success").addClass("error"); } } @@ -621,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 { @@ -644,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(); } @@ -666,6 +745,9 @@ var pwdMgr = { reset: function() { this.commError (""); + $("#login_area").show(); + $("#password").val(""); + $("#user").val(sypSettings.loggedUser).focus().select(); }, submit: function () { @@ -673,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 @@ -693,8 +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"); @@ -708,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": @@ -723,7 +811,7 @@ var pwdMgr = { this.commError(SypStrings.RequestError); break; default: - this.commError(SypStrings.UnknownError); + this.commError(SypStrings.UnconsistentError); break; } $("#login_error").show(); @@ -737,6 +825,10 @@ var pwdMgr = { user = $(xml).find("USER,user").text(); sypSettings.loggedUser = user; + if (sypSettings.loggedUser == "admin") { + userMgr.init(); + } + if (Admin.selFeatureControl) { Admin.selFeatureControl.destroy(); } @@ -771,6 +863,359 @@ var pwdMgr = { } } +var userMgr = { + _adduserDisplayed: 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").unbind("click").click(function () { + userMgr.toggleAddUser(); + return false; + }); + $("#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() { + this.close(); + $("#add_user").unbind("click"); + $("#add_user").hide(); + $("#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() { + if (this._adduserDisplayed) { + this.closeAddUser(); + } else { + this.showAddUser(); + } + }, + + showAddUser: function() { + if (!Admin.cancelCurrentFeature()) { + return; + } + + this.closeChangePass(); + + $(document).unbind("keydown").keydown(function(e) { + if (e.keyCode == 27) { + userMgr.closeAddUser() + e.preventDefault(); + } + }); + + $("#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() { + if (!this._adduserDisplayed) { + return; + } + $("#user_area, #newuser").hide(); + $(document).unbind("keydown"); + this._adduserDisplayed = false; + }, + + add: function() { + var newuser_name = $("#newuser_name").val(); + if (!newuser_name) { + this.commError(SypStrings.newUserNonameError); + $("#newuser_name").focus(); + return; + } + + var newuser_pass = $("#newuser_password").val(); + var newuser_pass_confirm = $("#newuser_password_confirm").val(); + if (newuser_pass != newuser_pass_confirm) { + 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), + 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) { + 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")) { + case "unauthorized": + pwdMgr.reset(); + $("#cookie_warning").show(); + Admin.reset(); + this.uninit(); + break; + case "server": + this.commError(SypStrings.ServerError); + if (this._adduserDisplayed) { + focusEl = $("#newuser_name"); + } else if (this._changepassDisplayed) { + focusEl = $("#pass_current"); + } + break; + case "request": + this.commError(SypStrings.RequestError); + 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); + focusEl = $("#newuser_name"); + break; + default: + this.commError(SypStrings.UnconsistentError); + if (this._adduserDisplayed) { + focusEl = $("#newuser_name"); + } else if (this._changepassDisplayed) { + focusEl = $("#pass_current"); + } + break; + } + break; + case "success": + switch (xml.documentElement.getAttribute("request")) { + case "newuser": + this.commSuccess(SypStrings.newUserSuccess); + needFormEnabling = false; + break; + case "changepass": + this.commSuccess(SypStrings.changePassSuccess); + needFormEnabling = false; + break; + default: + this.commError(SypStrings.UnconsistentError); + focusEl = $("newuser_name"); + break; + } + break; + default: + this.commError(SypStrings.UnconsistentError); + 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) { + $("#user_comm").text(message); + $("#user_comm").removeClass("error success").addClass("success"); + }, + + commError: function (message) { + $("#user_comm").text(message); + $("#user_comm").removeClass("error success").addClass("error"); + } +} + $(window).load(function () { // if using .ready, ie triggers an error when trying to access // document.namespaces @@ -803,5 +1248,6 @@ $(window).load(function () { $("#image_file").parent().show(); }); + userMgr.init(); Admin.init(); });