commit d1f56fdedc0d4787b7afe8f7e8a2eaeb3b8826f6 parent 2d447f0895de5b8d2b927957048b2bc1e2ba34df Author: Neil Deakin <neil@mozilla.com> Date: Wed, 3 Dec 2025 17:13:06 +0000 Bug 1930874, allow filling single fields when they have autocomplete attributes assigned, r=dimi,credential-management-reviewers Differential Revision: https://phabricator.services.mozilla.com/D273252 Diffstat:
12 files changed, 90 insertions(+), 41 deletions(-)
diff --git a/browser/extensions/formautofill/test/browser/browser_autofill_creditCard_name.js b/browser/extensions/formautofill/test/browser/browser_autofill_creditCard_name.js @@ -41,7 +41,6 @@ add_autofill_heuristic_tests([ ], }, { - invalid: true, fields: [ { fieldName: "given-name", @@ -128,7 +127,6 @@ add_autofill_heuristic_tests([ ], }, { - invalid: true, fields: [ { fieldName: "given-name", diff --git a/browser/extensions/formautofill/test/browser/browser_collectFormFields.js b/browser/extensions/formautofill/test/browser/browser_collectFormFields.js @@ -163,7 +163,6 @@ add_heuristic_tests([ </form>`, expectedResult: [ { - invalid: true, default: { reason: "autocomplete", }, diff --git a/browser/extensions/formautofill/test/browser/heuristics/browser_autocomplete_fields.js b/browser/extensions/formautofill/test/browser/heuristics/browser_autocomplete_fields.js @@ -51,7 +51,6 @@ add_heuristic_tests([ default: { reason: "autocomplete", }, - invalid: true, fields: [ { fieldName: "street-address" }, { fieldName: "address-level2" }, @@ -116,4 +115,34 @@ add_heuristic_tests([ }, ], }, + { + description: "Form containing a single field.", + fixtureData: `<form> + <input autocomplete="postal-code"> + </form>`, + expectedResult: [ + { + fields: [{ fieldName: "postal-code" }], + }, + ], + }, + { + description: "Form containing a single invalid field.", + fixtureData: `<form> + <input autocomplete="postalCode"> + </form>`, + expectedResult: [], + }, + { + description: "Form containing two fields, one invalid.", + fixtureData: `<form> + <input autocomplete="postal-code"> + <input autocomplete="town"> + </form>`, + expectedResult: [ + { + fields: [{ fieldName: "postal-code" }], + }, + ], + }, ]); diff --git a/browser/extensions/formautofill/test/browser/heuristics/browser_duplicate_fields.js b/browser/extensions/formautofill/test/browser/heuristics/browser_duplicate_fields.js @@ -140,7 +140,6 @@ add_heuristic_tests([ ], }, { - invalid: true, fields: [ { fieldName: "address-line1", @@ -179,7 +178,6 @@ add_heuristic_tests([ ], }, { - invalid: true, fields: [ { fieldName: "address-line1", @@ -218,7 +216,6 @@ add_heuristic_tests([ ], }, { - invalid: true, fields: [{ fieldName: "postal-code", reason: "autocomplete" }], }, ], @@ -252,7 +249,6 @@ add_heuristic_tests([ ], }, { - invalid: true, fields: [ { fieldName: "postal-code", reason: "autocomplete" }, { fieldName: "address-line1", reason: "autocomplete" }, @@ -310,14 +306,12 @@ add_heuristic_tests([ `, expectedResult: [ { - invalid: true, fields: [ { fieldName: "country", addressType: "shipping" }, { fieldName: "given-name", addressType: "shipping" }, ], }, { - invalid: true, fields: [ { fieldName: "country", addressType: "billing" }, { fieldName: "country", addressType: "billing" }, @@ -338,14 +332,12 @@ add_heuristic_tests([ `, expectedResult: [ { - invalid: true, fields: [ { fieldName: "country", addressType: "shipping" }, { fieldName: "given-name", addressType: "shipping" }, ], }, { - invalid: true, fields: [ { fieldName: "country", addressType: "billing" }, { fieldName: "country", addressType: "billing" }, @@ -366,14 +358,12 @@ add_heuristic_tests([ `, expectedResult: [ { - invalid: true, fields: [ { fieldName: "postal-code", addressType: "shipping" }, { fieldName: "tel", addressType: "shipping" }, ], }, { - invalid: true, fields: [ { fieldName: "postal-code", addressType: "billing" }, { fieldName: "postal-code", addressType: "billing" }, @@ -394,14 +384,12 @@ add_heuristic_tests([ `, expectedResult: [ { - invalid: true, fields: [ { fieldName: "postal-code", addressType: "shipping" }, { fieldName: "tel", addressType: "shipping" }, ], }, { - invalid: true, fields: [ { fieldName: "postal-code", addressType: "billing" }, { fieldName: "postal-code", addressType: "billing" }, @@ -492,7 +480,6 @@ add_heuristic_tests([ ], }, { - invalid: true, default: { reason: "regex-heuristic", }, @@ -507,7 +494,6 @@ add_heuristic_tests([ ], }, { - invalid: true, default: { reason: "regex-heuristic", }, @@ -576,7 +562,6 @@ add_heuristic_tests([ `, expectedResult: [ { - invalid: true, default: { reason: "autocomplete", }, @@ -597,7 +582,6 @@ add_heuristic_tests([ `, expectedResult: [ { - invalid: true, default: { reason: "autocomplete", addressType: "shipping", @@ -605,7 +589,6 @@ add_heuristic_tests([ fields: [{ fieldName: "email" }], }, { - invalid: true, default: { reason: "autocomplete", }, diff --git a/browser/extensions/formautofill/test/browser/heuristics/browser_multiple_section.js b/browser/extensions/formautofill/test/browser/heuristics/browser_multiple_section.js @@ -51,7 +51,6 @@ add_heuristic_tests( ], }, { - invalid: true, default: { reason: "autocomplete", }, @@ -104,7 +103,6 @@ add_heuristic_tests( ], }, { - invalid: true, default: { reason: "autocomplete", contactType: "home", diff --git a/browser/extensions/formautofill/test/browser/heuristics/browser_parse_name_fields.js b/browser/extensions/formautofill/test/browser/heuristics/browser_parse_name_fields.js @@ -135,7 +135,6 @@ add_heuristic_tests([ </form></body></html>`, expectedResult: [ { - invalid: true, fields: [ { fieldName: "given-name", reason: "autocomplete" }, { fieldName: "family-name", reason: "autocomplete" }, diff --git a/browser/extensions/formautofill/test/browser/heuristics/browser_section_validation_address.js b/browser/extensions/formautofill/test/browser/heuristics/browser_section_validation_address.js @@ -29,7 +29,7 @@ add_heuristic_tests([ ], }, { - description: `An address section is invalid when it contains less than three fields`, + description: `An address section valid when it contains less than three fields when autocomplete is used`, fixtureData: ` <html><body> <input id="postal-code" autocomplete="postal-code"> @@ -39,7 +39,6 @@ add_heuristic_tests([ expectedResult: [ { description: "A section with two fields", - invalid: true, fields: [ { fieldName: "postal-code", reason: "autocomplete" }, { fieldName: "email", reason: "autocomplete" }, @@ -48,23 +47,60 @@ add_heuristic_tests([ ], }, { - description: `Address section validation only counts the number of different address field name in the section`, + description: `An address section is invalid when it contains less than three fields when autocomplete is not used`, fixtureData: ` <html><body> - <input id="postal-code" autocomplete="postal-code"> - <input id="email" autocomplete="email"> + <input id="postal-code"> + <input id="email"> + </body></html> + `, + expectedResult: [ + { + description: "A section with two fields", + invalid: true, + fields: [ + { fieldName: "postal-code", reason: "regex-heuristic" }, + { fieldName: "email", reason: "regex-heuristic" }, + ], + }, + ], + }, + { + description: `An address section is invalid when it contains only less than three fields when autocomplete is used on only one field`, + fixtureData: ` + <html><body> + <input id="postal-code"> <input id="email" autocomplete="email"> </body></html> `, expectedResult: [ { + description: "A section with two fields", + fields: [ + { fieldName: "postal-code", reason: "regex-heuristic" }, + { fieldName: "email", reason: "autocomplete" }, + ], + }, + ], + }, + { + description: `Address section validation only counts the number of different address field name in the section`, + fixtureData: ` + <html><body> + <input id="postal-code"> + <input id="email"> + <input id="email"> + </body></html> + `, + expectedResult: [ + { description: "A section with three fields but has duplicated email fields", invalid: true, fields: [ - { fieldName: "postal-code", reason: "autocomplete" }, - { fieldName: "email", reason: "autocomplete" }, - { fieldName: "email", reason: "autocomplete" }, + { fieldName: "postal-code", reason: "regex-heuristic" }, + { fieldName: "email", reason: "regex-heuristic" }, + { fieldName: "email", reason: "regex-heuristic" }, ], }, ], diff --git a/browser/extensions/formautofill/test/browser/heuristics/browser_sections_by_name.js b/browser/extensions/formautofill/test/browser/heuristics/browser_sections_by_name.js @@ -248,7 +248,6 @@ add_heuristic_tests([ ], }, { - invalid: true, fields: [{ fieldName: "name", reason: "autocomplete" }], }, ], diff --git a/browser/extensions/formautofill/test/browser/heuristics/third_party/browser_HomeDepot.js b/browser/extensions/formautofill/test/browser/heuristics/third_party/browser_HomeDepot.js @@ -21,7 +21,6 @@ add_heuristic_tests( ], }, { - invalid: true, fields: [ { fieldName: "street-address", diff --git a/toolkit/components/formautofill/FormAutofillChild.sys.mjs b/toolkit/components/formautofill/FormAutofillChild.sys.mjs @@ -143,10 +143,7 @@ export class FormAutofillChild extends JSWindowActorChild { // Bug 1905040. This is only a temporarily workaround for now to skip marking address fields // autocompletable whenever we detect an address field. We only mark address field when // it is a valid address section (This is done in the parent) - const addressFieldSet = new Set(addressFields.map(fd => fd.fieldName)); - if ( - addressFieldSet.size < lazy.FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD - ) { + if (!lazy.FormAutofillUtils.isValidSection(addressFields)) { addressFields = []; } @@ -179,7 +176,9 @@ export class FormAutofillChild extends JSWindowActorChild { "address-line1", "address-line2", "address-line3", - ].some(fieldName => addressFieldSet.has(fieldName))) + ].some(fieldName => + addressFields.some(fd => fd.fieldName == fieldName) + )) ) { this.manager .getActor("FormHandler") diff --git a/toolkit/components/formautofill/shared/FormAutofillSection.sys.mjs b/toolkit/components/formautofill/shared/FormAutofillSection.sys.mjs @@ -495,8 +495,7 @@ export class FormAutofillSection { export class FormAutofillAddressSection extends FormAutofillSection { isValidSection() { - const fields = new Set(this.fieldDetails.map(f => f.fieldName)); - return fields.size >= lazy.FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD; + return lazy.FormAutofillUtils.isValidSection(this.fieldDetails); } isEnabled() { diff --git a/toolkit/components/formautofill/shared/FormAutofillUtils.sys.mjs b/toolkit/components/formautofill/shared/FormAutofillUtils.sys.mjs @@ -204,6 +204,17 @@ FormAutofillUtils = { ); }, + isValidSection(fieldDetails) { + // If one of the fields has the autocomplete reason, the section is valid. + if (fieldDetails.some(f => f.reason == "autocomplete")) { + return true; + } + + // Otherwise, there must be a minimum number of fields. + const fields = new Set(fieldDetails.map(f => f.fieldName)); + return fields.size >= this.AUTOFILL_FIELDS_THRESHOLD; + }, + queryEligibleElements(element, includeIframe = false) { const types = includeIframe ? [...ELIGIBLE_ELEMENT_TYPES, "iframe"]