diff --git a/browser/base/content/content.js b/browser/base/content/content.js index 3e517518a988..8fa4bd8123c8 100644 --- a/browser/base/content/content.js +++ b/browser/base/content/content.js @@ -61,7 +61,7 @@ addEventListener("DOMAutoComplete", function(event) { if (shouldIgnoreLoginManagerEvent(event)) { return; } - LoginManagerContent.onUsernameInput(event); + LoginManagerContent.onDOMAutoComplete(event); }); ContentMetaHandler.init(this); diff --git a/mobile/android/components/BrowserCLH.js b/mobile/android/components/BrowserCLH.js index b9ba1d3a8ee6..4f340c120ab4 100644 --- a/mobile/android/components/BrowserCLH.js +++ b/mobile/android/components/BrowserCLH.js @@ -214,15 +214,7 @@ BrowserCLH.prototype = { if (shouldIgnoreLoginManagerEvent(event)) { return; } - this.LoginManagerContent.onUsernameInput(event); - }, options); - - aWindow.addEventListener("blur", event => { - if (ChromeUtils.getClassName(event.target) !== "HTMLInputElement" || - shouldIgnoreLoginManagerEvent(event)) { - return; - } - this.LoginManagerContent.onUsernameInput(event); + this.LoginManagerContent.onDOMAutoComplete(event); }, options); aWindow.addEventListener("pageshow", event => { diff --git a/toolkit/components/passwordmgr/LoginManagerContent.jsm b/toolkit/components/passwordmgr/LoginManagerContent.jsm index de00004197bc..ec516a8ca16c 100644 --- a/toolkit/components/passwordmgr/LoginManagerContent.jsm +++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm @@ -10,6 +10,7 @@ var EXPORTED_SYMBOLS = [ "LoginManagerContent", const PASSWORD_INPUT_ADDED_COALESCING_THRESHOLD_MS = 1; const AUTOCOMPLETE_AFTER_RIGHT_CLICK_THRESHOLD_MS = 400; +const AUTOFILL_STATE = "-moz-autofill"; const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); @@ -605,9 +606,9 @@ var LoginManagerContent = { }, /** - * Listens for DOMAutoComplete and blur events on an input field. + * Listens for DOMAutoComplete event on login form. */ - onUsernameInput(event) { + onDOMAutoComplete(event) { if (!event.isTrusted) { return; } @@ -616,21 +617,27 @@ var LoginManagerContent = { return; } - var acInputField = event.target; + let acInputField = event.target; // This is probably a bit over-conservatative. if (ChromeUtils.getClassName(acInputField.ownerDocument) != "HTMLDocument") { return; } - if (!LoginHelper.isUsernameFieldType(acInputField)) { + if (!LoginFormFactory.createFromField(acInputField)) { return; } - var acForm = LoginFormFactory.createFromField(acInputField); - if (!acForm) { - return; + if (LoginHelper.isUsernameFieldType(acInputField)) { + this.onUsernameInput(event); } + }, + + /** + * Calls fill form on the username field. + */ + onUsernameInput(event) { + let acInputField = event.target; // If the username is blank, bail out now -- we don't want // fillForm() to try filling in a login without a username @@ -641,6 +648,7 @@ var LoginManagerContent = { log("onUsernameInput from", event.type); + let acForm = LoginFormFactory.createFromField(acInputField); let doc = acForm.ownerDocument; let formOrigin = LoginUtils._getPasswordOrigin(doc.documentURI); let recipes = LoginRecipesContent.getRecipes(formOrigin, doc.defaultView); @@ -998,6 +1006,28 @@ var LoginManagerContent = { }); }, + /** Remove login field highlight when its value is cleared or overwritten. + */ + _removeFillFieldHighlight(event) { + let winUtils = event.target.ownerGlobal.windowUtils; + winUtils.removeManuallyManagedState(event.target, AUTOFILL_STATE); + }, + + /** + * Highlight login fields on autocomplete or autofill on page load. + * @param {Node} element that needs highlighting. + */ + _highlightFilledField(element) { + let winUtils = element.ownerGlobal.windowUtils; + + winUtils.addManuallyManagedState(element, AUTOFILL_STATE); + // Remove highlighting when the field is changed. + element.addEventListener("input", this._removeFillFieldHighlight, { + mozSystemGroup: true, + once: true, + }); + }, + /** * Attempt to find the username and password fields in a form, and fill them * in using the provided logins and recipes. @@ -1248,8 +1278,12 @@ var LoginManagerContent = { let userEnteredDifferentCase = userTriggered && userNameDiffers && usernameField.value.toLowerCase() == selectedLogin.username.toLowerCase(); - if (!disabledOrReadOnly && !userEnteredDifferentCase && userNameDiffers) { - usernameField.setUserInput(selectedLogin.username); + if (!disabledOrReadOnly) { + if (!userEnteredDifferentCase && userNameDiffers) { + usernameField.setUserInput(selectedLogin.username); + } + + this._highlightFilledField(usernameField); } } @@ -1267,6 +1301,8 @@ var LoginManagerContent = { this.stateForDocument(doc).fillsByRootElement.set(form.rootElement, autoFilledLogin); } + this._highlightFilledField(passwordField); + log("_fillForm succeeded"); autofillResult = AUTOFILL_RESULT.FILLED; diff --git a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini index 846f677f22e5..3a42f6eb2623 100644 --- a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini +++ b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini @@ -21,11 +21,16 @@ support-files = ../authenticate.sjs skip-if = toolkit == 'android' && !isFennec # Don't run on GeckoView +[test_autocomplete_highlight.html] +scheme = https +skip-if = toolkit == 'android' # autocomplete [test_autocomplete_https_upgrade.html] skip-if = toolkit == 'android' # autocomplete [test_autocomplete_sandboxed.html] scheme = https skip-if = toolkit == 'android' # autocomplete +[test_autofill_highlight.html] +scheme = https [test_autofill_https_upgrade.html] skip-if = toolkit == 'android' # Bug 1259768 [test_autofill_sandboxed.html] diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight.html new file mode 100644 index 000000000000..0e0e6713a837 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight.html @@ -0,0 +1,81 @@ + + + + + Test form field autofill highlight + + + + + + + + + +

+
+
+ + + +
+
+
+
+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight.html
new file mode 100644
index 000000000000..893d2b0b3579
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight.html
@@ -0,0 +1,67 @@
+
+
+
+  
+  Test form field autofill highlight
+  
+  
+  
+  
+  
+
+
+
+

+ +
+
+ + + +
+ +
+
+
+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_upgrade.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_upgrade.html
index 32b4534492ee..135b6c93c488 100644
--- a/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_upgrade.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_upgrade.html
@@ -6,7 +6,6 @@
   
   
   
-