Bug 956906 - Save passwords by default for password fields with autocomplete=off. r=dolske
authorDrew Willcoxon <adw@mozilla.com>
Thu, 06 Mar 2014 10:07:34 -0800
changeset 189487 27061dc242e4ac16460a17b5f18d155273b8011f
parent 189486 69f04d5d6700c6e5fc4f06bcadb29f27d801fef1
child 189488 fb4b2b7e2a2d54afb2b1001555eeac90db4e3175
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdolske
bugs956906
milestone30.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 956906 - Save passwords by default for password fields with autocomplete=off. r=dolske
modules/libpref/src/init/all.js
toolkit/components/passwordmgr/LoginManagerContent.jsm
toolkit/components/passwordmgr/test/test_notifications.html
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -3712,19 +3712,18 @@ pref("print.print_command", "lp -c -s ${
 
 # Solaris
 #endif
 
 // Login Manager prefs
 pref("signon.rememberSignons",              true);
 pref("signon.autofillForms",                true);
 pref("signon.autologin.proxy",              false);
+pref("signon.storeWhenAutocompleteOff",     true);
 pref("signon.debug",                        false);
-// Override autocomplete=false for password manager
-pref("signon.overrideAutocomplete",         false);
 
 // Satchel (Form Manager) prefs
 pref("browser.formfill.debug",            false);
 pref("browser.formfill.enable",           true);
 pref("browser.formfill.expire_days",      180);
 pref("browser.formfill.saveHttpsForms",   true);
 pref("browser.formfill.agedWeight",       2);
 pref("browser.formfill.bucketSize",       1);
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -8,17 +8,18 @@ const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cc = Components.classes;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 
-var gEnabled = false, gDebug = false, gAutofillForms = true , gOverrideAutocompleteAttribute = false; // these mirror signon.* prefs
+// These mirror signon.* prefs.
+var gEnabled, gDebug, gAutofillForms, gStoreWhenAutocompleteOff;
 
 function log(...pieces) {
     function generateLogMessage(args) {
         let strings = ['Login Manager (content):'];
 
         args.forEach(function(arg) {
             if (typeof arg === 'string') {
                 strings.push(arg);
@@ -66,17 +67,17 @@ var observer = {
 
         return true; // Always return true, or form submit will be canceled.
     },
 
     onPrefChange : function() {
         gDebug = Services.prefs.getBoolPref("signon.debug");
         gEnabled = Services.prefs.getBoolPref("signon.rememberSignons");
         gAutofillForms = Services.prefs.getBoolPref("signon.autofillForms");
-        gOverrideAutocompleteAttribute = Services.prefs.getBoolPref("signon.overrideAutocomplete");
+        gStoreWhenAutocompleteOff = Services.prefs.getBoolPref("signon.storeWhenAutocompleteOff");
     },
 };
 
 Services.obs.addObserver(observer, "earlyformsubmit", false);
 var prefBranch = Services.prefs.getBranch("signon.");
 prefBranch.addObserver("", observer.onPrefChange, false);
 
 observer.onPrefChange(); // read initial values
@@ -352,19 +353,16 @@ var LoginManagerContent = {
 
     /*
      * _isAutoCompleteDisabled
      *
      * Returns true if the page requests autocomplete be disabled for the
      * specified form input.
      */
     _isAutocompleteDisabled :  function (element) {
-        if (gOverrideAutocompleteAttribute)
-            return false; 
-
         if (element && element.hasAttribute("autocomplete") &&
             element.getAttribute("autocomplete").toLowerCase() == "off")
             return true;
         
         return false;
     },
 
 
@@ -418,22 +416,23 @@ var LoginManagerContent = {
             this._getFormFields(form, true);
 
         // Need at least 1 valid password field to do anything.
         if (newPasswordField == null)
                 return;
 
         // Check for autocomplete=off attribute. We don't use it to prevent
         // autofilling (for existing logins), but won't save logins when it's
-        // present.
+        // present and the storeWhenAutocompleteOff pref is false.
         // XXX spin out a bug that we don't update timeLastUsed in this case?
-        if (this._isAutocompleteDisabled(form) ||
-            this._isAutocompleteDisabled(usernameField) ||
-            this._isAutocompleteDisabled(newPasswordField) ||
-            this._isAutocompleteDisabled(oldPasswordField)) {
+        if ((this._isAutocompleteDisabled(form) ||
+             this._isAutocompleteDisabled(usernameField) ||
+             this._isAutocompleteDisabled(newPasswordField) ||
+             this._isAutocompleteDisabled(oldPasswordField)) &&
+            !gStoreWhenAutocompleteOff) {
                 log("(form submission ignored -- autocomplete=off found)");
                 return;
         }
 
 
         var formLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
                         createInstance(Ci.nsILoginInfo);
         formLogin.init(hostname, formSubmitURL, null,
--- a/toolkit/components/passwordmgr/test/test_notifications.html
+++ b/toolkit/components/passwordmgr/test/test_notifications.html
@@ -188,37 +188,40 @@ function checkTest() {
         popup = getPopup(popupNotifications, "password-save");
         ok(popup, "got notification popup");
         popup.remove();
         break;
 
       /* autocomplete=off tests... */
 
       case 9:
-        // Check for no notification popup when autocomplete=off present
+        // Check for notification popup when autocomplete=off present
         is(gotUser, "notifyu1", "Checking submitted username");
         is(gotPass, "notifyp1", "Checking submitted password");
         popup = getPopup(popupNotifications, "password-save");
-        ok(!popup, "checking for no notification popup");
+        ok(popup, "checking for notification popup");
+        popup.remove();
         break;
 
       case 10:
-        // Check for no notification popup when autocomplete=off present
+        // Check for notification popup when autocomplete=off present
         is(gotUser, "notifyu1", "Checking submitted username");
         is(gotPass, "notifyp1", "Checking submitted password");
         popup = getPopup(popupNotifications, "password-save");
-        ok(!popup, "checking for no notification popup");
+        ok(popup, "checking for notification popup");
+        popup.remove();
         break;
 
       case 11:
-        // Check for no notification popup when autocomplete=off present
+        // Check for notification popup when autocomplete=off present
         is(gotUser, "notifyu1", "Checking submitted username");
         is(gotPass, "notifyp1", "Checking submitted password");
         popup = getPopup(popupNotifications, "password-save");
-        ok(!popup, "checking for no notification popup");
+        ok(popup, "checking for notification popup");
+        popup.remove();
         break;
 
       /* no password field test... */
 
       case 12:
         // Check for no notification popup when no password field present
         is(gotUser, "notifyu1", "Checking submitted username");
         is(gotPass, "null",     "Checking submitted password");