toolkit/components/prompts/content/tabprompts.xml

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/components/prompts/content/tabprompts.xml	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,336 @@
     1.4 +<?xml version="1.0"?>
     1.5 +<!-- This Source Code Form is subject to the terms of the Mozilla Public
     1.6 +   - License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 +   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
     1.8 +
     1.9 +<!DOCTYPE bindings [
    1.10 +<!ENTITY % commonDialogDTD  SYSTEM "chrome://global/locale/commonDialog.dtd">
    1.11 +<!ENTITY % dialogOverlayDTD SYSTEM "chrome://global/locale/dialogOverlay.dtd">
    1.12 +%commonDialogDTD;
    1.13 +%dialogOverlayDTD;
    1.14 +]>
    1.15 +
    1.16 +<bindings id="tabPrompts"
    1.17 +   xmlns="http://www.mozilla.org/xbl"
    1.18 +   xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    1.19 +   xmlns:xbl="http://www.mozilla.org/xbl">
    1.20 +
    1.21 +  <binding id="tabmodalprompt">
    1.22 +
    1.23 +    <resources>
    1.24 +        <stylesheet src="chrome://global/content/tabprompts.css"/>
    1.25 +        <stylesheet src="chrome://global/skin/tabprompts.css"/>
    1.26 +    </resources>
    1.27 +
    1.28 +    <xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    1.29 +                 role="dialog"
    1.30 +                 aria-describedby="info.body">
    1.31 +
    1.32 +        <!-- This is based on the guts of commonDialog.xul -->
    1.33 +        <spacer flex="1"/>
    1.34 +        <hbox pack="center">
    1.35 +            <vbox anonid="mainContainer" class="mainContainer">
    1.36 +                <grid class="topContainer" flex="1">
    1.37 +                    <columns>
    1.38 +                        <column/>
    1.39 +                        <column flex="1"/>
    1.40 +                    </columns>
    1.41 +
    1.42 +                    <rows>
    1.43 +                        <vbox anonid="infoContainer" align="center" pack="center" flex="1">
    1.44 +                            <description anonid="info.title" class="info.title" hidden="true" />
    1.45 +                            <description anonid="info.body" class="info.body"/>
    1.46 +                        </vbox>
    1.47 +
    1.48 +                        <row anonid="loginContainer" hidden="true" align="center">
    1.49 +                            <label anonid="loginLabel" value="&editfield0.label;" control="loginTextbox"/>
    1.50 +                            <textbox anonid="loginTextbox"/>
    1.51 +                        </row>
    1.52 +
    1.53 +                        <row anonid="password1Container" hidden="true" align="center">
    1.54 +                            <label anonid="password1Label" value="&editfield1.label;" control="password1Textbox"/>
    1.55 +                            <textbox anonid="password1Textbox" type="password"/>
    1.56 +                        </row>
    1.57 +
    1.58 +                        <row anonid="checkboxContainer" hidden="true">
    1.59 +                            <spacer/>
    1.60 +                            <checkbox anonid="checkbox"/>
    1.61 +                        </row>
    1.62 +                    </rows>
    1.63 +                </grid>
    1.64 +                <xbl:children/>
    1.65 +                <hbox class="buttonContainer">
    1.66 +#ifdef XP_UNIX
    1.67 +                    <button anonid="button3" hidden="true"/>
    1.68 +                    <button anonid="button2" hidden="true"/>
    1.69 +                    <spacer anonid="buttonSpacer" flex="1"/>
    1.70 +                    <button anonid="button1" label="&cancelButton.label;"/>
    1.71 +                    <button anonid="button0" label="&okButton.label;"/>
    1.72 +#else
    1.73 +                    <button anonid="button3" hidden="true"/>
    1.74 +                    <spacer anonid="buttonSpacer" flex="1"/>
    1.75 +                    <button anonid="button0" label="&okButton.label;"/>
    1.76 +                    <button anonid="button2" hidden="true"/>
    1.77 +                    <button anonid="button1" label="&cancelButton.label;"/>
    1.78 +#endif
    1.79 +                </hbox>
    1.80 +            </vbox>
    1.81 +        </hbox>
    1.82 +        <spacer flex="2"/>
    1.83 +    </xbl:content>
    1.84 +
    1.85 +    <implementation implements="nsIDOMEventListener">
    1.86 +        <constructor>
    1.87 +        <![CDATA[
    1.88 +            let self = this;
    1.89 +            function getElement(anonid) {
    1.90 +                return document.getAnonymousElementByAttribute(self, "anonid", anonid);
    1.91 +            }
    1.92 +
    1.93 +            this.ui = {
    1.94 +                prompt             : this,
    1.95 +                loginContainer     : getElement("loginContainer"),
    1.96 +                loginTextbox       : getElement("loginTextbox"),
    1.97 +                loginLabel         : getElement("loginLabel"),
    1.98 +                password1Container : getElement("password1Container"),
    1.99 +                password1Textbox   : getElement("password1Textbox"),
   1.100 +                password1Label     : getElement("password1Label"),
   1.101 +                infoBody           : getElement("info.body"),
   1.102 +                infoTitle          : getElement("info.title"),
   1.103 +                infoIcon           : null,
   1.104 +                checkbox           : getElement("checkbox"),
   1.105 +                checkboxContainer  : getElement("checkboxContainer"),
   1.106 +                button3            : getElement("button3"),
   1.107 +                button2            : getElement("button2"),
   1.108 +                button1            : getElement("button1"),
   1.109 +                button0            : getElement("button0"),
   1.110 +                // focusTarget (for BUTTON_DELAY_ENABLE) not yet supported
   1.111 +            };
   1.112 +
   1.113 +            this.ui.button0.addEventListener("command", this.onButtonClick.bind(this, 0), false);
   1.114 +            this.ui.button1.addEventListener("command", this.onButtonClick.bind(this, 1), false);
   1.115 +            this.ui.button2.addEventListener("command", this.onButtonClick.bind(this, 2), false);
   1.116 +            this.ui.button3.addEventListener("command", this.onButtonClick.bind(this, 3), false);
   1.117 +            // Anonymous wrapper used here because |Dialog| doesn't exist until init() is called!
   1.118 +            this.ui.checkbox.addEventListener("command", function() { self.Dialog.onCheckbox(); } , false);
   1.119 +            this.isLive = false;
   1.120 +        ]]>
   1.121 +        </constructor>
   1.122 +        <destructor>
   1.123 +        <![CDATA[
   1.124 +            if (this.isLive) {
   1.125 +                this.abortPrompt();
   1.126 +            }
   1.127 +        ]]>
   1.128 +        </destructor>
   1.129 +
   1.130 +        <field name="ui"/>
   1.131 +        <field name="args"/>
   1.132 +        <field name="linkedTab"/>
   1.133 +        <field name="onCloseCallback"/>
   1.134 +        <field name="Dialog"/>
   1.135 +        <field name="isLive"/>
   1.136 +        <field name="availWidth"/>
   1.137 +        <field name="availHeight"/>
   1.138 +        <field name="minWidth"/>
   1.139 +        <field name="minHeight"/>
   1.140 +
   1.141 +        <method name="init">
   1.142 +            <parameter name="args"/>
   1.143 +            <parameter name="linkedTab"/>
   1.144 +            <parameter name="onCloseCallback"/>
   1.145 +            <body>
   1.146 +            <![CDATA[
   1.147 +                this.args = args;
   1.148 +                this.linkedTab = linkedTab;
   1.149 +                this.onCloseCallback = onCloseCallback;
   1.150 +
   1.151 +                if (args.enableDelay)
   1.152 +                    throw "BUTTON_DELAY_ENABLE not yet supported for tab-modal prompts";
   1.153 +
   1.154 +                // We need to remove the prompt when the tab or browser window is closed or
   1.155 +                // the page navigates, else we never unwind the event loop and that's sad times.
   1.156 +                // Remember to cleanup in shutdownPrompt()!
   1.157 +                this.isLive = true;
   1.158 +                window.addEventListener("resize", this, false);
   1.159 +                window.addEventListener("unload", this, false);
   1.160 +                linkedTab.addEventListener("TabClose", this, false);
   1.161 +                // Note:
   1.162 +                // nsPrompter.js or in e10s mode browser-parent.js call abortPrompt,
   1.163 +                // when the domWindow, for which the prompt was created, generates
   1.164 +                // a "pagehide" event.
   1.165 +
   1.166 +                let tmp = {};
   1.167 +                Components.utils.import("resource://gre/modules/CommonDialog.jsm", tmp);
   1.168 +                this.Dialog = new tmp.CommonDialog(args, this.ui);
   1.169 +                this.Dialog.onLoad(null);
   1.170 +
   1.171 +                // Display the tabprompt title that shows the prompt origin when
   1.172 +                // the prompt origin is not the same as that of the top window.
   1.173 +                if (!args.showAlertOrigin)
   1.174 +                    this.ui.infoTitle.removeAttribute("hidden");
   1.175 +
   1.176 +                // TODO: should unhide buttonSpacer on Windows when there are 4 buttons.
   1.177 +                //       Better yet, just drop support for 4-button dialogs. (bug 609510)
   1.178 +
   1.179 +                this.onResize();
   1.180 +            ]]>
   1.181 +            </body>
   1.182 +        </method>
   1.183 +
   1.184 +        <method name="shutdownPrompt">
   1.185 +            <body>
   1.186 +            <![CDATA[
   1.187 +                // remove our event listeners
   1.188 +                try {
   1.189 +                    window.removeEventListener("resize", this, false);
   1.190 +                    window.removeEventListener("unload", this, false);
   1.191 +                    this.linkedTab.removeEventListener("TabClose", this, false);
   1.192 +                } catch(e) { }
   1.193 +                this.isLive = false;
   1.194 +                // invoke callback
   1.195 +                this.onCloseCallback();
   1.196 +            ]]>
   1.197 +            </body>
   1.198 +        </method>
   1.199 +
   1.200 +        <method name="abortPrompt">
   1.201 +            <body>
   1.202 +            <![CDATA[
   1.203 +                // Called from other code when the page changes.
   1.204 +                this.Dialog.abortPrompt();
   1.205 +                this.shutdownPrompt();
   1.206 +            ]]>
   1.207 +            </body>
   1.208 +        </method>
   1.209 +
   1.210 +        <method name="handleEvent">
   1.211 +            <parameter name="aEvent"/>
   1.212 +            <body>
   1.213 +            <![CDATA[
   1.214 +                switch (aEvent.type) {
   1.215 +                  case "resize":
   1.216 +                    this.onResize();
   1.217 +                    break;
   1.218 +                  case "unload":
   1.219 +                  case "TabClose":
   1.220 +                    this.abortPrompt();
   1.221 +                    break;
   1.222 +                }
   1.223 +            ]]>
   1.224 +            </body>
   1.225 +        </method>
   1.226 +
   1.227 +        <method name="onResize">
   1.228 +            <body>
   1.229 +            <![CDATA[
   1.230 +                let availWidth = this.clientWidth;
   1.231 +                let availHeight = this.clientHeight;
   1.232 +                if (availWidth == this.availWidth && availHeight == this.availHeight)
   1.233 +                    return;
   1.234 +                this.availWidth = availWidth;
   1.235 +                this.availHeight = availHeight;
   1.236 +
   1.237 +                let self = this;
   1.238 +                function getElement(anonid) {
   1.239 +                    return document.getAnonymousElementByAttribute(self, "anonid", anonid);
   1.240 +                }
   1.241 +                let main = getElement("mainContainer");
   1.242 +                let info = getElement("infoContainer");
   1.243 +                let body = this.ui.infoBody;
   1.244 +
   1.245 +                // cap prompt dimensions at 60% width and 60% height of content area
   1.246 +                if (!this.minWidth)
   1.247 +                  this.minWidth = parseInt(window.getComputedStyle(main).minWidth);
   1.248 +                if (!this.minHeight)
   1.249 +                  this.minHeight = parseInt(window.getComputedStyle(main).minHeight);
   1.250 +                let maxWidth = Math.max(Math.floor(availWidth * 0.6), this.minWidth) +
   1.251 +                               info.clientWidth - main.clientWidth;
   1.252 +                let maxHeight = Math.max(Math.floor(availHeight * 0.6), this.minHeight) +
   1.253 +                                info.clientHeight - main.clientHeight;
   1.254 +                body.style.maxWidth = maxWidth + "px";
   1.255 +                info.style.overflow = info.style.width = info.style.height = "";
   1.256 +
   1.257 +                // when prompt text is too long, use scrollbars
   1.258 +                if (info.clientWidth > maxWidth) {
   1.259 +                    info.style.overflow = "auto";
   1.260 +                    info.style.width = maxWidth + "px";
   1.261 +                }
   1.262 +                if (info.clientHeight > maxHeight) {
   1.263 +                    info.style.overflow = "auto";
   1.264 +                    info.style.height = maxHeight + "px";
   1.265 +                }
   1.266 +            ]]>
   1.267 +            </body>
   1.268 +        </method>
   1.269 +
   1.270 +        <method name="onButtonClick">
   1.271 +            <parameter name="buttonNum"/>
   1.272 +            <body>
   1.273 +            <![CDATA[
   1.274 +                this.Dialog["onButton" + buttonNum]();
   1.275 +                this.shutdownPrompt();
   1.276 +            ]]>
   1.277 +            </body>
   1.278 +        </method>
   1.279 +
   1.280 +        <method name="onKeyAction">
   1.281 +            <parameter name="action"/>
   1.282 +            <parameter name="event"/>
   1.283 +            <body>
   1.284 +            <![CDATA[
   1.285 +                if (event.defaultPrevented)
   1.286 +                    return;
   1.287 +
   1.288 +                event.stopPropagation();
   1.289 +                if (action == "default") {
   1.290 +                    let bnum = this.args.defaultButtonNum || 0;
   1.291 +                    let button = this.ui["button" + bnum];
   1.292 +                    this.onButtonClick(bnum);
   1.293 +                } else { // action == "cancel"
   1.294 +                    this.onButtonClick(1); // Cancel button
   1.295 +                }
   1.296 +            ]]>
   1.297 +            </body>
   1.298 +        </method>
   1.299 +    </implementation>
   1.300 +
   1.301 +    <handlers>
   1.302 +        <!-- Based on dialog.xml handlers -->
   1.303 +        <handler event="keypress" keycode="VK_RETURN"
   1.304 +                 group="system" action="this.onKeyAction('default', event);"/>
   1.305 +        <handler event="keypress" keycode="VK_ESCAPE"
   1.306 +                 group="system" action="this.onKeyAction('cancel', event);"/>
   1.307 +#ifdef XP_MACOSX
   1.308 +        <handler event="keypress" key="." modifiers="meta"
   1.309 +                 group="system" action="this.onKeyAction('cancel', event);"/>
   1.310 +#endif
   1.311 +        <handler event="focus" phase="capturing">
   1.312 +            let bnum = this.args.defaultButtonNum || 0;
   1.313 +            let defaultButton = this.ui["button" + bnum];
   1.314 +
   1.315 +#ifdef XP_MACOSX
   1.316 +            // On OS X, the default button always stays marked as such (until
   1.317 +            // the entire prompt blurs).
   1.318 +            defaultButton.setAttribute("default", true);
   1.319 +#else
   1.320 +            // On other platforms, the default button is only marked as such
   1.321 +            // when no other button has focus. XUL buttons on not-OSX will
   1.322 +            // react to pressing enter as a command, so you can't trigger the
   1.323 +            // default without tabbing to it or something that isn't a button.
   1.324 +            let focusedDefault = (event.originalTarget == defaultButton);
   1.325 +            let someButtonFocused = event.originalTarget instanceof Ci.nsIDOMXULButtonElement;
   1.326 +            defaultButton.setAttribute("default", focusedDefault || !someButtonFocused);
   1.327 +#endif
   1.328 +        </handler>
   1.329 +        <handler event="blur">
   1.330 +            // If focus shifted to somewhere else in the browser, don't make
   1.331 +            // the default button look active.
   1.332 +            let bnum = this.args.defaultButtonNum || 0;
   1.333 +            let button = this.ui["button" + bnum];
   1.334 +            button.setAttribute("default", false);
   1.335 +        </handler>
   1.336 +    </handlers>
   1.337 +
   1.338 +  </binding>
   1.339 +</bindings>

mercurial