Backed out 6 changesets (bug 1653392, bug 1648868, bug 1649202) for breaking bc at browser_modal_print.js on a CLOSED TREE
authorAndreea Pavel <apavel@mozilla.com>
Sat, 01 Aug 2020 02:25:16 +0300
changeset 542996 b36594479be22d5240e7c6bfc3e1cebf206d7011
parent 542995 c7d03304f6f8b71f5012bc1587a9f37c8ee672d6
child 542997 274e86c0eb8fcaf5dc3890b98b84026a44c40bfd
push id123157
push userapavel@mozilla.com
push dateFri, 31 Jul 2020 23:55:19 +0000
treeherderautoland@274e86c0eb8f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1653392, 1648868, 1649202
milestone81.0a1
backs oute6f8429bae890d2399a40559d239487768d95cbe
5360afed1ebad97369c6db808e1312693970d712
d3b3387338f857c2e76da0a3b4c6bff314fa981d
98b1c160e0654054a3ff346332752bb49b179950
5c984392950af82da28538cce086fc52a6c69e20
fa8732ebff701b7a7dceefeab7c9b4ccef842c20
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
Backed out 6 changesets (bug 1653392, bug 1648868, bug 1649202) for breaking bc at browser_modal_print.js on a CLOSED TREE Backed out changeset e6f8429bae89 (bug 1649202) Backed out changeset 5360afed1eba (bug 1649202) Backed out changeset d3b3387338f8 (bug 1649202) Backed out changeset 98b1c160e065 (bug 1653392) Backed out changeset 5c984392950a (bug 1648868) Backed out changeset fa8732ebff70 (bug 1648868)
browser/base/content/browser.xhtml
toolkit/components/printing/content/print.css
toolkit/components/printing/content/print.html
toolkit/components/printing/content/print.js
toolkit/components/printing/content/printUtils.js
toolkit/components/printing/tests/browser.ini
toolkit/components/printing/tests/browser_modal_print.js
toolkit/components/printing/tests/head.js
toolkit/components/prompts/content/tabprompts.css
toolkit/modules/SubDialog.jsm
--- a/browser/base/content/browser.xhtml
+++ b/browser/base/content/browser.xhtml
@@ -263,30 +263,16 @@
                  activateontab="true" position="after_start"
                  level="parent"
 #ifdef XP_WIN
                  consumeoutsideclicks="false" ignorekeys="shortcuts"
 #endif
         />
     </menulist>
 
-    <html:template id="printTabModalTemplate">
-      <vbox id="printTabModalTemplate" class="tabSubDialogBoxContainer printDialogContainer" hidden="true">
-        <vbox class="dialogBox" pack="end" role="dialog" aria-labelledby="dialogTitle">
-          <hbox class="dialogTitleBar" align="center" hidden="true">
-            <label class="dialogTitle" flex="1"/>
-            <button class="dialogClose close-icon"/>
-          </hbox>
-          <hbox class="printTabModalView">
-            <browser class="printSettingsBrowser dialogFrame"/>
-          </hbox>
-        </vbox>
-      </vbox>
-    </html:template>
-
     <html:template id="invalidFormTemplate">
       <!-- for invalid form error message -->
       <panel id="invalid-form-popup" type="arrow" orient="vertical" noautofocus="true" level="parent">
         <description/>
       </panel>
     </html:template>
 
     <html:template id="editBookmarkPanelTemplate">
