Bug 1370429 - Part 5: Add tel-extension support. r=MattN
MozReview-Commit-ID: 7XdiwYWERBC
--- a/browser/extensions/formautofill/FormAutofillHeuristics.jsm
+++ b/browser/extensions/formautofill/FormAutofillHeuristics.jsm
@@ -176,38 +176,16 @@ class FieldScanner {
return this.fieldDetails.filter(f => f.fieldName && !f._duplicated);
}
}
/**
* Returns the autocomplete information of fields according to heuristics.
*/
this.FormAutofillHeuristics = {
- FIELD_GROUPS: {
- NAME: [
- "name",
- "given-name",
- "additional-name",
- "family-name",
- ],
- ADDRESS: [
- "organization",
- "street-address",
- "address-line1",
- "address-line2",
- "address-line3",
- "address-level2",
- "address-level1",
- "postal-code",
- "country",
- ],
- TEL: ["tel"],
- EMAIL: ["email"],
- },
-
RULES: null,
/**
* This function tries to match the telephone related fields to the grammar
* list to see if there is any valid telephone set and correct their
* field names.
*
* @param {Object} fieldScanner
@@ -263,16 +241,22 @@ this.FormAutofillHeuristics = {
for (let i = ruleFrom; i < ruleTo; i++) {
fieldScanner.updateFieldName(detailStart, GRAMMARS[i][1]);
fieldScanner.indexParsing++;
detailStart++;
parsedField = true;
}
}
+ let nextField = fieldScanner.getFieldDetailByIndex(fieldScanner.indexParsing);
+ if (nextField && nextField.fieldName == "tel-extension") {
+ fieldScanner.indexParsing++;
+ parsedField = true;
+ }
+
return parsedField;
},
/**
* This function tries to find the correct address-line[1-3] sequence and
* correct their field names.
*
* @param {Object} fieldScanner
@@ -313,55 +297,16 @@ this.FormAutofillHeuristics = {
// forward to the next one.
if (!parsedPhoneFields && !parsedAddressFields) {
fieldScanner.indexParsing++;
}
}
return fieldScanner.trimmedFieldDetail;
},
- /**
- * Get the autocomplete info (e.g. fieldName) determined by the regexp
- * (this.RULES) matching to a feature string.
- *
- * @param {string} string a feature string to be determined.
- * @returns {Object}
- * Provide the predicting result including the field name.
- *
- */
- _matchStringToFieldName(string) {
- let result = {
- fieldName: "",
- section: "",
- addressType: "",
- contactType: "",
- };
- if (this.RULES.email.test(string)) {
- result.fieldName = "email";
- return result;
- }
- if (this.RULES.tel.test(string)) {
- result.fieldName = "tel";
- return result;
- }
- for (let fieldName of this.FIELD_GROUPS.ADDRESS) {
- if (this.RULES[fieldName].test(string)) {
- result.fieldName = fieldName;
- return result;
- }
- }
- for (let fieldName of this.FIELD_GROUPS.NAME) {
- if (this.RULES[fieldName].test(string)) {
- result.fieldName = fieldName;
- return result;
- }
- }
- return null;
- },
-
getInfo(element) {
if (!FormAutofillUtils.isFieldEligibleForAutofill(element)) {
return null;
}
let info = element.getAutocompleteInfo();
// An input[autocomplete="on"] will not be early return here since it stll
// needs to find the field name.
@@ -381,33 +326,42 @@ this.FormAutofillHeuristics = {
return {
fieldName: "email",
section: "",
addressType: "",
contactType: "",
};
}
- for (let elementString of [element.id, element.name]) {
- let fieldNameResult = this._matchStringToFieldName(elementString);
- if (fieldNameResult) {
- return fieldNameResult;
+ let regexps = Object.keys(this.RULES);
+
+ let labelStrings;
+ let getElementStrings = {};
+ getElementStrings[Symbol.iterator] = function* () {
+ yield element.id;
+ yield element.name;
+ if (!labelStrings) {
+ labelStrings = [];
+ let labels = FormAutofillUtils.findLabelElements(element);
+ for (let label of labels) {
+ labelStrings.push(...FormAutofillUtils.extractLabelStrings(label));
+ }
}
- }
- let labels = FormAutofillUtils.findLabelElements(element);
- if (!labels || labels.length == 0) {
- log.debug("No label found for", element);
- return null;
- }
- for (let label of labels) {
- let strings = FormAutofillUtils.extractLabelStrings(label);
- for (let string of strings) {
- let fieldNameResult = this._matchStringToFieldName(string);
- if (fieldNameResult) {
- return fieldNameResult;
+ yield *labelStrings;
+ };
+
+ for (let regexp of regexps) {
+ for (let string of getElementStrings) {
+ if (this.RULES[regexp].test(string)) {
+ return {
+ fieldName: regexp,
+ section: "",
+ addressType: "",
+ contactType: "",
+ };
}
}
}
return null;
},
/**
--- a/browser/extensions/formautofill/FormAutofillUtils.jsm
+++ b/browser/extensions/formautofill/FormAutofillUtils.jsm
@@ -32,16 +32,17 @@ this.FormAutofillUtils = {
"country-name": "address",
"tel": "tel",
"tel-country-code": "tel",
"tel-national": "tel",
"tel-area-code": "tel",
"tel-local": "tel",
"tel-local-prefix": "tel",
"tel-local-suffix": "tel",
+ "tel-extension": "tel",
"email": "email",
"cc-name": "creditCard",
"cc-number": "creditCard",
"cc-exp-month": "creditCard",
"cc-exp-year": "creditCard",
},
_addressDataLoaded: false,
--- a/browser/extensions/formautofill/content/heuristicsRegexp.js
+++ b/browser/extensions/formautofill/content/heuristicsRegexp.js
@@ -24,16 +24,21 @@ var HeuristicsRegExp = {
"|Электронной.?Почты" + // ru
"|邮件|邮箱" + // zh-CN
"|電郵地址" + // zh-TW
"|(?:이메일|전자.?우편|[Ee]-?mail)(.?주소)?", // ko-KR
"iu"
),
// ==== Telephone ====
+ "tel-extension": new RegExp(
+ "\\bext|ext\\b|extension" +
+ "|ramal", // pt-BR, pt-PT
+ "iu"
+ ),
"tel": new RegExp(
"phone|mobile|contact.?number" +
"|telefonnummer" + // de-DE
"|telefono|teléfono" + // es
"|telfixe" + // fr-FR
"|電話" + // ja-JP
"|telefone|telemovel" + // pt-BR, pt-PT
"|телефон" + // ru
@@ -150,16 +155,27 @@ var HeuristicsRegExp = {
"|país|pais" + // es
"|国" + // ja-JP
"|国家" + // zh-CN
"|국가|나라", // ko-KR
"iu"
),
// ==== Name Fields ====
+ "name": new RegExp(
+ "^name|full.?name|your.?name|customer.?name|bill.?name|ship.?name" +
+ "|name.*first.*last|firstandlastname" +
+ "|nombre.*y.*apellidos" + // es
+ "|^nom" + // fr-FR
+ "|お名前|氏名" + // ja-JP
+ "|^nome" + // pt-BR, pt-PT
+ "|姓名" + // zh-CN
+ "|성명", // ko-KR
+ "iu"
+ ),
"given-name": new RegExp(
"first.*name|initials|fname|first$|given.*name" +
"|vorname" + // de-DE
"|nombre" + // es
"|forename|prénom|prenom" + // fr-FR
"|名" + // ja-JP
"|nome" + // pt-BR, pt-PT
"|Имя" + // ru
@@ -181,21 +197,10 @@ var HeuristicsRegExp = {
"|famille|^nom" + // fr-FR
"|cognome" + // it-IT
"|姓" + // ja-JP
"|morada|apelidos|surename|sobrenome" + // pt-BR, pt-PT
"|Фамилия" + // ru
"|\\b성(?:[^명]|\\b)", // ko-KR
"iu"
),
- "name": new RegExp(
- "^name|full.?name|your.?name|customer.?name|bill.?name|ship.?name" +
- "|name.*first.*last|firstandlastname" +
- "|nombre.*y.*apellidos" + // es
- "|^nom" + // fr-FR
- "|お名前|氏名" + // ja-JP
- "|^nome" + // pt-BR, pt-PT
- "|姓名" + // zh-CN
- "|성명", // ko-KR
- "iu"
- ),
},
};