toolkit/content/widgets/button.xml

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 <?xml version="1.0"?>
     2 <!-- This Source Code Form is subject to the terms of the Mozilla Public
     3    - License, v. 2.0. If a copy of the MPL was not distributed with this
     4    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
     7 <bindings id="buttonBindings"
     8    xmlns="http://www.mozilla.org/xbl"
     9    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    10    xmlns:xbl="http://www.mozilla.org/xbl">
    12   <binding id="button-base" extends="chrome://global/content/bindings/general.xml#basetext" role="xul:button">
    13     <implementation implements="nsIDOMXULButtonElement">
    14       <property name="type"
    15                 onget="return this.getAttribute('type');"
    16                 onset="this.setAttribute('type', val); return val;"/>
    18       <property name="dlgType"
    19                 onget="return this.getAttribute('dlgtype');"
    20                 onset="this.setAttribute('dlgtype', val); return val;"/>
    22       <property name="group"
    23                 onget="return this.getAttribute('group');"
    24                 onset="this.setAttribute('group', val); return val;"/>
    26       <property name="open" onget="return this.hasAttribute('open');">
    27         <setter><![CDATA[
    28           if (this.boxObject instanceof
    29               Components.interfaces.nsIMenuBoxObject) {
    30             this.boxObject.openMenu(val);
    31           } else {
    32             // Fall back to just setting the attribute
    33             if (val) {
    34               this.setAttribute('open', 'true');
    35             } else {
    36               this.removeAttribute('open');
    37             }
    38           }
    39           return val;
    40         ]]></setter>
    41       </property>
    43       <property name="checked" onget="return this.hasAttribute('checked');">
    44         <setter><![CDATA[
    45           if (this.type == "checkbox") {
    46             this.checkState = val ? 1 : 0;
    47           } else if (this.type == "radio" && val) {
    48             var sibs = this.parentNode.getElementsByAttribute("group", this.group);
    49             for (var i = 0; i < sibs.length; ++i)
    50               sibs[i].removeAttribute("checked");
    51           }
    53           if (val)
    54             this.setAttribute("checked", "true");
    55           else
    56             this.removeAttribute("checked");
    58           return val;
    59         ]]></setter>
    60       </property>
    62       <property name="checkState">
    63         <getter><![CDATA[
    64           var state = this.getAttribute("checkState");
    65           if (state == "")
    66             return this.checked ? 1 : 0;
    67           else
    68             return state == "0" ? 0 : (state == "2" ? 2 : 1);
    69         ]]></getter>
    70         <setter><![CDATA[
    71           this.setAttribute("checkState", val);
    72           return val;
    73         ]]></setter>
    74       </property>
    76       <property name="autoCheck"
    77                 onget="return this.getAttribute('autoCheck') == 'true';"
    78                 onset="this.setAttribute('autoCheck', val); return val;"/>
    80       <method name ="filterButtons">
    81         <parameter name="node"/>
    82         <body>
    83         <![CDATA[
    84           // if the node isn't visible, don't descend into it.
    85           var cs = node.ownerDocument.defaultView.getComputedStyle(node, null);
    86           if (cs.visibility != "visible" || cs.display == "none") {
    87             return NodeFilter.FILTER_REJECT;
    88           }
    89           // but it may be a popup element, in which case we look at "state"...
    90           if (cs.display == "-moz-popup" && node.state != "open") {
    91             return NodeFilter.FILTER_REJECT;
    92           }
    93           // OK - the node seems visible, so it is a candidate.
    94           if (node.localName == "button" && node.accessKey && !node.disabled)
    95             return NodeFilter.FILTER_ACCEPT;
    96           return NodeFilter.FILTER_SKIP;
    97         ]]>
    98         </body>
    99       </method>
   101       <method name="fireAccessKeyButton">
   102         <parameter name="aSubtree"/>
   103         <parameter name="aAccessKeyLower"/>
   104         <body>
   105         <![CDATA[
   106           var iterator = aSubtree.ownerDocument.createTreeWalker(aSubtree, 
   107                                                                  NodeFilter.SHOW_ELEMENT, 
   108                                                                  this.filterButtons);
   109           while (iterator.nextNode()) {
   110             var test = iterator.currentNode;
   111             if (test.accessKey.toLowerCase() == aAccessKeyLower && 
   112                 !test.disabled && !test.collapsed && !test.hidden) {
   113               test.focus();
   114               test.click();
   115               return true;
   116             }
   117           }
   118           return false;
   119         ]]>
   120         </body>
   121       </method>
   123       <method name="_handleClick">
   124         <body>
   125         <![CDATA[
   126           if (!this.disabled &&
   127               (this.autoCheck || !this.hasAttribute("autoCheck"))) {
   129             if (this.type == "checkbox") {
   130               this.checked = !this.checked;
   131             } else if (this.type == "radio") {
   132               this.checked = true;
   133             }
   134           }
   135         ]]>
   136         </body>
   137       </method>
   138     </implementation>
   140     <handlers>
   141       <!-- While it would seem we could do this by handling oncommand, we can't
   142            because any external oncommand handlers might get called before ours,
   143            and then they would see the incorrect value of checked. Additionally
   144            a command attribute would redirect the command events anyway.-->
   145       <handler event="click" button="0" action="this._handleClick();"/>
   146       <handler event="keypress" key=" " action="this._handleClick();"/>
   148       <handler event="keypress">
   149       <![CDATA[
   150         if (this.boxObject instanceof Components.interfaces.nsIMenuBoxObject) {
   151           if (this.open)
   152             return;
   153         } else {
   154           if (event.keyCode == KeyEvent.DOM_VK_UP ||
   155               (event.keyCode == KeyEvent.DOM_VK_LEFT &&
   156                 document.defaultView.getComputedStyle(this.parentNode, "")
   157                         .direction == "ltr") ||
   158               (event.keyCode == KeyEvent.DOM_VK_RIGHT &&
   159                 document.defaultView.getComputedStyle(this.parentNode, "")
   160                         .direction == "rtl")) {
   161             event.preventDefault();
   162             window.document.commandDispatcher.rewindFocus();
   163             return;
   164           }
   166           if (event.keyCode == KeyEvent.DOM_VK_DOWN ||
   167               (event.keyCode == KeyEvent.DOM_VK_RIGHT &&
   168                 document.defaultView.getComputedStyle(this.parentNode, "")
   169                         .direction == "ltr") ||
   170               (event.keyCode == KeyEvent.DOM_VK_LEFT &&
   171                 document.defaultView.getComputedStyle(this.parentNode, "")
   172                         .direction == "rtl")) {
   173             event.preventDefault();
   174             window.document.commandDispatcher.advanceFocus();
   175             return;
   176           }
   177         }
   179         if (event.keyCode || event.charCode <= 32 || event.altKey || 
   180             event.ctrlKey || event.metaKey)
   181           return;  // No printable char pressed, not a potential accesskey
   183         // Possible accesskey pressed
   184         var charPressedLower = String.fromCharCode(event.charCode).toLowerCase();
   186         // If the accesskey of the current button is pressed, just activate it
   187         if (this.accessKey.toLowerCase() == charPressedLower) {
   188           this.click();
   189           return;
   190         }
   192         // Search for accesskey in the list of buttons for this doc and each subdoc
   193         // Get the buttons for the main document and all sub-frames
   194         for (var frameCount = -1; frameCount < window.top.frames.length; frameCount++) {
   195           var doc = (frameCount == -1)? window.top.document: 
   196             window.top.frames[frameCount].document
   197           if (this.fireAccessKeyButton(doc.documentElement, charPressedLower))
   198             return;
   199         }
   201         // Test anonymous buttons
   202         var dlg = window.top.document;
   203         var buttonBox = dlg.getAnonymousElementByAttribute(dlg.documentElement,
   204                                                          "anonid", "buttons");
   205         if (buttonBox)
   206           this.fireAccessKeyButton(buttonBox, charPressedLower);
   207       ]]>
   208       </handler>
   209     </handlers>
   210   </binding>
   212   <binding id="button" display="xul:button"
   213            extends="chrome://global/content/bindings/button.xml#button-base">
   214     <resources>
   215       <stylesheet src="chrome://global/skin/button.css"/>
   216     </resources>
   218     <content>
   219       <children includes="observes|template|menupopup|panel|tooltip"/>
   220       <xul:hbox class="box-inherit button-box" xbl:inherits="align,dir,pack,orient"
   221                 align="center" pack="center" flex="1" anonid="button-box">
   222         <children>
   223           <xul:image class="button-icon" xbl:inherits="src=image"/>
   224           <xul:label class="button-text" xbl:inherits="value=label,accesskey,crop"/>
   225         </children>
   226       </xul:hbox>
   227     </content>
   228   </binding>
   230   <binding id="menu" display="xul:menu"
   231            extends="chrome://global/content/bindings/button.xml#button">
   232     <content>
   233       <children includes="observes|template|menupopup|panel|tooltip"/>
   234       <xul:hbox class="box-inherit button-box" xbl:inherits="align,dir,pack,orient"
   235                 align="center" pack="center" flex="1">
   236         <children>
   237           <xul:hbox class="box-inherit" xbl:inherits="align,dir,pack,orient"
   238                     align="center" pack="center" flex="1">
   239             <xul:image class="button-icon" xbl:inherits="src=image"/>
   240             <xul:label class="button-text" xbl:inherits="value=label,accesskey,crop"/>
   241           </xul:hbox>
   242           <xul:dropmarker class="button-menu-dropmarker" xbl:inherits="open,disabled,label"/>
   243         </children>
   244       </xul:hbox>
   245     </content>
   247     <handlers>
   248       <handler event="keypress" keycode="VK_RETURN" action="this.open = true;"/>
   249       <handler event="keypress" key=" " action="this.open = true;"/>
   250     </handlers>
   251   </binding>
   253   <binding id="menu-button-base"
   254            extends="chrome://global/content/bindings/button.xml#button-base">
   255     <implementation implements="nsIDOMEventListener">
   256       <constructor>
   257         this.init();
   258       </constructor>
   260       <method name="init">
   261         <body>
   262         <![CDATA[
   263           var btn = document.getAnonymousElementByAttribute(this, "anonid", "button");
   264           if (!btn)
   265             throw "XBL binding for <button type=\"menu-button\"/> binding must contain an element with anonid=\"button\"";
   267           var menubuttonParent = this;
   268           btn.addEventListener("mouseover", function() { 
   269             if (!this.disabled)
   270               menubuttonParent.buttonover = true;
   271           }, true);
   272           btn.addEventListener("mouseout", function() {
   273             menubuttonParent.buttonover = false;
   274           }, true);
   275           btn.addEventListener("mousedown", function() {
   276             if (!this.disabled) {
   277               menubuttonParent.buttondown = true;
   278               document.addEventListener("mouseup", menubuttonParent, true);
   279             }
   280           }, true);
   281         ]]>
   282         </body>
   283       </method>
   285       <property name="buttonover" onget="return this.getAttribute('buttonover');">
   286         <setter>
   287         <![CDATA[
   288           var v = val || val == "true";
   289           if (!v && this.buttondown) { 
   290             this.buttondown = false;
   291             this._pendingActive = true;
   292           } 
   293           else {
   294             if (this._pendingActive) {
   295               this.buttondown = true;
   296               this._pendingActive = false;
   297             }
   298           }
   300           if (v)
   301             this.setAttribute("buttonover", "true");
   302           else
   303             this.removeAttribute("buttonover");
   304           return val;
   305         ]]>
   306         </setter>
   307       </property>
   309       <property name="buttondown" onget="return this.getAttribute('buttondown') == 'true';">
   310         <setter>
   311         <![CDATA[
   312           if (val || val == "true")
   313             this.setAttribute("buttondown", "true");
   314           else
   315             this.removeAttribute("buttondown");
   316           return val;
   317         ]]>
   318         </setter>
   319       </property>
   321       <field name="_pendingActive">false</field>
   323       <method name="handleEvent">
   324         <parameter name="aEvent"/>
   325         <body>
   326         <![CDATA[
   327           this._pendingActive = false;
   328           this.buttondown = false;
   329           document.removeEventListener("mouseup", this, true);
   330         ]]>
   331         </body>
   332       </method>
   334     </implementation>
   336     <handlers>
   337       <handler event="keypress" keycode="VK_RETURN">
   338         if (event.originalTarget == this)
   339           this.open = true;
   340       </handler>
   341       <handler event="keypress" key=" ">
   342         if (event.originalTarget == this)
   343           this.open = true;
   344       </handler>
   345     </handlers>
   346   </binding>
   348   <binding id="menu-button" display="xul:menu"
   349            extends="chrome://global/content/bindings/button.xml#menu-button-base">
   350     <resources>
   351       <stylesheet src="chrome://global/skin/button.css"/>
   352     </resources>
   354     <content>
   355       <children includes="observes|template|menupopup|panel|tooltip"/>
   356       <xul:button class="box-inherit button-menubutton-button"
   357                   anonid="button" flex="1" allowevents="true"
   358                   xbl:inherits="disabled,crop,image,label,accesskey,command,
   359                                 buttonover,buttondown,align,dir,pack,orient">
   360         <children/>
   361       </xul:button>
   362       <xul:dropmarker class="button-menubutton-dropmarker" xbl:inherits="open,disabled,label"/>
   363     </content>
   364   </binding>
   366   <binding id="button-image" display="xul:button"
   367            extends="chrome://global/content/bindings/button.xml#button">
   368     <content>
   369       <xul:image class="button-image-icon" xbl:inherits="src=image"/>
   370     </content>
   371   </binding>
   373   <binding id="button-repeat" display="xul:autorepeatbutton"
   374            extends="chrome://global/content/bindings/button.xml#button"/>
   376 </bindings>

mercurial