Bug 1446179 - Use ES Modules for the unprivileged Payment Request dialog code. r=jaws
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Thu, 12 Apr 2018 19:52:42 -0700
changeset 467475 64f5c8475f3b3087790dd23acee0e3499126c4fc
parent 467474 bfabe6333c854f8c003c7a71371f600099a24fd6
child 467476 4057d947afae2c4052ac66b8edab87b942eb9f08
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs1446179
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 1446179 - Use ES Modules for the unprivileged Payment Request dialog code. r=jaws MozReview-Commit-ID: fGVBVX1F2Q
toolkit/components/payments/.eslintrc.js
toolkit/components/payments/res/PaymentsStore.js
toolkit/components/payments/res/components/address-option.js
toolkit/components/payments/res/components/basic-card-option.js
toolkit/components/payments/res/components/currency-amount.js
toolkit/components/payments/res/components/payment-details-item.js
toolkit/components/payments/res/components/rich-option.js
toolkit/components/payments/res/components/rich-select.js
toolkit/components/payments/res/components/shipping-option.js
toolkit/components/payments/res/containers/address-picker.js
toolkit/components/payments/res/containers/basic-card-form.js
toolkit/components/payments/res/containers/order-details.js
toolkit/components/payments/res/containers/payment-dialog.js
toolkit/components/payments/res/containers/payment-method-picker.js
toolkit/components/payments/res/containers/shipping-option-picker.js
toolkit/components/payments/res/mixins/ObservedPropertiesMixin.js
toolkit/components/payments/res/mixins/PaymentStateSubscriberMixin.js
toolkit/components/payments/res/paymentRequest.js
toolkit/components/payments/res/paymentRequest.xhtml
--- a/toolkit/components/payments/.eslintrc.js
+++ b/toolkit/components/payments/.eslintrc.js
@@ -1,11 +1,24 @@
 "use strict";
 
 module.exports = {
+  overrides: [
+    {
+      files: [
+        "res/components/*.js",
+        "res/containers/*.js",
+        "res/mixins/*.js",
+        "res/PaymentsStore.js",
+      ],
+      parserOptions: {
+        sourceType: "module",
+      },
+    },
+  ],
   rules: {
     "mozilla/var-only-at-top-level": "error",
 
     "array-bracket-spacing": ["error", "never"],
     "block-scoped-var": "error",
     "comma-dangle": ["error", "always-multiline"],
     complexity: ["error", {
       max: 20,
--- a/toolkit/components/payments/res/PaymentsStore.js
+++ b/toolkit/components/payments/res/PaymentsStore.js
@@ -1,23 +1,19 @@
 /* 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/. */
 
-"use strict";
-
 /**
  * The PaymentsStore class provides lightweight storage with an async publish/subscribe mechanism.
  * Synchronous state changes are batched to improve application performance and to reduce partial
  * state propagation.
  */
 
-/* exported PaymentsStore */
-
-class PaymentsStore {
+export default class PaymentsStore {
   /**
    * @param {object} [defaultState = {}] The initial state of the store.
    */
   constructor(defaultState = {}) {
     this._state = defaultState;
     this._nextNotifification = 0;
     this._subscribers = new Set();
   }
--- a/toolkit/components/payments/res/components/address-option.js
+++ b/toolkit/components/payments/res/components/address-option.js
@@ -1,31 +1,32 @@
 /* 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/. */
 
+import ObservedPropertiesMixin from "../mixins/ObservedPropertiesMixin.js";
+import RichOption from "./rich-option.js";
+
 /**
  * <rich-select>
  *  <address-option guid="98hgvnbmytfc"
  *                  address-level1="MI"
  *                  address-level2="Some City"
  *                  email="foo@example.com"
  *                  country="USA"
  *                  name="Jared Wein"
  *                  postal-code="90210"
  *                  street-address="1234 Anywhere St"
  *                  tel="+1 650 555-5555"></address-option>
  * </rich-select>
  *
  * Attribute names follow FormAutofillStorage.jsm.
  */
 
-/* global ObservedPropertiesMixin, RichOption */
-
-class AddressOption extends ObservedPropertiesMixin(RichOption) {
+export default class AddressOption extends ObservedPropertiesMixin(RichOption) {
   static get recordAttributes() {
     return [
       "address-level1",
       "address-level2",
       "country",
       "email",
       "guid",
       "name",
--- a/toolkit/components/payments/res/components/basic-card-option.js
+++ b/toolkit/components/payments/res/components/basic-card-option.js
@@ -1,21 +1,22 @@
 /* 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/. */
 
+import ObservedPropertiesMixin from "../mixins/ObservedPropertiesMixin.js";
+import RichOption from "./rich-option.js";
+
 /**
  * <rich-select>
  *  <basic-card-option></basic-card-option>
  * </rich-select>
  */
 
-/* global ObservedPropertiesMixin, RichOption */
-
-class BasicCardOption extends ObservedPropertiesMixin(RichOption) {
+export default class BasicCardOption extends ObservedPropertiesMixin(RichOption) {
   static get recordAttributes() {
     return [
       "cc-exp",
       "cc-name",
       "cc-number",
       "guid",
       "type", // XXX Bug 1429181.
     ];
--- a/toolkit/components/payments/res/components/currency-amount.js
+++ b/toolkit/components/payments/res/components/currency-amount.js
@@ -3,19 +3,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 /**
  * <currency-amount value="7.5" currency="USD"></currency-amount>
  */
 
-/* global ObservedPropertiesMixin */
+import ObservedPropertiesMixin from "../mixins/ObservedPropertiesMixin.js";
 
-class CurrencyAmount extends ObservedPropertiesMixin(HTMLElement) {
+export default class CurrencyAmount extends ObservedPropertiesMixin(HTMLElement) {
   static get observedAttributes() {
     return ["currency", "value"];
   }
 
   render() {
     let output = "";
     try {
       if (this.value && this.currency) {
--- a/toolkit/components/payments/res/components/payment-details-item.js
+++ b/toolkit/components/payments/res/components/payment-details-item.js
@@ -1,39 +1,38 @@
 /* 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/. */
 
-"use strict";
-
 /**
  * <ul>
  *  <payment-details-item
                           label="Some item"
                           amount-value="1.00"
                           amount-currency="USD"></payment-details-item>
  * </ul>
  */
 
-/* global ObservedPropertiesMixin */
+import CurrencyAmount from "./currency-amount.js";
+import ObservedPropertiesMixin from "../mixins/ObservedPropertiesMixin.js";
 
-class PaymentDetailsItem extends ObservedPropertiesMixin(HTMLElement) {
+export default class PaymentDetailsItem extends ObservedPropertiesMixin(HTMLElement) {
   static get observedAttributes() {
     return [
       "label",
       "amount-currency",
       "amount-value",
     ];
   }
 
   constructor() {
     super();
     this._label = document.createElement("span");
     this._label.classList.add("label");
-    this._currencyAmount = document.createElement("currency-amount");
+    this._currencyAmount = new CurrencyAmount();
   }
 
   connectedCallback() {
     this.appendChild(this._label);
     this.appendChild(this._currencyAmount);
 
     if (super.connectedCallback) {
       super.connectedCallback();
--- a/toolkit/components/payments/res/components/rich-option.js
+++ b/toolkit/components/payments/res/components/rich-option.js
@@ -3,20 +3,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * <rich-select>
  *  <rich-option></rich-option>
  * </rich-select>
  */
 
-/* global ObservedPropertiesMixin */
-/* exported RichOption */
+import ObservedPropertiesMixin from "../mixins/ObservedPropertiesMixin.js";
 
-class RichOption extends ObservedPropertiesMixin(HTMLElement) {
+export default class RichOption extends ObservedPropertiesMixin(HTMLElement) {
   static get observedAttributes() {
     return [
       "selected",
       "value",
     ];
   }
 
   connectedCallback() {
--- a/toolkit/components/payments/res/components/rich-select.js
+++ b/toolkit/components/payments/res/components/rich-select.js
@@ -1,23 +1,24 @@
 /* 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/. */
 
-/* global ObservedPropertiesMixin */
+import ObservedPropertiesMixin from "../mixins/ObservedPropertiesMixin.js";
+import RichOption from "./rich-option.js";
 
 /**
  * <rich-select>
  *  <rich-option></rich-option>
  * </rich-select>
  *
  * Note: The only supported way to change the selected option is via the
  *       `selectedOption` setter.
  */
-class RichSelect extends ObservedPropertiesMixin(HTMLElement) {
+export default class RichSelect extends ObservedPropertiesMixin(HTMLElement) {
   static get observedAttributes() {
     return [
       "open",
       "disabled",
       "hidden",
     ];
   }
 
@@ -196,17 +197,17 @@ class RichSelect extends ObservedPropert
       selectedClone.remove();
     }
 
     if (selectedChild) {
       selectedClone = selectedChild.cloneNode(false);
       selectedClone.removeAttribute("id");
       selectedClone.removeAttribute("selected");
     } else {
-      selectedClone = document.createElement("rich-option");
+      selectedClone = new RichOption();
       selectedClone.textContent = "(None selected)";
     }
     selectedClone.classList.add("rich-select-selected-clone");
     selectedClone = this.appendChild(selectedClone);
   }
 }
 
 customElements.define("rich-select", RichSelect);
--- a/toolkit/components/payments/res/components/shipping-option.js
+++ b/toolkit/components/payments/res/components/shipping-option.js
@@ -1,34 +1,36 @@
 /* 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/. */
 
+import CurrencyAmount from "./currency-amount.js";
+import ObservedPropertiesMixin from "../mixins/ObservedPropertiesMixin.js";
+import RichOption from "./rich-option.js";
+
 /**
  * <rich-select>
  *  <shipping-option></shipping-option>
  * </rich-select>
  */
 
-/* global ObservedPropertiesMixin, RichOption */
-
-class ShippingOption extends ObservedPropertiesMixin(RichOption) {
+export default class ShippingOption extends ObservedPropertiesMixin(RichOption) {
   static get observedAttributes() {
     return RichOption.observedAttributes.concat([
       "label",
       "amount-currency",
       "amount-value",
     ]);
   }
 
   constructor() {
     super();
 
     this.amount = null;
-    this._currencyAmount = document.createElement("currency-amount");
+    this._currencyAmount = new CurrencyAmount();
     this._currencyAmount.classList.add("amount");
     this._label = document.createElement("span");
     this._label.classList.add("label");
   }
 
   connectedCallback() {
     this.appendChild(this._currencyAmount);
     this.appendChild(this._label);
--- a/toolkit/components/payments/res/containers/address-picker.js
+++ b/toolkit/components/payments/res/containers/address-picker.js
@@ -1,31 +1,30 @@
 /* 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/. */
 
-/* import-globals-from ../mixins/PaymentStateSubscriberMixin.js */
-/* import-globals-from ../components/address-option.js */
-
-"use strict";
+import AddressOption from "../components/address-option.js";
+import PaymentStateSubscriberMixin from "../mixins/PaymentStateSubscriberMixin.js";
+import RichSelect from "../components/rich-select.js";
 
 /**
  * <address-picker></address-picker>
  * Container around <rich-select> (eventually providing add/edit links) with
  * <address-option> listening to savedAddresses.
  */
 
-class AddressPicker extends PaymentStateSubscriberMixin(HTMLElement) {
+export default class AddressPicker extends PaymentStateSubscriberMixin(HTMLElement) {
   static get observedAttributes() {
     return ["address-fields"];
   }
 
   constructor() {
     super();
-    this.dropdown = document.createElement("rich-select");
+    this.dropdown = new RichSelect();
     this.dropdown.addEventListener("change", this);
   }
 
   connectedCallback() {
     this.appendChild(this.dropdown);
     super.connectedCallback();
   }
 
@@ -85,17 +84,17 @@ class AddressPicker extends PaymentState
         fieldNames = names;
       }
     }
     let filteredAddresses = this.filterAddresses(savedAddresses, fieldNames);
 
     for (let [guid, address] of Object.entries(filteredAddresses)) {
       let optionEl = this.dropdown.getOptionByValue(guid);
       if (!optionEl) {
-        optionEl = document.createElement("address-option");
+        optionEl = new AddressOption();
         optionEl.value = guid;
       }
 
       for (let key of AddressOption.recordAttributes) {
         let val = address[key];
         if (val) {
           optionEl.setAttribute(key, val);
         } else {
--- a/toolkit/components/payments/res/containers/basic-card-form.js
+++ b/toolkit/components/payments/res/containers/basic-card-form.js
@@ -1,27 +1,25 @@
 /* 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/. */
 
 /* import-globals-from ../../../../../browser/extensions/formautofill/content/autofillEditForms.js*/
-/* import-globals-from ../mixins/PaymentStateSubscriberMixin.js */
+import PaymentStateSubscriberMixin from "../mixins/PaymentStateSubscriberMixin.js";
 /* import-globals-from ../unprivileged-fallbacks.js */
 /* import-globals-from ../paymentRequest.js */
 
-"use strict";
-
 /**
  * <basic-card-form></basic-card-form>
  *
  * XXX: Bug 1446164 - This form isn't localized when used via this custom element
  * as it will be much easier to share the logic once we switch to Fluent.
  */
 
-class BasicCardForm extends PaymentStateSubscriberMixin(HTMLElement) {
+export default class BasicCardForm extends PaymentStateSubscriberMixin(HTMLElement) {
   constructor() {
     super();
 
     this.genericErrorText = document.createElement("div");
 
     this.backButton = document.createElement("button");
     this.backButton.addEventListener("click", this);
 
--- a/toolkit/components/payments/res/containers/order-details.js
+++ b/toolkit/components/payments/res/containers/order-details.js
@@ -1,21 +1,22 @@
 /* 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/. */
 
-/* global PaymentStateSubscriberMixin, PaymentRequest */
-
-"use strict";
+// <currency-amount> is used in the <template>
+import "../components/currency-amount.js";
+import PaymentDetailsItem from "../components/payment-details-item.js";
+import PaymentStateSubscriberMixin from "../mixins/PaymentStateSubscriberMixin.js";
 
 /**
  * <order-details></order-details>
  */
 
-class OrderDetails extends PaymentStateSubscriberMixin(HTMLElement) {
+export default class OrderDetails extends PaymentStateSubscriberMixin(HTMLElement) {
   connectedCallback() {
     if (!this._contents) {
       let template = document.getElementById("order-details-template");
       let contents = this._contents = document.importNode(template.content, true);
 
       this._mainItemsList = contents.querySelector(".main-list");
       this._footerItemsList = contents.querySelector(".footer-items-list");
       this._totalAmount = contents.querySelector(".details-total > currency-amount");
@@ -41,17 +42,17 @@ class OrderDetails extends PaymentStateS
     while (listEl.lastChild) {
       listEl.removeChild(listEl.lastChild);
     }
   }
 
   static _populateList(listEl, items) {
     let fragment = document.createDocumentFragment();
     for (let item of items) {
-      let row = document.createElement("payment-details-item");
+      let row = new PaymentDetailsItem();
       row.label = item.label;
       row.amountValue = item.amount.value;
       row.amountCurrency = item.amount.currency;
       fragment.appendChild(row);
     }
     listEl.appendChild(fragment);
     return listEl;
   }
--- a/toolkit/components/payments/res/containers/payment-dialog.js
+++ b/toolkit/components/payments/res/containers/payment-dialog.js
@@ -1,21 +1,30 @@
 /* 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/. */
 
-/* global PaymentStateSubscriberMixin, paymentRequest */
+import "../vendor/custom-elements.min.js";
+
+import PaymentStateSubscriberMixin from "../mixins/PaymentStateSubscriberMixin.js";
 
-"use strict";
+import "../components/currency-amount.js";
+import "./address-picker.js";
+import "./basic-card-form.js";
+import "./order-details.js";
+import "./payment-method-picker.js";
+import "./shipping-option-picker.js";
+
+/* global paymentRequest */
 
 /**
  * <payment-dialog></payment-dialog>
  */
 
-class PaymentDialog extends PaymentStateSubscriberMixin(HTMLElement) {
+export default class PaymentDialog extends PaymentStateSubscriberMixin(HTMLElement) {
   constructor() {
     super();
     this._template = document.getElementById("payment-dialog-template");
     this._cachedState = {};
   }
 
   connectedCallback() {
     let contents = document.importNode(this._template.content, true);
--- a/toolkit/components/payments/res/containers/payment-method-picker.js
+++ b/toolkit/components/payments/res/containers/payment-method-picker.js
@@ -1,27 +1,26 @@
 /* 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/. */
 
-/* import-globals-from ../mixins/PaymentStateSubscriberMixin.js */
-/* import-globals-from ../components/basic-card-option.js */
-
-"use strict";
+import BasicCardOption from "../components/basic-card-option.js";
+import PaymentStateSubscriberMixin from "../mixins/PaymentStateSubscriberMixin.js";
+import RichSelect from "../components/rich-select.js";
 
 /**
  * <payment-method-picker></payment-method-picker>
  * Container around add/edit links and <rich-select> with
  * <basic-card-option> listening to savedBasicCards.
  */
 
-class PaymentMethodPicker extends PaymentStateSubscriberMixin(HTMLElement) {
+export default class PaymentMethodPicker extends PaymentStateSubscriberMixin(HTMLElement) {
   constructor() {
     super();
-    this.dropdown = document.createElement("rich-select");
+    this.dropdown = new RichSelect();
     this.dropdown.addEventListener("change", this);
     this.spacerText = document.createTextNode(" ");
     this.securityCodeInput = document.createElement("input");
     this.securityCodeInput.autocomplete = "off";
     this.securityCodeInput.size = 3;
     this.securityCodeInput.addEventListener("change", this);
     this.addLink = document.createElement("a");
     this.addLink.href = "javascript:void(0)";
@@ -44,17 +43,17 @@ class PaymentMethodPicker extends Paymen
   }
 
   render(state) {
     let {savedBasicCards} = state;
     let desiredOptions = [];
     for (let [guid, basicCard] of Object.entries(savedBasicCards)) {
       let optionEl = this.dropdown.getOptionByValue(guid);
       if (!optionEl) {
-        optionEl = document.createElement("basic-card-option");
+        optionEl = new BasicCardOption();
         optionEl.value = guid;
       }
       for (let key of BasicCardOption.recordAttributes) {
         let val = basicCard[key];
         if (val) {
           optionEl.setAttribute(key, val);
         } else {
           optionEl.removeAttribute(key);
--- a/toolkit/components/payments/res/containers/shipping-option-picker.js
+++ b/toolkit/components/payments/res/containers/shipping-option-picker.js
@@ -1,41 +1,41 @@
 /* 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/. */
 
-/* global PaymentStateSubscriberMixin */
-
-"use strict";
+import PaymentStateSubscriberMixin from "../mixins/PaymentStateSubscriberMixin.js";
+import RichSelect from "../components/rich-select.js";
+import ShippingOption from "../components/shipping-option.js";
 
 /**
  * <shipping-option-picker></shipping-option-picker>
  * Container around <rich-select> with
  * <rich-option> listening to shippingOptions.
  */
 
-class ShippingOptionPicker extends PaymentStateSubscriberMixin(HTMLElement) {
+export default class ShippingOptionPicker extends PaymentStateSubscriberMixin(HTMLElement) {
   constructor() {
     super();
-    this.dropdown = document.createElement("rich-select");
+    this.dropdown = new RichSelect();
     this.dropdown.addEventListener("change", this);
   }
 
   connectedCallback() {
     this.appendChild(this.dropdown);
     super.connectedCallback();
   }
 
   render(state) {
     let {shippingOptions} = state.request.paymentDetails;
     let desiredOptions = [];
     for (let option of shippingOptions) {
       let optionEl = this.dropdown.getOptionByValue(option.id);
       if (!optionEl) {
-        optionEl = document.createElement("shipping-option");
+        optionEl = new ShippingOption();
         optionEl.value = option.id;
       }
       optionEl.label = option.label;
       optionEl.amountCurrency = option.amount.currency;
       optionEl.amountValue = option.amount.value;
       desiredOptions.push(optionEl);
     }
     let el = null;
--- a/toolkit/components/payments/res/mixins/ObservedPropertiesMixin.js
+++ b/toolkit/components/payments/res/mixins/ObservedPropertiesMixin.js
@@ -3,19 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Define getters and setters for observedAttributes converted to camelCase and
  * trigger a batched aynchronous call to `render` upon observed
  * attribute/property changes.
  */
 
-/* exported ObservedPropertiesMixin */
-
-function ObservedPropertiesMixin(superClass) {
+export default function ObservedPropertiesMixin(superClass) {
   return class ObservedProperties extends superClass {
     constructor() {
       super();
 
       this._observedPropertiesMixin = {
         pendingRender: false,
       };
 
--- a/toolkit/components/payments/res/mixins/PaymentStateSubscriberMixin.js
+++ b/toolkit/components/payments/res/mixins/PaymentStateSubscriberMixin.js
@@ -1,24 +1,22 @@
 /* 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/. */
 
-"use strict";
-
-/* global PaymentsStore */
+import PaymentsStore from "../PaymentsStore.js";
 
 /**
  * A mixin for a custom element to observe store changes to information about a payment request.
  */
 
 /**
  * State of the payment request dialog.
  */
-let requestStore = new PaymentsStore({
+export let requestStore = new PaymentsStore({
   changesPrevented: false,
   completionState: "initial",
   orderDetailsShowing: false,
   page: {
     id: "payment-summary",
   },
   request: {
     tabId: null,
@@ -46,26 +44,24 @@ let requestStore = new PaymentsStore({
   selectedPaymentCardSecurityCode: null,
   selectedShippingAddress: null,
   selectedShippingOption: null,
   savedAddresses: {},
   savedBasicCards: {},
 });
 
 
-/* exported PaymentStateSubscriberMixin */
-
 /**
  * A mixin to render UI based upon the requestStore and get updated when that store changes.
  *
  * Attaches `requestStore` to the element to give access to the store.
  * @param {class} superClass The class to extend
  * @returns {class}
  */
-function PaymentStateSubscriberMixin(superClass) {
+export default function PaymentStateSubscriberMixin(superClass) {
   return class PaymentStateSubscriber extends superClass {
     constructor() {
       super();
       this.requestStore = requestStore;
     }
 
     connectedCallback() {
       this.requestStore.subscribe(this);
--- a/toolkit/components/payments/res/paymentRequest.js
+++ b/toolkit/components/payments/res/paymentRequest.js
@@ -34,18 +34,17 @@ var paymentRequest = {
       case "DOMContentLoaded": {
         this.onPaymentRequestLoad();
         break;
       }
       case "keydown": {
         if (event.code != "KeyD" || !event.altKey || !event.ctrlKey) {
           break;
         }
-        let debuggingConsole = document.getElementById("debugging-console");
-        debuggingConsole.hidden = !debuggingConsole.hidden;
+        this.toggleDebuggingConsole();
         break;
       }
       case "unload": {
         this.onPaymentRequestUnload();
         break;
       }
       case "paymentChromeToContent": {
         this.onChromeToContent(event);
@@ -63,16 +62,24 @@ var paymentRequest = {
       bubbles: true,
       detail: Object.assign({
         messageType,
       }, detail),
     });
     document.dispatchEvent(event);
   },
 
+  toggleDebuggingConsole() {
+    let debuggingConsole = document.getElementById("debugging-console");
+    if (!debuggingConsole.src) {
+      debuggingConsole.src = "debugging.html";
+    }
+    debuggingConsole.hidden = !debuggingConsole.hidden;
+  },
+
   onChromeToContent({detail}) {
     let {messageType} = detail;
     log.debug("onChromeToContent: ", messageType);
 
     switch (messageType) {
       case "responseSent": {
         document.querySelector("payment-dialog").requestStore.setState({
           changesPrevented: true,
@@ -93,17 +100,17 @@ var paymentRequest = {
 
   onPaymentRequestLoad(requestId) {
     log.debug("onPaymentRequestLoad:", requestId);
     window.addEventListener("unload", this, {once: true});
     this.sendMessageToChrome("paymentDialogReady");
 
     // Automatically show the debugging console if loaded with a truthy `debug` query parameter.
     if (new URLSearchParams(location.search).get("debug")) {
-      document.getElementById("debugging-console").hidden = false;
+      this.toggleDebuggingConsole();
     }
   },
 
   async onShowPaymentRequest(detail) {
     // Handle getting called before the DOM is ready.
     log.debug("onShowPaymentRequest:", detail);
     await this.domReadyPromise;
 
--- a/toolkit/components/payments/res/paymentRequest.xhtml
+++ b/toolkit/components/payments/res/paymentRequest.xhtml
@@ -38,40 +38,21 @@
   <link rel="stylesheet" href="paymentRequest.css"/>
   <link rel="stylesheet" href="components/rich-select.css"/>
   <link rel="stylesheet" href="components/address-option.css"/>
   <link rel="stylesheet" href="components/basic-card-option.css"/>
   <link rel="stylesheet" href="components/shipping-option.css"/>
   <link rel="stylesheet" href="components/payment-details-item.css"/>
   <link rel="stylesheet" href="containers/order-details.css"/>
 
-  <script src="vendor/custom-elements.min.js"></script>
-
   <script src="unprivileged-fallbacks.js"></script>
 
-  <script src="PaymentsStore.js"></script>
-
-  <script src="mixins/ObservedPropertiesMixin.js"></script>
-  <script src="mixins/PaymentStateSubscriberMixin.js"></script>
-
   <script src="formautofill/autofillEditForms.js"></script>
 
-  <script src="components/currency-amount.js"></script>
-  <script src="containers/order-details.js"></script>
-  <script src="components/payment-details-item.js"></script>
-  <script src="components/rich-select.js"></script>
-  <script src="components/rich-option.js"></script>
-  <script src="components/address-option.js"></script>
-  <script src="components/shipping-option.js"></script>
-  <script src="containers/address-picker.js"></script>
-  <script src="components/basic-card-option.js"></script>
-  <script src="containers/shipping-option-picker.js"></script>
-  <script src="containers/payment-method-picker.js"></script>
-  <script src="containers/basic-card-form.js"></script>
-  <script src="containers/payment-dialog.js"></script>
+  <script type="module" src="containers/payment-dialog.js"></script>
 
   <script src="paymentRequest.js"></script>
 
   <template id="payment-dialog-template">
     <header>
       <div id="total">
         <h2 class="label"></h2>
         <currency-amount></currency-amount>
@@ -147,13 +128,12 @@
       <h2 class="label">&orderTotalLabel;</h2>
       <currency-amount></currency-amount>
     </div>
   </template>
 </head>
 <body dir="&locale.dir;">
   <iframe id="debugging-console"
           hidden="hidden"
-          height="400"
-          src="debugging.html"></iframe>
+          height="400"></iframe>
   <payment-dialog></payment-dialog>
 </body>
 </html>