--- a/toolkit/components/printing/content/print.css
+++ b/toolkit/components/printing/content/print.css
@@ -1,60 +1,50 @@
 /* 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/. */
 
 html, body {
-  width: 250px;
-  height: 600px;
+  height: 100%;
 }
 
 body {
   display: flex;
   flex-direction: column;
   justify-content: flex-start;
   overflow: hidden;
 }
 
 .row {
-  padding-inline-start: 18px;
+  padding-inline-start: 34px;
   margin-block: 18px;
 }
 
 .row .block-label {
   display: block;
   margin-bottom: 4px;
 }
 .row .block-label + input,
 .row .block-label + select,
 .row .block-label + .page-range-input select {
   margin-inline-start: 0;
 }
 
 .header-container {
   display: flex;
   flex-direction: row;
-  justify-content: space-between;
-  align-items: center;
   flex: 0 1 auto;
   border-bottom: 1px solid var(--in-content-border-color);
-  padding: 8px 18px;
+  margin-block: 18px 0;
 }
 .header-container > h2 {
-  margin: 0;
-  font-size: 17px;
-  line-height: 1;
+  margin-top: 0;
 }
-
-#sheet-count {
-  font-size: 11px;
-  border-radius: 5px;
-  border: solid 1px var(--in-content-border-color);
-  padding: 3px 8px;
-  margin: 0;
+.header-container > #sheets-count {
+  display: none;
 }
 
 form#print {
   display: flex;
   flex: 1 1 auto;
   flex-direction: column;
   justify-content: flex-start;
   overflow: hidden;
--- a/toolkit/components/printing/content/print.html
+++ b/toolkit/components/printing/content/print.html
@@ -54,19 +54,19 @@
         <div>
           <input type="radio" name="scale-choice" id="percent-scale-choice">
           <label for="percent-scale-choice" data-l10n-id="printui-scale-pcent"></label>
           <input id="percent-scale" placeholder="100%" type="text" disabled>
         </div>
       </div>
     </template>
 
-    <header class="header-container">
+    <header class="row header-container">
       <h2 data-l10n-id="printui-title"></h2>
-      <p id="sheet-count" is="page-count" hidden></p>
+      <p id="sheets-count" data-deferred-l10n-id="printui-sheets-count"></p>
     </header>
 
     <form id="print" is="print-form">
       <section class="body-container">
         <section id="destination" class="row">
           <label for="printer-picker" class="block-label" data-l10n-id="printui-destination-label"></label>
           <select is="destination-picker" id="printer-picker"></select>
         </section>
--- a/toolkit/components/printing/content/print.js
+++ b/toolkit/components/printing/content/print.js
@@ -1,35 +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/. */
 
 const { gBrowser, PrintUtils } = window.docShell.chromeEventHandler.ownerGlobal;
 
-document.addEventListener(
-  "DOMContentLoaded",
-  e => {
-    PrintEventHandler.init();
-  },
-  { once: true }
-);
+document.addEventListener("DOMContentLoaded", e => {
+  PrintEventHandler.init();
+});
 
