Bug 1428414 - Support re-using autofill edit forms for different records. r=jaws draft
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Thu, 22 Mar 2018 20:31:52 -0700
changeset 776192 a46a935e7886e81d7e39fe2d606305bba8bdddac
parent 776191 23865bf7c4ce13885cecae86b05661c66397d451
child 776193 3e3d975651dfa2adc1abc86fc807331493fdadbf
child 776695 9a1133aef407576ee1427b45e40161c9bfba897f
push id104830
push usermozilla@noorenberghe.ca
push dateMon, 02 Apr 2018 19:39:39 +0000
reviewersjaws
bugs1428414
milestone61.0a1
Bug 1428414 - Support re-using autofill edit forms for different records. r=jaws MozReview-Commit-ID: LnpaX9oAo1A
browser/extensions/formautofill/content/autofillEditForms.js
--- a/browser/extensions/formautofill/content/autofillEditForms.js
+++ b/browser/extensions/formautofill/content/autofillEditForms.js
@@ -3,31 +3,28 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* exported EditAddress, EditCreditCard */
 /* eslint-disable mozilla/balanced-listeners */ // Not relevant since the document gets unloaded.
 
 "use strict";
 
 class EditAutofillForm {
-  constructor(elements, record) {
+  constructor(elements) {
     this._elements = elements;
-    this._record = record;
   }
 
   /**
    * Fill the form with a record object.
-   * @param  {object} record
+   * @param  {object} [record = {}]
    */
-  loadInitialValues(record) {
-    for (let field in record) {
-      let input = document.getElementById(field);
-      if (input) {
-        input.value = record[field];
-      }
+  loadRecord(record = {}) {
+    for (let field of this._elements.form.elements) {
+      let value = record[field.id];
+      field.value = typeof(value) == "undefined" ? "" : value;
     }
   }
 
   /**
    * Get inputs from the form.
    * @returns {object}
    */
   buildFormObject() {
@@ -80,35 +77,43 @@ class EditAddress extends EditAutofillFo
    * @param {HTMLElement[]} elements
    * @param {object} record
    * @param {object} config
    * @param {string[]} config.DEFAULT_REGION
    * @param {function} config.getFormFormat Function to return form layout info for a given country.
    * @param {string[]} config.supportedCountries
    */
   constructor(elements, record, config) {
-    let country = record ? record.country :
-                    config.supportedCountries.find(supported => supported == config.DEFAULT_REGION);
-    super(elements, record || {country});
+    super(elements);
 
     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.loadRecord(record);
     this.attachEventListeners();
   }
 
+  loadRecord(record) {
+    this._record = record;
+    if (!record) {
+      record = {
+        country: this.supportedCountries.find(supported => supported == this.DEFAULT_REGION),
+      };
+    }
+    super.loadRecord(record);
+    this.formatForm(record.country);
+  }
+
   /**
    * Format the form based on country. The address-level1 and postal-code labels
    * should be specific to the given country.
    * @param  {string} country
    */
   formatForm(country) {
     const {addressLevel1Label, postalCodeLabel, fieldsOrder} = this.getFormFormat(country);
     this._elements.addressLevel1Label.dataset.localization = addressLevel1Label;
@@ -171,33 +176,43 @@ class EditAddress extends EditAutofillFo
 class EditCreditCard extends EditAutofillForm {
   /**
    * @param {HTMLElement[]} elements
    * @param {object} record with a decrypted cc-number
    * @param {object} config
    * @param {function} config.isCCNumber Function to determine is a string is a valid CC number.
    */
   constructor(elements, record, config) {
-    super(elements, record);
+    super(elements);
 
     Object.assign(this, config);
     Object.assign(this._elements, {
       ccNumber: this._elements.form.querySelector("#cc-number"),
       year: this._elements.form.querySelector("#cc-exp-year"),
     });
+
+    this.loadRecord(record);
+    this.attachEventListeners();
+  }
+
+  loadRecord(record) {
+    // _record must be updated before generateYears is called.
+    this._record = record;
     this.generateYears();
-    this.loadInitialValues(this._record);
-    this.attachEventListeners();
+    super.loadRecord(record);
   }
 
   generateYears() {
     const count = 11;
     const currentYear = new Date().getFullYear();
     const ccExpYear = this._record && this._record["cc-exp-year"];
 
+    // Clear the list
+    this._elements.year.textContent = "";
+
     if (ccExpYear && ccExpYear < currentYear) {
       this._elements.year.appendChild(new Option(ccExpYear));
     }
 
     for (let i = 0; i < count; i++) {
       let year = currentYear + i;
       let option = new Option(year);
       this._elements.year.appendChild(option);