Bug 1495530 - Use card icons in form autofill card preferences screen. r=MattN
authorSam Foster <sfoster@mozilla.com>
Wed, 03 Oct 2018 15:58:16 +0000
changeset 495153 32cde67dd330391a0fb6735be8309a64e646a5f7
parent 495152 ba9d952a37de83181cbf5e2ab3f35032401c75c8
child 495154 b58cfd180ba7f5d7daeb419b1c038c7ca182c9a4
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN
bugs1495530
milestone64.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 1495530 - Use card icons in form autofill card preferences screen. r=MattN Differential Revision: https://phabricator.services.mozilla.com/D7334
browser/extensions/formautofill/content/manageDialog.css
browser/extensions/formautofill/content/manageDialog.js
browser/extensions/formautofill/test/browser/browser_manageCreditCardsDialog.js
--- a/browser/extensions/formautofill/content/manageDialog.css
+++ b/browser/extensions/formautofill/content/manageDialog.css
@@ -67,13 +67,65 @@ option:nth-child(even) {
 
 #edit {
   margin-inline-end: 0;
 }
 
 #credit-cards > option::before {
   content: "";
   background: url("icon-credit-card-generic.svg") no-repeat;
+  background-size: contain;
   float: left;
   width: 16px;
   height: 16px;
   padding-inline-end: 10px;
 }
+
+/*
+  We use .png / @2x.png images where we don't yet have a vector version of a logo
+*/
+#credit-cards.branded > option[cc-type="amex"]::before {
+  background-image: url("third-party/cc-logo-amex.png");
+}
+
+#credit-cards.branded > option[cc-type="cartebancaire"]::before {
+  background-image: url("third-party/cc-logo-cartebancaire.png");
+}
+
+#credit-cards.branded > option[cc-type="diners"]::before {
+  background-image: url("third-party/cc-logo-diners.svg");
+}
+
+#credit-cards.branded > option[cc-type="discover"]::before {
+  background-image: url("third-party/cc-logo-discover.png");
+}
+
+#credit-cards.branded > option[cc-type="jcb"]::before {
+  background-image: url("third-party/cc-logo-jcb.svg");
+}
+
+#credit-cards.branded > option[cc-type="mastercard"]::before {
+  background-image: url("third-party/cc-logo-mastercard.svg");
+}
+
+#credit-cards.branded > option[cc-type="mir"]::before {
+  background-image: url("third-party/cc-logo-mir.svg");
+}
+
+#credit-cards.branded > option[cc-type="unionpay"]::before {
+  background-image: url("third-party/cc-logo-unionpay.svg");
+}
+
+#credit-cards.branded > option[cc-type="visa"]::before {
+  background-image: url("third-party/cc-logo-visa.svg");
+}
+
+@media (min-resolution: 1.1dppx) {
+  #credit-cards.branded > option[cc-type="amex"]::before {
+    background-image: url("third-party/cc-logo-amex@2x.png");
+  }
+  #credit-cards.branded > option[cc-type="cartebancaire"]::before {
+    background-image: url("third-party/cc-logo-cartebancaire@2x.png");
+  }
+  #credit-cards.branded > option[cc-type="discover"]::before {
+    background-image: url("third-party/cc-logo-discover@2x.png");
+  }
+}
--- a/browser/extensions/formautofill/content/manageDialog.js
+++ b/browser/extensions/formautofill/content/manageDialog.js
@@ -6,16 +6,17 @@
 
 "use strict";
 
 const EDIT_ADDRESS_URL = "chrome://formautofill/content/editAddress.xhtml";
 const EDIT_CREDIT_CARD_URL = "chrome://formautofill/content/editCreditCard.xhtml";
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://formautofill/FormAutofill.jsm");
+ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 
 ChromeUtils.defineModuleGetter(this, "CreditCard",
                                "resource://gre/modules/CreditCard.jsm");
 ChromeUtils.defineModuleGetter(this, "formAutofillStorage",
                                "resource://formautofill/FormAutofillStorage.jsm");
 ChromeUtils.defineModuleGetter(this, "FormAutofillUtils",
                                "resource://formautofill/FormAutofillUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "MasterPassword",
@@ -363,17 +364,29 @@ class ManageCreditCards extends ManageRe
     }
     // For testing only: Notify when credit cards labels have been updated
     this._elements.records.dispatchEvent(new CustomEvent("LabelsUpdated"));
   }
 
   async renderRecordElements(records) {
     // Revert back to encrypted form when re-rendering happens
     this._isDecrypted = false;
+    // Display third-party card icons when possible
+    this._elements.records.classList.toggle("branded", AppConstants.MOZILLA_OFFICIAL);
     await super.renderRecordElements(records);
+
+    let options = this._elements.records.options;
+    for (let option of options) {
+      let record = option.record;
+      if (record && record["cc-type"]) {
+        option.setAttribute("cc-type", record["cc-type"]);
+      } else {
+        option.removeAttribute("cc-type");
+      }
+    }
   }
 
   updateButtonsStates(selectedCount) {
     this.updateShowHideButtonState();
     super.updateButtonsStates(selectedCount);
   }
 
   updateShowHideButtonState() {
--- a/browser/extensions/formautofill/test/browser/browser_manageCreditCardsDialog.js
+++ b/browser/extensions/formautofill/test/browser/browser_manageCreditCardsDialog.js
@@ -153,16 +153,52 @@ add_task(async function test_showCreditC
   await removeCreditCards([selRecords.options[1].value]);
   await removeCreditCards([selRecords.options[0].value]);
   await BrowserTestUtils.waitForEvent(selRecords, "RecordsLoaded");
   is(btnShowHideCreditCards.disabled, true, "Show credit cards button is disabled when there is no card");
 
   win.close();
 });
 
