toolkit/content/widgets/dialog.xml

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/content/widgets/dialog.xml	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,440 @@
     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 +
    1.10 +<bindings id="dialogBindings"
    1.11 +          xmlns="http://www.mozilla.org/xbl"
    1.12 +          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    1.13 +          xmlns:xbl="http://www.mozilla.org/xbl">
    1.14 +  
    1.15 +  <binding id="dialog" extends="chrome://global/content/bindings/general.xml#root-element">
    1.16 +    <resources>
    1.17 +      <stylesheet src="chrome://global/skin/dialog.css"/>
    1.18 +    </resources>
    1.19 +    <content>
    1.20 +      <xul:vbox class="box-inherit dialog-content-box" flex="1">
    1.21 +        <children/>
    1.22 +      </xul:vbox>
    1.23 +          
    1.24 +      <xul:hbox class="dialog-button-box" anonid="buttons"
    1.25 +                xbl:inherits="pack=buttonpack,align=buttonalign,dir=buttondir,orient=buttonorient"
    1.26 +#ifdef XP_UNIX
    1.27 +                >
    1.28 +        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
    1.29 +        <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
    1.30 +        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
    1.31 +        <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
    1.32 +        <xul:spacer anonid="spacer" flex="1"/>
    1.33 +        <xul:button dlgtype="cancel" class="dialog-button"/>
    1.34 +        <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
    1.35 +#else
    1.36 +                pack="end">
    1.37 +        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
    1.38 +        <xul:spacer anonid="spacer" flex="1" hidden="true"/>
    1.39 +        <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
    1.40 +        <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
    1.41 +        <xul:button dlgtype="cancel" class="dialog-button"/>
    1.42 +        <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
    1.43 +        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
    1.44 +#endif
    1.45 +      </xul:hbox>
    1.46 +    </content>
    1.47 +
    1.48 +    <implementation>
    1.49 +      <field name="_mStrBundle">null</field>
    1.50 +      <field name="_closeHandler">(function(event) {
    1.51 +        if (!document.documentElement.cancelDialog())
    1.52 +          event.preventDefault();
    1.53 +      })</field>
    1.54 +
    1.55 +      <property name="buttons"
    1.56 +                onget="return this.getAttribute('buttons');"
    1.57 +                onset="this._configureButtons(val); return val;"/>
    1.58 +
    1.59 +      <property name="defaultButton">
    1.60 +        <getter>
    1.61 +        <![CDATA[
    1.62 +          if (this.hasAttribute("defaultButton"))
    1.63 +            return this.getAttribute("defaultButton");
    1.64 +          else // default to the accept button
    1.65 +            return "accept";
    1.66 +        ]]>
    1.67 +        </getter>
    1.68 +        <setter>
    1.69 +        <![CDATA[
    1.70 +          this._setDefaultButton(val);
    1.71 +          return val;
    1.72 +        ]]>
    1.73 +        </setter>
    1.74 +      </property>
    1.75 +
    1.76 +      <method name="acceptDialog">
    1.77 +        <body>
    1.78 +        <![CDATA[
    1.79 +          return this._doButtonCommand("accept");
    1.80 +        ]]>
    1.81 +        </body>
    1.82 +      </method>
    1.83 +      
    1.84 +      <method name="cancelDialog">
    1.85 +        <body>
    1.86 +        <![CDATA[
    1.87 +          return this._doButtonCommand("cancel");
    1.88 +        ]]>
    1.89 +        </body>
    1.90 +      </method>
    1.91 +      
    1.92 +      <method name="getButton">
    1.93 +        <parameter name="aDlgType"/>
    1.94 +        <body>
    1.95 +        <![CDATA[
    1.96 +          return this._buttons[aDlgType];
    1.97 +        ]]>
    1.98 +        </body>
    1.99 +      </method>
   1.100 +
   1.101 +      <method name="moveToAlertPosition">
   1.102 +        <body>
   1.103 +        <![CDATA[
   1.104 +          // hack. we need this so the window has something like its final size
   1.105 +          if (window.outerWidth == 1) {
   1.106 +            dump("Trying to position a sizeless window; caller should have called sizeToContent() or sizeTo(). See bug 75649.\n");
   1.107 +            sizeToContent();
   1.108 +          }
   1.109 +
   1.110 +          var xOffset = (opener.outerWidth - window.outerWidth) / 2;
   1.111 +          var yOffset = opener.outerHeight / 5;
   1.112 +
   1.113 +          var newX = opener.screenX + xOffset;
   1.114 +          var newY = opener.screenY + yOffset;
   1.115 +
   1.116 +          // ensure the window is fully onscreen (if smaller than the screen)
   1.117 +          if (newX < screen.availLeft)
   1.118 +            newX = screen.availLeft + 20;
   1.119 +          if ((newX + window.outerWidth) > (screen.availLeft + screen.availWidth))
   1.120 +            newX = (screen.availLeft + screen.availWidth) - window.outerWidth - 20;
   1.121 +
   1.122 +          if (newY < screen.availTop)
   1.123 +            newY = screen.availTop + 20;
   1.124 +          if ((newY + window.outerHeight) > (screen.availTop + screen.availHeight))
   1.125 +            newY = (screen.availTop + screen.availHeight) - window.outerHeight - 60;
   1.126 +
   1.127 +          window.moveTo( newX, newY );
   1.128 +        ]]>
   1.129 +        </body>
   1.130 +      </method>
   1.131 +
   1.132 +      <method name="centerWindowOnScreen">
   1.133 +        <body>
   1.134 +        <![CDATA[
   1.135 +          var xOffset = screen.availWidth/2 - window.outerWidth/2;
   1.136 +          var yOffset = screen.availHeight/2 - window.outerHeight/2; //(opener.outerHeight *2)/10;
   1.137 +  
   1.138 +          xOffset = xOffset > 0 ? xOffset : 0;
   1.139 +          yOffset = yOffset > 0 ? yOffset : 0;
   1.140 +          window.moveTo(xOffset, yOffset);
   1.141 +        ]]>
   1.142 +        </body>
   1.143 +      </method>
   1.144 +
   1.145 +      <constructor>
   1.146 +      <![CDATA[
   1.147 +        this._configureButtons(this.buttons);
   1.148 +
   1.149 +        // listen for when window is closed via native close buttons
   1.150 +        window.addEventListener("close", this._closeHandler, false);
   1.151 +
   1.152 +        // for things that we need to initialize after onload fires
   1.153 +        window.addEventListener("load", this.postLoadInit, false);
   1.154 +
   1.155 +        window.moveToAlertPosition = this.moveToAlertPosition;
   1.156 +        window.centerWindowOnScreen = this.centerWindowOnScreen;
   1.157 +      ]]>
   1.158 +      </constructor>
   1.159 +
   1.160 +      <method name="postLoadInit">
   1.161 +        <parameter name="aEvent"/>
   1.162 +        <body>
   1.163 +        <![CDATA[
   1.164 +          function focusInit() {
   1.165 +            const dialog = document.documentElement;
   1.166 +            const defaultButton = dialog.getButton(dialog.defaultButton);
   1.167 +            // give focus to the first focusable element in the dialog
   1.168 +            if (!document.commandDispatcher.focusedElement) {
   1.169 +              document.commandDispatcher.advanceFocusIntoSubtree(dialog);
   1.170 +
   1.171 +              var focusedElt = document.commandDispatcher.focusedElement;
   1.172 +              if (focusedElt) {
   1.173 +                var initialFocusedElt = focusedElt;
   1.174 +                while (focusedElt.localName == "tab" ||
   1.175 +                       focusedElt.getAttribute("noinitialfocus") == "true") {
   1.176 +                  document.commandDispatcher.advanceFocusIntoSubtree(focusedElt);
   1.177 +                  focusedElt = document.commandDispatcher.focusedElement;
   1.178 +                  if (focusedElt == initialFocusedElt)
   1.179 +                    break;
   1.180 +                }
   1.181 +
   1.182 +                if (initialFocusedElt.localName == "tab") {
   1.183 +                  if (focusedElt.hasAttribute("dlgtype")) {
   1.184 +                    // We don't want to focus on anonymous OK, Cancel, etc. buttons,
   1.185 +                    // so return focus to the tab itself
   1.186 +                    initialFocusedElt.focus();
   1.187 +                  }
   1.188 +                }
   1.189 +#ifndef XP_MACOSX
   1.190 +                else if (focusedElt.hasAttribute("dlgtype") && focusedElt != defaultButton) {
   1.191 +                  defaultButton.focus();
   1.192 +                }
   1.193 +#endif
   1.194 +              }
   1.195 +            }
   1.196 +
   1.197 +            try {
   1.198 +              if (defaultButton)
   1.199 +                window.notifyDefaultButtonLoaded(defaultButton);
   1.200 +            } catch (e) { }
   1.201 +          }
   1.202 +
   1.203 +          // Give focus after onload completes, see bug 103197.
   1.204 +          setTimeout(focusInit, 0);
   1.205 +        ]]>
   1.206 +        </body>
   1.207 +      </method>                
   1.208 +
   1.209 +      <property name="mStrBundle">
   1.210 +        <getter>
   1.211 +        <![CDATA[
   1.212 +          if (!this._mStrBundle) {
   1.213 +            // need to create string bundle manually instead of using <xul:stringbundle/>
   1.214 +            // see bug 63370 for details
   1.215 +            this._mStrBundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
   1.216 +                                         .getService(Components.interfaces.nsIStringBundleService)
   1.217 +                                         .createBundle("chrome://global/locale/dialog.properties");
   1.218 +          }
   1.219 +          return this._mStrBundle;
   1.220 +        ]]></getter>
   1.221 +      </property>
   1.222 +      
   1.223 +      <method name="_configureButtons">
   1.224 +        <parameter name="aButtons"/>
   1.225 +        <body>
   1.226 +        <![CDATA[
   1.227 +          // by default, get all the anonymous button elements
   1.228 +          var buttons = {};
   1.229 +          this._buttons = buttons;
   1.230 +          buttons.accept = document.getAnonymousElementByAttribute(this, "dlgtype", "accept");
   1.231 +          buttons.cancel = document.getAnonymousElementByAttribute(this, "dlgtype", "cancel");
   1.232 +          buttons.extra1 = document.getAnonymousElementByAttribute(this, "dlgtype", "extra1");
   1.233 +          buttons.extra2 = document.getAnonymousElementByAttribute(this, "dlgtype", "extra2");
   1.234 +          buttons.help = document.getAnonymousElementByAttribute(this, "dlgtype", "help");
   1.235 +          buttons.disclosure = document.getAnonymousElementByAttribute(this, "dlgtype", "disclosure");
   1.236 +
   1.237 +          // look for any overriding explicit button elements
   1.238 +          var exBtns = this.getElementsByAttribute("dlgtype", "*");
   1.239 +          var dlgtype;
   1.240 +          var i;
   1.241 +          for (i = 0; i < exBtns.length; ++i) {
   1.242 +            dlgtype = exBtns[i].getAttribute("dlgtype");
   1.243 +            buttons[dlgtype].hidden = true; // hide the anonymous button
   1.244 +            buttons[dlgtype] = exBtns[i];
   1.245 +          }
   1.246 +
   1.247 +          // add the label and oncommand handler to each button
   1.248 +          for (dlgtype in buttons) {
   1.249 +            var button = buttons[dlgtype];
   1.250 +            button.addEventListener("command", this._handleButtonCommand, true);
   1.251 +
   1.252 +            // don't override custom labels with pre-defined labels on explicit buttons
   1.253 +            if (!button.hasAttribute("label")) {
   1.254 +              // dialog attributes override the default labels in dialog.properties
   1.255 +              if (this.hasAttribute("buttonlabel"+dlgtype)) {
   1.256 +                button.setAttribute("label", this.getAttribute("buttonlabel"+dlgtype));
   1.257 +                if (this.hasAttribute("buttonaccesskey"+dlgtype))
   1.258 +                  button.setAttribute("accesskey", this.getAttribute("buttonaccesskey"+dlgtype));
   1.259 +              } else if (dlgtype != "extra1" && dlgtype != "extra2") {
   1.260 +                button.setAttribute("label", this.mStrBundle.GetStringFromName("button-"+dlgtype));
   1.261 +                var accessKey = this.mStrBundle.GetStringFromName("accesskey-"+dlgtype);
   1.262 +                if (accessKey)
   1.263 +                  button.setAttribute("accesskey", accessKey);
   1.264 +              }
   1.265 +            }
   1.266 +            // allow specifying alternate icons in the dialog header
   1.267 +            if (!button.hasAttribute("icon")) {
   1.268 +              // if there's an icon specified, use that
   1.269 +              if (this.hasAttribute("buttonicon"+dlgtype))
   1.270 +                button.setAttribute("icon", this.getAttribute("buttonicon"+dlgtype));
   1.271 +              // otherwise set defaults
   1.272 +              else
   1.273 +                switch (dlgtype) {
   1.274 +                  case "accept":
   1.275 +                    button.setAttribute("icon","accept");
   1.276 +                    break;
   1.277 +                  case "cancel":
   1.278 +                    button.setAttribute("icon","cancel");
   1.279 +                    break;
   1.280 +                  case "disclosure":
   1.281 +                    button.setAttribute("icon","properties");
   1.282 +                    break;
   1.283 +                  case "help":
   1.284 +                    button.setAttribute("icon","help");
   1.285 +                    break;
   1.286 +                  default:
   1.287 +                    break;
   1.288 +                }
   1.289 +            }
   1.290 +          }
   1.291 +
   1.292 +          // ensure that hitting enter triggers the default button command
   1.293 +          this.defaultButton = this.defaultButton;
   1.294 +          
   1.295 +          // if there is a special button configuration, use it
   1.296 +          if (aButtons) {
   1.297 +            // expect a comma delimited list of dlgtype values
   1.298 +            var list = aButtons.split(",");
   1.299 +
   1.300 +            // mark shown dlgtypes as true
   1.301 +            var shown = { accept: false, cancel: false, help: false,
   1.302 +                          disclosure: false, extra1: false, extra2: false };
   1.303 +            for (i = 0; i < list.length; ++i)
   1.304 +              shown[list[i].replace(/ /g, "")] = true;
   1.305 +
   1.306 +            // hide/show the buttons we want
   1.307 +            for (dlgtype in buttons) 
   1.308 +              buttons[dlgtype].hidden = !shown[dlgtype];
   1.309 +
   1.310 +#ifdef XP_WIN
   1.311 +#           show the spacer on Windows only when the extra2 button is present
   1.312 +            var spacer = document.getAnonymousElementByAttribute(this, "anonid", "spacer");
   1.313 +            spacer.removeAttribute("hidden");
   1.314 +            spacer.setAttribute("flex", shown["extra2"]?"1":"0");
   1.315 +#endif
   1.316 +
   1.317 +          }
   1.318 +        ]]>
   1.319 +        </body>
   1.320 +      </method>
   1.321 +
   1.322 +      <method name="_setDefaultButton">
   1.323 +        <parameter name="aNewDefault"/>
   1.324 +        <body>
   1.325 +        <![CDATA[
   1.326 +          // remove the default attribute from the previous default button, if any
   1.327 +          var oldDefaultButton = this.getButton(this.defaultButton);
   1.328 +          if (oldDefaultButton)
   1.329 +            oldDefaultButton.removeAttribute("default");
   1.330 +
   1.331 +          var newDefaultButton = this.getButton(aNewDefault);
   1.332 +          if (newDefaultButton) {
   1.333 +            this.setAttribute("defaultButton", aNewDefault);
   1.334 +            newDefaultButton.setAttribute("default", "true");
   1.335 +          }
   1.336 +          else {
   1.337 +            this.setAttribute("defaultButton", "none");
   1.338 +            if (aNewDefault != "none")
   1.339 +              dump("invalid new default button: " +  aNewDefault + ", assuming: none\n");
   1.340 +          }
   1.341 +        ]]>
   1.342 +        </body>
   1.343 +      </method>
   1.344 +
   1.345 +      <method name="_handleButtonCommand">
   1.346 +        <parameter name="aEvent"/>
   1.347 +        <body>
   1.348 +        <![CDATA[
   1.349 +          return document.documentElement._doButtonCommand(
   1.350 +                                        aEvent.target.getAttribute("dlgtype"));
   1.351 +        ]]>
   1.352 +        </body>
   1.353 +      </method>
   1.354 +      
   1.355 +      <method name="_doButtonCommand">
   1.356 +        <parameter name="aDlgType"/>
   1.357 +        <body>
   1.358 +        <![CDATA[
   1.359 +          var button = this.getButton(aDlgType);
   1.360 +          if (!button.disabled) {
   1.361 +            var noCancel = this._fireButtonEvent(aDlgType);
   1.362 +            if (noCancel) {
   1.363 +              if (aDlgType == "accept" || aDlgType == "cancel")
   1.364 +                window.close();
   1.365 +            }
   1.366 +            return noCancel;
   1.367 +          }
   1.368 +          return true;
   1.369 +        ]]>
   1.370 +        </body>
   1.371 +      </method>
   1.372 +      
   1.373 +      <method name="_fireButtonEvent">
   1.374 +        <parameter name="aDlgType"/>
   1.375 +        <body>
   1.376 +        <![CDATA[
   1.377 +          var event = document.createEvent("Events");
   1.378 +          event.initEvent("dialog"+aDlgType, true, true);
   1.379 +          
   1.380 +          // handle dom event handlers
   1.381 +          var noCancel = this.dispatchEvent(event);
   1.382 +          
   1.383 +          // handle any xml attribute event handlers
   1.384 +          var handler = this.getAttribute("ondialog"+aDlgType);
   1.385 +          if (handler != "") {
   1.386 +            var fn = new Function("event", handler);
   1.387 +            var returned = fn(event);
   1.388 +            if (returned == false)
   1.389 +              noCancel = false;
   1.390 +          }
   1.391 +          
   1.392 +          return noCancel;
   1.393 +        ]]>
   1.394 +        </body>
   1.395 +      </method>
   1.396 +
   1.397 +      <method name="_hitEnter">
   1.398 +        <parameter name="evt"/>
   1.399 +        <body>
   1.400 +        <![CDATA[
   1.401 +          if (evt.defaultPrevented)
   1.402 +            return;
   1.403 +
   1.404 +          var btn = this.getButton(this.defaultButton);
   1.405 +          if (btn)
   1.406 +            this._doButtonCommand(this.defaultButton);
   1.407 +        ]]>
   1.408 +        </body>
   1.409 +      </method>
   1.410 +
   1.411 +    </implementation>
   1.412 +    
   1.413 +    <handlers>
   1.414 +      <handler event="keypress" keycode="VK_RETURN"
   1.415 +               group="system" action="this._hitEnter(event);"/>
   1.416 +      <handler event="keypress" keycode="VK_ESCAPE" group="system">
   1.417 +        if (!event.defaultPrevented)
   1.418 +          this.cancelDialog();
   1.419 +      </handler>
   1.420 +#ifdef XP_MACOSX
   1.421 +      <handler event="keypress" key="." modifiers="meta" phase="capturing" action="this.cancelDialog();"/>
   1.422 +#else
   1.423 +      <handler event="focus" phase="capturing">
   1.424 +        var btn = this.getButton(this.defaultButton);
   1.425 +        if (btn)
   1.426 +          btn.setAttribute("default", event.originalTarget == btn || !(event.originalTarget instanceof Components.interfaces.nsIDOMXULButtonElement));
   1.427 +      </handler>
   1.428 +#endif
   1.429 +    </handlers>
   1.430 +
   1.431 +  </binding>
   1.432 +
   1.433 +  <binding id="dialogheader">
   1.434 +    <resources>
   1.435 +      <stylesheet src="chrome://global/skin/dialog.css"/>
   1.436 +    </resources>
   1.437 +    <content>
   1.438 +      <xul:label class="dialogheader-title" xbl:inherits="value=title,crop" crop="right" flex="1"/>
   1.439 +      <xul:label class="dialogheader-description" xbl:inherits="value=description"/>
   1.440 +    </content>
   1.441 +  </binding>
   1.442 +
   1.443 +</bindings>

mercurial