-window.addEventListener(
-  "unload",
-  e => {
-    document.textContent = "";
-  },
-  { once: true }
-);
-
-var PrintEventHandler = {
+const PrintEventHandler = {
   init() {
     this.sourceBrowser = this.getSourceBrowser();
     this.settings = PrintUtils.getPrintSettings();
-    this.updatePrintPreview();
 
     document.addEventListener("print", e => this.print({ silent: true }));
     document.addEventListener("update-print-setting", e =>
       this.updateSetting(e.detail)
     );
     document.addEventListener("cancel-print", () => this.cancelPrint());
     document.addEventListener("open-system-dialog", () =>
       this.print({ silent: false })
@@ -45,19 +32,18 @@ var PrintEventHandler = {
         printRange == "all"
           ? Ci.nsIPrintSettings.kRangeAllPages
           : Ci.nsIPrintSettings.kRangeSpecifiedPageRange,
       // TODO: There's also kRangeSelection, which should come into play
       // once we have a text box where the user can specify a range
     };
     this.settingFlags = {
       orientation: Ci.nsIPrintSettings.kInitSaveOrientation,
-      printerName: Ci.nsIPrintSettings.kInitSaveAll,
       scaling: Ci.nsIPrintSettings.kInitSaveScaling,
-      shrinkToFit: Ci.nsIPrintSettings.kInitSaveShrinkToFit,
+      printerName: Ci.nsIPrintSettings.kInitSavePrinterName,
     };
 
     document.dispatchEvent(
       new CustomEvent("print-settings", {
         detail: this.settings,
       })
     );
   },
@@ -69,17 +55,19 @@ var PrintEventHandler = {
     }
     if (printerName) {
       settings.printerName = printerName;
     }
     PrintUtils.printWindow(this.sourceBrowser.browsingContext, settings);
   },
 
   cancelPrint() {
-    window.close();
+    gBrowser.removeTab(
+      gBrowser.getTabForBrowser(window.docShell.chromeEventHandler)
+    );
   },
 
   updateSetting({ setting, value }) {
     let settingValue =
       setting in this.settingValues
         ? this.settingValues[setting](value)
         : value;
 
@@ -90,58 +78,24 @@ var PrintEventHandler = {
         Ci.nsIPrintSettingsService
       );
 
       let flag = this.settingFlags[setting];
       if (flag) {
         PSSVC.savePrintSettingsToPrefs(this.settings, true, flag);
       }
 
-      this.updatePrintPreview();
-
       document.dispatchEvent(
         new CustomEvent("print-settings", {
           detail: this.settings,
         })
       );
     }
   },
 
-  async updatePrintPreview() {
-    if (this._previewUpdatingPromise) {
-      if (!this._queuedPreviewUpdatePromise) {
-        this._queuedPreviewUpdatePromise = this._previewUpdatingPromise.then(
-          () => this._updatePrintPreview()
-        );
-      }
-      // else there's already an update queued.
-    } else {
-      this._previewUpdatingPromise = this._updatePrintPreview();
-    }
-  },
-
-  async _updatePrintPreview() {
-    let numPages = await PrintUtils.updatePrintPreview(
-      this.sourceBrowser,
-      this.settings
-    );
-    document.dispatchEvent(
-      new CustomEvent("page-count", { detail: { numPages } })
-    );
-
-    if (this._queuedPreviewUpdatePromise) {
-      // Now that we're done, the queued update (if there is one) will start.
-      this._previewUpdatingPromise = this._queuedPreviewUpdatePromise;
-      this._queuedPreviewUpdatePromise = null;
-    } else {
-      // Nothing queued so throw our promise away.
-      this._previewUpdatingPromise = null;
-    }
-  },
-
   getSourceBrowser() {
     let params = new URLSearchParams(location.search);
     let browsingContextId = params.get("browsingContextId");
     if (!browsingContextId) {
       return null;
     }
     let browsingContext = BrowsingContext.get(browsingContextId);
     if (!browsingContext) {
@@ -394,26 +348,8 @@ class TwistySummary extends PrintUIContr
       this.label,
       open
         ? this.getAttribute("data-open-l10n-id")
         : this.getAttribute("data-closed-l10n-id")
     );
   }
 }
 customElements.define("twisty-summary", TwistySummary);
-
-class PageCount extends HTMLParagraphElement {
-  constructor() {
-    super();
-    document.addEventListener("page-count", this);
-  }
-
-  handleEvent(e) {
-    let { numPages } = e.detail;
-    document.l10n.setAttributes(this, "printui-sheets-count", {
-      sheetCount: numPages,
-    });
-    if (this.hidden) {
-      document.l10n.translateElements([this]).then(() => (this.hidden = false));
-    }
-  }
-}
-customElements.define("page-count", PageCount, { extends: "p" });
--- a/toolkit/components/printing/content/printUtils.js
+++ b/toolkit/components/printing/content/printUtils.js
@@ -109,144 +109,34 @@ var PrintUtils = {
     } catch (e) {
       Cu.reportError(e);
     }
 
     return null;
   },
 
   /**
-   * Retrieve the template contents for the tab modal print UI.
-   */
-  _tabModalTemplate() {
-    return document.importNode(
-      document.getElementById("printTabModalTemplate").content,
-      true
-    ).firstElementChild;
-  },
-
-  /**
    * Opens the tab modal version of the print UI for the current tab.
    *
    * @param aBrowsingContext
    *        The BrowsingContext of the window to print.
    */
