Wed, 31 Dec 2014 06:09:35 +0100
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>