--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -100,17 +100,17 @@ AutofillProfileAutoCompleteSearch.protot
onSearchResult: (search, result) => {
listener.onSearchResult(this, result);
ProfileAutocomplete.setProfileAutoCompleteResult(result);
},
});
return;
}
- let collectionName = FormAutofillUtils.isAddressField(info.fieldName) ?
+ let collectionName = FormAutofillHandler.prototype.isAddressField(info.fieldName) ?
"addresses" : "creditCards";
this._getRecords({collectionName, info, searchString}).then((records) => {
if (this.forceStop) {
return;
}
// Sort addresses by timeLastUsed for showing the lastest used address at top.
records.sort((a, b) => b.timeLastUsed - a.timeLastUsed);
@@ -455,21 +455,16 @@ var FormAutofillContent = {
identifyAutofillFields(element) {
this.log.debug("identifyAutofillFields:", "" + element.ownerDocument.location);
if (!this.savedFieldNames) {
this.log.debug("identifyAutofillFields: savedFieldNames are not known yet");
Services.cpmm.sendAsyncMessage("FormAutofill:InitStorage");
}
- if (!FormAutofillUtils.isFieldEligibleForAutofill(element)) {
- this.log.debug("Not an eligible field.");
- return;
- }
-
let formHandler = this.getFormHandler(element);
if (!formHandler) {
let formLike = FormLikeFactory.createFromField(element);
formHandler = new FormAutofillHandler(formLike);
} else if (!formHandler.isFormChangedSinceLastCollection) {
this.log.debug("No control is removed or inserted since last collection.");
return;
}
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -3,26 +3,29 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Defines a handler object to represent forms that autofill can handle.
*/
"use strict";
-this.EXPORTED_SYMBOLS = ["FormAutofillHandler"];
+this.EXPORTED_SYMBOLS = ["FormAutofillHandler", "FormAutofillHeuristics"];
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "FormAutofillHeuristics",
- "resource://formautofill/FormAutofillHeuristics.jsm");
+const PREF_HEURISTICS_ENABLED = "extensions.formautofill.heuristics.enabled";
+
+const ALLOWED_TYPES = Array.from(FormAutofillUtils.ALLOWED_TYPES);
+const FIELD_NAME_INFO = Object.assign({}, FormAutofillUtils.FIELD_NAME_INFO);
+const AUTOFILL_FIELDS_THRESHOLD = FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD;
this.log = null;
FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
/**
* Handles profile autofill for a DOM Form element.
* @param {FormLike} form Form that need to be auto filled
*/
@@ -64,17 +67,17 @@ FormAutofillHandler.prototype = {
/**
* Similiar to `fieldDetails`, and `creditCardFieldDetails` contains the
* Credit Card records only.
*/
creditCardFieldDetails: null,
get isValidAddressForm() {
- return this.addressFieldDetails.length > FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD;
+ return this.addressFieldDetails.length > AUTOFILL_FIELDS_THRESHOLD;
},
get isValidCreditCardForm() {
return this.creditCardFieldDetails.some(i => i.fieldName == "cc-number");
},
/**
* String of the filled profile's guid.
@@ -112,20 +115,20 @@ FormAutofillHandler.prototype = {
collectFormFields() {
this._cacheValue.allFieldNames = null;
this._formFieldCount = this.form.elements.length;
let fieldDetails = FormAutofillHeuristics.getFormInfo(this.form);
this.fieldDetails = fieldDetails ? fieldDetails : [];
log.debug("Collected details on", this.fieldDetails.length, "fields");
this.addressFieldDetails = this.fieldDetails.filter(
- detail => FormAutofillUtils.isAddressField(detail.fieldName)
+ detail => this.isAddressField(detail.fieldName)
);
this.creditCardFieldDetails = this.fieldDetails.filter(
- detail => FormAutofillUtils.isCreditCardField(detail.fieldName)
+ detail => this.isCreditCardField(detail.fieldName)
);
},
getFieldDetailByName(fieldName) {
return this.fieldDetails.find(detail => detail.fieldName == fieldName);
},
_cacheValue: {
@@ -395,9 +398,292 @@ FormAutofillHandler.prototype = {
return;
}
profile[detail.fieldName] = value;
});
return profile;
},
+
+ isAddressField(fieldName) {
+ return !!FIELD_NAME_INFO[fieldName] && !this.isCreditCardField(fieldName);
+ },
+
+ isCreditCardField(fieldName) {
+ return FIELD_NAME_INFO[fieldName] == "creditCard";
+ },
};
+
+/**
+ * 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,
+
+ getFormInfo(form) {
+ let fieldDetails = [];
+ if (form.autocomplete == "off") {
+ return [];
+ }
+ for (let element of form.elements) {
+ // Exclude elements to which no autocomplete field has been assigned.
+ let info = this.getInfo(element, fieldDetails);
+ if (!info) {
+ continue;
+ }
+
+ // Store the association between the field metadata and the element.
+ if (fieldDetails.some(f => f.section == info.section &&
+ f.addressType == info.addressType &&
+ f.contactType == info.contactType &&
+ f.fieldName == info.fieldName)) {
+ // A field with the same identifier already exists.
+ log.debug("Not collecting a field matching another with the same info:", info);
+ continue;
+ }
+
+ let formatWithElement = {
+ section: info.section,
+ addressType: info.addressType,
+ contactType: info.contactType,
+ fieldName: info.fieldName,
+ elementWeakRef: Cu.getWeakReference(element),
+ };
+
+ fieldDetails.push(formatWithElement);
+ }
+
+ return fieldDetails;
+ },
+
+ /**
+ * Get the autocomplete info (e.g. fieldName) determined by the regexp
+ * (this.RULES) matching to a feature string. The result is based on the
+ * existing field names to prevent duplicating predictions
+ * (e.g. address-line[1-3).
+ *
+ * @param {string} string a feature string to be determined.
+ * @param {Array<string>} existingFieldNames the array of exising field names
+ * in a form.
+ * @returns {Object}
+ * Provide the predicting result including the field name.
+ *
+ */
+ _matchStringToFieldName(string, existingFieldNames) {
+ 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)) {
+ // If "address-line1" or "address-line2" exist already, the string
+ // could be satisfied with "address-line2" or "address-line3".
+ if ((fieldName == "address-line1" &&
+ existingFieldNames.includes("address-line1")) ||
+ (fieldName == "address-line2" &&
+ existingFieldNames.includes("address-line2"))) {
+ continue;
+ }
+ 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, fieldDetails) {
+ let autocomplete = element.autocomplete;
+ let tagName = element.tagName;
+ let type = element.type;
+
+ if (autocomplete == "off") {
+ return null;
+ } else if (tagName == "INPUT") {
+ if (!ALLOWED_TYPES.includes(type)) {
+ return null;
+ }
+ } else if (tagName != "SELECT") {
+ return null;
+ }
+
+ // An input[autocomplete="on"] will not be early return here since it stll
+ // needs to find the field name.
+ if (autocomplete != "on") {
+ let info = element.getAutocompleteInfo();
+ if (info && info.fieldName) {
+ return info;
+ }
+ }
+
+ if (!this._prefEnabled) {
+ return null;
+ }
+
+ // "email" type of input is accurate for heuristics to determine its Email
+ // field or not. However, "tel" type is used for ZIP code for some web site
+ // (e.g. HomeDepot, BestBuy), so "tel" type should be not used for "tel"
+ // prediction.
+ if (type == "email") {
+ return {
+ fieldName: "email",
+ section: "",
+ addressType: "",
+ contactType: "",
+ };
+ }
+
+ let existingFieldNames = fieldDetails ? fieldDetails.map(i => i.fieldName) : [];
+
+ for (let elementString of [element.id, element.name]) {
+ let fieldNameResult = this._matchStringToFieldName(elementString,
+ existingFieldNames);
+ if (fieldNameResult) {
+ return fieldNameResult;
+ }
+ }
+ let labels = this.findLabelElements(element);
+ if (!labels || labels.length == 0) {
+ log.debug("No label found for", element);
+ return null;
+ }
+ for (let label of labels) {
+ let strings = this.extractLabelStrings(label);
+ for (let string of strings) {
+ let fieldNameResult = this._matchStringToFieldName(string,
+ existingFieldNames);
+ if (fieldNameResult) {
+ return fieldNameResult;
+ }
+ }
+ }
+
+ return null;
+ },
+
+ // The tag name list is from Chromium except for "STYLE":
+ // eslint-disable-next-line max-len
+ // https://cs.chromium.org/chromium/src/components/autofill/content/renderer/form_autofill_util.cc?l=216&rcl=d33a171b7c308a64dc3372fac3da2179c63b419e
+ EXCLUDED_TAGS: ["SCRIPT", "NOSCRIPT", "OPTION", "STYLE"],
+ /**
+ * Extract all strings of an element's children to an array.
+ * "element.textContent" is a string which is merged of all children nodes,
+ * and this function provides an array of the strings contains in an element.
+ *
+ * @param {Object} element
+ * A DOM element to be extracted.
+ * @returns {Array}
+ * All strings in an element.
+ */
+ extractLabelStrings(element) {
+ let strings = [];
+ let _extractLabelStrings = (el) => {
+ if (this.EXCLUDED_TAGS.includes(el.tagName)) {
+ return;
+ }
+
+ if (el.nodeType == Ci.nsIDOMNode.TEXT_NODE ||
+ el.childNodes.length == 0) {
+ let trimmedText = el.textContent.trim();
+ if (trimmedText) {
+ strings.push(trimmedText);
+ }
+ return;
+ }
+
+ for (let node of el.childNodes) {
+ if (node.nodeType != Ci.nsIDOMNode.ELEMENT_NODE &&
+ node.nodeType != Ci.nsIDOMNode.TEXT_NODE) {
+ continue;
+ }
+ _extractLabelStrings(node);
+ }
+ };
+ _extractLabelStrings(element);
+ return strings;
+ },
+
+ findLabelElements(element) {
+ let document = element.ownerDocument;
+ let id = element.id;
+ let labels = [];
+ // TODO: querySelectorAll is inefficient here. However, bug 1339726 is for
+ // a more efficient implementation from DOM API perspective. This function
+ // should be refined after input.labels API landed.
+ for (let label of document.querySelectorAll("label[for]")) {
+ if (id == label.htmlFor) {
+ labels.push(label);
+ }
+ }
+
+ if (labels.length > 0) {
+ log.debug("Label found by ID", id);
+ return labels;
+ }
+
+ let parent = element.parentNode;
+ if (!parent) {
+ return [];
+ }
+ do {
+ if (parent.tagName == "LABEL" &&
+ parent.control == element &&
+ !parent.hasAttribute("for")) {
+ log.debug("Label found in input's parent or ancestor.");
+ return [parent];
+ }
+ parent = parent.parentNode;
+ } while (parent);
+
+ return [];
+ },
+};
+
+XPCOMUtils.defineLazyGetter(this.FormAutofillHeuristics, "RULES", () => {
+ let sandbox = {};
+ let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
+ .getService(Ci.mozIJSSubScriptLoader);
+ const HEURISTICS_REGEXP = "chrome://formautofill/content/heuristicsRegexp.js";
+ scriptLoader.loadSubScript(HEURISTICS_REGEXP, sandbox, "utf-8");
+ return sandbox.HeuristicsRegExp.RULES;
+});
+
+XPCOMUtils.defineLazyGetter(this.FormAutofillHeuristics, "_prefEnabled", () => {
+ return Services.prefs.getBoolPref(PREF_HEURISTICS_ENABLED);
+});
deleted file mode 100644
--- a/browser/extensions/formautofill/FormAutofillHeuristics.jsm
+++ /dev/null
@@ -1,301 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Form Autofill field heuristics.
- */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["FormAutofillHeuristics"];
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://formautofill/FormAutofillUtils.jsm");
-
-this.log = null;
-FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
-
-const PREF_HEURISTICS_ENABLED = "extensions.formautofill.heuristics.enabled";
-
-const ALLOWED_TYPES = Array.from(FormAutofillUtils.ALLOWED_TYPES);
-
-/**
- * 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,
-
- getFormInfo(form) {
- let fieldDetails = [];
- if (form.autocomplete == "off") {
- return [];
- }
- for (let element of form.elements) {
- // Exclude elements to which no autocomplete field has been assigned.
- let info = this.getInfo(element, fieldDetails);
- if (!info) {
- continue;
- }
-
- // Store the association between the field metadata and the element.
- if (fieldDetails.some(f => f.section == info.section &&
- f.addressType == info.addressType &&
- f.contactType == info.contactType &&
- f.fieldName == info.fieldName)) {
- // A field with the same identifier already exists.
- log.debug("Not collecting a field matching another with the same info:", info);
- continue;
- }
-
- let formatWithElement = {
- section: info.section,
- addressType: info.addressType,
- contactType: info.contactType,
- fieldName: info.fieldName,
- elementWeakRef: Cu.getWeakReference(element),
- };
-
- fieldDetails.push(formatWithElement);
- }
-
- return fieldDetails;
- },
-
- /**
- * Get the autocomplete info (e.g. fieldName) determined by the regexp
- * (this.RULES) matching to a feature string. The result is based on the
- * existing field names to prevent duplicating predictions
- * (e.g. address-line[1-3).
- *
- * @param {string} string a feature string to be determined.
- * @param {Array<string>} existingFieldNames the array of exising field names
- * in a form.
- * @returns {Object}
- * Provide the predicting result including the field name.
- *
- */
- _matchStringToFieldName(string, existingFieldNames) {
- 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)) {
- // If "address-line1" or "address-line2" exist already, the string
- // could be satisfied with "address-line2" or "address-line3".
- if ((fieldName == "address-line1" &&
- existingFieldNames.includes("address-line1")) ||
- (fieldName == "address-line2" &&
- existingFieldNames.includes("address-line2"))) {
- continue;
- }
- 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, fieldDetails) {
- let autocomplete = element.autocomplete;
- let tagName = element.tagName;
- let type = element.type;
-
- if (autocomplete == "off") {
- return null;
- } else if (tagName == "INPUT") {
- if (!ALLOWED_TYPES.includes(type)) {
- return null;
- }
- } else if (tagName != "SELECT") {
- return null;
- }
-
- // An input[autocomplete="on"] will not be early return here since it stll
- // needs to find the field name.
- let info = autocomplete && autocomplete != "on" ? element.getAutocompleteInfo() : null;
- if (info && info.fieldName) {
- return info;
- }
-
- if (!this._prefEnabled) {
- return null;
- }
-
- // "email" type of input is accurate for heuristics to determine its Email
- // field or not. However, "tel" type is used for ZIP code for some web site
- // (e.g. HomeDepot, BestBuy), so "tel" type should be not used for "tel"
- // prediction.
- if (type == "email") {
- return {
- fieldName: "email",
- section: "",
- addressType: "",
- contactType: "",
- };
- }
-
- let existingFieldNames = fieldDetails ? fieldDetails.map(i => i.fieldName) : [];
-
- for (let elementString of [element.id, element.name]) {
- let fieldNameResult = this._matchStringToFieldName(elementString,
- existingFieldNames);
- if (fieldNameResult) {
- return fieldNameResult;
- }
- }
- let labels = this.findLabelElements(element);
- if (!labels || labels.length == 0) {
- log.debug("No label found for", element);
- return null;
- }
- for (let label of labels) {
- let strings = this.extractLabelStrings(label);
- for (let string of strings) {
- let fieldNameResult = this._matchStringToFieldName(string,
- existingFieldNames);
- if (fieldNameResult) {
- return fieldNameResult;
- }
- }
- }
-
- return null;
- },
-
- // The tag name list is from Chromium except for "STYLE":
- // eslint-disable-next-line max-len
- // https://cs.chromium.org/chromium/src/components/autofill/content/renderer/form_autofill_util.cc?l=216&rcl=d33a171b7c308a64dc3372fac3da2179c63b419e
- EXCLUDED_TAGS: ["SCRIPT", "NOSCRIPT", "OPTION", "STYLE"],
- /**
- * Extract all strings of an element's children to an array.
- * "element.textContent" is a string which is merged of all children nodes,
- * and this function provides an array of the strings contains in an element.
- *
- * @param {Object} element
- * A DOM element to be extracted.
- * @returns {Array}
- * All strings in an element.
- */
- extractLabelStrings(element) {
- let strings = [];
- let _extractLabelStrings = (el) => {
- if (this.EXCLUDED_TAGS.includes(el.tagName)) {
- return;
- }
-
- if (el.nodeType == Ci.nsIDOMNode.TEXT_NODE ||
- el.childNodes.length == 0) {
- let trimmedText = el.textContent.trim();
- if (trimmedText) {
- strings.push(trimmedText);
- }
- return;
- }
-
- for (let node of el.childNodes) {
- if (node.nodeType != Ci.nsIDOMNode.ELEMENT_NODE &&
- node.nodeType != Ci.nsIDOMNode.TEXT_NODE) {
- continue;
- }
- _extractLabelStrings(node);
- }
- };
- _extractLabelStrings(element);
- return strings;
- },
-
- findLabelElements(element) {
- let document = element.ownerDocument;
- let id = element.id;
- let labels = [];
- // TODO: querySelectorAll is inefficient here. However, bug 1339726 is for
- // a more efficient implementation from DOM API perspective. This function
- // should be refined after input.labels API landed.
- for (let label of document.querySelectorAll("label[for]")) {
- if (id == label.htmlFor) {
- labels.push(label);
- }
- }
-
- if (labels.length > 0) {
- log.debug("Label found by ID", id);
- return labels;
- }
-
- let parent = element.parentNode;
- if (!parent) {
- return [];
- }
- do {
- if (parent.tagName == "LABEL" &&
- parent.control == element &&
- !parent.hasAttribute("for")) {
- log.debug("Label found in input's parent or ancestor.");
- return [parent];
- }
- parent = parent.parentNode;
- } while (parent);
-
- return [];
- },
-};
-
-XPCOMUtils.defineLazyGetter(this.FormAutofillHeuristics, "RULES", () => {
- let sandbox = {};
- let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader);
- const HEURISTICS_REGEXP = "chrome://formautofill/content/heuristicsRegexp.js";
- scriptLoader.loadSubScript(HEURISTICS_REGEXP, sandbox, "utf-8");
- return sandbox.HeuristicsRegExp.RULES;
-});
-
-XPCOMUtils.defineLazyGetter(this.FormAutofillHeuristics, "_prefEnabled", () => {
- return Services.prefs.getBoolPref(PREF_HEURISTICS_ENABLED);
-});
-
-Services.prefs.addObserver(PREF_HEURISTICS_ENABLED, () => {
- this.FormAutofillHeuristics._prefEnabled = Services.prefs.getBoolPref(PREF_HEURISTICS_ENABLED);
-});
--- a/browser/extensions/formautofill/FormAutofillUtils.jsm
+++ b/browser/extensions/formautofill/FormAutofillUtils.jsm
@@ -10,17 +10,17 @@ const {classes: Cc, interfaces: Ci, util
const ADDRESS_REFERENCES = "chrome://formautofill/content/addressReferences.js";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
this.FormAutofillUtils = {
get AUTOFILL_FIELDS_THRESHOLD() { return 3; },
- _fieldNameInfo: {
+ FIELD_NAME_INFO: {
"name": "name",
"given-name": "name",
"additional-name": "name",
"family-name": "name",
"organization": "organization",
"street-address": "address",
"address-line1": "address",
"address-line2": "address",
@@ -40,26 +40,18 @@ this.FormAutofillUtils = {
"email": "email",
"cc-name": "creditCard",
"cc-number": "creditCard",
"cc-exp-month": "creditCard",
"cc-exp-year": "creditCard",
},
_addressDataLoaded: false,
- isAddressField(fieldName) {
- return !!this._fieldNameInfo[fieldName] && !this.isCreditCardField(fieldName);
- },
-
- isCreditCardField(fieldName) {
- return this._fieldNameInfo[fieldName] == "creditCard";
- },
-
getCategoryFromFieldName(fieldName) {
- return this._fieldNameInfo[fieldName];
+ return this.FIELD_NAME_INFO[fieldName];
},
getCategoriesFromFieldNames(fieldNames) {
let categories = new Set();
for (let fieldName of fieldNames) {
let info = this.getCategoryFromFieldName(fieldName);
if (info) {
categories.add(info);
--- a/browser/extensions/formautofill/test/unit/head.js
+++ b/browser/extensions/formautofill/test/unit/head.js
@@ -1,12 +1,13 @@
/**
* Provides infrastructure for automated formautofill components tests.
*/
+/* global FormAutofillHeuristics */
/* exported getTempFile, loadFormAutofillContent, runHeuristicsTest, sinon,
* initProfileStorage, getSyncChangeCounter, objectMatches
*/
"use strict";
var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
@@ -113,17 +114,17 @@ async function initProfileStorage(fileNa
do_check_true(profileStorage.addresses.add(record));
await onChanged;
}
await profileStorage._saveImmediately();
return profileStorage;
}
function runHeuristicsTest(patterns, fixturePathPrefix) {
- Cu.import("resource://formautofill/FormAutofillHeuristics.jsm");
+ Cu.import("resource://formautofill/FormAutofillHandler.jsm");
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
patterns.forEach(testPattern => {
add_task(async function() {
do_print("Starting test fixture: " + testPattern.fixturePath);
let file = do_get_file(fixturePathPrefix + testPattern.fixturePath);
let doc = MockDocument.createTestDocumentFromFile("http://localhost:8080/test/", file);
--- a/browser/extensions/formautofill/test/unit/test_extractLabelStrings.js
+++ b/browser/extensions/formautofill/test/unit/test_extractLabelStrings.js
@@ -1,11 +1,11 @@
"use strict";
-Cu.import("resource://formautofill/FormAutofillHeuristics.jsm");
+Cu.import("resource://formautofill/FormAutofillHandler.jsm");
const TESTCASES = [
{
description: "A label element contains one input element.",
document: `<label id="typeA"> label type A
<!-- This comment should not be extracted. -->
<input type="text">
<script>FOO</script>
--- a/browser/extensions/formautofill/test/unit/test_findLabelElements.js
+++ b/browser/extensions/formautofill/test/unit/test_findLabelElements.js
@@ -1,11 +1,11 @@
"use strict";
-Cu.import("resource://formautofill/FormAutofillHeuristics.jsm");
+Cu.import("resource://formautofill/FormAutofillHandler.jsm");
const TESTCASES = [
{
description: "Input contains in a label element.",
document: `<form>
<label id="labelA"> label type A
<input id="typeA" type="text">
</label>
--- a/browser/extensions/formautofill/test/unit/test_getCategoriesFromFieldNames.js
+++ b/browser/extensions/formautofill/test/unit/test_getCategoriesFromFieldNames.js
@@ -1,12 +1,13 @@
"use strict";
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
+Cu.import("resource://formautofill/FormAutofillHandler.jsm");
add_task(async function test_isAddressField_isCreditCardField() {
const TEST_CASES = {
"given-name": {
isAddressField: true,
isCreditCardField: false,
},
"organization": {
@@ -37,20 +38,20 @@ add_task(async function test_isAddressFi
isAddressField: false,
isCreditCardField: false,
},
};
for (let fieldName of Object.keys(TEST_CASES)) {
do_print("Starting testcase: " + fieldName);
let info = TEST_CASES[fieldName];
- Assert.equal(FormAutofillUtils.isAddressField(fieldName),
+ Assert.equal(FormAutofillHandler.prototype.isAddressField(fieldName),
info.isAddressField,
"isAddressField");
- Assert.equal(FormAutofillUtils.isCreditCardField(fieldName),
+ Assert.equal(FormAutofillHandler.prototype.isCreditCardField(fieldName),
info.isCreditCardField,
"isCreditCardField");
}
});
add_task(async function test_getCategoriesFromFieldNames() {
const TEST_CASES = [
{
--- a/browser/extensions/formautofill/test/unit/test_getInfo.js
+++ b/browser/extensions/formautofill/test/unit/test_getInfo.js
@@ -1,11 +1,11 @@
"use strict";
-Cu.import("resource://formautofill/FormAutofillHeuristics.jsm");
+Cu.import("resource://formautofill/FormAutofillHandler.jsm");
const TESTCASES = [
{
description: "Input element in a label element",
document: `<form>
<label> E-Mail
<input id="targetElement" type="text">
</label>