mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Bug 1383058 - Always adopt the info from the autocomplete attribute for autofill. r=MattN
MozReview-Commit-ID: CdAX9XZX7R0 --HG-- extra : amend_source : 93a5873c356eb0fdf9e5f70b3775b6b1c332d63a
This commit is contained in:
parent
7aa262a783
commit
939e51f819
@ -115,13 +115,16 @@ FormAutofillHandler.prototype = {
|
||||
|
||||
/**
|
||||
* Set fieldDetails from the form about fields that can be autofilled.
|
||||
|
||||
*
|
||||
* @param {boolean} allowDuplicates
|
||||
* true to remain any duplicated field details otherwise to remove the
|
||||
* duplicated ones.
|
||||
* @returns {Array} The valid address and credit card details.
|
||||
*/
|
||||
collectFormFields() {
|
||||
collectFormFields(allowDuplicates = false) {
|
||||
this._cacheValue.allFieldNames = null;
|
||||
this._formFieldCount = this.form.elements.length;
|
||||
let fieldDetails = FormAutofillHeuristics.getFormInfo(this.form);
|
||||
let fieldDetails = FormAutofillHeuristics.getFormInfo(this.form, allowDuplicates);
|
||||
this.fieldDetails = fieldDetails ? fieldDetails : [];
|
||||
log.debug("Collected details on", this.fieldDetails.length, "fields");
|
||||
|
||||
|
@ -123,6 +123,10 @@ class FieldScanner {
|
||||
elementWeakRef: Cu.getWeakReference(element),
|
||||
};
|
||||
|
||||
if (info._reason) {
|
||||
fieldInfo._reason = info._reason;
|
||||
}
|
||||
|
||||
// Store the association between the field metadata and the element.
|
||||
if (this.findSameField(info) != -1) {
|
||||
// A field with the same identifier already exists.
|
||||
@ -204,7 +208,7 @@ this.FormAutofillHeuristics = {
|
||||
let ruleStart = i;
|
||||
for (; i < GRAMMARS.length && GRAMMARS[i][0] && fieldScanner.elementExisting(detailStart); i++, detailStart++) {
|
||||
let detail = fieldScanner.getFieldDetailByIndex(detailStart);
|
||||
if (!detail || GRAMMARS[i][0] != detail.fieldName) {
|
||||
if (!detail || GRAMMARS[i][0] != detail.fieldName || detail._reason == "autocomplete") {
|
||||
break;
|
||||
}
|
||||
let element = detail.elementWeakRef.get();
|
||||
@ -288,7 +292,23 @@ this.FormAutofillHeuristics = {
|
||||
return parsedFields;
|
||||
},
|
||||
|
||||
getFormInfo(form) {
|
||||
/**
|
||||
* This function should provide all field details of a form. The details
|
||||
* contain the autocomplete info (e.g. fieldName, section, etc).
|
||||
*
|
||||
* `allowDuplicates` is used for the xpcshell-test purpose currently because
|
||||
* the heuristics should be verified that some duplicated elements still can
|
||||
* be predicted correctly.
|
||||
*
|
||||
* @param {HTMLFormElement} form
|
||||
* the elements in this form to be predicted the field info.
|
||||
* @param {boolean} allowDuplicates
|
||||
* true to remain any duplicated field details otherwise to remove the
|
||||
* duplicated ones.
|
||||
* @returns {Array<Object>}
|
||||
* all field details in the form.
|
||||
*/
|
||||
getFormInfo(form, allowDuplicates = false) {
|
||||
if (form.autocomplete == "off" || form.elements.length <= 0) {
|
||||
return [];
|
||||
}
|
||||
@ -304,6 +324,10 @@ this.FormAutofillHeuristics = {
|
||||
fieldScanner.parsingIndex++;
|
||||
}
|
||||
}
|
||||
if (allowDuplicates) {
|
||||
return fieldScanner.fieldDetails;
|
||||
}
|
||||
|
||||
return fieldScanner.trimmedFieldDetail;
|
||||
},
|
||||
|
||||
@ -316,6 +340,7 @@ this.FormAutofillHeuristics = {
|
||||
// An input[autocomplete="on"] will not be early return here since it stll
|
||||
// needs to find the field name.
|
||||
if (info && info.fieldName && info.fieldName != "on") {
|
||||
info._reason = "autocomplete";
|
||||
return info;
|
||||
}
|
||||
|
||||
|
@ -149,6 +149,7 @@ function runHeuristicsTest(patterns, fixturePathPrefix) {
|
||||
Assert.equal(formInfo.length, testPattern.expectedResult[formIndex].length, "Expected field count.");
|
||||
formInfo.forEach((field, fieldIndex) => {
|
||||
let expectedField = testPattern.expectedResult[formIndex][fieldIndex];
|
||||
delete field._reason;
|
||||
expectedField.elementWeakRef = field.elementWeakRef;
|
||||
Assert.deepEqual(field, expectedField);
|
||||
});
|
||||
|
@ -174,28 +174,29 @@ const TESTCASES = [
|
||||
{
|
||||
description: "Three sets of adjacent phone number fields",
|
||||
document: `<form>
|
||||
<input id="shippingAreaCode" autocomplete="shipping tel" maxlength="3">
|
||||
<input id="shippingPrefix" autocomplete="shipping tel" maxlength="3">
|
||||
<input id="shippingSuffix" autocomplete="shipping tel" maxlength="4">
|
||||
<input id="shippingTelExt" autocomplete="shipping tel-extension">
|
||||
<input id="shippingAC" name="phone" maxlength="3">
|
||||
<input id="shippingPrefix" name="phone" maxlength="3">
|
||||
<input id="shippingSuffix" name="phone" maxlength="4">
|
||||
<input id="shippingTelExt" name="extension">
|
||||
|
||||
<input id="billingAreaCode" autocomplete="billing tel" maxlength="3">
|
||||
<input id="billingPrefix" autocomplete="billing tel" maxlength="3">
|
||||
<input id="billingSuffix" autocomplete="billing tel" maxlength="4">
|
||||
<input id="billingAC" name="phone" maxlength="3">
|
||||
<input id="billingPrefix" name="phone" maxlength="3">
|
||||
<input id="billingSuffix" name="phone" maxlength="4">
|
||||
|
||||
<input id="otherCountryCode" autocomplete="tel" maxlength="3">
|
||||
<input id="otherAreaCode" autocomplete="tel" maxlength="3">
|
||||
<input id="otherPrefix" autocomplete="tel" maxlength="3">
|
||||
<input id="otherSuffix" autocomplete="tel" maxlength="4">
|
||||
<input id="otherCC" name="phone" maxlength="3">
|
||||
<input id="otherAC" name="phone" maxlength="3">
|
||||
<input id="otherPrefix" name="phone" maxlength="3">
|
||||
<input id="otherSuffix" name="phone" maxlength="4">
|
||||
</form>`,
|
||||
allowDuplicates: true,
|
||||
addressFieldDetails: [
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-area-code"},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-local-suffix"},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-extension"},
|
||||
{"section": "", "addressType": "billing", "contactType": "", "fieldName": "tel-area-code"},
|
||||
{"section": "", "addressType": "billing", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
{"section": "", "addressType": "billing", "contactType": "", "fieldName": "tel-local-suffix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-country-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
@ -203,22 +204,22 @@ const TESTCASES = [
|
||||
],
|
||||
creditCardFieldDetails: [],
|
||||
validFieldDetails: [
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-area-code"},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-local-suffix"},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-extension"},
|
||||
{"section": "", "addressType": "billing", "contactType": "", "fieldName": "tel-area-code"},
|
||||
{"section": "", "addressType": "billing", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
{"section": "", "addressType": "billing", "contactType": "", "fieldName": "tel-local-suffix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-country-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
|
||||
],
|
||||
ids: [
|
||||
"shippingAreaCode", "shippingPrefix", "shippingSuffix", "shippingTelExt",
|
||||
"billingAreaCode", "billingPrefix", "billingSuffix",
|
||||
"otherCountryCode", "otherAreaCode", "otherPrefix", "otherSuffix",
|
||||
"shippingAC", "shippingPrefix", "shippingSuffix", "shippingTelExt",
|
||||
"billingAC", "billingPrefix", "billingSuffix",
|
||||
"otherCC", "otherAC", "otherPrefix", "otherSuffix",
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -290,6 +291,28 @@ const TESTCASES = [
|
||||
ids: ["i1", "i2", "i3", "i4", "singlePhone",
|
||||
"shippingAreaCode", "shippingPrefix", "shippingSuffix"],
|
||||
},
|
||||
{
|
||||
description: "Always adopt the info from autocomplete attribute.",
|
||||
document: `<form>
|
||||
<input id="given-name" autocomplete="shipping given-name">
|
||||
<input id="family-name" autocomplete="shipping family-name">
|
||||
<input id="dummyAreaCode" autocomplete="shipping tel" maxlength="3">
|
||||
<input id="dummyPrefix" autocomplete="shipping tel" maxlength="3">
|
||||
<input id="dummySuffix" autocomplete="shipping tel" maxlength="4">
|
||||
</form>`,
|
||||
addressFieldDetails: [
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
|
||||
],
|
||||
creditCardFieldDetails: [],
|
||||
validFieldDetails: [
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
|
||||
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
|
||||
],
|
||||
ids: ["given-name", "family-name", "dummyAreaCode"],
|
||||
},
|
||||
];
|
||||
|
||||
for (let tc of TESTCASES) {
|
||||
@ -340,7 +363,7 @@ for (let tc of TESTCASES) {
|
||||
].forEach(details => setElementWeakRef(details));
|
||||
|
||||
let handler = new FormAutofillHandler(formLike);
|
||||
let validFieldDetails = handler.collectFormFields();
|
||||
let validFieldDetails = handler.collectFormFields(testcase.allowDuplicates);
|
||||
|
||||
verifyDetails(handler.address.fieldDetails, testcase.addressFieldDetails);
|
||||
verifyDetails(handler.creditCard.fieldDetails, testcase.creditCardFieldDetails);
|
||||
|
Loading…
Reference in New Issue
Block a user