Bug 1339731 - Refactor some duplicated codes and remove the unused method. r=lchang,ralin draft
authorSean Lee <selee@mozilla.com>
Mon, 20 Nov 2017 09:19:51 +0800
changeset 700395 0c91687cd45d66ec12a68d5b48c0c7bdbea36048
parent 700394 aa30e44c554ccb6076422244da0fcb69134c660f
child 700537 13d747484190076914654acb576bce5a60144f6e
child 700662 03949e0b6aadadafdcfe53e90c63e9d84de6df98
push id89801
push userbmo:selee@mozilla.com
push dateMon, 20 Nov 2017 03:18:51 +0000
reviewerslchang, ralin
bugs1339731
milestone59.0a1
Bug 1339731 - Refactor some duplicated codes and remove the unused method. r=lchang,ralin MozReview-Commit-ID: 5BHR2sJBASl
browser/extensions/formautofill/FormAutofillContent.jsm
browser/extensions/formautofill/FormAutofillHandler.jsm
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -97,19 +97,18 @@ AutofillProfileAutoCompleteSearch.protot
     this.forceStop = false;
 
     let savedFieldNames = FormAutofillContent.savedFieldNames;
 
     let focusedInput = formFillController.focusedInput;
     let info = FormAutofillContent.getInputDetails(focusedInput);
     let isAddressField = FormAutofillUtils.isAddressField(info.fieldName);
     let handler = FormAutofillContent.getFormHandler(focusedInput);
-    let section = handler.getSectionByElement(focusedInput);
-    let allFieldNames = section.allFieldNames;
-    let filledRecordGUID = isAddressField ? section.address.filledRecordGUID : section.creditCard.filledRecordGUID;
+    let allFieldNames = handler.getAllFieldNames(focusedInput);
+    let filledRecordGUID = handler.getFilledRecordGUID(focusedInput);
     let searchPermitted = isAddressField ?
                           FormAutofillUtils.isAutofillAddressesEnabled :
                           FormAutofillUtils.isAutofillCreditCardsEnabled;
 
     ProfileAutocomplete.lastProfileAutoCompleteFocusedInput = focusedInput;
     // Fallback to form-history if ...
     //   - specified autofill feature is pref off.
     //   - no profile can fill the currently-focused input.
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -131,28 +131,38 @@ class FormAutofillSection {
     }
     return this._cacheValue.allFieldNames;
   }
 
   getFieldDetailByName(fieldName) {
     return this._validDetails.find(detail => detail.fieldName == fieldName);
   }
 
