Bug 1300989 - Part 2: Use WeakMap to manage the form details.; r?MattN draft
authorSean Lee <selee@mozilla.com>
Fri, 10 Feb 2017 11:15:13 +0800
changeset 483474 477c984b3495301df0a9e49bb6b00d16a16c90c6
parent 483473 629a34ec404f9c426857172644b4ae8003ac1b70
child 483475 36ed028ca214fc885cc700adca3be41e31e228ca
push id45322
push userbmo:selee@mozilla.com
push dateTue, 14 Feb 2017 10:36:08 +0000
reviewersMattN
bugs1300989
milestone54.0a1
Bug 1300989 - Part 2: Use WeakMap to manage the form details.; r?MattN MozReview-Commit-ID: AkfZnXQ2MkL
browser/extensions/formautofill/FormAutofillContent.jsm
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -234,16 +234,18 @@ let ProfileAutocomplete = {
 };
 
 /**
  * Handles content's interactions for the process.
  *
  * NOTE: Declares it by "var" to make it accessible in unit tests.
  */
 var FormAutofillContent = {
+  _formsDetails: new WeakMap(),
+
   init() {
     Services.cpmm.addMessageListener("FormAutofill:enabledStatus", (result) => {
       if (result.data) {
         ProfileAutocomplete.ensureRegistered();
       } else {
         ProfileAutocomplete.ensureUnregistered();
       }
     });
@@ -256,52 +258,47 @@ var FormAutofillContent = {
    * Get the input's information from cache which is created after page identified.
    *
    * @param {HTMLInputElement} element Focused input which triggered profile searching
    * @returns {Object|null}
    *          Return target input's information that cloned from content cache
    *          (or return null if the information is not found in the cache).
    */
   getInputDetails(element) {
-    for (let formDetails of this._formsDetails) {
-      for (let detail of formDetails) {
-        if (element == detail.element) {
-          return detail;
-        }
+    let formDetails = this.getFormDetails(element);
+    for (let detail of formDetails) {
+      if (element == detail.element) {
+        return detail;
       }
     }
     return null;
   },
 
   /**
    * Get the form's information from cache which is created after page identified.
    *
    * @param {HTMLInputElement} element Focused input which triggered profile searching
    * @returns {Array<Object>|null}
    *          Return target form's information that cloned from content cache
    *          (or return null if the information is not found in the cache).
    *
    */
   getFormDetails(element) {
-    for (let formDetails of this._formsDetails) {
-      if (formDetails.some((detail) => detail.element == element)) {
-        return formDetails;
-      }
-    }
-    return null;
+    let rootElement = FormLikeFactory.findRootForField(element);
+    let formDetails = this._formsDetails.get(rootElement);
+    return formDetails ? formDetails.fieldDetails : null;
   },
 
   getAllFieldNames(element) {
     let formDetails = this.getFormDetails(element);
     return formDetails.map(record => record.fieldName);
   },
 
   _identifyAutofillFields(doc) {
     let forms = [];
-    this._formsDetails = [];
 
     // Collects root forms from inputs.
     for (let field of doc.getElementsByTagName("input")) {
       // We only consider text-like fields for now until we support radio and
       // checkbox buttons in the future.
       if (!field.mozIsTextField(true)) {
         continue;
       }
@@ -316,17 +313,17 @@ var FormAutofillContent = {
     // as autofill fields if the amount is above the threshold.
     forms.forEach(form => {
       let formHandler = new FormAutofillHandler(form);
       formHandler.collectFormFields();
       if (formHandler.fieldDetails.length < AUTOFILL_FIELDS_THRESHOLD) {
         return;
       }
 
-      this._formsDetails.push(formHandler.fieldDetails);
+      this._formsDetails.set(form.rootElement, formHandler);
       formHandler.fieldDetails.forEach(
         detail => this._markAsAutofillField(detail.element));
     });
   },
 
   _markAsAutofillField(field) {
     formFillController.markAsAutofillField(field);
   },