From 0cca164e91eb31e2cf3e27dec41767c71b5175c7 Mon Sep 17 00:00:00 2001
From: Shane Tomlinson <stomlinson@mozilla.com>
Date: Tue, 15 Nov 2011 16:34:25 +0000
Subject: [PATCH] Unifying the "we sent email" messages across all locations.

* Unifying both the message (with slight variation for current action) and the styles across dialog and main site.
* Adding a throttling message to the signup page.
* Adding a couple of page helper functions to take care of showing notifications.
* Adding the ability to go "back" in all of the main site email sent notifications in case of error.
* When going "back" after sent email, ensure the stored email is restored.

close #579
close #577
---
 resources/static/css/style.css                | 10 +++-
 .../static/dialog/views/confirmemail.ejs      |  2 +-
 resources/static/pages/forgot.js              | 14 ++++--
 resources/static/pages/page_helpers.js        | 39 +++++++++++++--
 resources/static/pages/signup.js              | 30 +++++++-----
 resources/static/test/qunit.html              |  2 +
 .../test/qunit/pages/forgot_unit_test.js      | 20 ++++++++
 .../qunit/pages/page_helpers_unit_test.js     | 48 +++++++++++++++++++
 .../test/qunit/pages/signup_unit_test.js      | 27 +++++++++++
 resources/views/forgot.ejs                    | 23 +++++++--
 resources/views/signup.ejs                    | 27 ++++++++++-
 11 files changed, 213 insertions(+), 29 deletions(-)

diff --git a/resources/static/css/style.css b/resources/static/css/style.css
index 883ebede7..8232c5016 100644
--- a/resources/static/css/style.css
+++ b/resources/static/css/style.css
@@ -657,7 +657,7 @@ h1 {
 }
 
 #signUpFormWrap {
-  margin: 122px 160px;
+  margin: 122px 115px;
 }
 
 #signUpFormWrap a.signUpIn {
