Backed out 1 changesets (bug 1450813) for failing browser_page_change_print_original.js CLOSED TREE
authorCiure Andrei <aciure@mozilla.com>
Mon, 02 Jul 2018 22:38:18 +0300
changeset 479799 e242648cae8c3b1b89d44183a31230a9690584a5
parent 479798 e780c6b275a2b26c3c12aff9f59893659f90b664
child 479800 583f3742e6c918ab1824e6e351adc3317e9af020
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1450813
milestone63.0a1
backs outee4e2bfffe18b6e8136dc8fa10bd4625344f5661
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 1 changesets (bug 1450813) for failing browser_page_change_print_original.js CLOSED TREE Backed out changeset ee4e2bfffe18 (bug 1450813)
browser/base/content/browser.css
toolkit/components/printing/content/printPreviewBindings.xml
toolkit/components/printing/content/printPreviewToolbar.js
toolkit/components/printing/content/printUtils.js
toolkit/components/printing/jar.mn
toolkit/components/printing/tests/browser_page_change_print_original.js
toolkit/content/customElements.js
toolkit/themes/linux/global/global.css
toolkit/themes/linux/global/jar.mn
toolkit/themes/linux/global/printPreview.css
toolkit/themes/windows/global/global.css
toolkit/themes/windows/global/jar.mn
toolkit/themes/windows/global/printPreview.css
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -246,16 +246,20 @@ panelview[mainview] > .panel-header {
 /* Allow dropping a tab on buttons with associated drop actions. */
 #TabsToolbar[movingtab] + #nav-bar > #nav-bar-customization-target > #personal-bookmarks,
 #TabsToolbar[movingtab] + #nav-bar > #nav-bar-customization-target > #home-button,
 #TabsToolbar[movingtab] + #nav-bar > #nav-bar-customization-target > #downloads-button,
 #TabsToolbar[movingtab] + #nav-bar > #nav-bar-customization-target > #bookmarks-menu-button {
   pointer-events: auto;
 }
 
+toolbar[printpreview="true"] {
+  -moz-binding: url("chrome://global/content/printPreviewBindings.xml#printpreviewtoolbar");
+}
+
 toolbar[overflowable] > .customization-target {
   overflow: hidden;
 }
 
 toolbar:not([overflowing]) > .overflow-button,
 toolbar[customizing] > .overflow-button {
   display: none;
 }
rename from toolkit/components/printing/content/printPreviewToolbar.js
rename to toolkit/components/printing/content/printPreviewBindings.xml
--- a/toolkit/components/printing/content/printPreviewToolbar.js
+++ b/toolkit/components/printing/content/printPreviewBindings.xml
@@ -1,340 +1,459 @@
-// This file is loaded into the browser window scope.
-/* eslint-env mozilla/browser-window */
+<?xml version="1.0"?>
+
+<!-- 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/. -->
+
+<!-- this file depends on printUtils.js -->
 
-// -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*-
+<!DOCTYPE bindings [
+<!ENTITY % printPreviewDTD SYSTEM "chrome://global/locale/printPreview.dtd" >
+%printPreviewDTD;
+]>
+
+<bindings id="printPreviewBindings"
+   xmlns="http://www.mozilla.org/xbl"
+   xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <binding id="printpreviewtoolbar">
+    <resources>
+      <stylesheet src="chrome://global/skin/printPreview.css"/>
+    </resources>
 
-/* 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/. */
+    <content>
+      <xul:button label="&print.label;" accesskey="&print.accesskey;"
+        oncommand="this.parentNode.print();" icon="print"/>
+
+      <xul:button anonid="pageSetup" label="&pageSetup.label;" accesskey="&pageSetup.accesskey;"
+        oncommand="this.parentNode.doPageSetup();"/>
 