-  getFieldDetailsByElement(element) {
+  _getTargetSet(element) {
     let fieldDetail = this.getFieldDetailByElement(element);
     if (!fieldDetail) {
-      return [];
+      return null;
     }
     if (FormAutofillUtils.isAddressField(fieldDetail.fieldName)) {
-      return this.address.fieldDetails;
+      return this.address;
     }
     if (FormAutofillUtils.isCreditCardField(fieldDetail.fieldName)) {
-      return this.creditCard.fieldDetails;
+      return this.creditCard;
     }
-    return [];
+    return null;
+  }
+
+  getFieldDetailsByElement(element) {
+    let targetSet = this._getTargetSet(element);
+    return targetSet ? targetSet.fieldDetails : [];
+  }
+
+  getFilledRecordGUID(element) {
+    let targetSet = this._getTargetSet(element);
+    return targetSet ? targetSet.filledRecordGUID : null;
   }
 
   _getOneLineStreetAddress(address) {
     if (!this._cacheValue.oneLineStreetAddress) {
       this._cacheValue.oneLineStreetAddress = {};
     }
     if (!this._cacheValue.oneLineStreetAddress[address]) {
       this._cacheValue.oneLineStreetAddress[address] = FormAutofillUtils.toOneLineAddress(address);
@@ -332,37 +342,32 @@ class FormAutofillSection {
    *        A focused input element needed to determine the address or credit
    *        card field.
    */
   async autofillFields(profile, focusedInput) {
     let focusedDetail = this.getFieldDetailByElement(focusedInput);
     if (!focusedDetail) {
       throw new Error("No fieldDetail for the focused input.");
     }
-    let targetSet;
+    let targetSet = this._getTargetSet(focusedInput);
     if (FormAutofillUtils.isCreditCardField(focusedDetail.fieldName)) {
       // When Master Password is enabled by users, the decryption process
       // should prompt Master Password dialog to get the decrypted credit
       // card number. Otherwise, the number can be decrypted with the default
       // password.
       if (profile["cc-number-encrypted"]) {
         let decrypted = await this._decrypt(profile["cc-number-encrypted"], true);
 
         if (!decrypted) {
           // Early return if the decrypted is empty or undefined
           return;
         }
 
         profile["cc-number"] = decrypted;
       }
-      targetSet = this.creditCard;
-    } else if (FormAutofillUtils.isAddressField(focusedDetail.fieldName)) {
-      targetSet = this.address;
-    } else {
-      throw new Error("Unknown form fields");
     }
 
     log.debug("profile in autofillFields:", profile);
 
     targetSet.filledRecordGUID = profile.guid;
     for (let fieldDetail of targetSet.fieldDetails) {
       // Avoid filling field value in the following cases:
       // 1. a non-empty input field for an unfocused input
@@ -521,22 +526,17 @@ class FormAutofillSection {
     }
 
     fieldDetail.state = nextState;
   }
 
   clearFieldState(focusedInput) {
     let fieldDetail = this.getFieldDetailByElement(focusedInput);
     this.changeFieldState(fieldDetail, "NORMAL");
-    let targetSet;
-    if (FormAutofillUtils.isAddressField(focusedInput)) {
-      targetSet = this.address;
-    } else if (FormAutofillUtils.isCreditCardField(focusedInput)) {
-      targetSet = this.creditCard;
-    }
+    let targetSet = this._getTargetSet(focusedInput);
 
     if (!targetSet.fieldDetails.some(detail => detail.state == "AUTO_FILLED")) {
       targetSet.filledRecordGUID = null;
     }
   }
 
   resetFieldStates() {
     for (let fieldDetail of this._validDetails) {
@@ -808,16 +808,17 @@ class FormAutofillHandler {
      * the same exact combination of these values.
      *
      * A direct reference to the associated element cannot be sent to the user
      * interface because processing may be done in the parent process.
      */
     this.fieldDetails = null;
 
     this.sections = [];
+    this._sectionCache = new WeakMap();
   }
 
   /**
    * 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.
@@ -839,34 +840,25 @@ class FormAutofillHandler {
       }
       input.addEventListener("input", this);
     }
 
     this.fieldDetails = allValidDetails;
     return allValidDetails;
   }
 
-  getFieldDetailByElement(element) {
-    return this.fieldDetails.find(
-      detail => detail.elementWeakRef.get() == element
-    );
-  }
-
   getSectionByElement(element) {
-    return this.sections.find(
-      section => section.getFieldDetailByElement(element)
-    );
-  }
-
-  getFieldDetailsByElement(element) {
-    let fieldDetail = this.getFieldDetailByElement(element);
-    if (!fieldDetail) {
-      return [];
+    let section = this._sectionCache.get(element);
+    if (!section) {
+      section = this.sections.find(
+        s => s.getFieldDetailByElement(element)
+      );
+      this._sectionCache.set(element, section);
     }
-    return this.getSectionByElement(element).getFieldDetailsByElement(element);
+    return section;
   }
 
   getAllFieldNames(focusedInput) {
     let section = this.getSectionByElement(focusedInput);
     return section.allFieldNames;
   }
 
   previewFormFields(profile, focusedInput) {
@@ -874,16 +866,21 @@ class FormAutofillHandler {
     section.previewFormFields(profile, focusedInput);
   }
 
   clearPreviewedFormFields(focusedInput) {
     let section = this.getSectionByElement(focusedInput);
     section.clearPreviewedFormFields(focusedInput);
   }
 
+  getFilledRecordGUID(focusedInput) {
+    let section = this.getSectionByElement(focusedInput);
+    return section.getFilledRecordGUID(focusedInput);
+  }
+
   getAdaptedProfiles(originalProfiles, focusedInput) {
     let section = this.getSectionByElement(focusedInput);
     section.getAdaptedProfiles(originalProfiles);
     return originalProfiles;
   }
 
   hasFilledSection() {
     return this.sections.some(section => section.isFilled());