Bug 1520980 - Remove support for notification bars in Password Manager. r=MattN
authorprathiksha <prathikshaprasadsuman@gmail.com>
Wed, 23 Jan 2019 22:15:20 +0000
changeset 515208 0d52389e664d34f9f7315e59cb7127c32b90b2e7
parent 515207 4e5e0c80bae226d779ac3020defff5ccb82505da
child 515209 b94e3d7633e2dc5f3ba288a1970b2f24aaf04af1
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN
bugs1520980
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1520980 - Remove support for notification bars in Password Manager. r=MattN Differential Revision: https://phabricator.services.mozilla.com/D17343
toolkit/components/passwordmgr/nsLoginManagerPrompter.js
toolkit/locales/en-US/chrome/passwordmgr/passwordmgr.properties
--- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
+++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
@@ -548,17 +548,17 @@ LoginManagerPrompter.prototype = {
     var canAutologin = false;
     var notifyObj;
     var foundLogins;
 
     try {
       this.log("===== promptAuth called =====");
 
       // If the user submits a login but it fails, we need to remove the
-      // notification bar that was displayed. Conveniently, the user will
+      // notification prompt that was displayed. Conveniently, the user will
       // be prompted for authentication again, which brings us here.
       this._removeLoginNotifications();
 
       var [hostname, httpRealm] = this._getAuthTarget(aChannel, aAuthInfo);
 
       // Looks for existing logins to prefill the prompt with.
       foundLogins = LoginHelper.searchLoginsWithObject({
         hostname,
@@ -593,17 +593,17 @@ LoginManagerPrompter.prototype = {
       }
 
       var canRememberLogin = Services.logins.getLoginSavingEnabled(hostname);
       if (this._inPrivateBrowsing) {
         canRememberLogin = false;
       }
 
       // if checkboxLabel is null, the checkbox won't be shown at all.
-      notifyObj = this._getPopupNote() || this._getNotifyBox();
+      notifyObj = this._getPopupNote();
       if (canRememberLogin && !notifyObj) {
         checkboxLabel = this._getLocalizedString("rememberPassword");
       }
     } catch (e) {
       // Ignore any errors and display the prompt anyway.
       epicfail = true;
       Cu.reportError("LoginManagerPrompter: " +
           "Epic fail in promptAuth: " + e + "\n");
@@ -614,19 +614,19 @@ LoginManagerPrompter.prototype = {
       if (this._chromeWindow) {
         PromptUtils.fireDialogEvent(this._chromeWindow, "DOMWillOpenModalDialog", this._browser);
       }
       ok = Services.prompt.promptAuth(this._chromeWindow,
                                       aChannel, aLevel, aAuthInfo,
                                       checkboxLabel, checkbox);
     }
 
-    // If there's a notification box, use it to allow the user to
+    // If there's a notification prompt, use it to allow the user to
     // determine if the login should be saved. If there isn't a
-    // notification box, only save the login if the user set the
+    // notification prompt, only save the login if the user set the
     // checkbox to do so.
     var rememberLogin = notifyObj ? canRememberLogin : checkbox.value;
     if (!ok || !rememberLogin || epicfail) {
       return ok;
     }
 
     try {
       var [username, password] = this._GetAuthInfo(aAuthInfo);
@@ -647,17 +647,18 @@ LoginManagerPrompter.prototype = {
                      createInstance(Ci.nsILoginInfo);
       newLogin.init(hostname, null, httpRealm,
                     username, password, "", "");
       if (!selectedLogin) {
         this.log("New login seen for " + username +
                  " @ " + hostname + " (" + httpRealm + ")");
 
         if (notifyObj) {
-          this._showSaveLoginNotification(notifyObj, newLogin);
+          this._showLoginCaptureDoorhanger(newLogin, "password-save");
+          Services.obs.notifyObservers(newLogin, "passwordmgr-prompt-save");
         } else {
           Services.logins.addLogin(newLogin);
         }
       } else if (password != selectedLogin.password) {
         this.log("Updating password for " + username +
                  " @ " + hostname + " (" + httpRealm + ")");
         if (notifyObj) {
           this._showChangeLoginNotification(notifyObj,
@@ -679,17 +680,17 @@ LoginManagerPrompter.prototype = {
 
   asyncPromptAuth(aChannel, aCallback, aContext, aLevel, aAuthInfo) {
     var cancelable = null;
 
     try {
       this.log("===== asyncPromptAuth called =====");
 
       // If the user submits a login but it fails, we need to remove the
-      // notification bar that was displayed. Conveniently, the user will
+      // notification prompt that was displayed. Conveniently, the user will
       // be prompted for authentication again, which brings us here.
       this._removeLoginNotifications();
 
       cancelable = this._newAsyncPromptConsumer(aCallback, aContext);
 
       var [hostname, httpRealm] = this._getAuthTarget(aChannel, aAuthInfo);
 
       var hashKey = aLevel + "|" + hostname + "|" + httpRealm;
@@ -755,53 +756,26 @@ LoginManagerPrompter.prototype = {
   },
 
   set openerBrowser(aOpenerBrowser) {
     this._openerBrowser = aOpenerBrowser;
   },
 
   promptToSavePassword(aLogin) {
     this.log("promptToSavePassword");
-    var notifyObj = this._getPopupNote() || this._getNotifyBox();
+    var notifyObj = this._getPopupNote();
     if (notifyObj) {
-      this._showSaveLoginNotification(notifyObj, aLogin);
+      this._showLoginCaptureDoorhanger(aLogin, "password-save");
+      Services.obs.notifyObservers(aLogin, "passwordmgr-prompt-save");
     } else {
       this._showSaveLoginDialog(aLogin);
     }
   },
 
   /**
-   * Displays a notification bar.
-   */
-  _showLoginNotification(aNotifyBox, aName, aText, aButtons) {
-    var oldBar = aNotifyBox.getNotificationWithValue(aName);
-    const priority = aNotifyBox.PRIORITY_INFO_MEDIUM;
-
-    this.log("Adding new " + aName + " notification bar");
-    var newBar = aNotifyBox.appendNotification(
-      aText, aName, "",
-      priority, aButtons);
-
-    // The page we're going to hasn't loaded yet, so we want to persist
-    // across the first location change.
-    newBar.persistence++;
-
-    // Sites like Gmail perform a funky redirect dance before you end up
-    // at the post-authentication page. I don't see a good way to
-    // heuristically determine when to ignore such location changes, so
-    // we'll try ignoring location changes based on a time interval.
-    newBar.timeout = Date.now() + 20000; // 20 seconds
-
-    if (oldBar) {
-      this.log("(...and removing old " + aName + " notification bar)");
-      aNotifyBox.removeNotification(oldBar);
-    }
-  },
-
-  /**
    * Displays the PopupNotifications.jsm doorhanger for password save or change.
    *
    * @param {nsILoginInfo} login
    *        Login to save or change. For changes, this login should contain the
    *        new password.
    * @param {string} type
    *        This is "password-save" or "password-change" depending on the
    *        original notification type. This is used for telemetry and tests.
@@ -994,18 +968,18 @@ LoginManagerPrompter.prototype = {
         histogram.add(PROMPT_NOTNOW);
         Services.obs.notifyObservers(null, "weave:telemetry:histogram", histogramName);
         browser.focus();
       },
     }];
     // Include a "Never for this site" button when saving a new password.
     if (type == "password-save") {
       secondaryActions.push({
-        label: this._getLocalizedString("notifyBarNeverRememberButtonText2"),
-        accessKey: this._getLocalizedString("notifyBarNeverRememberButtonAccessKey2"),
+        label: this._getLocalizedString("saveLoginButtonNever.label"),
+        accessKey: this._getLocalizedString("saveLoginButtonNever.accesskey"),
         callback: () => {
           histogram.add(PROMPT_NEVER);
           Services.obs.notifyObservers(null, "weave:telemetry:histogram", histogramName);
           Services.logins.setLoginSavingEnabled(login.hostname, false);
           browser.focus();
         },
       });
     }
@@ -1069,115 +1043,26 @@ LoginManagerPrompter.prototype = {
               break;
           }
           return false;
         },
       }
     );
   },
 
-  /**
-   * Displays a notification bar or a popup notification, to allow the user
-   * to save the specified login. This allows the user to see the results of
-   * their login, and only save a login which they know worked.
-   *
-   * @param aNotifyObj
-   *        A notification box or a popup notification.
-   * @param aLogin
-   *        The login captured from the form.
-   */
-  _showSaveLoginNotification(aNotifyObj, aLogin) {
-    // Ugh. We can't use the strings from the popup window, because they
-    // have the access key marked in the string (eg "Mo&zilla"), along
-    // with some weird rules for handling access keys that do not occur
-    // in the string, for L10N. See CommonDialog.jsm's setLabelForNode().
-    var neverButtonText =
-          this._getLocalizedString("notifyBarNeverRememberButtonText2");
-    var neverButtonAccessKey =
-          this._getLocalizedString("notifyBarNeverRememberButtonAccessKey2");
-    var rememberButtonText =
-          this._getLocalizedString("notifyBarRememberPasswordButtonText");
-    var rememberButtonAccessKey =
-          this._getLocalizedString("notifyBarRememberPasswordButtonAccessKey");
-
-    var displayHost = this._getShortDisplayHost(aLogin.hostname);
-    var notificationText = this._getLocalizedString("rememberPasswordMsgNoUsername",
-                                                    [displayHost]);
-
-    // Notification is a PopupNotification
-    if (aNotifyObj == this._getPopupNote()) {
-      this._showLoginCaptureDoorhanger(aLogin, "password-save");
-    } else {
-      var notNowButtonText =
-            this._getLocalizedString("notifyBarNotNowButtonText");
-      var notNowButtonAccessKey =
-            this._getLocalizedString("notifyBarNotNowButtonAccessKey");
-      var buttons = [
-        // "Remember" button
-        {
-          label:     rememberButtonText,
-          accessKey: rememberButtonAccessKey,
-          popup:     null,
-          callback(aNotifyObj, aButton) {
-            Services.logins.addLogin(aLogin);
-          },
-        },
-
-        // "Never for this site" button
-        {
-          label:     neverButtonText,
-          accessKey: neverButtonAccessKey,
-          popup:     null,
-          callback(aNotifyObj, aButton) {
-            Services.logins.setLoginSavingEnabled(aLogin.hostname, false);
-          },
-        },
-
-        // "Not now" button
-        {
-          label:     notNowButtonText,
-          accessKey: notNowButtonAccessKey,
-          popup:     null,
-          callback() { /* NOP */ },
-        },
-      ];
-
-      this._showLoginNotification(aNotifyObj, "password-save",
-                                  notificationText, buttons);
-    }
-
-    Services.obs.notifyObservers(aLogin, "passwordmgr-prompt-save");
-  },
-
   _removeLoginNotifications() {
     var popupNote = this._getPopupNote();
     if (popupNote) {
       popupNote = popupNote.getNotification("password");
     }
     if (popupNote) {
       popupNote.remove();
     }
-
-    var notifyBox = this._getNotifyBox();
-    if (notifyBox) {
-      var oldBar = notifyBox.getNotificationWithValue("password-save");
-      if (oldBar) {
-        this.log("Removing save-password notification bar.");
-        notifyBox.removeNotification(oldBar);
-      }
-
-      oldBar = notifyBox.getNotificationWithValue("password-change");
-      if (oldBar) {
-        this.log("Removing change-password notification bar.");
-        notifyBox.removeNotification(oldBar);
-      }
-    }
   },
 
-
   /**
    * Called when we detect a new login in a form submission,
    * asks the user what to do.
    */
   _showSaveLoginDialog(aLogin) {
     const buttonFlags = Ci.nsIPrompt.BUTTON_POS_1_DEFAULT +
         (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_0) +
         (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_1) +
@@ -1232,87 +1117,44 @@ LoginManagerPrompter.prototype = {
    *
    * @param {nsILoginInfo} aOldLogin
    *                       The old login we may want to update.
    * @param {nsILoginInfo} aNewLogin
    *                       The new login from the page form.
    */
   promptToChangePassword(aOldLogin, aNewLogin) {
     this.log("promptToChangePassword");
-    let notifyObj = this._getPopupNote() || this._getNotifyBox();
+    let notifyObj = this._getPopupNote();
 
     if (notifyObj) {
       this._showChangeLoginNotification(notifyObj, aOldLogin,
                                         aNewLogin);
     } else {
       this._showChangeLoginDialog(aOldLogin, aNewLogin);
     }
   },
 
   /**
-   * Shows the Change Password notification bar or popup notification.
+   * Shows the Change Password popup notification.
    *
    * @param aNotifyObj
-   *        A notification box or a popup notification.
+   *        A popup notification.
    *
    * @param aOldLogin
    *        The stored login we want to update.
    *
    * @param aNewLogin
    *        The login object with the changes we want to make.
    */
   _showChangeLoginNotification(aNotifyObj, aOldLogin, aNewLogin) {
-    var changeButtonText =
-          this._getLocalizedString("notifyBarUpdateButtonText");
-    var changeButtonAccessKey =
-          this._getLocalizedString("notifyBarUpdateButtonAccessKey");
-
-    // We reuse the existing message, even if it expects a username, until we
-    // switch to the final terminology in bug 1144856.
-    var displayHost = this._getShortDisplayHost(aOldLogin.hostname);
-    var notificationText = this._getLocalizedString("updatePasswordMsg",
-                                                    [displayHost]);
-
-    // Notification is a PopupNotification
-    if (aNotifyObj == this._getPopupNote()) {
-      aOldLogin.hostname = aNewLogin.hostname;
-      aOldLogin.formSubmitURL = aNewLogin.formSubmitURL;
-      aOldLogin.password = aNewLogin.password;
-      aOldLogin.username = aNewLogin.username;
-      this._showLoginCaptureDoorhanger(aOldLogin, "password-change");
-    } else {
-      var dontChangeButtonText =
-            this._getLocalizedString("notifyBarDontChangeButtonText");
-      var dontChangeButtonAccessKey =
-            this._getLocalizedString("notifyBarDontChangeButtonAccessKey");
-      var buttons = [
-        // "Yes" button
-        {
-          label:     changeButtonText,
-          accessKey: changeButtonAccessKey,
-          popup:     null,
-          callback(aNotifyObj, aButton) {
-            Services.logins._updateLogin(aOldLogin, aNewLogin);
-          },
-        },
-
-        // "No" button
-        {
-          label:     dontChangeButtonText,
-          accessKey: dontChangeButtonAccessKey,
-          popup:     null,
-          callback(aNotifyObj, aButton) {
-            // do nothing
-          },
-        },
-      ];
-
-      this._showLoginNotification(aNotifyObj, "password-change",
-                                  notificationText, buttons);
-    }
+    aOldLogin.hostname = aNewLogin.hostname;
+    aOldLogin.formSubmitURL = aNewLogin.formSubmitURL;
+    aOldLogin.password = aNewLogin.password;
+    aOldLogin.username = aNewLogin.username;
+    this._showLoginCaptureDoorhanger(aOldLogin, "password-change");
 
     let oldGUID = aOldLogin.QueryInterface(Ci.nsILoginMetaInfo).guid;
     Services.obs.notifyObservers(aNewLogin, "passwordmgr-prompt-change", oldGUID);
   },
 
 
   /**
    * Shows the Change Password dialog.
@@ -1431,26 +1273,26 @@ LoginManagerPrompter.prototype = {
     }
 
     return null;
   },
 
   _getNotifyWindow() {
     // Some sites pop up a temporary login window, which disappears
     // upon submission of credentials. We want to put the notification
-    // bar in the opener window if this seems to be happening.
+    // prompt in the opener window if this seems to be happening.
     if (this._openerBrowser) {
       let chromeDoc = this._chromeWindow.document.documentElement;
 
       // Check to see if the current window was opened with chrome
       // disabled, and if so use the opener window. But if the window
       // has been used to visit other pages (ie, has a history),
       // assume it'll stick around and *don't* use the opener.
       if (chromeDoc.getAttribute("chromehidden") && !this._browser.canGoBack) {
-        this.log("Using opener window for notification bar.");
+        this.log("Using opener window for notification prompt.");
         return { win: this._openerBrowser.ownerGlobal, browser: this._openerBrowser };
       }
     }
 
     return {
       win: this._chromeWindow,
       browser: this._browser,
     };
@@ -1470,37 +1312,16 @@ LoginManagerPrompter.prototype = {
       popupNote = notifyWin.wrappedJSObject.PopupNotifications;
     } catch (e) {
       this.log("Popup notifications not available on window");
     }
 
     return popupNote;
   },
 
-
-  /**
-   * Returns the notification box to this prompter, or null if there isn't
-   * a notification box available.
-   */
-  _getNotifyBox() {
-    let notifyBox = null;
-
-    try {
-      let { win: notifyWin } = this._getNotifyWindow();
-
-      // .wrappedJSObject needed here -- see bug 422974 comment 5.
-      notifyBox = notifyWin.wrappedJSObject.getNotificationBox(notifyWin);
-    } catch (e) {
-      this.log("Notification bars not available on window");
-    }
-
-    return notifyBox;
-  },
-
-
   /**
    * The user might enter a login that isn't the one we prefilled, but
    * is the same as some other existing login. So, pick a login with a
    * matching username, or return null.
    */
   _repickSelectedLogin(foundLogins, username) {
     for (var i = 0; i < foundLogins.length; i++) {
       if (foundLogins[i].username == username) {
--- a/toolkit/locales/en-US/chrome/passwordmgr/passwordmgr.properties
+++ b/toolkit/locales/en-US/chrome/passwordmgr/passwordmgr.properties
@@ -8,16 +8,18 @@ savePasswordTitle = Confirm
 # LOCALIZATION NOTE (saveLoginMsg, saveLoginMsgNoUser):
 # %1$S is brandShortName, %2$S is the login's hostname.
 saveLoginMsg = Would you like %1$S to save this login for %2$S?
 saveLoginMsgNoUser = Would you like %1$S to save this password for %2$S?
 saveLoginButtonAllow.label = Save
 saveLoginButtonAllow.accesskey = S
 saveLoginButtonDeny.label = Don’t Save
 saveLoginButtonDeny.accesskey = D
+saveLoginButtonNever.label = Never Save
+saveLoginButtonNever.accesskey = e
 updateLoginMsg = Would you like to update this login?
 updateLoginMsgNoUser = Would you like to update this password?
 updateLoginButtonText = Update
 updateLoginButtonAccessKey = U
 updateLoginButtonDeny.label = Don’t Update
 updateLoginButtonDeny.accesskey = D
 # LOCALIZATION NOTE (rememberPasswordMsg):
 # 1st string is the username for the login, 2nd is the login's hostname.
@@ -27,33 +29,23 @@ rememberPasswordMsg = Would you like to remember the password for “%1$S” on %2$S?
 # String is the login's hostname.
 rememberPasswordMsgNoUsername = Would you like to remember the password on %S?
 # LOCALIZATION NOTE (noUsernamePlaceholder):
 # This is displayed in place of the username when it is missing.
 noUsernamePlaceholder=No username
 togglePasswordLabel=Show password
 togglePasswordAccessKey2=h
 notNowButtonText = &Not Now
-notifyBarNotNowButtonText = Not Now
-notifyBarNotNowButtonAccessKey = N
 neverForSiteButtonText = Ne&ver for This Site
-notifyBarNeverRememberButtonText2 = Never Save
-notifyBarNeverRememberButtonAccessKey2 = e
 rememberButtonText = &Remember
-notifyBarRememberPasswordButtonText = Remember Password
-notifyBarRememberPasswordButtonAccessKey = R
 passwordChangeTitle = Confirm Password Change
 # LOCALIZATION NOTE (updatePasswordMsg):
 # String is the username for the login.
 updatePasswordMsg = Would you like to update the saved password for “%S”?
 updatePasswordMsgNoUser = Would you like to update the saved password?
-notifyBarUpdateButtonText = Update Password
-notifyBarUpdateButtonAccessKey = U
-notifyBarDontChangeButtonText = Don’t Change
-notifyBarDontChangeButtonAccessKey = D
 userSelectText2 = Select which login to update:
 hidePasswords=Hide Passwords
 hidePasswordsAccessKey=P
 showPasswords=Show Passwords
 showPasswordsAccessKey=P
 noMasterPasswordPrompt=Are you sure you wish to show your passwords?
 removeAllPasswordsPrompt=Are you sure you wish to remove all passwords?
 removeAllPasswordsTitle=Remove all passwords