Bug 1495621 - convert wizard binding to Custom Element
authorAlexander Surkov <surkov.alexander@gmail.com>
Thu, 04 Apr 2019 11:42:15 -0400
changeset 480343 a6fd4af8043d7291b8ef9dd1504e776db5c30f34
parent 480342 832dc7b097435208284ba764057fa00d649a7396
child 480344 6cccb5ecea4fa6e0b46709cc7d617a8e1a0d3d6f
push id113543
push usersurkov.alexander@gmail.com
push dateThu, 27 Jun 2019 20:02:26 +0000
treeherdermozilla-inbound@a6fd4af8043d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1495621
milestone69.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 1495621 - convert wizard binding to Custom Element Differential Revision: https://phabricator.services.mozilla.com/D26334
.eslintignore
testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/update_wizard/wizard.py
toolkit/content/jar.mn
toolkit/content/widgets/wizard.js
toolkit/content/widgets/wizard.xml
toolkit/content/xul.css
--- a/.eslintignore
+++ b/.eslintignore
@@ -330,19 +330,16 @@ toolkit/components/workerloader/tests/mo
 
 # External code:
 toolkit/components/reader/Readability.js
 toolkit/components/reader/JSDOMParser.js
 
 # Uses preprocessing
 toolkit/components/reader/Readerable.jsm
 
-# Should be going away soon
-toolkit/content/widgets/wizard.xml
-
 # Uses preprocessing
 toolkit/mozapps/update/tests/data/xpcshellConstantsPP.js
 toolkit/modules/AppConstants.jsm
 
 # Tests old non-star function generators
 toolkit/modules/tests/xpcshell/test_task.js
 
 # Third party
--- a/testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/update_wizard/wizard.py
+++ b/testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/update_wizard/wizard.py
@@ -45,17 +45,17 @@ class Wizard(UIBaseLib):
 
         panel = self.element.find_element(By.ID, panel_id)
         return mapping.get(panel_id, Panel)(self.marionette, self.window, panel)
 
     # Properties for visual buttons of the wizard #
 
     @property
     def _buttons(self):
-        return self.element.find_element(By.ANON_ATTRIBUTE, {'anonid': 'Buttons'})
+        return self.element.get_property('_wizardButtons')
 
     @property
     def cancel_button(self):
         return self._buttons.find_element(By.CSS_SELECTOR, '[dlgtype="cancel"]')
 
     @property
     def extra1_button(self):
         return self._buttons.find_element(By.CSS_SELECTOR, '[dlgtype="extra1"]')
--- a/toolkit/content/jar.mn
+++ b/toolkit/content/jar.mn
@@ -70,17 +70,16 @@ toolkit.jar:
    content/global/bindings/popup.xml           (widgets/popup.xml)
    content/global/bindings/richlistbox.xml     (widgets/richlistbox.xml)
    content/global/bindings/scrollbox.xml       (widgets/scrollbox.xml)
    content/global/bindings/spinner.js          (widgets/spinner.js)
    content/global/bindings/tabbox.xml          (widgets/tabbox.xml)
 *  content/global/bindings/textbox.xml         (widgets/textbox.xml)
    content/global/bindings/timekeeper.js       (widgets/timekeeper.js)
    content/global/bindings/timepicker.js       (widgets/timepicker.js)
-   content/global/bindings/wizard.xml          (widgets/wizard.xml)
    content/global/elements/autocomplete-popup.js              (widgets/autocomplete-popup.js)
    content/global/elements/autocomplete-richlistitem.js       (widgets/autocomplete-richlistitem.js)
    content/global/elements/browser-custom-element.js          (widgets/browser-custom-element.js)
    content/global/elements/button.js           (widgets/button.js)
    content/global/elements/checkbox.js         (widgets/checkbox.js)
    content/global/elements/datetimebox.js      (widgets/datetimebox.js)
    content/global/elements/dialog.js           (widgets/dialog.js)
    content/global/elements/findbar.js          (widgets/findbar.js)