@@ -815,7 +815,9 @@ a.forgot {
 .notifications > .notification {
   margin-top: 20px;
   padding: 5px;
-  line-height: 16px;
+  line-height: 21px;
+  color: #62615F;
+  text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
   -webkit-border-radius: 3px;
      -moz-border-radius: 3px;
        -o-border-radius: 3px;
@@ -824,6 +826,10 @@ a.forgot {
   text-align: center;
 }
 
+.notifications > .notification a, .notifications > .notification strong {
+  color: #222;
+}
+
 .notifications .notification.error {
   color: red;
   background-color: rgba(255,0,0,0.25);
diff --git a/resources/static/dialog/views/confirmemail.ejs b/resources/static/dialog/views/confirmemail.ejs
index 6b264b862..51488eda9 100644
--- a/resources/static/dialog/views/confirmemail.ejs
+++ b/resources/static/dialog/views/confirmemail.ejs
@@ -1,5 +1,5 @@
     <h2>Check your email!</h2>
     <p>We sent a confirmation email to <strong><%= email %></strong></p>
     <p>To finish signing in just click the verify link we sent to your email address.</p><br />
-    <p>If this is a mistake, <a href="#" id="back">cancel this email</a>.</p>
+    <p>If this is a mistake, just ignore the sent email and <a href="#" id="back">use another</a>.</p>
 
diff --git a/resources/static/pages/forgot.js b/resources/static/pages/forgot.js
index ab7c8c0ad..9bd1689d2 100644
--- a/resources/static/pages/forgot.js
+++ b/resources/static/pages/forgot.js
@@ -54,10 +54,7 @@ BrowserID.forgot = (function() {
     if (valid) {
       user.requestPasswordReset(email, function onSuccess(info) {
         if (info.success) {
-          pageHelpers.clearStoredEmail();
-          $('#sent_to_email').html(email);
-          $('#forminputs').fadeOut();
-          $(".notifications .notification.emailsent").fadeIn();
+          pageHelpers.showEmailSent();
         }
         else {
           var tooltipEl = info.reason === "throttle" ? "#could_not_add" : "#not_registered";
@@ -67,20 +64,29 @@ BrowserID.forgot = (function() {
     }
   };
 
+  function back(event) {
+    if (event) event.preventDefault();
+
+    pageHelpers.cancelEmailSent();
+  }
+
   function init() {
     $("form input[autofocus]").focus();
 
     pageHelpers.setupEmail();
 
     $("form").bind("submit", submit);
+    $("#back").bind("click", back);
   }
 
   function reset() {
     $("form").unbind("submit", submit);
+    $("#back").unbind("click", back);
   }
 
   init.submit = submit; 
   init.reset = reset;
+  init.back = back;
 
   return init;
 
diff --git a/resources/static/pages/page_helpers.js b/resources/static/pages/page_helpers.js
index 11e8546b3..3d9f8981a 100644
--- a/resources/static/pages/page_helpers.js
+++ b/resources/static/pages/page_helpers.js
@@ -40,7 +40,9 @@ BrowserID.PageHelpers = (function() {
   var win = window,
       locStorage = win.localStorage,
       bid = BrowserID,
-      errorDisplay = bid.ErrorDisplay;
+      errorDisplay = bid.ErrorDisplay,
+      ANIMATION_SPEED = 250,
+      origStoredEmail;
 
   function setStoredEmail(email) {
     locStorage.signInEmail = email;
@@ -88,17 +90,46 @@ BrowserID.PageHelpers = (function() {
     return function onFailure(info) {
       info = $.extend(info, { action: error, dialog: false });
       bid.Screens.error("error", info);
-      $("#errorBackground").fadeIn();
-      $("#error").fadeIn();
+      $("#errorBackground").stop().fadeIn();
+      $("#error").stop().fadeIn();
     }
   }
 
+  function replaceInputsWithNotice(selector, onComplete) {
+    $('.forminputs').hide();
+    $(selector).stop().hide().css({opacity:1}).fadeIn(ANIMATION_SPEED, onComplete);
+  }
+
+  function showInputs(onComplete) {
+    $('.notification').hide();
+    $('.forminputs').stop().hide().css({opacity:1}).fadeIn(ANIMATION_SPEED, onComplete);
+  }
+
+  function showEmailSent(onComplete) {
+    origStoredEmail = getStoredEmail();
+    $('#sentToorigStoredEmail').html(origStoredEmail);
+
+    clearStoredEmail();
+
+    replaceInputsWithNotice(".emailsent", onComplete);
+  }
+
+  function cancelEmailSent(onComplete) {
+    setStoredEmail(origStoredEmail);
+
+    showInputs(onComplete);
+  }
+
   return {
     setupEmail: prefillEmail,
     setStoredEmail: setStoredEmail,
     clearStoredEmail: clearStoredEmail,
     getStoredEmail: getStoredEmail,
     getParameterByName: getParameterByName,
-    getFailure: getFailure
+    getFailure: getFailure,
+    replaceInputsWithNotice: replaceInputsWithNotice,
+    showInputs: showInputs,
+    showEmailSent: showEmailSent,
+    cancelEmailSent: cancelEmailSent
   };
 }());
diff --git a/resources/static/pages/signup.js b/resources/static/pages/signup.js
index 02449bb9f..77727ba71 100644
--- a/resources/static/pages/signup.js
+++ b/resources/static/pages/signup.js
@@ -41,13 +41,9 @@ BrowserID.signUp = (function() {
       user = bid.User,
       pageHelpers = bid.PageHelpers,
       errors = bid.Errors,
-      ANIMATION_SPEED = 250;
-
-    function replaceWithMessage(selector) {
-        $('.forminputs').fadeOut(ANIMATION_SPEED, function() {
-          $(selector).fadeIn(ANIMATION_SPEED);
-        });
-    }
+      tooltip = BrowserID.Tooltip,
+      ANIMATION_SPEED = 250,
+      storedEmail = pageHelpers;
 
     function showNotice(selector) {
       $(selector).fadeIn(ANIMATION_SPEED);
@@ -65,10 +61,13 @@ BrowserID.signUp = (function() {
 
       user.isEmailRegistered(email, function(registered) {
         if (!registered) {
-          pageHelpers.clearStoredEmail();
-          user.createUser(email, function onSuccess(keypair) {
-            $('#sentToEmail').html(email);
-            replaceWithMessage(".emailsent");
+          user.createUser(email, function onSuccess(success) {
+            if(success) {
+              pageHelpers.showEmailSent();
+            }
+            else {
+              tooltip.showTooltip("#could_not_add");
+            }
           }, pageHelpers.getFailure(errors.createUser));
         }
         else {
@@ -78,6 +77,12 @@ BrowserID.signUp = (function() {
       }, pageHelpers.getFailure(errors.isEmailRegistered));
     }
 
+    function back(event) {
+      if (event) event.preventDefault();
+
+      pageHelpers.cancelEmailSent();
+    }
+
     function onEmailKeyUp(event) {
       if (event.which !== 13) $(".notification").fadeOut(ANIMATION_SPEED);
     }
@@ -89,15 +94,18 @@ BrowserID.signUp = (function() {
 
       $("#email").bind("keyup", onEmailKeyUp);
       $("form").bind("submit", submit);
+      $("#back").bind("click", back);
     }
 
     function reset() {
       $("form").unbind("submit", submit);
       $("#email").unbind("keyup", onEmailKeyUp);
+      $("#back").unbind("click", back);
     }
 
     init.submit = submit;
     init.reset = reset;
+    init.back = back;
 
     return init;
 }());
diff --git a/resources/static/test/qunit.html b/resources/static/test/qunit.html
index 05fcf8726..bbb3030f9 100644
--- a/resources/static/test/qunit.html
+++ b/resources/static/test/qunit.html
@@ -65,6 +65,8 @@
     <ul id="emailList">
     </ul>
 
+    <div id="sentToEmail"></div>
+
     <script type="text/html" id="templateUser">
       <li>{{email}}</li>
     </script>
diff --git a/resources/static/test/qunit/pages/forgot_unit_test.js b/resources/static/test/qunit/pages/forgot_unit_test.js
index ab17c1d0e..8bcf91595 100644
--- a/resources/static/test/qunit/pages/forgot_unit_test.js
+++ b/resources/static/test/qunit/pages/forgot_unit_test.js
@@ -117,4 +117,24 @@ steal.then("/pages/forgot", function() {
     });
   });
 
+  test("signup with unregistered email and cancel button pressed", function() {
+    $("#email").val("unregistered@testuser.com");
+
+    bid.signUp.submit();
+
+    setTimeout(function() {
+      bid.forgot.back();
+
+      setTimeout(function() {
+        equal($(".notification:visible").length, 0, "no notifications are visible");
+        equal($(".forminputs:visible").length, 1, "form inputs are again visible");
+        equal($("#email").val(), "unregistered@testuser.com", "email address restored");
+        start();
+      }, 500);
+    }, 100);
+
+    stop();
+  });
+
+
 });
diff --git a/resources/static/test/qunit/pages/page_helpers_unit_test.js b/resources/static/test/qunit/pages/page_helpers_unit_test.js
index 813b669be..f162ac3ab 100644
--- a/resources/static/test/qunit/pages/page_helpers_unit_test.js
+++ b/resources/static/test/qunit/pages/page_helpers_unit_test.js
@@ -76,6 +76,54 @@ steal.then(function() {
     equal(pageHelpers.getStoredEmail(), "", "clearStoredEmail clears stored email");
   });
 
+  test("replaceInputsWithNotice replaces contents", function() {
+    pageHelpers.replaceInputsWithNotice(".emailsent", function() {
+      equal($(".emailsent").is(":visible"), true, "emailsent is visible");
+      equal($(".forminputs").is(":visible"), false, "inputs are hidden");
+      start();
+    });
+
+    stop();
+  });
+
+  test("showInputs hides notices and shows the inputs", function() {
+    pageHelpers.replaceInputsWithNotice(".emailsent", function() {
+      pageHelpers.showInputs(function() {
+        equal($(".emailsent").is(":visible"), false, "emailsent is hidden");
+        equal($(".forminputs").is(":visible"), true, "inputs are shown");
+        start();
+      });
+    });
+
+    stop();
+  });
+
+
+  test("showEmailSent shows correct email sent message", function() {
+    pageHelpers.setStoredEmail("testuser@testuser.com");
+    pageHelpers.showEmailSent(function() {
+      equal($("#sentToEmail").html(), "testuser@testuser.com", "correct email is set");
+      equal($(".emailsent").is(":visible"), true, "emailsent is visible");
+      equal($(".forminputs").is(":visible"), false, "inputs are hidden");
+      start();
+    });
+  });
+
+  test("cancelEmailSent restores the stored email, inputs are shown again", function() {
+    pageHelpers.setStoredEmail("testuser@testuser.com");
+    pageHelpers.showEmailSent(function() {
+      pageHelpers.cancelEmailSent(function() {
+        var email = pageHelpers.getStoredEmail();
+        equal(email, "testuser@testuser.com", "stored email is reset on cancel");
+        equal($(".emailsent").is(":visible"), false, "emailsent is not visible");
+        equal($(".forminputs").is(":visible"), true, "inputs are visible");
+        start();
+      });
+    });
+
+    stop();
+  });
+
 });
 
 
diff --git a/resources/static/test/qunit/pages/signup_unit_test.js b/resources/static/test/qunit/pages/signup_unit_test.js
index e6aae6e93..4756b0a8a 100644
--- a/resources/static/test/qunit/pages/signup_unit_test.js
+++ b/resources/static/test/qunit/pages/signup_unit_test.js
@@ -99,6 +99,14 @@ steal.then("/pages/signup", function() {
     testNoticeNotVisible();
   });
 
+  test("signup with throttling", function() {
+    xhr.useResult("throttle");
+
+    $("#email").val("throttled@testuser.com");
+
+    testNoticeNotVisible();
+  });
+
   test("signup with invalid XHR error", function() {
     xhr.useResult("invalid");
     $("#email").val("unregistered@testuser.com");
@@ -109,4 +117,23 @@ steal.then("/pages/signup", function() {
     });
   });
 
+  test("signup with unregistered email and cancel button pressed", function() {
+    $("#email").val("unregistered@testuser.com");
+
+    bid.signUp.submit();
+
+    setTimeout(function() {
+      bid.signUp.back();
+
+      setTimeout(function() {
+        equal($(".notification:visible").length, 0, "no notifications are visible");
+        equal($(".forminputs:visible").length, 1, "form inputs are again visible");
+        equal($("#email").val(), "unregistered@testuser.com", "email address restored");
+        start();
+      }, 500);
+    }, 100);
+
+    stop();
+  });
+
 });
diff --git a/resources/views/forgot.ejs b/resources/views/forgot.ejs
index 93c8ed7f4..5824e0c34 100644
--- a/resources/views/forgot.ejs
+++ b/resources/views/forgot.ejs
@@ -4,10 +4,23 @@
         <form id="signUpForm" class="cf authform" novalidate>
             <h1 class="serif">Forgot Password</h1>
             <div class="notifications">
-                <div class="notification emailsent">A confirmation email has been sent to you at <strong id="sent_to_email"></strong>. Check it!</div>
+                <div class="notification emailsent">
+                  <p>
+                    We sent a confirmation email to <strong id="sentToEmail"></strong>. 
+                  </p>
+
+                  <p>
+                    To finish resetting your password just click the verify link we sent to your email address.
+                  </p>
+
+                  <br />
+                  <p>
+                    If this is a mistake, just ignore the sent email and <a href="/signup" id="back">use another</a>.
+                  </p>
+                </div>
             </div>
-            <div id="forminputs">
-            <ul class="inputs">
+
+            <ul class="inputs forminputs">
                 <li>
                     <label class="serif" for="email">Email Address</label>
                     <input class="sans" id="email" autofocus required placeholder="Your Email" type="email" autocapitalize="off" autocorrect="off" maxlength="254" />
@@ -31,13 +44,13 @@
 
 
             </ul>
-            <div class="submit cf">
+
+            <div class="submit cf forminputs">
                 <div class="remember cf">
                     <a class="signUpIn" href="/signin">Know your password? Sign in.</a>
                 </div>
                 <input type="submit" class="create" value="Reset Password"/>
             </div>
-            </div>
         </form>
     </div>
 </div>
diff --git a/resources/views/signup.ejs b/resources/views/signup.ejs
index cc95cd345..d64061f67 100644
--- a/resources/views/signup.ejs
+++ b/resources/views/signup.ejs
@@ -6,8 +6,27 @@
 
             <ul class="notifications">
                 <li class="notification error doh">Doh! Something went wrong :-( </li>
-                <li class="notification alreadyRegistered"><strong id="registeredEmail"></strong> is already registered. Would you like to <a class="signUpIn" href="/signin">sign in</a> instead?</li>
-                <li class="notification emailsent">A confirmation email has been sent to you at <strong id="sentToEmail"></strong>. Check it!</li>
+
+                <li class="notification alreadyRegistered">
+                  <strong id="registeredEmail"></strong> is already registered. 
+                  Would you like to <a class="signUpIn" href="/signin">sign in</a> instead?
+                </li>
+
+                <li class="notification emailsent">
+                  <p>
+                    We sent a confirmation email to <strong id="sentToEmail"></strong>. 
+                  </p>
+
+                  <p>
+                    To finish signing up just click the verify link we sent to your email address.
+                  </p>
+
+                  <br />
+                  <p>
+                    If this is a mistake, just ignore the sent email and <a href="/signup" id="back">use another</a>.
+                  </p>
+                </li>
+
             </ul>
 
             <ul class="inputs forminputs">
@@ -22,6 +41,10 @@
                     <div id="email_required" class="tooltip" for="email">
                       The email field is required.
                     </div>
+
+                    <div id="could_not_add" class="tooltip" for="email">
+                      We just sent an email to that address! If you really want to send another, wait a minute or two and try again.
+                    </div>
                 </li>
             </ul>
 
-- 
GitLab