+add_task(async function test_showCreditCardIcons() {
+  await SpecialPowers.pushPrefEnv({"set": [["privacy.reduceTimerPrecision", false]]});
+  await saveCreditCard(TEST_CREDIT_CARD_1);
+  let unknownCard = Object.assign({}, TEST_CREDIT_CARD_3, {"cc-type": "gringotts"});
+  await saveCreditCard(unknownCard);
+
+  let win = window.openDialog(MANAGE_CREDIT_CARDS_DIALOG_URL, null, DIALOG_SIZE);
+  await waitForFocusAndFormReady(win);
+
+  let selRecords = win.document.querySelector(TEST_SELECTORS.selRecords);
+
+  is(selRecords.classList.contains("branded"), AppConstants.MOZILLA_OFFICIAL,
+     "record picker has 'branded' class in an MOZILLA_OFFICIAL build");
+
+  let option0 = selRecords.options[0];
+  let icon0Url = win.getComputedStyle(option0, "::before").backgroundImage;
+  let option1 = selRecords.options[1];
+  let icon1Url = win.getComputedStyle(option1, "::before").backgroundImage;
+
+  is(option0.getAttribute("cc-type"), "gringotts", "Option has the expected cc-type");
+  is(option1.getAttribute("cc-type"), "visa", "Option has the expected cc-type");
+
+  if (AppConstants.MOZILLA_OFFICIAL) {
+    ok(icon0Url.includes("icon-credit-card-generic.svg"),
+       "unknown network option ::before element has the generic icon as backgroundImage: " + icon0Url);
+    ok(icon1Url.includes("cc-logo-visa.svg"),
+       "visa option ::before element has the visa icon as backgroundImage " + icon1Url);
+  }
+
+  await removeCreditCards([option0.value, option1.value]);
+  await BrowserTestUtils.waitForEvent(selRecords, "RecordsLoaded");
+  is(selRecords.length, 0, "Credit card is removed");
+  win.close();
+});
+
+
 add_task(async function test_hasMasterPassword() {
   await saveCreditCard(TEST_CREDIT_CARD_1);
   LoginTestUtils.masterPassword.enable();
 
   let win = window.openDialog(MANAGE_CREDIT_CARDS_DIALOG_URL, null, DIALOG_SIZE);
   await waitForFocusAndFormReady(win);
 
   let selRecords = win.document.querySelector(TEST_SELECTORS.selRecords);