Bug 1427954 - Pass supported and default countries to EditAutofillForm and move loadInitialValues. r=sfoster
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Wed, 14 Mar 2018 18:11:36 -0700
changeset 408639 6ab0e835a7f4e2823d5ae5a80ffbdeb775ab5591
parent 408638 4e5ce4f1f57901ebaf9d932b41db13b4fe574274
child 408640 101a4cf38f89696111c911993268d7dd961a46c7
push id100996
push userbtara@mozilla.com
push dateSat, 17 Mar 2018 10:37:43 +0000
treeherdermozilla-inbound@97160a734959 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfoster
bugs1427954
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1427954 - Pass supported and default countries to EditAutofillForm and move loadInitialValues. r=sfoster The point of this is to remove dependencies on privileged code from autofillEditForms.js so it can be used in the unprivileged PaymentRequest dialog. The PaymentRequest dialog will be able to inject the privileged APIs in a different way. MozReview-Commit-ID: 4KITOMz7Uxh
browser/extensions/formautofill/content/autofillEditForms.js
browser/extensions/formautofill/content/editAddress.xhtml
browser/extensions/formautofill/content/editDialog.js
browser/extensions/formautofill/content/manageDialog.js
--- a/browser/extensions/formautofill/content/autofillEditForms.js
+++ b/browser/extensions/formautofill/content/autofillEditForms.js
@@ -73,28 +73,32 @@ class EditAutofillForm {
     this._elements.form.addEventListener("input", this);
   }
 
   // An interface to be inherited.
   handleChange(event) {}
 }
 
 class EditAddress extends EditAutofillForm {
-  constructor(elements, record) {
+  constructor(elements, record, config) {
     let country = record ? record.country :
-                  FormAutofillUtils.supportedCountries.find(supported => supported == FormAutofillUtils.DEFAULT_REGION);
+                    config.supportedCountries.find(supported => supported == config.DEFAULT_REGION);
     super(elements, record || {country});
 
+    Object.assign(this, config);
     Object.assign(this._elements, {
       addressLevel1Label: this._elements.form.querySelector("#address-level1-container > span"),
       postalCodeLabel: this._elements.form.querySelector("#postal-code-container > span"),
       country: this._elements.form.querySelector("#country"),
     });
 
     this.populateCountries();
+    // Need to populate the countries before trying to set the initial country.
+    // Also need to use this._record so it has the default country selected.
+    this.loadInitialValues(this._record);
     this.formatForm(country);
     this.attachEventListeners();
   }
 
   /**
    * Format the form based on country. The address-level1 and postal-code labels
    * should be specific to the given country.
    * @param  {string} country
@@ -134,17 +138,17 @@ class EditAddress extends EditAutofillFo
     for (let field of fields) {
       let container = document.getElementById(`${field}-container`);
       container.style.display = "none";
     }
   }
 
   populateCountries() {
     let fragment = document.createDocumentFragment();
-    for (let country of FormAutofillUtils.supportedCountries) {
+    for (let country of this.supportedCountries) {
       let option = new Option();
       option.value = country;
       option.dataset.localizationRegion = country.toLowerCase();
       fragment.appendChild(option);
     }
     this._elements.country.appendChild(fragment);
   }
 
@@ -161,16 +165,17 @@ class EditAddress extends EditAutofillFo
 class EditCreditCard extends EditAutofillForm {
   constructor(elements, record) {
     super(elements, record);
     Object.assign(this._elements, {
       ccNumber: this._elements.form.querySelector("#cc-number"),
       year: this._elements.form.querySelector("#cc-exp-year"),
     });
     this.generateYears();
+    this.loadInitialValues(this._record);
     this.attachEventListeners();
   }
 
   generateYears() {
     const count = 11;
     const currentYear = new Date().getFullYear();
     const ccExpYear = this._record && this._record["cc-exp-year"];
 
--- a/browser/extensions/formautofill/content/editAddress.xhtml
+++ b/browser/extensions/formautofill/content/editAddress.xhtml
@@ -72,21 +72,26 @@
   </form>
   <div id="controls-container">
     <button id="cancel" data-localization="cancelBtnLabel"/>
     <button id="save" disabled="disabled" data-localization="saveBtnLabel"/>
   </div>
   <script type="application/javascript"><![CDATA[
     "use strict";
 
+    let {supportedCountries, DEFAULT_REGION} = FormAutofillUtils;
     let record = window.arguments && window.arguments[0];
+
     /* import-globals-from autofillEditForms.js */
     let fieldContainer = new EditAddress({
       form: document.getElementById("form"),
-    }, record);
+    }, record, {
+      DEFAULT_REGION,
+      supportedCountries,
+    });
 
     /* import-globals-from editDialog.js */
     new EditAddressDialog({
       title: document.querySelector("title"),
       fieldContainer,
       controlsContainer: document.getElementById("controls-container"),
       cancel: document.getElementById("cancel"),
       save: document.getElementById("save"),
--- a/browser/extensions/formautofill/content/editDialog.js
+++ b/browser/extensions/formautofill/content/editDialog.js
@@ -20,39 +20,24 @@ class AutofillEditDialog {
     this._subStorageName = subStorageName;
     this._elements = elements;
     this._record = record;
     this.localizeDocument();
     window.addEventListener("DOMContentLoaded", this, {once: true});
   }
 
   async init() {
-    if (this._record) {
-      await this.loadInitialValues(this._record);
-    }
     this.attachEventListeners();
-    // For testing only: loadInitialValues for credit card is an async method, and tests
-    // need to wait until the values have been filled before editing the fields.
+    // For testing only: signal to tests that the dialog is ready for testing.
+    // This is likely no longer needed since retrieving from storage is fully
+    // handled in manageDialog.js now.
     window.dispatchEvent(new CustomEvent("FormReady"));
   }
 
   /**
-   * Fill the form with a record object.
-   * @param  {object} record
-   */
-  loadInitialValues(record) {
-    for (let field in record) {
-      let input = document.getElementById(field);
-      if (input) {
-        input.value = record[field];
-      }
-    }
-  }
-
-  /**
    * Get storage and ensure it has been initialized.
    * @returns {object}
    */
   async getStorage() {
     await this._storageInitPromise;
     return formAutofillStorage[this._subStorageName];
   }
 
@@ -154,19 +139,17 @@ class AutofillEditDialog {
   }
 
   // An interface to be inherited.
   localizeDocument() {}
 }
 
 class EditAddressDialog extends AutofillEditDialog {
   constructor(elements, record) {
-    let country = record ? record.country :
-                  FormAutofillUtils.supportedCountries.find(supported => supported == FormAutofillUtils.DEFAULT_REGION);
-    super("addresses", elements, record || {country});
+    super("addresses", elements, record);
   }
 
   localizeDocument() {
     if (this._record) {
       this._elements.title.dataset.localization = "editAddressTitle";
     }
   }
 
@@ -182,25 +165,16 @@ class EditCreditCardDialog extends Autof
   }
 
   localizeDocument() {
     if (this._record) {
       this._elements.title.dataset.localization = "editCreditCardTitle";
     }
   }
 
-  /**
-   * Decrypt cc-number first and fill the form.
-   * @param  {object} creditCard
-   */
-  async loadInitialValues(creditCard) {
-    let decryptedCC = await MasterPassword.decrypt(creditCard["cc-number-encrypted"]);
-    super.loadInitialValues(Object.assign({}, creditCard, {"cc-number": decryptedCC}));
-  }
-
   async handleSubmit() {
     let creditCard = this._elements.fieldContainer.buildFormObject();
     // Show error on the cc-number field if it's empty or invalid
     if (!FormAutofillUtils.isCCNumber(creditCard["cc-number"])) {
       this._elements.ccNumber.setCustomValidity(true);
       return;
     }
 
--- a/browser/extensions/formautofill/content/manageDialog.js
+++ b/browser/extensions/formautofill/content/manageDialog.js
@@ -312,17 +312,22 @@ class ManageCreditCards extends ManageRe
    * Open the edit address dialog to create/edit a credit card.
    *
    * @param  {object} creditCard [optional]
    */
   async openEditDialog(creditCard) {
     // If master password is set, ask for password if user is trying to edit an
     // existing credit card.
     if (!creditCard || !this._hasMasterPassword || await MasterPassword.ensureLoggedIn(true)) {
-      this.prefWin.gSubDialog.open(EDIT_CREDIT_CARD_URL, "resizable=no", creditCard);
+      let decryptedCCNumObj = {};
+      if (creditCard) {
+        decryptedCCNumObj["cc-number"] = await MasterPassword.decrypt(creditCard["cc-number-encrypted"]);
+      }
+      let decryptedCreditCard = Object.assign({}, creditCard, decryptedCCNumObj);
+      this.prefWin.gSubDialog.open(EDIT_CREDIT_CARD_URL, "resizable=no", decryptedCreditCard);
     }
   }
 
   /**
    * Get credit card display label. It should display masked numbers and the
    * cardholder's name, separated by a comma. If `showCreditCards` is set to
    * true, decrypted credit card numbers are shown instead.
    *