-  async _openTabModalPrint(aBrowsingContext) {
-    const { SubDialog } = ChromeUtils.import(
-      "resource://gre/modules/SubDialog.jsm"
-    );
-
-    let container = gBrowser.getBrowserContainer(
-      aBrowsingContext.embedderElement
-    );
-    if (container.querySelector(".printDialogContainer")) {
-      // Don't open another dialog if we're already printing.
-      return;
-    }
-
-    let dialog = new SubDialog({
-      id: `printModal${aBrowsingContext.id}`,
-      template: this._tabModalTemplate(),
-      parentElement: container,
-      dialogOptions: {
-        consumeOutsideClicks: false,
-        reuseDialog: false,
-      },
-    });
-
-    // Move the overlay so it overlaps the chrome and content.
-    container.prepend(dialog._overlay);
-
-    // Store the dialog on the overlay for access in the tests.
-    dialog._overlay._dialog = dialog;
-    let sourceBrowser = aBrowsingContext.embedderElement;
-    let printPreviewBrowser = gBrowser.createBrowser({
-      remoteType: sourceBrowser.remoteType,
-      sameProcessAsFrameLoader: sourceBrowser.frameLoader,
-      skipLoad: false,
-    });
-    printPreviewBrowser.classList.add("printPreviewBrowser");
-    container.querySelector(".printTabModalView").prepend(printPreviewBrowser);
-    printPreviewBrowser.loadURI("about:printpreview", {
-      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
-    });
-
-    await dialog.open(
-      `chrome://global/content/print.html?browsingContextId=${aBrowsingContext.id}`
+  _openTabModalPrint(aBrowsingContext) {
+    let printPath = "chrome://global/content/print.html";
+    gBrowser.loadOneTab(
+      `${printPath}?browsingContextId=${aBrowsingContext.id}`,
+      {
+        inBackground: false,
+        relatedToCurrent: true,
+        triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+      }
     );
   },
 
   /**
-   * Update the preview browser for the provided tab browser and print settings.
-   *
-   * @param sourceBrowser
-   *        The source Browser (the one associated with a tab) that should be updated.
-   * @param printSettings
-   *        The nsIPrintSettings object to be used to render the preview.
-   *        Note: Only printerName is currently used.
-   *
-   * @return {Promise<Integer>} The number of pages that were rendered in the preview.
-   */
-  async updatePrintPreview(sourceBrowser, printSettings) {
-    let container = gBrowser.getBrowserContainer(sourceBrowser);
-    let printPreviewBrowser = container.querySelector(".printPreviewBrowser");
-
-    if (!printPreviewBrowser) {
-      // TODO: This should probably throw and close the print dialog.
-      return 0;
-    }
-
-    let numPages = await this._updatePrintPreview(
-      sourceBrowser,
-      printPreviewBrowser,
-      printSettings
-    );
-    return numPages;
-  },
-
-  /**
-   * Update a print preview for the provided source Browser, print preview Browser
-   * and nsIPrintSettings. This should probably only be called from updatePrintPreview.
-   *
-   * @param sourceBrowser
-   *        The source Browser (the one associated with a tab) that should be updated.
-   * @param printPreviewBrowser
-   *        The Browser that contains the print preview.
-   * @param printSettings
-   *        The nsIPrintSettings object to be used to render the preview.
-   *        Note: Only printerName is currently used.
-   *
-   * @return {Promise<Integer>} The number of pages that were rendered in the preview.
-   */
-  _updatePrintPreview(sourceBrowser, printPreviewBrowser, printSettings) {
-    return new Promise(resolve => {
-      printPreviewBrowser.messageManager.addMessageListener(
-        "Printing:Preview:UpdatePageCount",
-        function done(message) {
-          printPreviewBrowser.messageManager.removeMessageListener(
-            "Printing:Preview:UpdatePageCount",
-            done
-          );
-          resolve(message.data.numPages);
-        }
-      );
-
-      printPreviewBrowser.messageManager.sendAsyncMessage(
-        "Printing:Preview:Enter",
-        {
-          changingBrowsers: false,
-          lastUsedPrinterName: printSettings.printerName,
-          simplifiedMode: false,
-          windowID: sourceBrowser.outerWindowID,
-        }
-      );
-    });
-  },
-
-  /**
    * Initialize a print, this will open the tab modal UI if it is enabled or
    * defer to the native dialog/silent print.
    *
    * @param aBrowsingContext
    *        The BrowsingContext of the window to print.
    */
   startPrintWindow(aBrowsingContext) {
     if (PRINT_TAB_MODAL) {
@@ -343,17 +233,17 @@ var PrintUtils = {
    *
    *        These methods must be defined. printPreview can be called
    *        with aListenerObj as null iff this window is already displaying
    *        print preview (in which case, the previous aListenerObj passed
    *        to it will be used).
    */
   printPreview(aListenerObj) {
     if (PRINT_TAB_MODAL) {
-      this._openTabModalPrint(gBrowser.selectedBrowser.browsingContext);
+      this._openTabModalPrint(aListenerObj.getSourceBrowser().browsingContext);
       return;
     }
 
     // If we already have a toolbar someone is calling printPreview() to get us
     // to refresh the display and aListenerObj won't be passed.
     let printPreviewTB = document.getElementById("print-preview-toolbar");
     if (!printPreviewTB) {
       this._listener = aListenerObj;
--- a/toolkit/components/printing/tests/browser.ini
+++ b/toolkit/components/printing/tests/browser.ini
@@ -1,17 +1,8 @@
-[DEFAULT]
-support-files =
-  head.js
-
-[browser_modal_print.js]
-support-files =
-  simplifyArticleSample.html
-skip-if = os == "mac" || (verify && (os == 'win' || os == 'linux'))
-
 [browser_page_change_print_original.js]
 support-files =
   file_page_change_print_original_1.html
   file_page_change_print_original_2.html
 skip-if = os == "mac"
 
 [browser_preview_print_simplify_non_article.js]
 support-files =
deleted file mode 100644
--- a/toolkit/components/printing/tests/browser_modal_print.js
+++ /dev/null
@@ -1,74 +0,0 @@
-function assertExpectedPrintPage(helper) {
-  let printBrowser = helper.win.PrintEventHandler.sourceBrowser;
-  is(
-    printBrowser,
-    gBrowser.selectedBrowser,
-    "The current browser is being printed"
-  );
-  is(
-    printBrowser.currentURI.spec,
-    PrintHelper.defaultTestPageUrl,
-    "The URL of the browser is the one we expect"
-  );
-}
-
-add_task(async function testModalPrintDialog() {
-  await PrintHelper.withTestPage(async helper => {
-    helper.assertDialogHidden();
-
-    await helper.startPrint();
-
-    helper.assertDialogVisible();
-
-    // Check that we're printing the right page.
-    assertExpectedPrintPage(helper);
-
-    // Close the dialog with Escape.
-    await helper.withClosingFn(() => {
-      EventUtils.synthesizeKey("VK_ESCAPE", {}, helper.win);
-    });
-
-    helper.assertDialogHidden();
-  });
-});
-
-add_task(async function testPrintMultiple() {
-  await PrintHelper.withTestPage(async helper => {
-    helper.assertDialogHidden();
-
-    // First print as usual.
-    await helper.startPrint();
-    helper.assertDialogVisible();
-    assertExpectedPrintPage(helper);
-
-    // Trigger the command a few more times, verify the overlay still exists.
-    await helper.startPrint();
-    helper.assertDialogVisible();
-    await helper.startPrint();
-    helper.assertDialogVisible();
-    await helper.startPrint();
-    helper.assertDialogVisible();
-
-    // Verify it's still the correct page.
-    assertExpectedPrintPage(helper);
-
-    // Make sure we clean up, ideally this would be handled by the helper.
-    await helper.closeDialog();
-  });
-});
-
-add_task(async function testCancelButton() {
-  await PrintHelper.withTestPage(async helper => {
-    helper.assertDialogHidden();
-    await helper.startPrint();
-    helper.assertDialogVisible();
-
-    let cancelButton = helper.doc.querySelector("button[name=cancel]");
-    ok(cancelButton, "Got the cancel button");
-    await helper.withClosingFn(() =>
-      EventUtils.synthesizeMouseAtCenter(cancelButton, {}, helper.win)
-    );
-
-    helper.assertDialogHidden();
-  });
-});
deleted file mode 100644
--- a/toolkit/components/printing/tests/head.js
+++ /dev/null
@@ -1,82 +0,0 @@
-const PRINT_DOCUMENT_URI = "chrome://global/content/print.html";
-
-class PrintHelper {
-  static async withTestPage(testFn) {
-    await SpecialPowers.pushPrefEnv({
-      set: [["print.tab_modal.enabled", true]],
-    });
-
-    let taskReturn = await BrowserTestUtils.withNewTab(
-      this.defaultTestPageUrl,
-      async function(browser) {
-        await testFn(new PrintHelper(browser));
-      }
-    );
-
-    await SpecialPowers.popPrefEnv();
-
-    return taskReturn;
-  }
-
-  static get defaultTestPageUrl() {
-    const testPath = getRootDirectory(gTestPath).replace(
-      "chrome://mochitests/content",
-      "http://example.com"
-    );
-    return testPath + "simplifyArticleSample.html";
-  }
-
-  constructor(sourceBrowser) {
-    this.sourceBrowser = sourceBrowser;
-  }
-
-  async startPrint() {
-    document.getElementById("cmd_print").doCommand();
-    let dialog = await TestUtils.waitForCondition(() => this._dialogs[0]);
-    await dialog._dialog._dialogReady;
-  }
-
-  async withClosingFn(closeFn) {
-    await closeFn();
-    await this._dialogs[0]._dialog._closingPromise;
-  }
-
-  async closeDialog() {
-    await this.withClosingFn(() => this._dialogs[0]._dialog.close());
-  }
-
-  assertDialogHidden() {
-    is(this._dialogs.length, 0, "There are no print dialogs");
-  }
-
-  assertDialogVisible() {
-    is(this._dialogs.length, 1, "There is one print dialog");
-    BrowserTestUtils.is_visible(this._dialogs[0], "The dialog is visible");
-  }
-
-  get _container() {
-    return this.sourceBrowser.ownerGlobal.gBrowser.getBrowserContainer(
-      this.sourceBrowser
-    );
-  }
-
-  get _dialogs() {
-    return this._container.querySelectorAll(".printDialogContainer");
-  }
-
-  get _printBrowser() {
-    let dialogs = this._dialogs;
-    is(dialogs.length, 1, "There's one dialog");
-    let frame = dialogs[0].querySelector(".dialogFrame");
-    ok(frame, "Found the print dialog frame");
-    return frame;
-  }
-
-  get doc() {
-    return this._printBrowser.contentDocument;
-  }
-
-  get win() {
-    return this._printBrowser.contentWindow;
-  }
-}
--- a/toolkit/components/prompts/content/tabprompts.css
+++ b/toolkit/components/prompts/content/tabprompts.css
@@ -86,38 +86,8 @@ tabmodalprompt label[value=""] {
   width: 600px;
 }
 
 .paymentDialogContainerFrame {
   box-sizing: border-box;
   height: 100%;
   width: 100%;
 }
-
-/**
- * Tab modal SubDialog hosted overlay.
- */
-.tabSubDialogBoxContainer {
-  display: flex;
-  justify-content: center;
-  position: absolute;
-  /* TODO: figure out which element is preventing this from showing */
-  z-index: 1;
-  width: 100%;
-  margin-top: -3px;
-}
-
-.tabSubDialogBoxContainer .dialogBox {
-  box-shadow: 0 2px 8px rgba(12,12,13,.3);
-  outline: 1px solid rgba(12,12,13,.2);
-  background-color: var(--toolbar-bgcolor);
-  color: var(--toolbar-color);
-}
-
-.printPreviewBrowser {
-  width: 500px;
-  height: 600px;
-}
-
-.printSettingsBrowser {
-  width: 250px;
-  height: 600px;
-}
--- a/toolkit/modules/SubDialog.jsm
+++ b/toolkit/modules/SubDialog.jsm
@@ -23,35 +23,31 @@ const { Services } = ChromeUtils.import(
  * @param {String}  id - A unique identifier for the dialog.
  * @param {Object}  dialogOptions - Dialog options object.
  * @param {String[]} [dialogOptions.styleSheets] - An array of URLs to additional
  * stylesheets to inject into the frame.
  * @param {Boolean} [consumeOutsideClicks] - Whether to close the dialog when
  * its background overlay is clicked.
  * @param {SubDialog~resizeCallback} [resizeCallback] - Function to be called on
  * dialog resize.
- * @param {Boolean} [dialogOptions.reuseDialog] - If false, remove the SubDialog
- * from the DOM when closed. Defaults to true.
  */
 function SubDialog({
   template,
   parentElement,
   id,
   dialogOptions: {
     styleSheets = [],
     consumeOutsideClicks = true,
     resizeCallback,
-    reuseDialog = true,
   } = {},
 }) {
   this._id = id;
 
   this._injectedStyleSheets = this._injectedStyleSheets.concat(styleSheets);
   this._consumeOutsideClicks = consumeOutsideClicks;
-  this._reuseDialog = reuseDialog;
   this._resizeCallback = resizeCallback;
   this._overlay = template.cloneNode(true);
   this._box = this._overlay.querySelector(".dialogBox");
   this._titleBar = this._overlay.querySelector(".dialogTitleBar");
   this._titleElement = this._overlay.querySelector(".dialogTitle");
   this._closeButton = this._overlay.querySelector(".dialogClose");
   this._frame = this._overlay.querySelector(".dialogFrame");
 
@@ -113,21 +109,16 @@ SubDialog.prototype = {
     let contentStylesheet = doc.createProcessingInstruction(
       "xml-stylesheet",
       'href="' + aStylesheetURL + '" type="text/css"'
     );
     doc.insertBefore(contentStylesheet, doc.documentElement);
   },
 
   async open(aURL, aFeatures = null, aParams = null, aClosingCallback = null) {
-    // Create a promise so consumers can tell when we're done setting up.
-    this._dialogReady = new Promise(resolve => {
-      this._resolveDialogReady = resolve;
-    });
-
     // Wait until frame is ready to prevent browser crash in tests
     await this._frameCreated;
 
     if (!this._frame.contentWindow) {
       // Given the binding constructor execution is asynchronous, and "load"
       // event can be dispatched before the browser element is shown, the
       // browser binding might not be constructed at this point.  Forcibly
       // construct the frame and construct the binding.
@@ -217,41 +208,36 @@ SubDialog.prototype = {
       })
     );
 
     this._window.setTimeout(() => {
       // Unload the dialog after the event listeners run so that the load of about:blank isn't
       // cancelled by the ESC <key>.
       let onBlankLoad = e => {
         if (this._frame.contentWindow.location.href == "about:blank") {
-          this._frame.removeEventListener("load", onBlankLoad, true);
+          this._frame.removeEventListener("load", onBlankLoad);
           // We're now officially done closing, so update the state to reflect that.
           this._openedURL = null;
           this._isClosing = false;
-
-          if (!this._reuseDialog) {
-            this._overlay.remove();
-          }
-
           this._resolveClosePromise();
         }
       };
 
       // Depending on the context of the frame, we need either a system caller
       // (chrome) or a null principal (content) to load a new URI.
       let triggeringPrincipal;
       if (this._window.isChromeWindow) {
         triggeringPrincipal = this._window.document.nodePrincipal;
       } else {
         triggeringPrincipal = Services.scriptSecurityManager.createNullPrincipal(
           {}
         );
       }
 
-      this._frame.addEventListener("load", onBlankLoad, true);
+      this._frame.addEventListener("load", onBlankLoad, { capture: true });
       this._frame.loadURI("about:blank", {
         triggeringPrincipal,
       });
     }, 0);
   },
 
   handleEvent(aEvent) {
     switch (aEvent.type) {
@@ -375,17 +361,16 @@ SubDialog.prototype = {
     //
     // In that case, we expect them to define a Promise which will delay measuring
     // until the promise is fulfilled.
     if (target.contentDocument.mozSubdialogReady) {
       await target.contentDocument.mozSubdialogReady;
     }
 
     await this.resizeDialog();
-    this._resolveDialogReady();
   },
 
   async resizeDialog() {
     // Do this on load to wait for the CSS to load and apply before calculating the size.
     let docEl = this._frame.contentDocument.documentElement;
 
     // These are deduced from styles which we don't change, so it's safe to get them now:
     let boxHorizontalBorder =
@@ -625,17 +610,17 @@ SubDialog.prototype = {
       chromeEventHandler.addEventListener("DOMTitleChanged", this, true);
     }
 
     // DOMFrameContentLoaded only fires on the top window
     this._window.addEventListener("DOMFrameContentLoaded", this, true);
 
     // Wait for the stylesheets injected during DOMContentLoaded to load before showing the dialog
     // otherwise there is a flicker of the stylesheet applying.
-    this._frame.addEventListener("load", this, true);
+    this._frame.addEventListener("load", this, { capture: true });
 
     chromeEventHandler.addEventListener("unload", this, true);
 
     // Ensure we get <esc> keypresses even if nothing in the subdialog is focusable
     // (happens on OS X when only text inputs and lists are focusable, and
     //  the subdialog only has checkboxes/radiobuttons/buttons)
     this._window.addEventListener("keydown", this, true);
 
@@ -645,17 +630,17 @@ SubDialog.prototype = {
   _removeDialogEventListeners() {
     let chromeEventHandler = this._chromeEventHandler;
     chromeEventHandler.removeEventListener("DOMTitleChanged", this, true);
     chromeEventHandler.removeEventListener("unload", this, true);
 
     this._closeButton?.removeEventListener("command", this);
 
     this._window.removeEventListener("DOMFrameContentLoaded", this, true);
-    this._frame.removeEventListener("load", this, true);
+    this._frame.removeEventListener("load", this);
     this._frame.contentWindow.removeEventListener("dialogclosing", this);
     this._window.removeEventListener("keydown", this, true);
 
     this._overlay.removeEventListener("click", this, true);
 
     if (this._resizeObserver) {
       this._resizeObserver.disconnect();
       this._resizeObserver = null;
@@ -670,17 +655,17 @@ SubDialog.prototype = {
     this._closeButton?.addEventListener("keydown", this);
 
     this._window.addEventListener("focus", this, true);
   },
 
   _untrapFocus() {
     this._frame.contentDocument.removeEventListener("keydown", this, true);
     this._closeButton?.removeEventListener("keydown", this);
-    this._window.removeEventListener("focus", this, true);
+    this._window.removeEventListener("focus", this);
   },
 };
 
 /**
  * Manages multiple SubDialogs in a dialog stack element.
  */
 class SubDialogManager {
   /**