diff --git a/resources/static/dialog/controllers/authenticate_controller.js b/resources/static/dialog/controllers/authenticate_controller.js index c025f0e65cb942f13be574f18f970f5ef6d595de..f6b4157abf13b4ff7ecc28e060dcdc2aaa96fe04 100644 --- a/resources/static/dialog/controllers/authenticate_controller.js +++ b/resources/static/dialog/controllers/authenticate_controller.js @@ -51,7 +51,7 @@ return helpers.getAndValidateEmail("#email"); } - function checkEmail(el, event) { + function checkEmail(event) { var email = getEmail(), self = this; @@ -69,7 +69,7 @@ }, self.getErrorDialog(errors.isEmailRegistered)); } - function createUser(el, event) { + function createUser(event) { var self=this, email = getEmail(); @@ -80,7 +80,7 @@ } } - function authenticate(el, event) { + function authenticate(event) { var email = getEmail(), pass = helpers.getAndValidatePassword("#password"), self = this; @@ -96,7 +96,7 @@ } } - function resetPassword(el, event) { + function resetPassword(event) { var email = getEmail(); cancelEvent(event); @@ -117,17 +117,14 @@ if (event) event.preventDefault(); } - function enterEmailState(el, event) { - // Enter key, do nothing - if (event && event.which === 13) return; - + function enterEmailState(el) { if (!el.is(":disabled")) { this.submit = checkEmail; animateSwap(".returning:visible,.newuser:visible,.forgot:visible", ".start"); } } - function enterPasswordState(el, event) { + function enterPasswordState(event) { cancelEvent(event); var self=this; @@ -138,7 +135,7 @@ }); } - function forgotPasswordState(el, event) { + function forgotPasswordState(event) { cancelEvent(event); this.submit = resetPassword; @@ -147,14 +144,14 @@ animateSwap(".start:visible,.newuser:visible,.returning:visible", ".forgot"); } - function cancelForgotPassword(el, event) { + function cancelForgotPassword(event) { cancelEvent(event); dom.removeAttr("#email", "disabled"); enterPasswordState.call(this); } - function createUserState(el, event) { + function createUserState(event) { cancelEvent(event); var self=this; @@ -165,33 +162,35 @@ } + function emailKeyUp(event) { + var newEmail = dom.getInner(event.target); + if (newEmail !== lastEmail) { + lastEmail = newEmail; + enterEmailState.call(this, $(event.target)); + } + } + PageController.extend("Authenticate", {}, { - init: function(el, options) { - options = options || {}; - - this._super(el, { - bodyTemplate: "authenticate", - bodyVars: { - sitename: user.getHostname(), - email: options.email || "" - } + start: function(options) { + var self=this; + self.renderDialog("authenticate", { + sitename: user.getHostname(), + email: options.email || "" }); - this.submit = checkEmail; + self.submit = checkEmail; // If we already have an email address, check if it is valid, if so, show // password. - if (options.email) this.submit(); - }, + if (options.email) self.submit(); - "#email keyup": function(el, event) { - var newEmail = el.val(); - if (newEmail !== lastEmail) { - lastEmail = newEmail; - enterEmailState.call(this, el); - } + + self.bind("#email", "keyup", emailKeyUp); + self.bind("#forgotPassword", "click", forgotPasswordState); + self.bind("#cancel_forgot_password", "click", cancelForgotPassword); + + self._super(); }, - "#forgotPassword click": forgotPasswordState, - "#cancel_forgot_password click": cancelForgotPassword, + checkEmail: checkEmail, createUser: createUser, authenticate: authenticate, diff --git a/resources/static/dialog/controllers/checkregistration_controller.js b/resources/static/dialog/controllers/checkregistration_controller.js index c6269895c6fac9ad34aae20185fc5c0bc179a17c..78038e68307bdbd6c4743a07c4063fe9f1408983 100644 --- a/resources/static/dialog/controllers/checkregistration_controller.js +++ b/resources/static/dialog/controllers/checkregistration_controller.js @@ -52,17 +52,11 @@ self.verifier = options.verifier; self.verificationMessage = options.verificationMessage; - dom.bindEvent("#back", "click", self.cancel.bind(self)); + self.bind("#back", "click", self.cancel); self._super(); }, - stop: function() { - dom.unbindEvent("#back", "click"); - - this._super(); - }, - startCheck: function() { var self=this; user[self.verifier](self.email, function(status) { diff --git a/resources/static/dialog/controllers/dialog_controller.js b/resources/static/dialog/controllers/dialog_controller.js index 9efb1d683554618f92b77130bc7d8aa32a552622..4cb10c89d956c07e5427e4e0a0a847044b6a7285 100644 --- a/resources/static/dialog/controllers/dialog_controller.js +++ b/resources/static/dialog/controllers/dialog_controller.js @@ -67,6 +67,9 @@ var self=this; + self.domEvents = []; + self._super(); + // keep track of where we are and what we do on success and error self.onsuccess = null; self.onerror = null; @@ -117,7 +120,7 @@ self.doCheckAuth(); - dom.bindEvent(win, "unload", function() { + self.bind(win, "unload", function() { // do this only if something else hasn't // declared success if (!self.success) { @@ -226,12 +229,11 @@ doConfirmUser: function(email) { this.confirmEmail = email; - this.element.checkregistration({ + var controller = this.element.checkregistration({ email: email, verifier: "waitForUserValidation", verificationMessage: "user_confirmed" - }); - var controller = this.element.controller("checkregistration"); + }).controller(); controller.startCheck(); }, @@ -278,12 +280,11 @@ doConfirmEmail: function(email) { this.confirmEmail = email; - this.element.checkregistration({ + var controller = this.element.checkregistration({ email: email, verifier: "waitForEmailValidation", verificationMessage: "email_confirmed" - }); - var controller = this.element.controller("checkregistration"); + }).controller(); controller.startCheck(); }, diff --git a/resources/static/dialog/controllers/page_controller.js b/resources/static/dialog/controllers/page_controller.js index 816724e04acd5596d6c7c68911ab34edbcfc5c07..0c66dfe58a7a493af9ab55833d836c9de01b12d6 100644 --- a/resources/static/dialog/controllers/page_controller.js +++ b/resources/static/dialog/controllers/page_controller.js @@ -42,6 +42,16 @@ dom = bid.DOM, screens = bid.Screens; + function onSubmit(event) { + event.stopPropagation(); + event.preventDefault(); + + if (this.validate()) { + this.submit(); + } + return false; + } + $.Controller.extend("PageController", { }, { @@ -50,6 +60,8 @@ var self=this; + this.domEvents = []; + if(options.bodyTemplate) { self.renderDialog(options.bodyTemplate, options.bodyVars); } @@ -67,15 +79,12 @@ start: function() { var self=this; - // XXX move all of these, bleck. - dom.bindEvent("form", "submit", self.onSubmit.bind(self)); - dom.bindEvent("#thisIsNotMe", "click", self.close.bind(self, "notme")); + self.bind("form", "submit", onSubmit); + self.bind("#thisIsNotMe", "click", self.close.bind(self, "notme")); }, stop: function() { - dom.unbindEvent("form", "submit"); - dom.unbindEvent("input", "keyup"); - dom.unbindEvent("#thisIsNotMe", "click"); + this.unbindAll(); dom.removeClass("body", "waiting"); }, @@ -85,6 +94,28 @@ this._super(); }, + bind: function(target, type, callback, context) { + var self=this, + cb = callback.bind(context || this); + + dom.bindEvent(target, type, cb); + + self.domEvents.push({ + target: target, + type: type, + cb: cb + }); + }, + + unbindAll: function() { + var self=this, + evt; + + while(evt = self.domEvents.pop()) { + dom.unbindEvent(evt.target, evt.type, evt.cb); + } + }, + renderDialog: function(body, body_vars) { screens.form(body, body_vars); $("#wait, #error").stop().fadeOut(ANIMATION_TIME); @@ -104,7 +135,7 @@ /** * TODO XXX - Use the error-display for this. */ - dom.bindEvent("#openMoreInfo", "click", function(event) { + this.bind("#openMoreInfo", "click", function(event) { event.preventDefault(); $("#moreInfo").slideDown(); @@ -112,28 +143,11 @@ }); }, - onSubmit: function(event) { - event.stopPropagation(); - event.preventDefault(); - - if (this.validate()) { - this.submit(); - } - return false; - }, - validate: function() { return true; }, submit: function() { - // this.close("submit"); - }, - - doWait: function(info) { - this.renderWait("wait", info); - - dom.addClass("body", "waiting"); }, close: function(message, data) { diff --git a/resources/static/dialog/controllers/pickemail_controller.js b/resources/static/dialog/controllers/pickemail_controller.js index 987756cd63d4c935447c9c11d7c4ab02fee3da3a..57bcb677c286b282dab402dc4fd14f9e63116f4a 100644 --- a/resources/static/dialog/controllers/pickemail_controller.js +++ b/resources/static/dialog/controllers/pickemail_controller.js @@ -44,7 +44,6 @@ storage = bid.Storage, helpers = bid.Helpers, dom = bid.DOM, - body = $("body"), assertion; function animateSwap(fadeOutSelector, fadeInSelector, callback) { @@ -57,10 +56,10 @@ function cancelEvent(event) { - if (event) event.preventDefault(); + event && event.preventDefault(); } - function pickEmailState(element, event) { + function pickEmailState(event) { cancelEvent(event); var self=this; @@ -75,7 +74,7 @@ }); } - function addEmailState(element, event) { + function addEmailState(event) { cancelEvent(event); this.submit = addEmail; @@ -136,41 +135,39 @@ PageController.extend("Pickemail", {}, { - init: function(el, options) { + start: function(options) { var origin = user.getOrigin(), self=this; options = options || {}; self.allowPersistent = options.allow_persistent; - - self._super(el, { - bodyTemplate: "pickemail", - bodyVars: { - identities: user.getStoredEmailKeypairs(), - // XXX ideal is to get rid of self and have a User function - // that takes care of getting email addresses AND the last used email - // for self site. - siteemail: storage.site.get(origin, "email"), - allow_persistent: options.allow_persistent || false, - remember: storage.site.get(origin, "remember") || false - } + self.renderDialog("pickemail", { + identities: user.getStoredEmailKeypairs(), + // XXX ideal is to get rid of self and have a User function + // that takes care of getting email addresses AND the last used email + // for self site. + siteemail: storage.site.get(origin, "email"), + allow_persistent: options.allow_persistent || false, + remember: storage.site.get(origin, "remember") || false }); - body.css("opacity", "1"); + dom.getElements("body").css("opacity", "1"); if (dom.getElements("#selectEmail input[type=radio]:visible").length === 0) { // If there is only one email address, the radio button is never shown, // instead focus the sign in button so that the user can click enter. // issue #412 - $("#signInButton").focus(); + dom.focus("#signInButton"); } + self.bind("#useNewEmail", "click", addEmailState); + self.bind("#cancelNewEmail", "click", pickEmailState); + + self._super(); + pickEmailState.call(self); }, - "#useNewEmail click": addEmailState, - "#cancelNewEmail click": pickEmailState, - signIn: signIn, addEmail: addEmail }); diff --git a/resources/static/dialog/controllers/required_email_controller.js b/resources/static/dialog/controllers/required_email_controller.js index 0e6dfea3d017d9e529c3a51e9f32f4ef46eb8595..812c48dacf826bb3c9919630f98a6e90758c91fa 100644 --- a/resources/static/dialog/controllers/required_email_controller.js +++ b/resources/static/dialog/controllers/required_email_controller.js @@ -144,24 +144,15 @@ showPassword: showPassword }); - dom.bindEvent("#sign_in", "click", signIn.bind(self)); - dom.bindEvent("#verify_address", "click", verifyAddress.bind(self)); - dom.bindEvent("#forgotPassword", "click", forgotPassword.bind(self)); - dom.bindEvent("#cancel", "click", cancel.bind(self)); + self.bind("#sign_in", "click", signIn); + self.bind("#verify_address", "click", verifyAddress); + self.bind("#forgotPassword", "click", forgotPassword); + self.bind("#cancel", "click", cancel); } self._super(); }, - stop: function() { - dom.unbindEvent("#sign_in", "click"); - dom.unbindEvent("#verify_address", "click"); - dom.unbindEvent("#forgotPassword", "click"); - dom.unbindEvent("#cancel", "click"); - - this._super(); - }, - signIn: signIn, verifyAddress: verifyAddress, forgotPassword: forgotPassword, diff --git a/resources/static/test/qunit/controllers/page_controller_unit_test.js b/resources/static/test/qunit/controllers/page_controller_unit_test.js index 8d898fc49c23c4af2d5a91ec91f522f185cbc339..00a21936d653f47ba720231944d7815aee559cf3 100644 --- a/resources/static/test/qunit/controllers/page_controller_unit_test.js +++ b/resources/static/test/qunit/controllers/page_controller_unit_test.js @@ -197,5 +197,40 @@ steal.plugins("jquery").then("/dialog/controllers/page_controller", function() { }); + test("bind DOM Events", function() { + controller = el.page().controller(); + + controller.bind("body", "click", function(event) { + event.preventDefault(); + + strictEqual(this, controller, "context is correct"); + start(); + }); + + $("body").trigger("click"); + stop(); + }); + + test("unbindAll removes all listeners", function() { + controller = el.page().controller(); + var listenerCalled = false; + + controller.bind("body", "click", function(event) { + event.preventDefault(); + + listenerCalled = true; + }); + + controller.unbindAll(); + + $("body").trigger("click"); + stop(); + + setTimeout(function() { + equal(listenerCalled, false, "all events are unbound, listener should not be called"); + start(); + }, 100); + }); + });