]> dev.renevier.net Git - syj.git/blobdiff - public/js/syj.js
ajax for account creation to known if a pseudo is available
[syj.git] / public / js / syj.js
index efff5ea89325c840aed04f7f4888e88453e572a9..44dd2ff6d4aba093b7b363fe6594e7f5ac095553 100644 (file)
@@ -1,19 +1,5 @@
 /*  This file is part of Syj, Copyright (c) 2010 Arnaud Renevier,
     and is published under the AGPL license. */
-Element.addMethods('input', {
-    observe : Element.Methods.observe.wrap(function(proceed, element, eventName, handler) {
-        if (eventName === "contentchange") {
-            proceed(element, 'keyup', function(evt) {
-                if (evt.keyCode == 13) {
-                    return;
-                }
-                handler.apply(null, arguments);
-            });
-            return proceed(element, 'change', handler);
-        }
-        return proceed(element, eventName, handler);
-    })
-});
 
 // avoid openlayers alerts
 OpenLayers.Console.userError = function(error) {
@@ -46,8 +32,7 @@ var SyjSaveUI = {
         }
         this.enableSubmit();
         $("geom_title").disabled = false;
-        $("geom_title").focus();
-        $("geom_title").select();
+        $("geom_title").activate();
         $("geomform").removeClassName("disabled");
         this.status = "enabled";
         return this;
@@ -80,10 +65,6 @@ var SyjSaveUI = {
 };
 
 var SyjEditUI = {
-    init: function() {
-        return this;
-    },
-
     hide: function() {
         $("edit-btn").blur();
         $("edit-btn").hide();
@@ -231,7 +212,7 @@ var SYJView = {
     needsFormResubmit: false,
 
     init: function() {
-        var externalGraphic, baseURL, baseLayer, layerOptions, extent = null, hidemessenger;
+        var externalGraphic, baseURL, baseLayer, layerOptions, extent, hidemessenger;
 
         // is svg context, opera does not resolve links with base element is svg context
         externalGraphic = styleMap.edit.styles.select.defaultStyle.externalGraphic;
@@ -252,8 +233,8 @@ var SYJView = {
         layerOptions = {format:     OpenLayers.Format.WKT,
                         projection: WGS84,
                         styleMap:   styleMap.view};
-        if (gLoggedInfo.ownername) {
-            layerOptions.attribution = SyjStrings.routeBy + ' ' + '<strong>' + gLoggedInfo.ownername + '</strong>';
+        if (gLoggedInfo.creatorname) {
+            layerOptions.attribution = SyjStrings.routeBy + ' ' + '<strong>' + gLoggedInfo.creatorname + '</strong>';
         }
 
         this.viewLayer = new OpenLayers.Layer.Vector("View Layer", layerOptions);
@@ -263,7 +244,6 @@ var SYJView = {
             this.messenger.hide();
             this.editMode();
         }).bind(this));
-        SyjEditUI.init().hide();
 
         $("geomform").ajaxize({
                 presubmit: this.prepareForm.bind(this),
@@ -283,18 +263,15 @@ var SYJView = {
             this.messenger.hide();
         }
 
-        extent = null;
         if ($("geom_data").value) {
             this.viewLayer.addFeatures([this.wkt.read($("geom_data").value)]);
             extent = this.viewLayer.getDataExtent();
             // XXX: ie has not guessed height of map main div yet during map
             // initialisation. Now, it will read it correctly.
             this.map.updateSize();
-            SyjEditUI.show();
         } else {
             extent = new OpenLayers.Bounds(gMaxExtent.minlon, gMaxExtent.minlat, gMaxExtent.maxlon, gMaxExtent.maxlat)
                                          .transform(WGS84, Mercator);
-            this.editMode();
         }
         this.map.zoomToExtent(extent);
         document.observe('simplebox:shown', this.observer.bindAsEventListener(this));
@@ -307,6 +284,13 @@ var SYJView = {
     },
 
     prepareForm: function(form) {
+        if (!LoginMgr.logged && !$("geom_accept").checked) {
+            this.messenger.setMessage(SyjStrings.acceptTermsofuseWarn, "warn");
+            $("geom_accept_container").highlight('#F08080');
+            $("geom_accept").activate();
+            return false;
+        }
+
         var line, realPoints, idx, handler;
 
         line = new OpenLayers.Geometry.LineString();
@@ -327,6 +311,7 @@ var SYJView = {
         this.needsFormResubmit = false;
         SyjSaveUI.disable.bind(SyjSaveUI).defer();
         this.messenger.hide();
+        return true;
     },
 
     editMode: function() {
@@ -394,12 +379,12 @@ var SYJView = {
     },
 
     saveSuccess: function(transport) {
-      if (!$("geom_id").value) {
-          location = "idx/" + transport.responseText;
+      if (transport.responseJSON && (typeof transport.responseJSON.redirect === "string")) {
+          location = transport.responseJSON.redirect;
           return;
       }
-      this.messenger.setMessage(SyjStrings.saveSuccess, "success");
 
+      this.messenger.setMessage(SyjStrings.saveSuccess, "success");
       SyjSaveUI.hide();
       SyjEditUI.show();
       document.title = $('geom_title').value;
@@ -411,20 +396,15 @@ var SYJView = {
         if (transport) {
             httpCode = transport.getStatus();
         }
-        message = "";
         switch (httpCode) {
             case 0:
                 message = SyjStrings.notReachedError;
             break;
             case 400:
             case 404:
-            case 410:
-                message = SyjStrings.requestError; // default message
+                message = SyjStrings.requestError;
                 if (transport.responseJSON) {
                     switch (transport.responseJSON.message) {
-                        case "unreferenced":
-                            message = SyjStrings.unreferencedError;
-                        break;
                         case "uniquepath":
                             message = SyjStrings.uniquePathError;
                         break;
@@ -435,13 +415,12 @@ var SYJView = {
             break;
             case 403:
                 message = "";
-                this.needsFormResubmit = true;
-                if (loginMgr.hasAlreadyConnected()) {
-                    SYJLogin.messenger.setMessage(SyjStrings.cookiesNeeded, "warn");
-                } else {
-                    SYJLogin.messenger.setMessage(SyjStrings.loginNeeded, "warn");
-                }
+                SYJLogin.messenger.setMessage(SyjStrings.loginNeeded, "warn");
                 SYJLogin.modalbox.show();
+                this.needsFormResubmit = true;
+            break;
+            case 410:
+                message = SyjStrings.gonePathError;
             break;
             case 500:
                 message = SyjStrings.serverError;
@@ -491,7 +470,7 @@ var SYJModalClass = Class.create({
     checkNotEmpty: function(input, message) {
         if ($(input).value.strip().empty()) {
             this.messenger.setMessage(message, "warn");
-            $(input).highlight('#F08080').focus();
+            $(input).highlight('#F08080').activate();
             return false;
         }
         return true;
@@ -505,8 +484,7 @@ var SYJModalClass = Class.create({
             if (simplebox === this.modalbox) {
                 input = this.area.select('input[type="text"]')[0];
                 (function () {
-                    input.focus();
-                    input.select();
+                    input.activate();
                 }).defer();
             } else {
                 this.modalbox.hide();
@@ -543,8 +521,7 @@ var SYJModalClass = Class.create({
 
         this.messenger.setMessage(message, "error");
         input = this.area.select('input[type="text"]')[0];
-        input.highlight('#F08080').focus();
-        input.select();
+        input.highlight('#F08080').activate();
     },
 
     reset: function() {
@@ -561,7 +538,7 @@ var SYJUserClass = Class.create(SYJModalClass, {
         $super();
         $("termsofusearea").hide();
 
-        $("user_termsofuse_anchor").observe("click", function(evt) {
+        $$("#user_termsofuse_anchor, #geom_termsofuse_anchor").invoke('observe', "click", function(evt) {
             if (!this.toubox) {
                 $("termsofusearea").show();
                 $("termsofuseiframe").setAttribute("src", evt.target.href);
@@ -579,6 +556,19 @@ var SYJUserClass = Class.create(SYJModalClass, {
                 evt.stop();
             }.bindAsEventListener(this));
 
+        $("user_pseudo-desc").hide();
+        $("user_pseudo").observe('contentchange', function(evt) {
+            var value = evt.target.value;
+            PseudoChecker.reset();
+            if (value && !(value.match(/^[a-zA-Z0-9_.]+$/))) {
+                $("user_pseudo-desc").show().setMessageStatus("warn");
+            } else {
+                $("user_pseudo-desc").hide();
+            }
+        }).timedobserve(function() {
+            PseudoChecker.check();
+        });
+
         $("user_password").observe('contentchange', function(evt) {
             if (evt.target.value.length < 6) {
                 $("user_password-desc").setMessageStatus("warn");
@@ -586,17 +576,37 @@ var SYJUserClass = Class.create(SYJModalClass, {
                 $("user_password-desc").setMessageStatus("success");
             }
         }.bindAsEventListener(this));
+
+        $("account-info").hide();
+        $("account-info-bullet").observe('click', function(evt) {
+            var elt = $("account-info");
+            if (elt.visible()) {
+                evt.target.src = "icons/bullet_arrow_right.png";
+                elt.hide();
+            } else {
+                evt.target.src = "icons/bullet_arrow_down.png";
+                elt.show();
+            }
+            evt.stop();
+        });
     },
 
     presubmit: function() {
+        this.messenger.hide();
+        PseudoChecker.reset();
         if (!(this.checkNotEmpty("user_pseudo", SyjStrings.userEmptyWarn))) {
             return false;
         }
 
-        if (!($("user_pseudo").value.match(/[a-zA-Z0-9_.]+$/))) {
-            this.messenger.setMessage(SyjStrings.invalidPseudo, "warn");
-            $("user_pseudo").highlight('#F08080').focus();
-            $("user_pseudo").select();
+        if (!($("user_pseudo").value.match(/^[a-zA-Z0-9_.]+$/))) {
+            $("user_pseudo-desc").show().setMessageStatus("warn");
+            $("user_pseudo").highlight('#F08080').activate();
+            return false;
+        }
+
+        if (PseudoChecker.exists[$("user_pseudo").value]) {
+            PseudoChecker.availableMessage(false);
+            $("user_pseudo").highlight('#F08080').activate();
             return false;
         }
 
@@ -606,15 +616,13 @@ var SYJUserClass = Class.create(SYJModalClass, {
 
         if ($("user_password").value.length < 6) {
             $("user_password-desc").setMessageStatus("warn");
-            $("user_password").highlight('#F08080').focus();
-            $("user_password").select();
+            $("user_password").highlight('#F08080').activate();
             return false;
         }
 
         if ($("user_password").value !== $("user_password_confirm").value) {
             this.messenger.setMessage(SyjStrings.passwordNoMatchWarn, "warn");
-            $("user_password").highlight('#F08080').focus();
-            $("user_password").select();
+            $("user_password").highlight('#F08080').activate();
             return false;
         }
 
@@ -624,7 +632,8 @@ var SYJUserClass = Class.create(SYJModalClass, {
 
         if (!$("user_accept").checked) {
             this.messenger.setMessage(SyjStrings.acceptTermsofuseWarn, "warn");
-            $("user_accept").highlight('#F08080').focus();
+            $("user_accept_container").highlight('#F08080');
+            $("user_accept").activate();
             return false;
         }
 
@@ -633,12 +642,12 @@ var SYJUserClass = Class.create(SYJModalClass, {
     },
 
     success: function(transport) {
-        loginMgr.login();
+        LoginMgr.login();
         SYJView.messenger.setMessage(SyjStrings.userSuccess, "success");
         this.modalbox.hide();
         if (SYJView.needsFormResubmit) {
             SYJView.messenger.addMessage(SyjStrings.canResubmit);
-            $("geom_submit").focus();
+            $("geom_submit").activate();
         }
     },
 
@@ -661,7 +670,7 @@ var SYJUserClass = Class.create(SYJModalClass, {
                             focusInput = $("user_email");
                         break;
                         case "uniquepseudo":
-                            message = SyjStrings.uniqueUserError;
+                            PseudoChecker.availableMessage(false);
                             focusInput = $("user_pseudo");
                         break;
                         case "uniqueemail":
@@ -673,12 +682,11 @@ var SYJUserClass = Class.create(SYJModalClass, {
             break;
         }
 
-        if (message) {
-            this.messenger.setMessage(message, "error");
-            if (focusInput) {
-                focusInput.highlight('#F08080').focus();
-                focusInput.select();
+        if (focusInput) {
+            if (message) {
+                this.messenger.setMessage(message, "error");
             }
+            focusInput.highlight('#F08080').activate();
             return;
         }
 
@@ -695,6 +703,7 @@ var SYJLoginClass = Class.create(SYJModalClass, {
     },
 
     presubmit: function() {
+        this.messenger.hide();
         if (!(this.checkNotEmpty("login_user", SyjStrings.userEmptyWarn))) {
             return false;
         }
@@ -705,15 +714,15 @@ var SYJLoginClass = Class.create(SYJModalClass, {
 
     success: function(transport) {
         if (transport.responseText === "1") {
-            loginMgr.login(true);
+            LoginMgr.login(true);
         } else {
-            loginMgr.login();
+            LoginMgr.login();
         }
         SYJView.messenger.setMessage(SyjStrings.loginSuccess, "success");
         this.modalbox.hide();
         if (SYJView.needsFormResubmit) {
             SYJView.messenger.addMessage(SyjStrings.canResubmit);
-            $("geom_submit").focus();
+            $("geom_submit").activate();
         }
     },
 
@@ -737,8 +746,7 @@ var SYJLoginClass = Class.create(SYJModalClass, {
         if (message) {
             this.messenger.setMessage(message, "error");
             if (focusInput) {
-                focusInput.highlight('#F08080').focus();
-                focusInput.select();
+                focusInput.highlight('#F08080').activate();
             }
             return;
         }
@@ -766,7 +774,7 @@ var SYJNewpwdClass = Class.create(SYJModalClass, {
 });
 var SYJNewpwd = new SYJNewpwdClass();
 
-var loginMgr = Object.extend(gLoggedInfo, {
+var LoginMgr = Object.extend(gLoggedInfo, {
     controlsdeck: null,
 
     updateUI: function() {
@@ -775,37 +783,128 @@ var loginMgr = Object.extend(gLoggedInfo, {
         }
         if (this.logged) {
             this.controlsdeck.setIndex(1);
+            $$(".logged-hide").invoke('hide');
+            $$(".logged-show").invoke('show');
         } else {
             this.controlsdeck.setIndex(0);
+            $$(".logged-hide").invoke('show');
+            $$(".logged-show").invoke('hide');
         }
 
-        if (this.isowner) {
+        if (this.iscreator) {
             $("data_controls").show();
         } else {
             $("data_controls").hide();
         }
     },
 
-    login: function(aIsOwner) {
-        if (typeof aIsOwner === "boolean") {
-            this.isowner = aIsOwner;
+    login: function(aIsCreator) {
+        if (typeof aIsCreator === "boolean") {
+            this.iscreator = aIsCreator;
         }
         this.logged = true;
-        this.connections++;
         this.updateUI();
+    }
+});
+
+var PseudoChecker = {
+    req: null,
+    exists: {},
+    currentvalue: null,
+    messageelt: null,
+    throbber: null,
+
+    message: function(str, status, throbber) {
+        var row;
+        if (!this.messageelt) {
+            row = new Element('tr');
+            // we can't use row.update('<td></td><td><div></div></td>')
+            // because gecko would mangle the <td>s
+            row.insert(new Element('td'))
+               .insert((new Element('td')).update(new Element('div')));
+
+            $("user_pseudo").up('tr').insert({after: row});
+            this.messageelt = new Element('span');
+            this.throbber = new Element("img", { src: "icons/pseudo-throbber.gif"});
+            row.down('div').insert(this.throbber).insert(this.messageelt);
+        }
+        if (throbber) {
+            this.throbber.show();
+        } else {
+            this.throbber.hide();
+        }
+        this.messageelt.up().setStyle({visibility: ''});
+        this.messageelt.className = status;
+        this.messageelt.update(str);
     },
 
-    // needed in case of 403 errors: if user has already connected successfully
-    // before, it probably means he has cookies disabled
-    hasAlreadyConnected: function() {
-        return (this.connections >= 1);
+    availableMessage: function(available) {
+        var message = available ? SyjStrings.availablePseudo: SyjStrings.unavailablePseudo,
+            status = available ? "success": "warn";
+        this.message(message, status, false);
+    },
+
+    reset: function() {
+        if (this.req) {
+            this.req.abort();
+            this.req = this.currentvalue = null;
+        }
+        if (this.messageelt) {
+            this.messageelt.up().setStyle({visibility: 'hidden'});
+        }
+    },
+
+    check: function() {
+        var pseudo = $("user_pseudo").value;
+
+        this.reset();
+
+        if (!pseudo || !(pseudo.match(/^[a-zA-Z0-9_.]+$/))) {
+            return;
+        }
+
+        if (typeof this.exists[pseudo] === "boolean") {
+            this.reset();
+            this.availableMessage(!this.exists[pseudo]);
+            return;
+        }
+
+        this.message(SyjStrings.pseudoChecking, "", true);
+
+        this.currentvalue = pseudo;
+        this.req = new Ajax.TimedRequest('userexists/' + encodeURIComponent(pseudo), 20, {
+            onFailure: this.failure.bind(this),
+            onSuccess: this.success.bind(this)
+        });
+    },
+
+    failure: function(transport) {
+        var httpCode = 0, value = this.currentvalue;
+
+        if (transport) {
+            httpCode = transport.getStatus();
+        }
+        this.reset();
+        if (httpCode === 404) {
+            this.exists[value] = false;
+            this.availableMessage(true);
+        }
+
+    },
+
+    success: function(transport) {
+        var httpCode = transport.getStatus(), value = this.currentvalue;
+        this.reset();
+        this.exists[value] = true;
+        this.availableMessage(false);
     }
-});
+};
+
 
 document.observe("dom:loaded", function() {
     SYJLogin.init();
     SYJUser.init();
     SYJView.init();
     SYJNewpwd.init();
-    loginMgr.updateUI();
+    LoginMgr.updateUI();
 });