diff options
Diffstat (limited to 'toolkit/content/widgets/wizard.xml')
-rw-r--r-- | toolkit/content/widgets/wizard.xml | 607 |
1 files changed, 607 insertions, 0 deletions
diff --git a/toolkit/content/widgets/wizard.xml b/toolkit/content/widgets/wizard.xml new file mode 100644 index 000000000..3a8ec2cfe --- /dev/null +++ b/toolkit/content/widgets/wizard.xml @@ -0,0 +1,607 @@ +<?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/. --> + + +<!DOCTYPE bindings [ + <!ENTITY % wizardDTD SYSTEM "chrome://global/locale/wizard.dtd"> + %wizardDTD; +]> + +<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-base"> + <resources> + <stylesheet src="chrome://global/skin/wizard.css"/> + </resources> + </binding> + + <binding id="wizard" extends="chrome://global/content/bindings/general.xml#root-element"> + <resources> + <stylesheet src="chrome://global/skin/wizard.css"/> + </resources> + <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:hbox 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._nextButton.disabled = !val; return this._canAdvance = val;"/> + <property name="canRewind" onget="return this._canRewind;" + onset="this._backButton.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._backButton.setAttribute('hidden', 'true'); + } + } else { + this.canRewind = true; + this.setAttribute("firstpage", "false"); + if (/Linux/.test(navigator.platform)) { + this._backButton.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[ + var btns = this.getElementsByAttribute("dlgtype", aDlgType); + return btns.item(0) ? btns[0] : document.getAnonymousElementByAttribute(this._wizardButtons, "dlgtype", aDlgType); + ]]> + </body> + </method> + + <field name="_canAdvance"/> + <field name="_canRewind"/> + <field name="_wizardHeader"/> + <field name="_wizardButtons"/> + <field name="_deck"/> + <field name="_backButton"/> + <field name="_nextButton"/> + <field name="_cancelButton"/> + + <!-- functions to be added as oncommand listeners to the wizard buttons --> + <field name="_backFunc">(function() { document.documentElement.rewind(); })</field> + <field name="_nextFunc">(function() { document.documentElement.advance(); })</field> + <field name="_finishFunc">(function() { document.documentElement.advance(); })</field> + <field name="_cancelFunc">(function() { document.documentElement.cancel(); })</field> + <field name="_extra1Func">(function() { document.documentElement.extra1(); })</field> + <field name="_extra2Func">(function() { document.documentElement.extra2(); })</field> + + <field name="_closeHandler">(function(event) { + if (document.documentElement.cancel()) + event.preventDefault(); + })</field> + + <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 = Components.classes["@mozilla.org/intl/stringbundle;1"] + .getService(Components.interfaces.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._wizardButtons = document.getAnonymousElementByAttribute(this, "anonid", "Buttons"); + this._deck = document.getAnonymousElementByAttribute(this, "anonid", "Deck"); + + this._initWizardButton("back"); + this._initWizardButton("next"); + this._initWizardButton("finish"); + this._initWizardButton("cancel"); + this._initWizardButton("extra1"); + this._initWizardButton("extra2"); + + this._initPages(); + + window.addEventListener("close", this._closeHandler, false); + + // 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, false); + ]]></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="_initWizardButton"> + <parameter name="aName"/> + <body><![CDATA[ + var btn = document.getAnonymousElementByAttribute(this._wizardButtons, "dlgtype", aName); + if (btn) { + btn.addEventListener("command", this["_"+aName+"Func"], false); + this["_"+aName+"Button"] = btn; + } + return btn; + ]]></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], 1); + } + } 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], 1); + } + } + this._wizardHeader.setAttribute("label", label); + this._wizardHeader.setAttribute("description", 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 + var noCancel = aTarget.dispatchEvent(event); + + // handle any xml attribute event handlers + var handler = aTarget.getAttribute("on"+aType); + if (handler != "") { + var fn = new Function("event", handler); + var returned = fn.apply(aTarget, [event]); + if (returned == false) + noCancel = false; + } + + return noCancel; + ]]> + </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> + + <binding id="wizardpage" extends="chrome://global/content/bindings/wizard.xml#wizard-base"> + <implementation> + <field name="pageIndex">-1</field> + + <property name="pageid" onget="return this.getAttribute('pageid');" + onset="this.setAttribute('pageid', val);"/> + + <property name="next" onget="return this.getAttribute('next');" + onset="this.setAttribute('next', val); + this.parentNode._accessMethod = 'random'; + return val;"/> + </implementation> + </binding> + +#ifdef XP_MACOSX + <binding id="wizard-header" extends="chrome://global/content/bindings/wizard.xml#wizard-base"> + <content> + <xul:stack class="wizard-header-stack" flex="1"> + <xul:vbox class="wizard-header-box-1"> + <xul:vbox class="wizard-header-box-text"> + <xul:label class="wizard-header-label" xbl:inherits="xbl:text=label"/> + </xul:vbox> + </xul:vbox> + <xul:hbox class="wizard-header-box-icon"> + <xul:spacer flex="1"/> + <xul:image class="wizard-header-icon" xbl:inherits="src=iconsrc"/> + </xul:hbox> + </xul:stack> + </content> + </binding> + + <binding id="wizard-buttons" extends="chrome://global/content/bindings/wizard.xml#wizard-base"> + <content> + <xul:vbox flex="1"> + <xul:hbox class="wizard-buttons-btm"> + <xul:button class="wizard-button" dlgtype="extra1" hidden="true"/> + <xul:button class="wizard-button" dlgtype="extra2" hidden="true"/> + <xul:button label="&button-cancel-mac.label;" class="wizard-button" dlgtype="cancel"/> + <xul:spacer flex="1"/> + <xul:button label="&button-back-mac.label;" accesskey="&button-back-mac.accesskey;" + class="wizard-button wizard-nav-button" dlgtype="back"/> + <xul:button label="&button-next-mac.label;" accesskey="&button-next-mac.accesskey;" + class="wizard-button wizard-nav-button" dlgtype="next" + default="true" xbl:inherits="hidden=lastpage" /> + <xul:button label="&button-finish-mac.label;" class="wizard-button" + dlgtype="finish" default="true" xbl:inherits="hidden=hidefinishbutton" /> + </xul:hbox> + </xul:vbox> + </content> + + <implementation> + <method name="onPageChange"> + <body><![CDATA[ + this.setAttribute("hidefinishbutton", !(this.getAttribute("lastpage") == "true")); + ]]></body> + </method> + </implementation> + + </binding> + +#else + + <binding id="wizard-header" extends="chrome://global/content/bindings/wizard.xml#wizard-base"> + <content> + <xul:hbox class="wizard-header-box-1" flex="1"> + <xul:vbox class="wizard-header-box-text" flex="1"> + <xul:label class="wizard-header-label" xbl:inherits="xbl:text=label"/> + <xul:label class="wizard-header-description" xbl:inherits="xbl:text=description"/> + </xul:vbox> + <xul:image class="wizard-header-icon" xbl:inherits="src=iconsrc"/> + </xul:hbox> + </content> + </binding> + + <binding id="wizard-buttons" extends="chrome://global/content/bindings/wizard.xml#wizard-base"> + <content> + <xul:vbox class="wizard-buttons-box-1" flex="1"> + <xul:separator class="wizard-buttons-separator groove"/> + <xul:hbox class="wizard-buttons-box-2"> + <xul:button class="wizard-button" dlgtype="extra1" hidden="true"/> + <xul:button class="wizard-button" dlgtype="extra2" hidden="true"/> + <xul:spacer flex="1" anonid="spacer"/> +#ifdef XP_UNIX + <xul:button label="&button-cancel-unix.label;" class="wizard-button" + dlgtype="cancel" icon="cancel"/> + <xul:spacer style="width: 24px"/> + <xul:button label="&button-back-unix.label;" accesskey="&button-back-unix.accesskey;" + class="wizard-button" dlgtype="back" icon="go-back"/> + <xul:deck class="wizard-next-deck" anonid="WizardButtonDeck"> + <xul:hbox> + <xul:button label="&button-finish-unix.label;" class="wizard-button" + dlgtype="finish" default="true" flex="1"/> + </xul:hbox> + <xul:hbox> + <xul:button label="&button-next-unix.label;" accesskey="&button-next-unix.accesskey;" + class="wizard-button" dlgtype="next" icon="go-forward" + default="true" flex="1"/> + </xul:hbox> + </xul:deck> +#else + <xul:button label="&button-back-win.label;" accesskey="&button-back-win.accesskey;" + class="wizard-button" dlgtype="back" icon="go-back"/> + <xul:deck class="wizard-next-deck" anonid="WizardButtonDeck"> + <xul:hbox> + <xul:button label="&button-finish-win.label;" class="wizard-button" + dlgtype="finish" default="true" flex="1"/> + </xul:hbox> + <xul:hbox> + <xul:button label="&button-next-win.label;" accesskey="&button-next-win.accesskey;" + class="wizard-button" dlgtype="next" icon="go-forward" + default="true" flex="1"/> + </xul:hbox> + </xul:deck> + <xul:button label="&button-cancel-win.label;" class="wizard-button" + dlgtype="cancel" icon="cancel"/> +#endif + </xul:hbox> + </xul:vbox> + </content> + + <implementation> + <field name="_wizardButtonDeck" readonly="true"> + document.getAnonymousElementByAttribute(this, "anonid", "WizardButtonDeck"); + </field> + + <method name="onPageChange"> + <body><![CDATA[ + if (this.getAttribute("lastpage") == "true") { + this._wizardButtonDeck.setAttribute("selectedIndex", 0); + } else { + this._wizardButtonDeck.setAttribute("selectedIndex", 1); + } + ]]></body> + </method> + + <property name="defaultButton" readonly="true"> + <getter><![CDATA[ + const kXULNS = + "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + var buttons = this._wizardButtonDeck.selectedPanel + .getElementsByTagNameNS(kXULNS, "button"); + for (var i = 0; i < buttons.length; i++) { + if (buttons[i].getAttribute("default") == "true" && + !buttons[i].hidden && !buttons[i].disabled) + return buttons[i]; + } + return null; + ]]></getter> + </property> + </implementation> + </binding> +#endif + +</bindings> |