Bug 1648868 - Move modal print UI into a tab modal r=Gijs
☠☠ backed out by 4a5520ecb075 ☠ ☠
authorMark Striemer <mstriemer@mozilla.com>
Fri, 24 Jul 2020 15:53:36 +0000
changeset 542079 9f8b675f0f6bcb72c974a913572afb04d9258b69
parent 542078 7e36006e76d07501db910a4073a4dabee58f22a5
child 542080 7fac5bd02bb3c962c2b68ea682877772ddd98268
push id122620
push usermstriemer@mozilla.com
push dateFri, 24 Jul 2020 16:49:23 +0000
treeherderautoland@7fac5bd02bb3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs
bugs1648868, 1653317
milestone80.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 1648868 - Move modal print UI into a tab modal r=Gijs This gets the print UI into a tab modal but does so by abusing SubDialog. This should be migrated to TabDialogBox in bug 1653317. Differential Revision: https://phabricator.services.mozilla.com/D84244
browser/base/content/browser.xhtml
toolkit/components/printing/content/print.css
toolkit/components/printing/content/print.js
toolkit/components/printing/content/printUtils.js
toolkit/components/prompts/content/tabprompts.css
--- a/browser/base/content/browser.xhtml
+++ b/browser/base/content/browser.xhtml
@@ -263,16 +263,28 @@
                  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>
+          <browser class="dialogFrame"/>
+        </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,25 +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/. */
 
 html, body {
-  height: 100%;
+  width: 250px;
+  height: 600px;
 }
 
 body {
   display: flex;
   flex-direction: column;
   justify-content: flex-start;
   overflow: hidden;
 }
 
 .row {
-  padding-inline-start: 34px;
+  padding-inline-start: 18px;
   margin-block: 18px;
 }
 
 .row .block-label {
   display: block;
   margin-bottom: 4px;
 }
 .row .block-label + input,
--- a/toolkit/components/printing/content/print.js
+++ b/toolkit/components/printing/content/print.js
@@ -52,19 +52,17 @@ const PrintUI = {
       switch (event.submitter.name) {
         case "print":
           PrintUtils.printWindow(this.sourceBrowser.browsingContext, {
             printSilent: true,
             printerName: this._printerPicker.value,
           });
           break;
         case "cancel":
-          console.log(
-            "TODO: trigger any teardown, exit the print preview and close the tab-modal"
-          );
+          window.close();
           break;
       }
     }
     /* TODO:
      * handle clicks to the system dialog link
      * handle change of the selected printer/destination
      * handle changes from each of the print settings controls
      */
--- a/toolkit/components/printing/content/printUtils.js
+++ b/toolkit/components/printing/content/printUtils.js
@@ -109,29 +109,81 @@ var PrintUtils = {
     } catch (e) {
       Cu.reportError(e);
     }
 
     return null;
   },
 
   /**
+   * Retrieve the template for the tab modal print UI. The element
+   * could be inside of a template tag, so we'll want to unwrap it
+   * the first time it's accessed.
+   */
+  _tabModalTemplate() {
+    let template = document.getElementById("printTabModalTemplate");
+    if (template.localName == "template") {
+      template.replaceWith(template.content);
+      return document.getElementById("printTabModalTemplate");
+    }
+    return template;
+  },
+
+  /**
    * Opens the tab modal version of the print UI for the current tab.
    *
    * @param aBrowsingContext
    *        The BrowsingContext of the window to print.
    */
   _openTabModalPrint(aBrowsingContext) {
-    let printPath = "chrome://global/content/print.html";
-    gBrowser.loadOneTab(
-      `${printPath}?browsingContextId=${aBrowsingContext.id}`,
-      {
-        inBackground: false,
-        relatedToCurrent: true,
-        triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+    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,
+    });
+
+    // Store some Promises on the overlay for use in the tests.
+    dialog._overlay._ready = dialog._frameCreated;
+    let resolveDialogClosed;
+    dialog._overlay._closed = new Promise(
+      resolve => (resolveDialogClosed = resolve)
+    );
+
+    // Move the overlay so it overlaps the chrome and content.
+    container.prepend(dialog._overlay);
+
+    dialog.open(
+      `chrome://global/content/print.html?browsingContextId=${aBrowsingContext.id}`,
+      null,
+      null,
+      async () => {
+        // Cleanup the overlay since a new one will be created the next time
+        // a print is initiated for this tab.
+        let overlay = dialog._overlay;
+        await dialog._closingPromise;
+        overlay.remove();
+
+        // Cleanup all our references to the dialog.
+        dialog = null;
+        overlay._dialog = null;
+
+        // Let the tests know the dialog has been closed.
+        resolveDialogClosed();
       }
     );
   },
 
   /**
    * Initialize a print, this will open the tab modal UI if it is enabled or
    * defer to the native dialog/silent print.
    *
@@ -233,17 +285,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(aListenerObj.getSourceBrowser().browsingContext);
+      this._openTabModalPrint(gBrowser.selectedBrowser.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/prompts/content/tabprompts.css
+++ b/toolkit/components/prompts/content/tabprompts.css
@@ -86,8 +86,26 @@ 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);
+}