--- a/toolkit/content/widgets/wizard.js
+++ b/toolkit/content/widgets/wizard.js
@@ -3,24 +3,395 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 // This is loaded into chrome windows with the subscript loader. Wrap in
 // a block to prevent accidentally leaking globals onto `window`.
 {
 const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 const kDTDs = [ "chrome://global/locale/wizard.dtd" ];
 
+class MozWizard extends MozXULElement {
+  constructor() {
+    super();
+
+    this._accessMethod = null;
+    this._currentPage = null;
+    this._canAdvance = true;
+    this._canRewind = false;
+    this._hasLoaded = false;
+    this._pageStack = [];
+
+    this._bundle =
+      Services.strings.createBundle("chrome://global/locale/wizard.properties");
+
+    this.addEventListener("keypress", (event) => {
+      if (event.keyCode == KeyEvent.DOM_VK_RETURN) {
+        this._hitEnter(event);
+      } else if (event.keyCode == KeyEvent.DOM_VK_ESCAPE && !event.defaultPrevented) {
+        this.cancel();
+      }
+    }, { mozSystemGroup: true });
+
+    this.attachShadow({ mode: "open" }).appendChild(
+      MozXULElement.parseXULToFragment(`
+        <html:link rel="stylesheet" href="chrome://global/content/widgets.css" />
+        <hbox class="wizard-header"></hbox>
+        <deck class="wizard-page-box" flex="1">
+          <slot xmlns="http://www.w3.org/1999/xhtml" name="wizardpage"></slot>
+        </deck>
+        <slot xmlns="http://www.w3.org/1999/xhtml"></slot>
+        <wizard-buttons class="wizard-buttons"></wizard-buttons>
+    `));
+    this.initializeAttributeInheritance();
+
+    this._deck = this.shadowRoot.querySelector(".wizard-page-box");
+    this._wizardButtons = this.shadowRoot.querySelector(".wizard-buttons");
+
+    this._wizardHeader = this.shadowRoot.querySelector(".wizard-header");
+    this._wizardHeader.appendChild(
+      MozXULElement.parseXULToFragment(AppConstants.platform == "macosx" ?
+        `<stack class="wizard-header-stack" flex="1">
+           <vbox class="wizard-header-box-1">
+             <vbox class="wizard-header-box-text">
+               <label class="wizard-header-label"/>
+             </vbox>
+           </vbox>
+           <hbox class="wizard-header-box-icon">
+             <spacer flex="1"/>
+             <image class="wizard-header-icon"/>
+           </hbox>
+         </stack>` :
+        `<hbox class="wizard-header-box-1" flex="1">
+           <vbox class="wizard-header-box-text" flex="1">
+             <label class="wizard-header-label"/>
+             <label class="wizard-header-description"/>
+           </vbox>
+           <image class="wizard-header-icon"/>
+         </hbox>`
+      )
+    );
+  }
+
+  static get inheritedAttributes() {
+    return {
+      ".wizard-buttons": "pagestep,firstpage,lastpage",
+    };
+  }
+
+  connectedCallback() {
+    if (this.delayConnectedCallback()) {
+      return;
+    }
+
+    this.pageCount = this.wizardPages.length;
+
+    this._initPages();
+    this.advance(); // start off on the first page
+
+    window.addEventListener("close", (event) => {
+      if (document.documentElement.cancel()) {
+        event.preventDefault();
+      }
+    });
+
+    // Give focus to the first focusable element in the wizard, do it after
+    // onload completes, see bug 103197.
+    window.addEventListener("load", () => window.setTimeout(() => {
+      document.documentElement._hasLoaded = true;
+        if (!document.commandDispatcher.focusedElement) {
+          document.commandDispatcher.advanceFocusIntoSubtree(this);
+        }
+        try {
+          let button = document.documentElement._wizardButtons.defaultButton;
+          if (button) {
+            window.notifyDefaultButtonLoaded(button);
+          }
+        } catch (e) {}
+      }, 0));
+  }
+
+  set title(val) {
+    return document.title = val;
+  }
+
+  get title() {
+    return document.title;
+  }
+
+  set canAdvance(val) {
+    this.getButton("next").disabled = !val;
+    return this._canAdvance = val;
+  }
+
+  get canAdvance() {
+    return this._canAdvance;
+  }
+
+  set canRewind(val) {
+    this.getButton("back").disabled = !val;
+    return this._canRewind = val;
+  }
+
+  get canRewind() {
+    return this._canRewind;
+  }
+
+  get pageStep() {
+    return this._pageStack.length;
+  }
+
+  get wizardPages() {
+    const xulns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+    return this.getElementsByTagNameNS(xulns, "wizardpage");
+  }
+
+  set currentPage(val) {
+    if (!val)
+      return val;
+
+    this._currentPage = val;
+
+    // Setting this attribute allows wizard's clients to dynamically
+    // change the styles of each page based on purpose of the page.
+    this.setAttribute("currentpageid", val.pageid);
+    if (this.onFirstPage) {
+      this.canRewind = false;
+      this.setAttribute("firstpage", "true");
+      if (AppConstants.platform == "linux") {
+        this.getButton("back").setAttribute("hidden", "true");
+      }
+    } else {
+      this.canRewind = true;
+      this.setAttribute("firstpage", "false");
+      if (AppConstants.platform == "linux") {
+        this.getButton("back").setAttribute("hidden", "false");
+      }
+    }
+
+    if (this.onLastPage) {
+      this.canAdvance = true;
+      this.setAttribute("lastpage", "true");
+    } else {
+      this.setAttribute("lastpage", "false");
+    }
+
+    this._deck.setAttribute("selectedIndex", val.pageIndex);
+    this._advanceFocusToPage(val);
+
+    this._adjustWizardHeader();
+    this._wizardButtons.onPageChange();
+
+    this._fireEvent(val, "pageshow");
+
+    return val;
+  }
+
+  get currentPage() {
+    return this._currentPage;
+  }
+
+  set pageIndex(val) {
+    if (val < 0 || val >= this.pageCount)
+      return val;
+
+    var page = this.wizardPages[val];
+    this._pageStack[this._pageStack.length - 1] = page;
+    this.currentPage = page;
+
+    return val;
+  }
+
+  get pageIndex() {
+    return this._currentPage ? this._currentPage.pageIndex : -1;
+  }
+
+  get onFirstPage() {
+    return this._pageStack.length == 1;
+  }
+
+  get onLastPage() {
+    var cp = this.currentPage;
+    return cp && ((this._accessMethod == "sequential" && cp.pageIndex == this.pageCount - 1) ||
+      (this._accessMethod == "random" && cp.next == ""));
+  }
+
+  getButton(aDlgType) {
+    return this._wizardButtons.getButton(aDlgType);
+  }
+
+  getPageById(aPageId) {
+    var els = this.getElementsByAttribute("pageid", aPageId);
+    return els.item(0);
+  }
+
+  extra1() {
+    if (this.currentPage)
+      this._fireEvent(this.currentPage, "extra1");
+  }
+
+  extra2() {
+    if (this.currentPage)
+      this._fireEvent(this.currentPage, "extra2");
+  }
+
+  rewind() {
+    if (!this.canRewind)
+      return;
+
+    if (this.currentPage && !this._fireEvent(this.currentPage, "pagehide"))
+      return;
+
+    if (this.currentPage && !this._fireEvent(this.currentPage, "pagerewound"))
+      return;
+
+    if (!this._fireEvent(this, "wizardback"))
+      return;
+
+    this._pageStack.pop();
+    this.currentPage = this._pageStack[this._pageStack.length - 1];
+    this.setAttribute("pagestep", this._pageStack.length);
+  }
+
+  advance(aPageId) {
+    if (!this.canAdvance)
+      return;
+
+    if (this.currentPage && !this._fireEvent(this.currentPage, "pagehide"))
+      return;
+
+    if (this.currentPage && !this._fireEvent(this.currentPage, "pageadvanced"))
+      return;
+
+    if (this.onLastPage && !aPageId) {
+      if (this._fireEvent(this, "wizardfinish"))
+        window.setTimeout(function() { window.close(); }, 1);
+    } else {
+      if (!this._fireEvent(this, "wizardnext"))
+        return;
+
+      let page;
+      if (aPageId) {
+        page = this.getPageById(aPageId);
+      } else if (this.currentPage) {
+        if (this._accessMethod == "random") {
+          page = this.getPageById(this.currentPage.next);
+        } else {
+          page = this.wizardPages[this.currentPage.pageIndex + 1];
+        }
+      } else {
+        page = this.wizardPages[0];
+      }
+
+      if (page) {
+        this._pageStack.push(page);
+        this.setAttribute("pagestep", this._pageStack.length);
+
+        this.currentPage = page;
+      }
+    }
+  }
+
+  goTo(aPageId) {
+    var page = this.getPageById(aPageId);
+    if (page) {
+      this._pageStack[this._pageStack.length - 1] = page;
+      this.currentPage = page;
+    }
+  }
+
+  cancel() {
+    if (!this._fireEvent(this, "wizardcancel"))
+      return true;
+
+    window.close();
+    window.setTimeout(function() { window.close(); }, 1);
+    return false;
+  }
+
+  _advanceFocusToPage(aPage) {
+    if (!this._hasLoaded)
+      return;
+
+    // XXX: it'd be correct to advance focus into the panel, however we can't do
+    // it until bug 1558990 is fixed, so moving the focus into a wizard itsef
+    // as a workaround - it's same behavior but less optimal.
+    document.commandDispatcher.advanceFocusIntoSubtree(this);
+
+    // if advanceFocusIntoSubtree tries to focus one of our
+    // dialog buttons, then remove it and put it on the root
+    var focused = document.commandDispatcher.focusedElement;
+    if (focused && focused.hasAttribute("dlgtype"))
+      this.focus();
+  }
+
+  _initPages() {
+    var meth = "sequential";
+    var pages = this.wizardPages;
+    for (var i = 0; i < pages.length; ++i) {
+      var page = pages[i];
+      page.pageIndex = i;
+      if (page.next != "")
+        meth = "random";
+    }
+    this._accessMethod = meth;
+  }
+
+  _adjustWizardHeader() {
+    var label = this.currentPage.getAttribute("label");
+    if (!label && this.onFirstPage && this._bundle) {
+      if (AppConstants.platform == "macosx") {
+        label = this._bundle.GetStringFromName("default-first-title-mac");
+      } else {
+        label = this._bundle.formatStringFromName("default-first-title", [this.title]);
+      }
+    } else if (!label && this.onLastPage && this._bundle) {
+      if (AppConstants.platform == "macosx") {
+        label = this._bundle.GetStringFromName("default-last-title-mac");
+      } else {
+        label = this._bundle.formatStringFromName("default-last-title", [this.title]);
+      }
+    }
+    this._wizardHeader.
+    querySelector(".wizard-header-label").textContent = label;
+    let headerDescEl =
+      this._wizardHeader.querySelector(".wizard-header-description");
+    if (headerDescEl) {
+      headerDescEl.textContent =
+        this.currentPage.getAttribute("description");
+    }
+  }
+
+  _hitEnter(evt) {
+    if (!evt.defaultPrevented)
+      this.advance();
+  }
+
+  _fireEvent(aTarget, aType) {
+    var event = document.createEvent("Events");
+    event.initEvent(aType, true, true);
+
+    // handle dom event handlers
+    return aTarget.dispatchEvent(event);
+  }
+}
+
+customElements.define("wizard", MozWizard);
+
 class MozWizardPage extends MozXULElement {
   constructor() {
     super();
     this.pageIndex = -1;
   }
+  connectedCallback() {
+    this.setAttribute("slot", "wizardpage");
+  }
   get pageid() {
     return this.getAttribute("pageid");
   }
   set pageid(val) {
     this.setAttribute("pageid", val);
   }
   get next() {
     return this.getAttribute("next");
deleted file mode 100644
--- a/toolkit/content/widgets/wizard.xml
+++ /dev/null
@@ -1,428 +0,0 @@
-<?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/. -->
-
-
-<bindings id="wizardBindings"
-   xmlns="http://www.mozilla.org/xbl"
-   xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-   xmlns:xbl="http://www.mozilla.org/xbl">
-
-  <binding id="wizard">
-    <content>
-      <xul:hbox class="wizard-header" anonid="Header"/>
-
-      <xul:deck class="wizard-page-box" flex="1" anonid="Deck">
-        <children includes="wizardpage"/>
-      </xul:deck>
-      <children/>
-
-      <xul:wizard-buttons class="wizard-buttons" anonid="Buttons" xbl:inherits="pagestep,firstpage,lastpage"/>
-    </content>
-
-    <implementation>
-      <property name="title" onget="return document.title;"
-                             onset="return document.title = val;"/>
-
-      <property name="canAdvance" onget="return this._canAdvance;"
-                                  onset="this.getButton('next').disabled = !val; return this._canAdvance = val;"/>
-      <property name="canRewind" onget="return this._canRewind;"
-                                 onset="this.getButton('back').disabled = !val; return this._canRewind = val;"/>
-
-      <property name="pageStep" readonly="true" onget="return this._pageStack.length"/>
-
-      <field name="pageCount">0</field>
-
-      <field name="_accessMethod">null</field>
-      <field name="_pageStack">null</field>
-      <field name="_currentPage">null</field>
-
-      <property name="wizardPages">
-        <getter>
-        <![CDATA[
-          var xulns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-          return this.getElementsByTagNameNS(xulns, "wizardpage");
-        ]]>
-        </getter>
-      </property>
-
-      <property name="currentPage" onget="return this._currentPage">
-        <setter>
-        <![CDATA[
-          if (!val)
-            return val;
-
-          this._currentPage = val;
-
-          // Setting this attribute allows wizard's clients to dynamically
-          // change the styles of each page based on purpose of the page.
-          this.setAttribute("currentpageid", val.pageid);
-          if (this.onFirstPage) {
-            this.canRewind = false;
-            this.setAttribute("firstpage", "true");
-            if (/Linux/.test(navigator.platform)) {
-              this.getButton("back").setAttribute("hidden", "true");
-            }
-          } else {
-            this.canRewind = true;
-            this.setAttribute("firstpage", "false");
-            if (/Linux/.test(navigator.platform)) {
-              this.getButton("back").setAttribute("hidden", "false");
-            }
-          }
-
-          if (this.onLastPage) {
-            this.canAdvance = true;
-            this.setAttribute("lastpage", "true");
-          } else {
-            this.setAttribute("lastpage", "false");
-          }
-
-          this._deck.setAttribute("selectedIndex", val.pageIndex);
-          this._advanceFocusToPage(val);
-
-          this._adjustWizardHeader();
-          this._wizardButtons.onPageChange();
-
-          this._fireEvent(val, "pageshow");
-
-          return val;
-        ]]>
-        </setter>
-      </property>
-
-      <property name="pageIndex"
-                onget="return this._currentPage ? this._currentPage.pageIndex : -1;">
-        <setter>
-        <![CDATA[
-          if (val < 0 || val >= this.pageCount)
-            return val;
-
-          var page = this.wizardPages[val];
-          this._pageStack[this._pageStack.length-1] = page;
-          this.currentPage = page;
-
-          return val;
-        ]]>
-        </setter>
-      </property>
-
-      <property name="onFirstPage" readonly="true"
-                onget="return this._pageStack.length == 1;"/>
-
-      <property name="onLastPage" readonly="true">
-        <getter><![CDATA[
-          var cp = this.currentPage;
-          return cp && ((this._accessMethod == "sequential" && cp.pageIndex == this.pageCount-1) ||
-                       (this._accessMethod == "random" && cp.next == ""));
-         ]]></getter>
-      </property>
-
-      <method name="getButton">
-        <parameter name="aDlgType"/>
-        <body>
-        <![CDATA[
-          return this._wizardButtons.getButton(aDlgType);
-        ]]>
-        </body>
-      </method>
-
-      <field name="_canAdvance"/>
-      <field name="_canRewind"/>
-      <field name="_wizardHeader"/>
-      <field name="_wizardButtons"/>
-      <field name="_deck"/>
-
-      <constructor><![CDATA[
-        this._canAdvance = true;
-        this._canRewind = false;
-        this._hasLoaded = false;
-
-        this._pageStack = [];
-
-        try {
-          // need to create string bundle manually instead of using <xul:stringbundle/>
-          // see bug 63370 for details
-          this._bundle = Cc["@mozilla.org/intl/stringbundle;1"]
-                           .getService(Ci.nsIStringBundleService)
-                           .createBundle("chrome://global/locale/wizard.properties");
-        } catch (e) {
-          // This fails in remote XUL, which has to provide titles for all pages
-          // see bug 142502
-        }
-
-        // get anonymous content references
-        this._wizardHeader = document.getAnonymousElementByAttribute(this, "anonid", "Header");
-
-        this._wizardHeader.appendChild(
-          MozXULElement.parseXULToFragment(/Mac/.test(navigator.platform) ?
-            `<stack class="wizard-header-stack" flex="1">
-              <vbox class="wizard-header-box-1">
-                <vbox class="wizard-header-box-text">
-                  <label class="wizard-header-label"/>
-                </vbox>
-              </vbox>
-              <hbox class="wizard-header-box-icon">
-                <spacer flex="1"/>
-                <image class="wizard-header-icon"/>
-              </hbox>
-            </stack>` :
-            `<hbox class="wizard-header-box-1" flex="1">
-              <vbox class="wizard-header-box-text" flex="1">
-                <label class="wizard-header-label"/>
-                <label class="wizard-header-description"/>
-              </vbox>
-              <image class="wizard-header-icon"/>
-            </hbox>`
-          )
-        );
-
-        this._wizardButtons = document.getAnonymousElementByAttribute(this, "anonid", "Buttons");
-        customElements.upgrade(this._wizardButtons);
-
-        this._deck = document.getAnonymousElementByAttribute(this, "anonid", "Deck");
-
-        this._initPages();
-
-        window.addEventListener("close", (event) => {
-          if (document.documentElement.cancel()) {
-            event.preventDefault();
-          }
-        });
-
-        // start off on the first page
-        this.pageCount = this.wizardPages.length;
-        this.advance();
-
-        // give focus to the first focusable element in the dialog
-        window.addEventListener("load", this._setInitialFocus);
-      ]]></constructor>
-
-      <method name="getPageById">
-        <parameter name="aPageId"/>
-        <body><![CDATA[
-          var els = this.getElementsByAttribute("pageid", aPageId);
-          return els.item(0);
-        ]]></body>
-      </method>
-
-      <method name="extra1">
-        <body><![CDATA[
-          if (this.currentPage)
-            this._fireEvent(this.currentPage, "extra1");
-        ]]></body>
-      </method>
-
-      <method name="extra2">
-        <body><![CDATA[
-          if (this.currentPage)
-            this._fireEvent(this.currentPage, "extra2");
-        ]]></body>
-      </method>
-
-      <method name="rewind">
-        <body><![CDATA[
-          if (!this.canRewind)
-            return;
-
-          if (this.currentPage && !this._fireEvent(this.currentPage, "pagehide"))
-            return;
-
-          if (this.currentPage && !this._fireEvent(this.currentPage, "pagerewound"))
-            return;
-
-          if (!this._fireEvent(this, "wizardback"))
-            return;
-
-
-          this._pageStack.pop();
-          this.currentPage = this._pageStack[this._pageStack.length-1];
-          this.setAttribute("pagestep", this._pageStack.length);
-        ]]></body>
-      </method>
-
-      <method name="advance">
-        <parameter name="aPageId"/>
-        <body><![CDATA[
-          if (!this.canAdvance)
-            return;
-
-          if (this.currentPage && !this._fireEvent(this.currentPage, "pagehide"))
-            return;
-
-          if (this.currentPage && !this._fireEvent(this.currentPage, "pageadvanced"))
-            return;
-
-          if (this.onLastPage && !aPageId) {
-            if (this._fireEvent(this, "wizardfinish"))
-              window.setTimeout(function() {window.close();}, 1);
-          } else {
-            if (!this._fireEvent(this, "wizardnext"))
-              return;
-
-            var page;
-            if (aPageId)
-              page = this.getPageById(aPageId);
-            else {
-              if (this.currentPage) {
-                if (this._accessMethod == "random")
-                  page = this.getPageById(this.currentPage.next);
-                else
-                  page = this.wizardPages[this.currentPage.pageIndex+1];
-              } else
-                page = this.wizardPages[0];
-            }
-
-            if (page) {
-              this._pageStack.push(page);
-              this.setAttribute("pagestep", this._pageStack.length);
-
-              this.currentPage = page;
-            }
-          }
-        ]]></body>
-      </method>
-
-      <method name="goTo">
-        <parameter name="aPageId"/>
-        <body><![CDATA[
-          var page = this.getPageById(aPageId);
-          if (page) {
-            this._pageStack[this._pageStack.length-1] = page;
-            this.currentPage = page;
-          }
-        ]]></body>
-      </method>
-
-      <method name="cancel">
-        <body><![CDATA[
-          if (!this._fireEvent(this, "wizardcancel"))
-            return true;
-
-          window.close();
-          window.setTimeout(function() {window.close();}, 1);
-          return false;
-        ]]></body>
-      </method>
-
-      <method name="_setInitialFocus">
-        <parameter name="aEvent"/>
-        <body>
-        <![CDATA[
-          document.documentElement._hasLoaded = true;
-          var focusInit =
-            function() {
-              // give focus to the first focusable element in the dialog
-              if (!document.commandDispatcher.focusedElement)
-                document.commandDispatcher.advanceFocusIntoSubtree(document.documentElement);
-
-              try {
-                var button =
-                      document.documentElement._wizardButtons.defaultButton;
-                if (button)
-                  window.notifyDefaultButtonLoaded(button);
-              } catch (e) { }
-            };
-
-          // Give focus after onload completes, see bug 103197.
-          setTimeout(focusInit, 0);
-        ]]>
-        </body>
-      </method>
-
-      <method name="_advanceFocusToPage">
-        <parameter name="aPage"/>
-        <body>
-        <![CDATA[
-          if (!this._hasLoaded)
-            return;
-
-          document.commandDispatcher.advanceFocusIntoSubtree(aPage);
-
-          // if advanceFocusIntoSubtree tries to focus one of our
-          // dialog buttons, then remove it and put it on the root
-          var focused = document.commandDispatcher.focusedElement;
-          if (focused && focused.hasAttribute("dlgtype"))
-            this.focus();
-        ]]>
-        </body>
-      </method>
-
-      <method name="_initPages">
-        <body><![CDATA[
-          var meth = "sequential";
-          var pages = this.wizardPages;
-          for (var i = 0; i < pages.length; ++i) {
-            var page = pages[i];
-            page.pageIndex = i;
-            if (page.next != "")
-              meth = "random";
-          }
-          this._accessMethod = meth;
-        ]]></body>
-      </method>
-
-      <method name="_adjustWizardHeader">
-        <body><![CDATA[
-          var label = this.currentPage.getAttribute("label");
-          if (!label && this.onFirstPage && this._bundle) {
-            if (/Mac/.test(navigator.platform)) {
-              label = this._bundle.GetStringFromName("default-first-title-mac");
-            } else {
-              label = this._bundle.formatStringFromName("default-first-title", [this.title]);
-            }
-          } else if (!label && this.onLastPage && this._bundle) {
-            if (/Mac/.test(navigator.platform)) {
-              label = this._bundle.GetStringFromName("default-last-title-mac");
-            } else {
-              label = this._bundle.formatStringFromName("default-last-title", [this.title]);
-            }
-          }
-          this._wizardHeader.
-            querySelector(".wizard-header-label").textContent = label;
-          let headerDescEl =
-            this._wizardHeader.querySelector(".wizard-header-description");
-          if (headerDescEl) {
-            headerDescEl.textContent =
-              this.currentPage.getAttribute("description");
-          }
-        ]]></body>
-      </method>
-
-      <method name="_hitEnter">
-        <parameter name="evt"/>
-        <body>
-        <![CDATA[
-          if (!evt.defaultPrevented)
-            this.advance();
-        ]]>
-        </body>
-      </method>
-
-      <method name="_fireEvent">
-        <parameter name="aTarget"/>
-        <parameter name="aType"/>
-        <body>
-        <![CDATA[
-          var event = document.createEvent("Events");
-          event.initEvent(aType, true, true);
-
-          // handle dom event handlers
-          return aTarget.dispatchEvent(event);
-        ]]>
-        </body>
-      </method>
-
-    </implementation>
-
-    <handlers>
-      <handler event="keypress" keycode="VK_RETURN"
-               group="system" action="this._hitEnter(event)"/>
-      <handler event="keypress" keycode="VK_ESCAPE" group="system">
-        if (!event.defaultPrevented)
-          this.cancel();
-      </handler>
-    </handlers>
-  </binding>
-</bindings>
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -583,17 +583,16 @@ dialog:root /* override :root from above
 page {
   -moz-box-orient: vertical;
 }
 
 /********** wizard **********/
 
 wizard,
 wizard:root /* override :root from above */ {
-  -moz-binding: url("chrome://global/content/bindings/wizard.xml#wizard");
   -moz-box-orient: vertical;
   width: 40em;
   height: 30em;
 }
 
 wizardpage {
   -moz-box-orient: vertical;
   overflow: auto;