commit b752cf4a106bfa69b8708c76d62089c2aac0eb44
parent f98af662d58a91c89dcfeec1c84a6fa7e78f13c3
Author: Dimi <dlee@mozilla.com>
Date: Fri, 17 Oct 2025 08:12:47 +0000
Bug 1990145 - Do not refill autofilled value if the value is not emty r=NeilDeakin,credential-management-reviewers
This is to address the case when sites reformat the value after we
autofill.
Differential Revision: https://phabricator.services.mozilla.com/D268870
Diffstat:
2 files changed, 57 insertions(+), 6 deletions(-)
diff --git a/browser/extensions/formautofill/test/browser/browser_dynamic_form_refill_on_site_clearing_values.js b/browser/extensions/formautofill/test/browser/browser_dynamic_form_refill_on_site_clearing_values.js
@@ -13,6 +13,7 @@ add_setup(async () => {
});
await setStorage(TEST_ADDRESS_1);
+ await setStorage(TEST_CREDIT_CARD_1);
registerCleanupFunction(async () => {
await removeAllRecords();
@@ -95,7 +96,7 @@ add_task(async function address_field_refilled_after_cleared_by_site() {
/* eslint-disable mozilla/no-arbitrary-setTimeout */
await new Promise(resolve => {
- setTimeout(resolve, FormAutofill.refillOnSiteClearingFields);
+ setTimeout(resolve, FormAutofill.refillOnSiteClearingFieldsTimeout);
});
let [org, postalCode] = await SpecialPowers.spawn(browser, [], async () => {
@@ -146,7 +147,7 @@ add_task(
/* eslint-disable mozilla/no-arbitrary-setTimeout */
await new Promise(resolve => {
- setTimeout(resolve, FormAutofill.refillOnSiteClearingFields);
+ setTimeout(resolve, FormAutofill.refillOnSiteClearingFieldsTimeout);
});
return await SpecialPowers.spawn(
@@ -161,3 +162,56 @@ add_task(
Assert.equal(orgaValue, "", "Element was not refilled");
}
);
+
+add_task(async function address_field_not_refilled_after_reformat_by_site() {
+ const value = await BrowserTestUtils.withNewTab(
+ CREDITCARD_FORM_URL,
+ async browser => {
+ const selectorToTriggerAutocompletion = "#cc-number";
+ const elementValueToVerifyAutofill = TEST_CREDIT_CARD_1["cc-number"];
+
+ info("Triggering autocompletion.");
+ await openPopupOn(browser, selectorToTriggerAutocompletion);
+ await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
+ await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, browser);
+ await waitForAutofill(
+ browser,
+ selectorToTriggerAutocompletion,
+ elementValueToVerifyAutofill
+ );
+
+ const formatValue = TEST_CREDIT_CARD_1["cc-number"]
+ .replace(/(.{4})/g, "$1 ")
+ .trim();
+ await SpecialPowers.spawn(
+ browser,
+ [selectorToTriggerAutocompletion, formatValue],
+ async (ccNumberSelector, reformatValue) => {
+ const ccNumberInput =
+ content.document.querySelector(ccNumberSelector);
+
+ info("Simulating site reformats an input");
+ ccNumberInput.value = reformatValue;
+ }
+ );
+
+ /* eslint-disable mozilla/no-arbitrary-setTimeout */
+ await new Promise(resolve => {
+ setTimeout(resolve, FormAutofill.refillOnSiteClearingFieldsTimeout);
+ });
+
+ return await SpecialPowers.spawn(
+ browser,
+ [selectorToTriggerAutocompletion],
+ async ccNumberSelector => {
+ return content.document.querySelector(ccNumberSelector).value;
+ }
+ );
+ }
+ );
+
+ const formatValue = TEST_CREDIT_CARD_1["cc-number"]
+ .replace(/(.{4})/g, "$1 ")
+ .trim();
+ Assert.equal(value, formatValue, "Element was not refilled");
+});
diff --git a/toolkit/components/formautofill/shared/FormAutofillHandler.sys.mjs b/toolkit/components/formautofill/shared/FormAutofillHandler.sys.mjs
@@ -608,10 +608,7 @@ export class FormAutofillHandler {
// Only reclear if the value was changed back to the original value.
continue;
}
- } else if (
- e.autofillState == FIELD_STATES.AUTO_FILLED &&
- e.value === v
- ) {
+ } else if (e.autofillState == FIELD_STATES.NORMAL || e.value) {
// Nothing to do if the autofilled value wasn't cleared or the
// element's autofill state has changed to NORMAL in the meantime
continue;