Bug 1392947 - (experimental) Use memoize function to help caching previous extracted label result.
MozReview-Commit-ID: J5h2MSLebkK
--- a/browser/extensions/formautofill/FormAutofillHeuristics.jsm
+++ b/browser/extensions/formautofill/FormAutofillHeuristics.jsm
@@ -282,17 +282,16 @@ this.LabelUtils = {
},
};
/**
* Returns the autocomplete information of fields according to heuristics.
*/
this.FormAutofillHeuristics = {
RULES: null,
- extractedLabelStrings: new WeakMap(),
/**
* Try to find a contiguous sub-array within an array.
*
* @param {Array} array
* @param {Array} subArray
*
* @returns {boolean}
@@ -738,32 +737,30 @@ this.FormAutofillHeuristics = {
/**
* Extract all the signature strings of an element.
*
* @param {HTMLElement} element
* @returns {ElementStrings}
*/
_getElementStrings(element) {
- const extractedLabelStrings = this.extractedLabelStrings;
+ return {
+ extractLabelStrings: FormAutofillUtils.memoize((elem) => {
+ const labels = LabelUtils.findLabelElements(elem);
+ const labelStrings = [];
+ for (let label of labels) {
+ labelStrings.push(...LabelUtils.extractLabelStrings(label));
+ }
+ return labelStrings;
+ }),
- return {
* [Symbol.iterator]() {
yield element.id;
yield element.name;
-
- if (!extractedLabelStrings.has(element)) {
- const labels = LabelUtils.findLabelElements(element);
- const labelStrings = [];
- for (let label of labels) {
- labelStrings.push(...LabelUtils.extractLabelStrings(label));
- }
- extractedLabelStrings.set(element, labelStrings);
- }
- yield *extractedLabelStrings.get(element);
+ yield *this.extractLabelStrings(element);
},
};
},
/**
* Find the first matched field name of the element wih given regex list.
*
* @param {HTMLElement} element
--- a/browser/extensions/formautofill/FormAutofillUtils.jsm
+++ b/browser/extensions/formautofill/FormAutofillUtils.jsm
@@ -590,16 +590,41 @@ this.FormAutofillUtils = {
localizeMarkup(bundleURI, root) {
const bundle = Services.strings.createBundle(bundleURI);
let elements = root.querySelectorAll("[data-localization]");
for (let element of elements) {
element.textContent = bundle.GetStringFromName(element.getAttribute("data-localization"));
element.removeAttribute("data-localization");
}
},
+
+ memoize(fn) {
+ if (fn.length != 1) {
+ // TODO: implement variadic version for non-unary function.
+ throw new Error("only unary function is accepted");
+ }
+ return this.monadicMemoize(fn);
+ },
+
+ monadicMemoize(fn) {
+ let objectCache = new WeakMap();
+ let primitiveCache = new Map();
+
+ return arg => {
+ const cache = (arg == null || (typeof arg !== "function" && typeof arg !== "object")) ?
+ primitiveCache :
+ objectCache;
+ const result = cache.get(arg) || fn(arg);
+ if (!cache.has(arg)) {
+ cache.set(arg, result);
+ }
+
+ return result;
+ };
+ },
};
XPCOMUtils.defineLazyGetter(this.FormAutofillUtils, "DEFAULT_COUNTRY_CODE", () => {
return Services.prefs.getCharPref("browser.search.countryCode", "US");
});
this.log = null;
this.FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);