<?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="dialogBindings" 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="dialog" extends="chrome://global/content/bindings/general.xml#root-element"> <resources> <stylesheet src="chrome://global/skin/dialog.css"/> </resources> <content> <xul:vbox class="box-inherit dialog-content-box" flex="1"> <children/> </xul:vbox> <xul:hbox class="dialog-button-box" anonid="buttons" xbl:inherits="pack=buttonpack,align=buttonalign,dir=buttondir,orient=buttonorient" #ifdef XP_UNIX > <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/> <xul:button dlgtype="help" class="dialog-button" hidden="true"/> <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/> <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/> <xul:spacer anonid="spacer" flex="1"/> <xul:button dlgtype="cancel" class="dialog-button"/> <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/> #else pack="end"> <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/> <xul:spacer anonid="spacer" flex="1" hidden="true"/> <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/> <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/> <xul:button dlgtype="cancel" class="dialog-button"/> <xul:button dlgtype="help" class="dialog-button" hidden="true"/> <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/> #endif </xul:hbox> </content> <implementation> <field name="_mStrBundle">null</field> <field name="_closeHandler">(function(event) { if (!document.documentElement.cancelDialog()) event.preventDefault(); })</field> <property name="buttons" onget="return this.getAttribute('buttons');" onset="this._configureButtons(val); return val;"/> <property name="defaultButton"> <getter> <![CDATA[ if (this.hasAttribute("defaultButton")) return this.getAttribute("defaultButton"); return "accept"; // default to the accept button ]]> </getter> <setter> <![CDATA[ this._setDefaultButton(val); return val; ]]> </setter> </property> <method name="acceptDialog"> <body> <![CDATA[ return this._doButtonCommand("accept"); ]]> </body> </method> <method name="cancelDialog"> <body> <![CDATA[ return this._doButtonCommand("cancel"); ]]> </body> </method> <method name="getButton"> <parameter name="aDlgType"/> <body> <![CDATA[ return this._buttons[aDlgType]; ]]> </body> </method> <method name="moveToAlertPosition"> <body> <![CDATA[ // hack. we need this so the window has something like its final size if (window.outerWidth == 1) { dump("Trying to position a sizeless window; caller should have called sizeToContent() or sizeTo(). See bug 75649.\n"); sizeToContent(); } if (opener) { var xOffset = (opener.outerWidth - window.outerWidth) / 2; var yOffset = opener.outerHeight / 5; var newX = opener.screenX + xOffset; var newY = opener.screenY + yOffset; } else { newX = (screen.availWidth - window.outerWidth) / 2; newY = (screen.availHeight - window.outerHeight) / 2; } // ensure the window is fully onscreen (if smaller than the screen) if (newX < screen.availLeft) newX = screen.availLeft + 20; if ((newX + window.outerWidth) > (screen.availLeft + screen.availWidth)) newX = (screen.availLeft + screen.availWidth) - window.outerWidth - 20; if (newY < screen.availTop) newY = screen.availTop + 20; if ((newY + window.outerHeight) > (screen.availTop + screen.availHeight)) newY = (screen.availTop + screen.availHeight) - window.outerHeight - 60; window.moveTo( newX, newY ); ]]> </body> </method> <method name="centerWindowOnScreen"> <body> <![CDATA[ var xOffset = screen.availWidth/2 - window.outerWidth/2; var yOffset = screen.availHeight/2 - window.outerHeight/2; xOffset = xOffset > 0 ? xOffset : 0; yOffset = yOffset > 0 ? yOffset : 0; window.moveTo(xOffset, yOffset); ]]> </body> </method> <constructor> <![CDATA[ this._configureButtons(this.buttons); // listen for when window is closed via native close buttons window.addEventListener("close", this._closeHandler, false); // for things that we need to initialize after onload fires window.addEventListener("load", this.postLoadInit, false); window.moveToAlertPosition = this.moveToAlertPosition; window.centerWindowOnScreen = this.centerWindowOnScreen; ]]> </constructor> <method name="postLoadInit"> <parameter name="aEvent"/> <body> <![CDATA[ function focusInit() { const dialog = document.documentElement; const defaultButton = dialog.getButton(dialog.defaultButton); // give focus to the first focusable element in the dialog if (!document.commandDispatcher.focusedElement) { document.commandDispatcher.advanceFocusIntoSubtree(dialog); var focusedElt = document.commandDispatcher.focusedElement; if (focusedElt) { var initialFocusedElt = focusedElt; while (focusedElt.localName == "tab" || focusedElt.getAttribute("noinitialfocus") == "true") { document.commandDispatcher.advanceFocusIntoSubtree(focusedElt); focusedElt = document.commandDispatcher.focusedElement; if (focusedElt == initialFocusedElt) break; } if (initialFocusedElt.localName == "tab") { if (focusedElt.hasAttribute("dlgtype")) { // We don't want to focus on anonymous OK, Cancel, etc. buttons, // so return focus to the tab itself initialFocusedElt.focus(); } } else if (!/Mac/.test(navigator.platform) && focusedElt.hasAttribute("dlgtype") && focusedElt != defaultButton) { defaultButton.focus(); } } } try { if (defaultButton) window.notifyDefaultButtonLoaded(defaultButton); } catch (e) { } } // Give focus after onload completes, see bug 103197. setTimeout(focusInit, 0); ]]> </body> </method> <property name="mStrBundle"> <getter> <![CDATA[ if (!this._mStrBundle) { // need to create string bundle manually instead of using <xul:stringbundle/> // see bug 63370 for details this._mStrBundle = Components.classes["@mozilla.org/intl/stringbundle;1"] .getService(Components.interfaces.nsIStringBundleService) .createBundle("chrome://global/locale/dialog.properties"); } return this._mStrBundle; ]]></getter> </property> <method name="_configureButtons"> <parameter name="aButtons"/> <body> <![CDATA[ // by default, get all the anonymous button elements var buttons = {}; this._buttons = buttons; buttons.accept = document.getAnonymousElementByAttribute(this, "dlgtype", "accept"); buttons.cancel = document.getAnonymousElementByAttribute(this, "dlgtype", "cancel"); buttons.extra1 = document.getAnonymousElementByAttribute(this, "dlgtype", "extra1"); buttons.extra2 = document.getAnonymousElementByAttribute(this, "dlgtype", "extra2"); buttons.help = document.getAnonymousElementByAttribute(this, "dlgtype", "help"); buttons.disclosure = document.getAnonymousElementByAttribute(this, "dlgtype", "disclosure"); // look for any overriding explicit button elements var exBtns = this.getElementsByAttribute("dlgtype", "*"); var dlgtype; var i; for (i = 0; i < exBtns.length; ++i) { dlgtype = exBtns[i].getAttribute("dlgtype"); buttons[dlgtype].hidden = true; // hide the anonymous button buttons[dlgtype] = exBtns[i]; } // add the label and oncommand handler to each button for (dlgtype in buttons) { var button = buttons[dlgtype]; button.addEventListener("command", this._handleButtonCommand, true); // don't override custom labels with pre-defined labels on explicit buttons if (!button.hasAttribute("label")) { // dialog attributes override the default labels in dialog.properties if (this.hasAttribute("buttonlabel"+dlgtype)) { button.setAttribute("label", this.getAttribute("buttonlabel"+dlgtype)); if (this.hasAttribute("buttonaccesskey"+dlgtype)) button.setAttribute("accesskey", this.getAttribute("buttonaccesskey"+dlgtype)); } else if (dlgtype != "extra1" && dlgtype != "extra2") { button.setAttribute("label", this.mStrBundle.GetStringFromName("button-"+dlgtype)); var accessKey = this.mStrBundle.GetStringFromName("accesskey-"+dlgtype); if (accessKey) button.setAttribute("accesskey", accessKey); } } // allow specifying alternate icons in the dialog header if (!button.hasAttribute("icon")) { // if there's an icon specified, use that if (this.hasAttribute("buttonicon"+dlgtype)) button.setAttribute("icon", this.getAttribute("buttonicon"+dlgtype)); // otherwise set defaults else switch (dlgtype) { case "accept": button.setAttribute("icon", "accept"); break; case "cancel": button.setAttribute("icon", "cancel"); break; case "disclosure": button.setAttribute("icon", "properties"); break; case "help": button.setAttribute("icon", "help"); break; default: break; } } } // ensure that hitting enter triggers the default button command this.defaultButton = this.defaultButton; // if there is a special button configuration, use it if (aButtons) { // expect a comma delimited list of dlgtype values var list = aButtons.split(","); // mark shown dlgtypes as true var shown = { accept: false, cancel: false, help: false, disclosure: false, extra1: false, extra2: false }; for (i = 0; i < list.length; ++i) shown[list[i].replace(/ /g, "")] = true; // hide/show the buttons we want for (dlgtype in buttons) buttons[dlgtype].hidden = !shown[dlgtype]; // show the spacer on Windows only when the extra2 button is present if (/Win/.test(navigator.platform)) { var spacer = document.getAnonymousElementByAttribute(this, "anonid", "spacer"); spacer.removeAttribute("hidden"); spacer.setAttribute("flex", shown["extra2"]?"1":"0"); } } ]]> </body> </method> <method name="_setDefaultButton"> <parameter name="aNewDefault"/> <body> <![CDATA[ // remove the default attribute from the previous default button, if any var oldDefaultButton = this.getButton(this.defaultButton); if (oldDefaultButton) oldDefaultButton.removeAttribute("default"); var newDefaultButton = this.getButton(aNewDefault); if (newDefaultButton) { this.setAttribute("defaultButton", aNewDefault); newDefaultButton.setAttribute("default", "true"); } else { this.setAttribute("defaultButton", "none"); if (aNewDefault != "none") dump("invalid new default button: " + aNewDefault + ", assuming: none\n"); } ]]> </body> </method> <method name="_handleButtonCommand"> <parameter name="aEvent"/> <body> <![CDATA[ return document.documentElement._doButtonCommand( aEvent.target.getAttribute("dlgtype")); ]]> </body> </method> <method name="_doButtonCommand"> <parameter name="aDlgType"/> <body> <![CDATA[ var button = this.getButton(aDlgType); if (!button.disabled) { var noCancel = this._fireButtonEvent(aDlgType); if (noCancel) { if (aDlgType == "accept" || aDlgType == "cancel") { var closingEvent = new CustomEvent("dialogclosing", { bubbles: true, detail: { button: aDlgType }, }); this.dispatchEvent(closingEvent); window.close(); } } return noCancel; } return true; ]]> </body> </method> <method name="_fireButtonEvent"> <parameter name="aDlgType"/> <body> <![CDATA[ var event = document.createEvent("Events"); event.initEvent("dialog"+aDlgType, true, true); // handle dom event handlers var noCancel = this.dispatchEvent(event); // handle any xml attribute event handlers var handler = this.getAttribute("ondialog"+aDlgType); if (handler != "") { var fn = new Function("event", handler); var returned = fn(event); if (returned == false) noCancel = false; } return noCancel; ]]> </body> </method> <method name="_hitEnter"> <parameter name="evt"/> <body> <![CDATA[ if (evt.defaultPrevented) return; var btn = this.getButton(this.defaultButton); if (btn) this._doButtonCommand(this.defaultButton); ]]> </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.cancelDialog(); </handler> #ifdef XP_MACOSX <handler event="keypress" key="." modifiers="meta" phase="capturing" action="this.cancelDialog();"/> #else <handler event="focus" phase="capturing"> var btn = this.getButton(this.defaultButton); if (btn) btn.setAttribute("default", event.originalTarget == btn || !(event.originalTarget instanceof Components.interfaces.nsIDOMXULButtonElement)); </handler> #endif </handlers> </binding> <binding id="dialogheader"> <resources> <stylesheet src="chrome://global/skin/dialog.css"/> </resources> <content> <xul:label class="dialogheader-title" xbl:inherits="value=title,crop" crop="right" flex="1"/> <xul:label class="dialogheader-description" xbl:inherits="value=description"/> </content> </binding> </bindings>