<?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>