Bug 1370766 - Allow users to enable/disable credit card autofill and launch the list dialog in about:preferences. r=lchang draft
authorScott Wu <scottcwwu@gmail.com>
Fri, 25 Aug 2017 15:28:19 +0800
changeset 652878 fa3e862c7d7299ffed22af387f460cd585f6405d
parent 652781 264b0550a2a60ace45c4d0ab009a504510946e20
child 728209 b0b677d0adf5f28fd06704f0753bc35e9a9b3536
push id76184
push userbmo:scwwu@mozilla.com
push dateFri, 25 Aug 2017 09:17:39 +0000
reviewerslchang
bugs1370766
milestone57.0a1
Bug 1370766 - Allow users to enable/disable credit card autofill and launch the list dialog in about:preferences. r=lchang MozReview-Commit-ID: D7JtXBaPaJI
browser/base/content/test/static/browser_all_files_referenced.js
browser/extensions/formautofill/FormAutofillPreferences.jsm
browser/extensions/formautofill/locales/en-US/formautofill.properties
browser/extensions/formautofill/test/browser/browser_first_time_use_doorhanger.js
browser/extensions/formautofill/test/browser/browser_privacyPreferences.js
browser/extensions/formautofill/test/browser/head.js
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -126,18 +126,16 @@ var whitelist = [
   {file: "resource://gre/modules/Localization.jsm"},
 
   // Starting from here, files in the whitelist are bugs that need fixing.
   // Bug 1339420
   {file: "chrome://branding/content/icon128.png"},
   // Bug 1339424 (wontfix?)
   {file: "chrome://browser/locale/taskbar.properties",
    platforms: ["linux", "macosx"]},
-  // Bug 1370766 will reference this file
-  {file: "chrome://formautofill/content/manageCreditCards.xhtml"},
   // Bug 1316187
   {file: "chrome://global/content/customizeToolbar.xul"},
   // Bug 1343837
   {file: "chrome://global/content/findUtils.js"},
   // Bug 1343843
   {file: "chrome://global/content/url-classifier/unittests.xul"},
   // Bug 1348362
   {file: "chrome://global/skin/icons/warning-64.png", platforms: ["linux", "win"]},
--- a/browser/extensions/formautofill/FormAutofillPreferences.jsm
+++ b/browser/extensions/formautofill/FormAutofillPreferences.jsm
@@ -10,27 +10,26 @@
 
 this.EXPORTED_SYMBOLS = ["FormAutofillPreferences"];
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 // Add addresses enabled flag in telemetry environment for recording the number of
 // users who disable/enable the address autofill feature.
 const BUNDLE_URI = "chrome://formautofill/locale/formautofill.properties";
 const MANAGE_ADDRESSES_URL = "chrome://formautofill/content/manageAddresses.xhtml";
+const MANAGE_CREDITCARDS_URL = "chrome://formautofill/content/manageCreditCards.xhtml";
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://formautofill/FormAutofillUtils.jsm");
 
-const {ENABLED_AUTOFILL_ADDRESSES_PREF} = FormAutofillUtils;
+const {ENABLED_AUTOFILL_ADDRESSES_PREF, ENABLED_AUTOFILL_CREDITCARDS_PREF} = FormAutofillUtils;
 // Add credit card enabled flag in telemetry environment for recording the number of
 // users who disable/enable the credit card autofill feature.
-// TODO: Add const PREF_CREDITCARD_ENABLED = "extensions.formautofill.creditCards.enabled";
-//       when the credit card preferences UI is ready
 
 this.log = null;
 FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
 
 function FormAutofillPreferences({useOldOrganization}) {
   this.useOldOrganization = useOldOrganization;
   this.bundle = Services.strings.createBundle(BUNDLE_URI);
 }
@@ -62,71 +61,91 @@ FormAutofillPreferences.prototype = {
    *
    * @param  {XULDocument} document
    */
   createPreferenceGroup(document) {
     let formAutofillGroup;
     let addressAutofill = document.createElementNS(XUL_NS, "hbox");
     let addressAutofillCheckbox = document.createElementNS(XUL_NS, "checkbox");
     let savedAddressesBtn = document.createElementNS(XUL_NS, "button");
+    let creditCardAutofill = document.createElementNS(XUL_NS, "hbox");
+    let creditCardAutofillCheckbox = document.createElementNS(XUL_NS, "checkbox");
+    let savedCreditCardsBtn = document.createElementNS(XUL_NS, "button");
 
     if (this.useOldOrganization) {
       let caption = document.createElementNS(XUL_NS, "caption");
       let captionLabel = document.createElementNS(XUL_NS, "label");
 
       formAutofillGroup = document.createElementNS(XUL_NS, "groupbox");
       formAutofillGroup.hidden = document.location.href != "about:preferences#privacy";
       // Use .setAttribute because HTMLElement.dataset is not available on XUL elements
       formAutofillGroup.setAttribute("data-category", "panePrivacy");
       formAutofillGroup.appendChild(caption);
       caption.appendChild(captionLabel);
       captionLabel.textContent = this.bundle.GetStringFromName("preferenceGroupTitle");
     } else {
       formAutofillGroup = document.createElementNS(XUL_NS, "vbox");
       savedAddressesBtn.className = "accessory-button";
+      savedCreditCardsBtn.className = "accessory-button";
     }
 
     this.refs = {
       formAutofillGroup,
       addressAutofillCheckbox,
       savedAddressesBtn,
+      creditCardAutofillCheckbox,
+      savedCreditCardsBtn,
     };
 
     formAutofillGroup.id = "formAutofillGroup";
     addressAutofill.id = "addressAutofill";
+    addressAutofillCheckbox.setAttribute("label", this.bundle.GetStringFromName("enableAddressAutofill"));
     savedAddressesBtn.setAttribute("label", this.bundle.GetStringFromName("savedAddresses"));
-    addressAutofillCheckbox.setAttribute("label", this.bundle.GetStringFromName("enableAddressAutofill"));
+    creditCardAutofill.id = "creditCardAutofill";
+    creditCardAutofillCheckbox.setAttribute("label", this.bundle.GetStringFromName("enableCreditCardAutofill"));
+    savedCreditCardsBtn.setAttribute("label", this.bundle.GetStringFromName("savedCreditCards"));
 
     // Manually set the checked state
     if (FormAutofillUtils.isAutofillAddressesEnabled) {
       addressAutofillCheckbox.setAttribute("checked", true);
     }
+    if (FormAutofillUtils.isAutofillCreditCardsEnabled) {
+      creditCardAutofillCheckbox.setAttribute("checked", true);
+    }
 
     addressAutofillCheckbox.flex = 1;
+    creditCardAutofillCheckbox.flex = 1;
 
     formAutofillGroup.appendChild(addressAutofill);
     addressAutofill.appendChild(addressAutofillCheckbox);
     addressAutofill.appendChild(savedAddressesBtn);
+    formAutofillGroup.appendChild(creditCardAutofill);
+    creditCardAutofill.appendChild(creditCardAutofillCheckbox);
+    creditCardAutofill.appendChild(savedCreditCardsBtn);
   },
 
   /**
    * Handle events
    *
    * @param  {DOMEvent} event
    */
   handleEvent(event) {
     switch (event.type) {
       case "command": {
         let target = event.target;
 
         if (target == this.refs.addressAutofillCheckbox) {
           // Set preference directly instead of relying on <Preference>
           Services.prefs.setBoolPref(ENABLED_AUTOFILL_ADDRESSES_PREF, target.checked);
+        } else if (target == this.refs.creditCardAutofillCheckbox) {
+          Services.prefs.setBoolPref(ENABLED_AUTOFILL_CREDITCARDS_PREF, target.checked);
         } else if (target == this.refs.savedAddressesBtn) {
           target.ownerGlobal.gSubDialog.open(MANAGE_ADDRESSES_URL);
+        } else if (target == this.refs.savedCreditCardsBtn) {
+          target.ownerGlobal.gSubDialog.open(MANAGE_CREDITCARDS_URL);
         }
         break;
       }
     }
   },
 
   /**
    * Attach event listener
--- a/browser/extensions/formautofill/locales/en-US/formautofill.properties
+++ b/browser/extensions/formautofill/locales/en-US/formautofill.properties
@@ -1,15 +1,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 preferenceGroupTitle = Form Autofill
 enableAddressAutofill = Autofill addresses
 savedAddresses = Saved Addresses…
+enableCreditCardAutofill = Autofill credit cards
+savedCreditCards = Saved Credit Cards…
 saveAddressesMessage = Firefox now saves addresses so you can fill out forms faster.
 viewAutofillOptionsLink = View Form Autofill Options
 changeAutofillOptions = Change Form Autofill Options
 viewAutofillOptionsLinkOSX = View Form Autofill Preferences
 changeAutofillOptionsOSX = Change Form Autofill Preferences
 addressesSyncCheckbox = Share addresses with synced devices
 updateAddressMessage = Would you like to update your address with this new information?
 createAddressLabel = Create New Address
--- a/browser/extensions/formautofill/test/browser/browser_first_time_use_doorhanger.js
+++ b/browser/extensions/formautofill/test/browser/browser_first_time_use_doorhanger.js
@@ -2,17 +2,17 @@
 "use strict";
 
 add_task(async function test_first_time_save() {
   let addresses = await getAddresses();
   is(addresses.length, 0, "No address in storage");
   await SpecialPowers.pushPrefEnv({
     "set": [
       [FTU_PREF, true],
-      [ENABLED_PREF, true],
+      [ENABLED_AUTOFILL_ADDRESSES_PREF, true],
     ],
   });
 
   await BrowserTestUtils.withNewTab({gBrowser, url: FORM_URL},
     async function(browser) {
       let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
                                                        "popupshown");
       let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:preferences#privacy");
@@ -73,17 +73,17 @@ add_task(async function test_non_first_t
   addresses = await getAddresses();
   is(addresses.length, 2, "Another address saved");
 });
 
 add_task(async function test_first_time_save_with_sync_account() {
   await SpecialPowers.pushPrefEnv({
     "set": [
       [FTU_PREF, true],
-      [ENABLED_PREF, true],
+      [ENABLED_AUTOFILL_ADDRESSES_PREF, true],
       [SYNC_USERNAME_PREF, "foo@bar.com"],
     ],
   });
 
   await BrowserTestUtils.withNewTab({gBrowser, url: FORM_URL},
     async function(browser) {
       let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
                                                        "popupshown");
--- a/browser/extensions/formautofill/test/browser/browser_privacyPreferences.js
+++ b/browser/extensions/formautofill/test/browser/browser_privacyPreferences.js
@@ -1,49 +1,72 @@
 "use strict";
 
 const PAGE_PREFS = "about:preferences";
 const PAGE_PRIVACY = PAGE_PREFS + "#privacy";
-const GROUP_AUTOFILL = "#passwordsGroup";
-const CHECKBOX_AUTOFILL = "#addressAutofill checkbox";
-const PREF_AUTOFILL_ENABLED = "extensions.formautofill.addresses.enabled";
-const TEST_SELECTORS = {
-  group: GROUP_AUTOFILL,
-  checkbox: CHECKBOX_AUTOFILL,
+const SELECTORS = {
+  group: "#passwordsGroup",
+  addressAutofillCheckbox: "#addressAutofill checkbox",
+  creditCardAutofillCheckbox: "#creditCardAutofill checkbox",
+  savedAddressesBtn: "#addressAutofill button",
+  savedCreditCardsBtn: "#creditCardAutofill button",
 };
 
 // Visibility of form autofill group should be hidden when opening
 // preferences page.
 add_task(async function test_aboutPreferences() {
   await BrowserTestUtils.withNewTab({gBrowser, url: PAGE_PREFS}, async function(browser) {
-    await ContentTask.spawn(browser, TEST_SELECTORS, (args) => {
-      is(content.document.querySelector(args.group).hidden, true,
+    await ContentTask.spawn(browser, SELECTORS, (selectors) => {
+      is(content.document.querySelector(selectors.group).hidden, true,
         "Form Autofill group should be hidden");
     });
   });
 });
 
 // Visibility of form autofill group should be visible when opening
 // directly to privacy page. Checkbox is checked by default.
 add_task(async function test_aboutPreferencesPrivacy() {
   await BrowserTestUtils.withNewTab({gBrowser, url: PAGE_PRIVACY}, async function(browser) {
-    await ContentTask.spawn(browser, TEST_SELECTORS, (args) => {
-      is(content.document.querySelector(args.group).hidden, false,
+    await ContentTask.spawn(browser, SELECTORS, (selectors) => {
+      is(content.document.querySelector(selectors.group).hidden, false,
         "Form Autofill group should be visible");
-      is(content.document.querySelector(args.checkbox).checked, true,
-        "Checkbox should be checked");
+      is(content.document.querySelector(selectors.addressAutofillCheckbox).checked, true,
+        "Autofill addresses checkbox should be checked");
+      is(content.document.querySelector(selectors.creditCardAutofillCheckbox).checked, true,
+        "Autofill credit cards checkbox should be checked");
     });
   });
 });
 
-// Checkbox should be unchecked when form autofill is disabled.
-add_task(async function test_autofillDisabledCheckbox() {
-  SpecialPowers.pushPrefEnv({set: [[PREF_AUTOFILL_ENABLED, false]]});
-
+add_task(async function test_openManageAutofillDialogs() {
   await BrowserTestUtils.withNewTab({gBrowser, url: PAGE_PRIVACY}, async function(browser) {
-    await ContentTask.spawn(browser, TEST_SELECTORS, (args) => {
-      is(content.document.querySelector(args.group).hidden, false,
-        "Form Autofill group should be visible");
-      is(content.document.querySelector(args.checkbox).checked, false,
-        "Checkbox should be unchecked when Form Autofill is disabled");
+    const args = [SELECTORS, MANAGE_ADDRESSES_DIALOG_URL, MANAGE_CREDIT_CARDS_DIALOG_URL];
+    await ContentTask.spawn(browser, args, ([selectors, addrUrl, ccUrl]) => {
+      function testManageDialogOpened(expectedUrl) {
+        return {open: openUrl => is(openUrl, expectedUrl, "Manage dialog called")};
+      }
+
+      let realgSubDialog = content.window.gSubDialog;
+      content.window.gSubDialog = testManageDialogOpened(addrUrl);
+      content.document.querySelector(selectors.savedAddressesBtn).click();
+      content.window.gSubDialog = testManageDialogOpened(ccUrl);
+      content.document.querySelector(selectors.savedCreditCardsBtn).click();
+      content.window.gSubDialog = realgSubDialog;
     });
   });
 });
+
+// Checkbox should be unchecked when form autofill addresses and credit cards are disabled.
+add_task(async function test_autofillDisabledCheckbox() {
+  SpecialPowers.pushPrefEnv({set: [[ENABLED_AUTOFILL_ADDRESSES_PREF, false]]});
+  SpecialPowers.pushPrefEnv({set: [[ENABLED_AUTOFILL_CREDITCARDS_PREF, false]]});
+
+  await BrowserTestUtils.withNewTab({gBrowser, url: PAGE_PRIVACY}, async function(browser) {
+    await ContentTask.spawn(browser, SELECTORS, (selectors) => {
+      is(content.document.querySelector(selectors.group).hidden, false,
+        "Form Autofill group should be visible");
+      is(content.document.querySelector(selectors.addressAutofillCheckbox).checked, false,
+        "Checkbox should be unchecked when Autofill Addresses is disabled");
+      is(content.document.querySelector(selectors.creditCardAutofillCheckbox).checked, false,
+        "Checkbox should be unchecked when Autofill Credit Cards is disabled");
+    });
+  });
+});
--- a/browser/extensions/formautofill/test/browser/head.js
+++ b/browser/extensions/formautofill/test/browser/head.js
@@ -1,26 +1,27 @@
 /* exported MANAGE_ADDRESSES_DIALOG_URL, MANAGE_CREDIT_CARDS_DIALOG_URL, EDIT_ADDRESS_DIALOG_URL, EDIT_CREDIT_CARD_DIALOG_URL,
             BASE_URL, TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3, TEST_ADDRESS_4, TEST_ADDRESS_5,
             TEST_CREDIT_CARD_1, TEST_CREDIT_CARD_2, TEST_CREDIT_CARD_3, FORM_URL,
-            FTU_PREF, ENABLED_PREF, SYNC_USERNAME_PREF, SYNC_ADDRESSES_PREF,
+            FTU_PREF, ENABLED_AUTOFILL_ADDRESSES_PREF, ENABLED_AUTOFILL_CREDITCARDS_PREF, SYNC_USERNAME_PREF, SYNC_ADDRESSES_PREF,
             sleep, expectPopupOpen, openPopupOn, expectPopupClose, closePopup, clickDoorhangerButton,
             getAddresses, saveAddress, removeAddresses, saveCreditCard,
             getDisplayedPopupItems, getDoorhangerCheckbox, waitForMasterPasswordDialog */
 
 "use strict";
 
 const MANAGE_ADDRESSES_DIALOG_URL = "chrome://formautofill/content/manageAddresses.xhtml";
 const MANAGE_CREDIT_CARDS_DIALOG_URL = "chrome://formautofill/content/manageCreditCards.xhtml";
 const EDIT_ADDRESS_DIALOG_URL = "chrome://formautofill/content/editAddress.xhtml";
 const EDIT_CREDIT_CARD_DIALOG_URL = "chrome://formautofill/content/editCreditCard.xhtml";
 const BASE_URL = "http://mochi.test:8888/browser/browser/extensions/formautofill/test/browser/";
 const FORM_URL = "http://mochi.test:8888/browser/browser/extensions/formautofill/test/browser/autocomplete_basic.html";
 const FTU_PREF = "extensions.formautofill.firstTimeUse";
-const ENABLED_PREF = "extensions.formautofill.addresses.enabled";
+const ENABLED_AUTOFILL_ADDRESSES_PREF = "extensions.formautofill.addresses.enabled";
+const ENABLED_AUTOFILL_CREDITCARDS_PREF = "extensions.formautofill.creditCards.enabled";
 const SYNC_USERNAME_PREF = "services.sync.username";
 const SYNC_ADDRESSES_PREF = "services.sync.engine.addresses";
 
 const TEST_ADDRESS_1 = {
   "given-name": "John",
   "additional-name": "R.",
   "family-name": "Smith",
   organization: "World Wide Web Consortium",