-customElements.define("printpreview-toolbar", class PrintPreviewToolbar extends MozXULElement {
+      <xul:vbox align="center" pack="center">
+        <xul:label value="&page.label;" accesskey="&page.accesskey;" control="pageNumber"/>
+      </xul:vbox>
+      <xul:toolbarbutton anonid="navigateHome" class="navigate-button tabbable"
+        oncommand="parentNode.navigate(0, 0, 'home');" tooltiptext="&homearrow.tooltip;"/>
+      <xul:toolbarbutton anonid="navigatePrevious" class="navigate-button tabbable"
+        oncommand="parentNode.navigate(-1, 0, 0);" tooltiptext="&previousarrow.tooltip;"/>
+      <xul:hbox align="center" pack="center">
+        <xul:textbox id="pageNumber" value="1" min="1" type="number"
+          hidespinbuttons="true" onchange="navigate(0, this.valueNumber, 0);"/>
+        <xul:label value="&of.label;"/>
+        <xul:label value="1"/>
+      </xul:hbox>
+      <xul:toolbarbutton anonid="navigateNext" class="navigate-button tabbable"
+        oncommand="parentNode.navigate(1, 0, 0);" tooltiptext="&nextarrow.tooltip;"/>
+      <xul:toolbarbutton anonid="navigateEnd" class="navigate-button tabbable"
+        oncommand="parentNode.navigate(0, 0, 'end');" tooltiptext="&endarrow.tooltip;"/>
 
-  constructor() {
-    super();
-    this.disconnectedCallback = this.disconnectedCallback.bind(this);
-  }
-  connectedCallback() {
-    window.addEventListener("unload", this.disconnectedCallback, { once: true });
-    this.appendChild(MozXULElement.parseXULToFragment(`
-      <button label="&print.label;" accesskey="&print.accesskey;" oncommand="this.parentNode.print();" icon="print"></button>
-      <button anonid="pageSetup" label="&pageSetup.label;" accesskey="&pageSetup.accesskey;" oncommand="this.parentNode.doPageSetup();"></button>
-      <vbox align="center" pack="center">
-        <label value="&page.label;" accesskey="&page.accesskey;" control="pageNumber"></label>
-      </vbox>
-      <toolbarbutton anonid="navigateHome" class="navigate-button tabbable" oncommand="parentNode.navigate(0, 0, 'home');" tooltiptext="&homearrow.tooltip;"></toolbarbutton>
-      <toolbarbutton anonid="navigatePrevious" class="navigate-button tabbable" oncommand="parentNode.navigate(-1, 0, 0);" tooltiptext="&previousarrow.tooltip;"></toolbarbutton>
-      <hbox align="center" pack="center">
-        <textbox id="pageNumber" value="1" min="1" type="number" hidespinbuttons="true" onchange="navigate(0, this.valueNumber, 0);"></textbox>
-        <label value="&of.label;"></label>
-        <label value="1"></label>
-      </hbox>
-      <toolbarbutton anonid="navigateNext" class="navigate-button tabbable" oncommand="parentNode.navigate(1, 0, 0);" tooltiptext="&nextarrow.tooltip;"></toolbarbutton>
-      <toolbarbutton anonid="navigateEnd" class="navigate-button tabbable" oncommand="parentNode.navigate(0, 0, 'end');" tooltiptext="&endarrow.tooltip;"></toolbarbutton>
-      <toolbarseparator class="toolbarseparator-primary"></toolbarseparator>
-      <vbox align="center" pack="center">
-        <label value="&scale.label;" accesskey="&scale.accesskey;" control="scale"></label>
-      </vbox>
-      <hbox align="center" pack="center">
-        <menulist id="scale" crop="none" oncommand="parentNode.parentNode.scale(this.selectedItem.value);">
-          <menupopup>
-            <menuitem value="0.3" label="&p30.label;"></menuitem>
-            <menuitem value="0.4" label="&p40.label;"></menuitem>
-            <menuitem value="0.5" label="&p50.label;"></menuitem>
-            <menuitem value="0.6" label="&p60.label;"></menuitem>
-            <menuitem value="0.7" label="&p70.label;"></menuitem>
-            <menuitem value="0.8" label="&p80.label;"></menuitem>
-            <menuitem value="0.9" label="&p90.label;"></menuitem>
-            <menuitem value="1" label="&p100.label;"></menuitem>
-            <menuitem value="1.25" label="&p125.label;"></menuitem>
-            <menuitem value="1.5" label="&p150.label;"></menuitem>
-            <menuitem value="1.75" label="&p175.label;"></menuitem>
-            <menuitem value="2" label="&p200.label;"></menuitem>
-            <menuseparator></menuseparator>
-            <menuitem flex="1" value="ShrinkToFit" label="&ShrinkToFit.label;"></menuitem>
-            <menuitem value="Custom" label="&Custom.label;"></menuitem>
-          </menupopup>
-        </menulist>
-      </hbox>
-      <toolbarseparator class="toolbarseparator-primary"></toolbarseparator>
-      <hbox align="center" pack="center">
-        <toolbarbutton label="&portrait.label;" checked="true" accesskey="&portrait.accesskey;" type="radio" group="orient" class="toolbar-portrait-page tabbable" oncommand="parentNode.parentNode.orient('portrait');"></toolbarbutton>
-        <toolbarbutton label="&landscape.label;" accesskey="&landscape.accesskey;" type="radio" group="orient" class="toolbar-landscape-page tabbable" oncommand="parentNode.parentNode.orient('landscape');"></toolbarbutton>
-      </hbox>
-      <toolbarseparator class="toolbarseparator-primary"></toolbarseparator>
-      <checkbox label="&simplifyPage.label;" checked="false" disabled="true" accesskey="&simplifyPage.accesskey;" tooltiptext-disabled="&simplifyPage.disabled.tooltip;" tooltiptext-enabled="&simplifyPage.enabled.tooltip;" oncommand="this.parentNode.simplify();"></checkbox>
-      <toolbarseparator class="toolbarseparator-primary"></toolbarseparator>
-      <button label="&close.label;" accesskey="&close.accesskey;" oncommand="PrintUtils.exitPrintPreview();" icon="close"></button>
-      <data value="&customPrompt.title;"></data>
-    `, `
-    <!DOCTYPE bindings [
-      <!ENTITY % printPreviewDTD SYSTEM "chrome://global/locale/printPreview.dtd" >
-      %printPreviewDTD;
-    ]>`));
+      <xul:toolbarseparator class="toolbarseparator-primary"/>
+      <xul:vbox align="center" pack="center">
+        <xul:label value="&scale.label;" accesskey="&scale.accesskey;" control="scale"/>
+      </xul:vbox>
 
-    this.mPrintButton = this.childNodes[0];
-
-    this.mPageSetupButton = this.querySelector("[anonid=pageSetup]");
+      <xul:hbox align="center" pack="center">
+        <xul:menulist id="scale" crop="none"
+          oncommand="parentNode.parentNode.scale(this.selectedItem.value);">
+          <xul:menupopup>
+            <xul:menuitem value="0.3" label="&p30.label;"/>
+            <xul:menuitem value="0.4" label="&p40.label;"/>
+            <xul:menuitem value="0.5" label="&p50.label;"/>
+            <xul:menuitem value="0.6" label="&p60.label;"/>
+            <xul:menuitem value="0.7" label="&p70.label;"/>
+            <xul:menuitem value="0.8" label="&p80.label;"/>
+            <xul:menuitem value="0.9" label="&p90.label;"/>
+            <xul:menuitem value="1" label="&p100.label;"/>
+            <xul:menuitem value="1.25" label="&p125.label;"/>
+            <xul:menuitem value="1.5" label="&p150.label;"/>
+            <xul:menuitem value="1.75" label="&p175.label;"/>
+            <xul:menuitem value="2" label="&p200.label;"/>
+            <xul:menuseparator/>
+            <xul:menuitem flex="1" value="ShrinkToFit"
+              label="&ShrinkToFit.label;"/>
+            <xul:menuitem value="Custom" label="&Custom.label;"/>
+          </xul:menupopup>
+        </xul:menulist>
+      </xul:hbox>
 
-    this.mNavigateHomeButton = this.querySelector("[anonid=navigateHome]");
+      <xul:toolbarseparator class="toolbarseparator-primary"/>
+      <xul:hbox align="center" pack="center">
+        <xul:toolbarbutton label="&portrait.label;" checked="true"
+          accesskey="&portrait.accesskey;"
+          type="radio" group="orient" class="toolbar-portrait-page tabbable"
+          oncommand="parentNode.parentNode.orient('portrait');"/>
+        <xul:toolbarbutton label="&landscape.label;"
+          accesskey="&landscape.accesskey;"
+          type="radio" group="orient" class="toolbar-landscape-page tabbable"
+          oncommand="parentNode.parentNode.orient('landscape');"/>
+      </xul:hbox>
 
-    this.mNavigatePreviousButton = this.querySelector("[anonid=navigatePrevious]");
+      <xul:toolbarseparator class="toolbarseparator-primary"/>
+      <xul:checkbox label="&simplifyPage.label;" checked="false" disabled="true"
+        accesskey="&simplifyPage.accesskey;"
+        tooltiptext-disabled="&simplifyPage.disabled.tooltip;"
+        tooltiptext-enabled="&simplifyPage.enabled.tooltip;"
+        oncommand="this.parentNode.simplify();"/>
 
-    this.mPageTextBox = this.childNodes[5].childNodes[0];
+      <xul:toolbarseparator class="toolbarseparator-primary"/>
+      <xul:button label="&close.label;" accesskey="&close.accesskey;"
+        oncommand="PrintUtils.exitPrintPreview();" icon="close"/>
+      <xul:data value="&customPrompt.title;"/>
+    </content>
 
-    this.mNavigateNextButton = this.querySelector("[anonid=navigateNext]");
-
-    this.mNavigateEndButton = this.querySelector("[anonid=navigateEnd]");
-
-    this.mTotalPages = this.childNodes[5].childNodes[2];
-
-    this.mScaleLabel = this.childNodes[9].firstChild;
-
-    this.mScaleCombobox = this.childNodes[10].firstChild;
-
-    this.mOrientButtonsBox = this.childNodes[12];
-
-    this.mPortaitButton = this.mOrientButtonsBox.childNodes[0];
-
-    this.mLandscapeButton = this.mOrientButtonsBox.childNodes[1];
-
-    this.mSimplifyPageCheckbox = this.childNodes[14];
-
-    this.mSimplifyPageNotAllowed = this.mSimplifyPageCheckbox.disabled;
-
-    this.mSimplifyPageToolbarSeparator = this.childNodes[15];
-
-    this.mCustomTitle = this.childNodes[17].firstChild;
-
-    this.mPrintPreviewObs = "";
-
-    this.mWebProgress = "";
-
-    this.mPPBrowser = null;
-
-    this.mMessageManager = null;
-  }
+    <implementation>
+      <field name="mPrintButton">
+        document.getAnonymousNodes(this)[0]
+      </field>
+      <field name="mPageSetupButton">
+        document.getAnonymousElementByAttribute(this, "anonid", "pageSetup");
+      </field>
+      <field name="mNavigateHomeButton">
+        document.getAnonymousElementByAttribute(this, "anonid", "navigateHome");
+      </field>
+      <field name="mNavigatePreviousButton">
+        document.getAnonymousElementByAttribute(this, "anonid", "navigatePrevious");
+      </field>
+      <field name="mPageTextBox">
+        document.getAnonymousNodes(this)[5].childNodes[0]
+      </field>
+      <field name="mNavigateNextButton">
+        document.getAnonymousElementByAttribute(this, "anonid", "navigateNext");
+      </field>
+      <field name="mNavigateEndButton">
+        document.getAnonymousElementByAttribute(this, "anonid", "navigateEnd");
+      </field>
+      <field name="mTotalPages">
+        document.getAnonymousNodes(this)[5].childNodes[2]
+      </field>
+      <field name="mScaleLabel">
+        document.getAnonymousNodes(this)[9].firstChild
+      </field>
+      <field name="mScaleCombobox">
+        document.getAnonymousNodes(this)[10].firstChild
+      </field>
+      <field name="mOrientButtonsBox">
+        document.getAnonymousNodes(this)[12]
+      </field>
+      <field name="mPortaitButton">
+        this.mOrientButtonsBox.childNodes[0]
+      </field>
+      <field name="mLandscapeButton">
+        this.mOrientButtonsBox.childNodes[1]
+      </field>
+      <field name="mSimplifyPageCheckbox">
+        document.getAnonymousNodes(this)[14]
+      </field>
+      <field name="mSimplifyPageNotAllowed">
+        this.mSimplifyPageCheckbox.disabled
+      </field>
+      <field name="mSimplifyPageToolbarSeparator">
+        document.getAnonymousNodes(this)[15]
+      </field>
+      <field name="mCustomTitle">
+        document.getAnonymousNodes(this)[17].firstChild
+      </field>
+      <field name="mPrintPreviewObs">
+      </field>
+      <field name="mWebProgress">
+      </field>
+      <field name="mPPBrowser">
+        null
+      </field>
+      <field name="mMessageManager">
+        null
+      </field>
 
-  initialize(aPPBrowser) {
-    let { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
-    if (!Services.prefs.getBoolPref("print.use_simplify_page")) {
-      this.mSimplifyPageCheckbox.hidden = true;
-      this.mSimplifyPageToolbarSeparator.hidden = true;
-    }
-    this.mPPBrowser = aPPBrowser;
-    this.mMessageManager = aPPBrowser.messageManager;
-    this.mMessageManager.addMessageListener("Printing:Preview:UpdatePageCount", this);
-    this.updateToolbar();
-
-    let ltr = document.documentElement.matches(":root:-moz-locale-dir(ltr)");
-    // Windows 7 doesn't support ⏮ and ⏭ by default, and fallback doesn't
-    // always work (bug 1343330).
-    let { AppConstants } = ChromeUtils.import("resource://gre/modules/AppConstants.jsm", {});
-    let useCompatCharacters = AppConstants.isPlatformAndVersionAtMost("win", "6.1");
-    let leftEnd = useCompatCharacters ? "\u23EA" : "\u23EE";
-    let rightEnd = useCompatCharacters ? "\u23E9" : "\u23ED";
-    this.querySelector("[anonid=navigateHome]").label = ltr ? leftEnd : rightEnd;
-    this.querySelector("[anonid=navigatePrevious]").label = ltr ? "\u25C2" : "\u25B8";
-    this.querySelector("[anonid=navigateNext]").label = ltr ? "\u25B8" : "\u25C2";
-    this.querySelector("[anonid=navigateEnd]").label = ltr ? rightEnd : leftEnd;
-  }
+      <method name="initialize">
+        <parameter name="aPPBrowser"/>
+        <body>
+        <![CDATA[
+          let {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
+          if (!Services.prefs.getBoolPref("print.use_simplify_page")) {
+            this.mSimplifyPageCheckbox.hidden = true;
+            this.mSimplifyPageToolbarSeparator.hidden = true;
+          }
+          this.mPPBrowser = aPPBrowser;
+          this.mMessageManager = aPPBrowser.messageManager;
+          this.mMessageManager.addMessageListener("Printing:Preview:UpdatePageCount", this);
+          this.updateToolbar();
 
-  destroy() {
-    if (this.mMessageManager) {
-      this.mMessageManager.removeMessageListener("Printing:Preview:UpdatePageCount", this);
-      delete this.mMessageManager;
-      delete this.mPPBrowser;
-    }
-  }
-
-  disconnectedCallback() {
-    window.removeEventListener("unload", this.disconnectedCallback);
-    this.destroy();
-  }
+          let $ = id => document.getAnonymousElementByAttribute(this, "anonid", id);
+          let ltr = document.documentElement.matches(":root:-moz-locale-dir(ltr)");
+          // Windows 7 doesn't support ⏮ and ⏭ by default, and fallback doesn't
+          // always work (bug 1343330).
+          let {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm", {});
+          let useCompatCharacters = AppConstants.isPlatformAndVersionAtMost("win", "6.1");
+          let leftEnd = useCompatCharacters ? "⏪" : "⏮";
+          let rightEnd = useCompatCharacters ? "⏩" : "⏭";
+          $("navigateHome").label = ltr ? leftEnd : rightEnd;
+          $("navigatePrevious").label = ltr ? "◂" : "▸";
+          $("navigateNext").label = ltr ? "▸" : "◂";
+          $("navigateEnd").label = ltr ? rightEnd : leftEnd;
+        ]]>
+        </body>
+      </method>
 
-  disableUpdateTriggers(aDisabled) {
-    this.mPrintButton.disabled = aDisabled;
-    this.mPageSetupButton.disabled = aDisabled;
-    this.mNavigateHomeButton.disabled = aDisabled;
-    this.mNavigatePreviousButton.disabled = aDisabled;
-    this.mPageTextBox.disabled = aDisabled;
-    this.mNavigateNextButton.disabled = aDisabled;
-    this.mNavigateEndButton.disabled = aDisabled;
-    this.mScaleCombobox.disabled = aDisabled;
-    this.mPortaitButton.disabled = aDisabled;
-    this.mLandscapeButton.disabled = aDisabled;
-    this.mSimplifyPageCheckbox.disabled = this.mSimplifyPageNotAllowed || aDisabled;
-  }
+      <method name="destroy">
+        <body>
+        <![CDATA[
+          this.mMessageManager.removeMessageListener("Printing:Preview:UpdatePageCount", this);
+          delete this.mMessageManager;
+          delete this.mPPBrowser;
+        ]]>
+        </body>
+      </method>
+
+      <method name="disableUpdateTriggers">
+        <parameter name="aDisabled"/>
+        <body>
+        <![CDATA[
+          this.mPrintButton.disabled = aDisabled;
+          this.mPageSetupButton.disabled = aDisabled;
+          this.mNavigateHomeButton.disabled = aDisabled;
+          this.mNavigatePreviousButton.disabled = aDisabled;
+          this.mPageTextBox.disabled = aDisabled;
+          this.mNavigateNextButton.disabled = aDisabled;
+          this.mNavigateEndButton.disabled = aDisabled;
+          this.mScaleCombobox.disabled = aDisabled;
+          this.mPortaitButton.disabled = aDisabled;
+          this.mLandscapeButton.disabled = aDisabled;
+          this.mSimplifyPageCheckbox.disabled = this.mSimplifyPageNotAllowed || aDisabled;
+        ]]>
+        </body>
+      </method>
 
-  doPageSetup() {
-    /* import-globals-from printUtils.js */
-    var didOK = PrintUtils.showPageSetup();
-    if (didOK) {
-      // the changes that effect the UI
-      this.updateToolbar();
+      <method name="doPageSetup">
+        <body>
+        <![CDATA[
+          /* import-globals-from printUtils.js */
+          var didOK = PrintUtils.showPageSetup();
+          if (didOK) {
+            // the changes that effect the UI
+            this.updateToolbar();
+
+            // Now do PrintPreview
+            PrintUtils.printPreview();
+          }
+        ]]>
+        </body>
+      </method>
+
+      <method name="navigate">
+        <parameter name="aDirection"/>
+        <parameter name="aPageNum"/>
+        <parameter name="aHomeOrEnd"/>
+        <body>
+        <![CDATA[
+          const nsIWebBrowserPrint = Ci.nsIWebBrowserPrint;
+          let navType, pageNum;
 
-      // Now do PrintPreview
-      PrintUtils.printPreview();
-    }
-  }
+          // we use only one of aHomeOrEnd, aDirection, or aPageNum
+          if (aHomeOrEnd) {
+            // We're going to either the very first page ("home"), or the
+            // very last page ("end").
+            if (aHomeOrEnd == "home") {
+              navType = nsIWebBrowserPrint.PRINTPREVIEW_HOME;
+              this.mPageTextBox.value = 1;
+            } else {
+              navType = nsIWebBrowserPrint.PRINTPREVIEW_END;
+              this.mPageTextBox.value = this.mPageTextBox.max;
+            }
+            pageNum = 0;
+          } else if (aDirection) {
+            // aDirection is either +1 or -1, and allows us to increment
+            // or decrement our currently viewed page.
+            this.mPageTextBox.valueNumber += aDirection;
+            navType = nsIWebBrowserPrint.PRINTPREVIEW_GOTO_PAGENUM;
+            pageNum = this.mPageTextBox.value; // TODO: back to valueNumber?
+          } else {
+            // We're going to a specific page (aPageNum)
+            navType = nsIWebBrowserPrint.PRINTPREVIEW_GOTO_PAGENUM;
+            pageNum = aPageNum;
+          }
 
-  navigate(aDirection, aPageNum, aHomeOrEnd) {
-    const nsIWebBrowserPrint = Ci.nsIWebBrowserPrint;
-    let navType, pageNum;
+          this.mMessageManager.sendAsyncMessage("Printing:Preview:Navigate", {
+            navType,
+            pageNum,
+          });
+        ]]>
+        </body>
+      </method>
 
-    // we use only one of aHomeOrEnd, aDirection, or aPageNum
-    if (aHomeOrEnd) {
-      // We're going to either the very first page ("home"), or the
-      // very last page ("end").
-      if (aHomeOrEnd == "home") {
-        navType = nsIWebBrowserPrint.PRINTPREVIEW_HOME;
-        this.mPageTextBox.value = 1;
-      } else {
-        navType = nsIWebBrowserPrint.PRINTPREVIEW_END;
-        this.mPageTextBox.value = this.mPageTextBox.max;
-      }
-      pageNum = 0;
-    } else if (aDirection) {
-      // aDirection is either +1 or -1, and allows us to increment
-      // or decrement our currently viewed page.
-      this.mPageTextBox.valueNumber += aDirection;
-      navType = nsIWebBrowserPrint.PRINTPREVIEW_GOTO_PAGENUM;
-      pageNum = this.mPageTextBox.value; // TODO: back to valueNumber?
-    } else {
-      // We're going to a specific page (aPageNum)
-      navType = nsIWebBrowserPrint.PRINTPREVIEW_GOTO_PAGENUM;
-      pageNum = aPageNum;
-    }
+      <method name="print">
+        <body>
+        <![CDATA[
+          PrintUtils.printWindow(this.mPPBrowser.outerWindowID, this.mPPBrowser);
+        ]]>
+        </body>
+      </method>
 
-    this.mMessageManager.sendAsyncMessage("Printing:Preview:Navigate", {
-      navType,
-      pageNum,
-    });
-  }
+      <method name="promptForScaleValue">
+        <parameter name="aValue"/>
+        <body>
+        <![CDATA[
+          var value = Math.round(aValue);
+          var promptStr = this.mScaleLabel.value;
+          var renameTitle = this.mCustomTitle;
+          var result = {value};
+          let {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
+          var confirmed = Services.prompt.prompt(window, renameTitle, promptStr, result, null, {value});
+          if (!confirmed || (!result.value) || (result.value == "")) {
+            return -1;
+          }
+          return result.value;
+        ]]>
+        </body>
+      </method>
 
-  print() {
-    PrintUtils.printWindow(this.mPPBrowser.outerWindowID, this.mPPBrowser);
-  }
+      <method name="setScaleCombobox">
+        <parameter name="aValue"/>
+        <body>
+        <![CDATA[
+          var scaleValues = [0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.25, 1.5, 1.75, 2];
+
+          aValue = Number(aValue);
 
-  promptForScaleValue(aValue) {
-    var value = Math.round(aValue);
-    var promptStr = this.mScaleLabel.value;
-    var renameTitle = this.mCustomTitle;
-    var result = { value };
-    let { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
-    var confirmed = Services.prompt.prompt(window, renameTitle, promptStr, result, null, { value });
-    if (!confirmed || (!result.value) || (result.value == "")) {
-      return -1;
-    }
-    return result.value;
-  }
+          for (var i = 0; i < scaleValues.length; i++) {
+            if (aValue == scaleValues[i]) {
+              this.mScaleCombobox.selectedIndex = i;
+              return;
+            }
+          }
+          this.mScaleCombobox.value = "Custom";
+        ]]>
+        </body>
+      </method>
 
-  setScaleCombobox(aValue) {
-    var scaleValues = [0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.25, 1.5, 1.75, 2];
-
-    aValue = Number(aValue);
-
-    for (var i = 0; i < scaleValues.length; i++) {
-      if (aValue == scaleValues[i]) {
-        this.mScaleCombobox.selectedIndex = i;
-        return;
-      }
-    }
-    this.mScaleCombobox.value = "Custom";
-  }
+      <method name="scale">
+        <parameter name="aValue"/>
+        <body>
+        <![CDATA[
+          var settings = PrintUtils.getPrintSettings();
+          if (aValue == "ShrinkToFit") {
+            if (!settings.shrinkToFit) {
+              settings.shrinkToFit = true;
+              this.savePrintSettings(settings, settings.kInitSaveShrinkToFit | settings.kInitSaveScaling);
+              PrintUtils.printPreview();
+            }
+            return;
+          }
 
-  scale(aValue) {
-    var settings = PrintUtils.getPrintSettings();
-    if (aValue == "ShrinkToFit") {
-      if (!settings.shrinkToFit) {
-        settings.shrinkToFit = true;
-        this.savePrintSettings(settings, settings.kInitSaveShrinkToFit | settings.kInitSaveScaling);
-        PrintUtils.printPreview();
-      }
-      return;
-    }
+          if (aValue == "Custom") {
+            aValue = this.promptForScaleValue(settings.scaling * 100.0);
+            if (aValue >= 10) {
+              aValue /= 100.0;
+            } else {
+              if (this.mScaleCombobox.hasAttribute("lastValidInx")) {
+                this.mScaleCombobox.selectedIndex = this.mScaleCombobox.getAttribute("lastValidInx");
+              }
+              return;
+            }
+          }
 
-    if (aValue == "Custom") {
-      aValue = this.promptForScaleValue(settings.scaling * 100.0);
-      if (aValue >= 10) {
-        aValue /= 100.0;
-      } else {
-        if (this.mScaleCombobox.hasAttribute("lastValidInx")) {
-          this.mScaleCombobox.selectedIndex = this.mScaleCombobox.getAttribute("lastValidInx");
-        }
-        return;
-      }
-    }
+          this.setScaleCombobox(aValue);
+          this.mScaleCombobox.setAttribute("lastValidInx", this.mScaleCombobox.selectedIndex);
+
+          if (settings.scaling != aValue || settings.shrinkToFit) {
+            settings.shrinkToFit = false;
+            settings.scaling = aValue;
+            this.savePrintSettings(settings, settings.kInitSaveShrinkToFit | settings.kInitSaveScaling);
+            PrintUtils.printPreview();
+          }
+        ]]>
+        </body>
+      </method>
 
-    this.setScaleCombobox(aValue);
-    this.mScaleCombobox.setAttribute("lastValidInx", this.mScaleCombobox.selectedIndex);
-
-    if (settings.scaling != aValue || settings.shrinkToFit) {
-      settings.shrinkToFit = false;
-      settings.scaling = aValue;
-      this.savePrintSettings(settings, settings.kInitSaveShrinkToFit | settings.kInitSaveScaling);
-      PrintUtils.printPreview();
-    }
-  }
+      <method name="orient">
+        <parameter name="aOrientation"/>
+        <body>
+        <![CDATA[
+          const kIPrintSettings = Ci.nsIPrintSettings;
+          var orientValue = (aOrientation == "portrait") ? kIPrintSettings.kPortraitOrientation :
+                                                           kIPrintSettings.kLandscapeOrientation;
+          var settings = PrintUtils.getPrintSettings();
+          if (settings.orientation != orientValue) {
+            settings.orientation = orientValue;
+            this.savePrintSettings(settings, settings.kInitSaveOrientation);
+            PrintUtils.printPreview();
+          }
+        ]]>
+        </body>
+      </method>
 
-  orient(aOrientation) {
-    const kIPrintSettings = Ci.nsIPrintSettings;
-    var orientValue = (aOrientation == "portrait") ? kIPrintSettings.kPortraitOrientation :
-      kIPrintSettings.kLandscapeOrientation;
-    var settings = PrintUtils.getPrintSettings();
-    if (settings.orientation != orientValue) {
-      settings.orientation = orientValue;
-      this.savePrintSettings(settings, settings.kInitSaveOrientation);
-      PrintUtils.printPreview();
-    }
-  }
+      <method name="simplify">
+        <body>
+        <![CDATA[
+          PrintUtils.setSimplifiedMode(this.mSimplifyPageCheckbox.checked);
+          PrintUtils.printPreview();
+        ]]>
+        </body>
+      </method>
 
-  simplify() {
-    PrintUtils.setSimplifiedMode(this.mSimplifyPageCheckbox.checked);
-    PrintUtils.printPreview();
-  }
-
-  enableSimplifyPage() {
-    this.mSimplifyPageNotAllowed = false;
-    this.mSimplifyPageCheckbox.disabled = false;
-    this.mSimplifyPageCheckbox.setAttribute("tooltiptext",
-      this.mSimplifyPageCheckbox.getAttribute("tooltiptext-enabled"));
-  }
+      <method name="enableSimplifyPage">
+        <body>
+        <![CDATA[
+          this.mSimplifyPageNotAllowed = false;
+          this.mSimplifyPageCheckbox.disabled = false;
+          this.mSimplifyPageCheckbox.setAttribute("tooltiptext",
+               this.mSimplifyPageCheckbox.getAttribute("tooltiptext-enabled"));
+        ]]>
+        </body>
+      </method>
 
-  disableSimplifyPage() {
-    this.mSimplifyPageNotAllowed = true;
-    this.mSimplifyPageCheckbox.disabled = true;
-    this.mSimplifyPageCheckbox.setAttribute("tooltiptext",
-      this.mSimplifyPageCheckbox.getAttribute("tooltiptext-disabled"));
-  }
+      <method name="disableSimplifyPage">
+        <body>
+        <![CDATA[
+          this.mSimplifyPageNotAllowed = true;
+          this.mSimplifyPageCheckbox.disabled = true;
+          this.mSimplifyPageCheckbox.setAttribute("tooltiptext",
+               this.mSimplifyPageCheckbox.getAttribute("tooltiptext-disabled"));
+        ]]>
+        </body>
+      </method>
 
-  updateToolbar() {
-    var settings = PrintUtils.getPrintSettings();
+      <method name="updateToolbar">
+        <body>
+        <![CDATA[
+          var settings = PrintUtils.getPrintSettings();
 
-    var isPortrait = settings.orientation == Ci.nsIPrintSettings.kPortraitOrientation;
+          var isPortrait = settings.orientation == Ci.nsIPrintSettings.kPortraitOrientation;
+
+          this.mPortaitButton.checked = isPortrait;
+          this.mLandscapeButton.checked = !isPortrait;
 
-    this.mPortaitButton.checked = isPortrait;
-    this.mLandscapeButton.checked = !isPortrait;
+          if (settings.shrinkToFit) {
+            this.mScaleCombobox.value = "ShrinkToFit";
+          } else {
+            this.setScaleCombobox(settings.scaling);
+          }
 
-    if (settings.shrinkToFit) {
-      this.mScaleCombobox.value = "ShrinkToFit";
-    } else {
-      this.setScaleCombobox(settings.scaling);
-    }
-
-    this.mPageTextBox.value = 1;
-  }
+          this.mPageTextBox.value = 1;
+        ]]>
+        </body>
+      </method>
 
-  savePrintSettings(settings, flags) {
-    var PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"]
-      .getService(Ci.nsIPrintSettingsService);
-    PSSVC.savePrintSettingsToPrefs(settings, true, flags);
-  }
+      <method name="savePrintSettings">
+        <parameter name="settings"/>
+        <parameter name="flags"/>
+        <body><![CDATA[
+          var PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"]
+                        .getService(Ci.nsIPrintSettingsService);
+          PSSVC.savePrintSettingsToPrefs(settings, true, flags);
+        ]]></body>
+      </method>
 
-  receiveMessage(message) {
-    if (message.name == "Printing:Preview:UpdatePageCount") {
-      let numPages = message.data.numPages;
-      this.mTotalPages.value = numPages;
-      this.mPageTextBox.max = numPages;
-    }
-  }
-}, { extends: "toolbar" });
+      <method name="receiveMessage">
+        <parameter name="message"/>
+        <body>
+        <![CDATA[
+          if (message.name == "Printing:Preview:UpdatePageCount") {
+            let numPages = message.data.numPages;
+            this.mTotalPages.value = numPages;
+            this.mPageTextBox.max = numPages;
+          }
+        ]]>
+        </body>
+      </method>
+    </implementation>
+  </binding>
+
+</bindings>
--- a/toolkit/components/printing/content/printUtils.js
+++ b/toolkit/components/printing/content/printUtils.js
@@ -540,19 +540,18 @@ var PrintUtils = {
       } else {
         this._sourceBrowser.docShellIsActive = true;
       }
 
       // show the toolbar after we go into print preview mode so
       // that we can initialize the toolbar with total num pages
       const XUL_NS =
         "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-
-      printPreviewTB = document.createElementNS(XUL_NS, "toolbar",
-        { is: "printpreview-toolbar" });
+      printPreviewTB = document.createElementNS(XUL_NS, "toolbar");
+      printPreviewTB.setAttribute("printpreview", true);
       printPreviewTB.setAttribute("fullscreentoolbar", true);
       printPreviewTB.id = "print-preview-toolbar";
 
       let navToolbox = this._listener.getNavToolbox();
       navToolbox.parentNode.insertBefore(printPreviewTB, navToolbox);
       printPreviewTB.initialize(ppBrowser);
 
       // The print preview processing may not have fully completed, so if we
--- a/toolkit/components/printing/jar.mn
+++ b/toolkit/components/printing/jar.mn
@@ -8,11 +8,11 @@ toolkit.jar:
    content/global/printPageSetup.js                 (content/printPageSetup.js)
    content/global/printPageSetup.xul                (content/printPageSetup.xul)
 #endif
    content/global/printPreviewProgress.js           (content/printPreviewProgress.js)
    content/global/printPreviewProgress.xul          (content/printPreviewProgress.xul)
    content/global/printProgress.js                  (content/printProgress.js)
    content/global/printProgress.xul                 (content/printProgress.xul)
 #endif
-   content/global/printPreviewToolbar.js            (content/printPreviewToolbar.js)
+   content/global/printPreviewBindings.xml          (content/printPreviewBindings.xml)
    content/global/printUtils.js                     (content/printUtils.js)
    content/global/simplifyMode.css                  (content/simplifyMode.css)
--- a/toolkit/components/printing/tests/browser_page_change_print_original.js
+++ b/toolkit/components/printing/tests/browser_page_change_print_original.js
@@ -36,17 +36,17 @@ add_task(async function pp_after_orienta
   });
 
   await originalTabNavigated;
 
   // Change orientation and wait for print preview to re-enter:
   let orient = PrintUtils.getPrintSettings().orientation;
   let orientToSwitchTo = orient != Ci.nsIPrintSettings.kPortraitOrientation ?
     "portrait" : "landscape";
-  let printPreviewToolbar = document.querySelector("toolbar[is=printpreview-toolbar]");
+  let printPreviewToolbar = document.querySelector("toolbar[printpreview=true]");
 
   printPreviewEntered = BrowserTestUtils.waitForMessage(ppBrowser.messageManager, "Printing:Preview:Entered");
   printPreviewToolbar.orient(orientToSwitchTo);
   await printPreviewEntered;
 
   // Check that we're still showing the original page.
   await ContentTask.spawn(ppBrowser, null, async function() {
     is(content.document.body.textContent.trim(), "INITIAL PAGE", "Should still have initial page print previewed.");
--- a/toolkit/content/customElements.js
+++ b/toolkit/content/customElements.js
@@ -32,48 +32,42 @@ class MozXULElement extends XULElement {
    * the reflector is garbage collected and the element is touched again.
    *
    * @param str
    *        String with the XML representation of XUL elements.
    *
    * @return DocumentFragment containing the corresponding element tree, including
    *         element nodes but excluding any text node.
    */
-  static parseXULToFragment(str, entities = "") {
+  static parseXULToFragment(str) {
     let doc = gXULDOMParser.parseFromString(`
-      ${entities}
       <box xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
         ${str}
       </box>
     `, "application/xml");
     // The XUL/XBL parser is set to ignore all-whitespace nodes, whereas (X)HTML
     // does not do this. Most XUL code assumes that the whitespace has been
     // stripped out, so we simply remove all text nodes after using the parser.
     let nodeIterator = doc.createNodeIterator(doc, NodeFilter.SHOW_TEXT);
     let currentNode = nodeIterator.nextNode();
     while (currentNode) {
       currentNode.remove();
       currentNode = nodeIterator.nextNode();
     }
     // We use a range here so that we don't access the inner DOM elements from
     // JavaScript before they are imported and inserted into a document.
     let range = doc.createRange();
-    range.selectNodeContents(doc.querySelector("box"));
+    range.selectNodeContents(doc.firstChild);
     return range.extractContents();
   }
 }
 
 // Attach the base class to the window so other scripts can use it:
 window.MozXULElement = MozXULElement;
 
 for (let script of [
   "chrome://global/content/elements/stringbundle.js",
   "chrome://global/content/elements/general.js",
 ]) {
   Services.scriptloader.loadSubScript(script, window);
 }
 
-customElements.setElementCreationCallback("printpreview-toolbar", type => {
-  Services.scriptloader.loadSubScript(
-    "chrome://global/content/printPreviewToolbar.js", window);
-});
-
 }
--- a/toolkit/themes/linux/global/global.css
+++ b/toolkit/themes/linux/global/global.css
@@ -116,37 +116,16 @@ sidebarheader > label {
   -moz-user-focus: ignore !important;
 }
 
 toolbar[mode="text"] .toolbarbutton-text {
   padding: 0 !important;
   margin: 3px 5px !important;
 }
 
-toolbar[is="printpreview-toolbar"] .navigate-button {
-  min-width: 1.9em;
-}
-
-toolbar[is="printpreview-toolbar"] .navigate-button > .toolbarbutton-icon {
-  display: none;
-}
-
-toolbar[is="printpreview-toolbar"] .toolbar-portrait-page {
-  list-style-image: url("moz-icon://stock/gtk-orientation-portrait?size=button");
-}
-
-toolbar[is="printpreview-toolbar"] .toolbar-landscape-page {
-  list-style-image: url("moz-icon://stock/gtk-orientation-landscape?size=button");
-}
-
-toolbar[is="printpreview-toolbar"] #pageNumber {
-  /* 3 chars + 4px padding left + 2px padding right + 2*6px border */
-  width: calc(18px + 3ch);
-}
-
 /* ::::: miscellaneous formatting ::::: */
 
 :root:-moz-lwtheme {
   -moz-appearance: none;
 }
 
 :root[lwtheme-image]:-moz-lwtheme-darktext {
   text-shadow: 0 -0.5px 1.5px white;
--- a/toolkit/themes/linux/global/jar.mn
+++ b/toolkit/themes/linux/global/jar.mn
@@ -16,16 +16,17 @@ toolkit.jar:
    skin/classic/global/groupbox.css
    skin/classic/global/listbox.css
    skin/classic/global/menu.css
    skin/classic/global/menulist.css
    skin/classic/global/netError.css
 *  skin/classic/global/notification.css
 *  skin/classic/global/numberbox.css
    skin/classic/global/popup.css
+   skin/classic/global/printPreview.css
    skin/classic/global/radio.css
    skin/classic/global/scrollbox.css
    skin/classic/global/splitter.css
    skin/classic/global/tabbox.css
    skin/classic/global/textbox.css
    skin/classic/global/toolbar.css
    skin/classic/global/toolbarbutton.css
    skin/classic/global/tree.css
new file mode 100644
--- /dev/null
+++ b/toolkit/themes/linux/global/printPreview.css
@@ -0,0 +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/. */
+
+.navigate-button {
+  min-width: 1.9em;
+}
+
+.navigate-button > .toolbarbutton-icon {
+  display: none;
+}
+
+.toolbar-portrait-page {
+  list-style-image: url("moz-icon://stock/gtk-orientation-portrait?size=button");
+}
+
+.toolbar-landscape-page {
+  list-style-image: url("moz-icon://stock/gtk-orientation-landscape?size=button");
+}
+
+#pageNumber {
+  /* 3 chars + 4px padding left + 2px padding right + 2*6px border */
+  width: calc(18px + 3ch);
+}
--- a/toolkit/themes/windows/global/global.css
+++ b/toolkit/themes/windows/global/global.css
@@ -126,38 +126,16 @@ sidebarheader > label {
   -moz-user-focus: ignore !important;
 }
 
 toolbar[mode="text"] .toolbarbutton-text {
   padding: 0 !important;
   margin: 3px 5px !important;
 }
 
-toolbar[is="printpreview-toolbar"] .navigate-button {
-  min-width: 1.9em;
-}
-
-toolbar[is="printpreview-toolbar"] .navigate-button > .toolbarbutton-icon {
-  display: none;
-}
-
-toolbar[is="printpreview-toolbar"] .toolbar-portrait-page {
-  list-style-image: url("chrome://global/skin/icons/Print-preview.png");
-  -moz-image-region: rect(0px 16px 16px 0px);
-}
-
-toolbar[is="printpreview-toolbar"] .toolbar-landscape-page {
-  list-style-image: url("chrome://global/skin/icons/Print-preview.png");
-  -moz-image-region: rect(0px 32px 16px 16px);
-}
-
-toolbar[is="printpreview-toolbar"] #pageNumber {
-  width: 3ch;
-}
-
 /* ::::: miscellaneous formatting ::::: */
 
 :root[lwtheme-image]:-moz-lwtheme-darktext {
   text-shadow: 0 -0.5px 1.5px white;
 }
 
 :root[lwtheme-image]:-moz-lwtheme-brighttext {
   text-shadow: 1px 1px 1.5px black;
--- a/toolkit/themes/windows/global/jar.mn
+++ b/toolkit/themes/windows/global/jar.mn
@@ -20,16 +20,17 @@ toolkit.jar:
   skin/classic/global/commonDialog.css
 * skin/classic/global/findBar.css
 * skin/classic/global/global.css
   skin/classic/global/listbox.css
   skin/classic/global/netError.css
 * skin/classic/global/numberbox.css
 * skin/classic/global/notification.css
   skin/classic/global/printPageSetup.css
+  skin/classic/global/printPreview.css
   skin/classic/global/scrollbox.css
   skin/classic/global/splitter.css
   skin/classic/global/toolbar.css
   skin/classic/global/toolbarbutton.css
 * skin/classic/global/tree.css
 * skin/classic/global/alerts/alert.css                     (alerts/alert.css)
   skin/classic/global/arrow/arrow-lft.gif                  (arrow/arrow-lft.gif)
   skin/classic/global/arrow/arrow-lft-dis.gif              (arrow/arrow-lft-dis.gif)
new file mode 100644
--- /dev/null
+++ b/toolkit/themes/windows/global/printPreview.css
@@ -0,0 +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/. */
+
+.navigate-button {
+  min-width: 1.9em;
+}
+
+.navigate-button > .toolbarbutton-icon {
+  display: none;
+}
+
+.toolbar-portrait-page {
+  list-style-image: url("chrome://global/skin/icons/Print-preview.png");
+  -moz-image-region: rect(0px 16px 16px 0px);
+}
+
+.toolbar-landscape-page {
+  list-style-image: url("chrome://global/skin/icons/Print-preview.png");
+  -moz-image-region: rect(0px 32px 16px 16px);
+}
+
+#pageNumber {
+  width: 3ch;
+}