toolkit/content/widgets/tabbox.xml

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:9752308b3552
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/. -->
5
6
7 <bindings id="tabBindings"
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">
11
12 <binding id="tab-base">
13 <resources>
14 <stylesheet src="chrome://global/skin/tabbox.css"/>
15 </resources>
16 </binding>
17
18 <binding id="tabbox"
19 extends="chrome://global/content/bindings/tabbox.xml#tab-base">
20 <implementation implements="nsIDOMEventListener">
21 <property name="handleCtrlTab">
22 <setter>
23 <![CDATA[
24 this.setAttribute("handleCtrlTab", val);
25 return val;
26 ]]>
27 </setter>
28 <getter>
29 <![CDATA[
30 return (this.getAttribute("handleCtrlTab") != "false");
31 ]]>
32 </getter>
33 </property>
34
35 <property name="handleCtrlPageUpDown">
36 <setter>
37 <![CDATA[
38 this.setAttribute("handleCtrlPageUpDown", val);
39 return val;
40 ]]>
41 </setter>
42 <getter>
43 <![CDATA[
44 return (this.getAttribute("handleCtrlPageUpDown") != "false");
45 ]]>
46 </getter>
47 </property>
48
49 <field name="_handleMetaAltArrows" readonly="true">
50 #ifdef XP_MACOSX
51 true
52 #else
53 false
54 #endif
55 </field>
56
57 <!-- _tabs and _tabpanels are deprecated, they exist only for
58 backwards compatibility. -->
59 <property name="_tabs" readonly="true" onget="return this.tabs;"/>
60 <property name="_tabpanels" readonly="true" onget="return this.tabpanels;"/>
61
62 <property name="tabs" readonly="true">
63 <getter>
64 <![CDATA[
65 return this.getElementsByTagNameNS(
66 "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
67 "tabs").item(0);
68 ]]>
69 </getter>
70 </property>
71
72 <property name="tabpanels" readonly="true">
73 <getter>
74 <![CDATA[
75 return this.getElementsByTagNameNS(
76 "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
77 "tabpanels").item(0);
78 ]]>
79 </getter>
80 </property>
81
82 <property name="selectedIndex">
83 <getter>
84 <![CDATA[
85 var tabs = this.tabs;
86 return tabs ? tabs.selectedIndex : -1;
87 ]]>
88 </getter>
89
90 <setter>
91 <![CDATA[
92 var tabs = this.tabs;
93 if (tabs)
94 tabs.selectedIndex = val;
95 this.setAttribute("selectedIndex", val);
96 return val;
97 ]]>
98 </setter>
99 </property>
100
101 <property name="selectedTab">
102 <getter>
103 <![CDATA[
104 var tabs = this.tabs;
105 return tabs && tabs.selectedItem;
106 ]]>
107 </getter>
108
109 <setter>
110 <![CDATA[
111 if (val) {
112 var tabs = this.tabs;
113 if (tabs)
114 tabs.selectedItem = val;
115 }
116 return val;
117 ]]>
118 </setter>
119 </property>
120
121 <property name="selectedPanel">
122 <getter>
123 <![CDATA[
124 var tabpanels = this.tabpanels;
125 return tabpanels && tabpanels.selectedPanel;
126 ]]>
127 </getter>
128
129 <setter>
130 <![CDATA[
131 if (val) {
132 var tabpanels = this.tabpanels;
133 if (tabpanels)
134 tabpanels.selectedPanel = val;
135 }
136 return val;
137 ]]>
138 </setter>
139 </property>
140
141 <method name="handleEvent">
142 <parameter name="event"/>
143 <body>
144 <![CDATA[
145 if (!event.isTrusted) {
146 // Don't let untrusted events mess with tabs.
147 return;
148 }
149
150 switch (event.keyCode) {
151 case event.DOM_VK_TAB:
152 if (event.ctrlKey && !event.altKey && !event.metaKey)
153 if (this.tabs && this.handleCtrlTab) {
154 this.tabs.advanceSelectedTab(event.shiftKey ? -1 : 1, true);
155 event.stopPropagation();
156 event.preventDefault();
157 }
158 break;
159 case event.DOM_VK_PAGE_UP:
160 if (event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey)
161 if (this.tabs && this.handleCtrlPageUpDown) {
162 this.tabs.advanceSelectedTab(-1, true);
163 event.stopPropagation();
164 event.preventDefault();
165 }
166 break;
167 case event.DOM_VK_PAGE_DOWN:
168 if (event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey)
169 if (this.tabs && this.handleCtrlPageUpDown) {
170 this.tabs.advanceSelectedTab(1, true);
171 event.stopPropagation();
172 event.preventDefault();
173 }
174 break;
175 case event.DOM_VK_LEFT:
176 if (event.metaKey && event.altKey && !event.shiftKey && !event.ctrlKey)
177 if (this.tabs && this._handleMetaAltArrows) {
178 var offset = window.getComputedStyle(this, "")
179 .direction == "ltr" ? -1 : 1;
180 this.tabs.advanceSelectedTab(offset, true);
181 event.stopPropagation();
182 event.preventDefault();
183 }
184 break;
185 case event.DOM_VK_RIGHT:
186 if (event.metaKey && event.altKey && !event.shiftKey && !event.ctrlKey)
187 if (this.tabs && this._handleMetaAltArrows) {
188 var offset = window.getComputedStyle(this, "")
189 .direction == "ltr" ? 1 : -1;
190 this.tabs.advanceSelectedTab(offset, true);
191 event.stopPropagation();
192 event.preventDefault();
193 }
194 break;
195 }
196 ]]>
197 </body>
198 </method>
199
200 <field name="_eventNode">this</field>
201
202 <property name="eventNode" onget="return this._eventNode;">
203 <setter>
204 <![CDATA[
205 if (val != this._eventNode) {
206 val.addEventListener("keypress", this, false);
207 this._eventNode.removeEventListener("keypress", this, false);
208 this._eventNode = val;
209 }
210 return val;
211 ]]>
212 </setter>
213 </property>
214
215 <constructor>
216 switch (this.getAttribute("eventnode")) {
217 case "parent": this._eventNode = this.parentNode; break;
218 case "window": this._eventNode = window; break;
219 case "document": this._eventNode = document; break;
220 }
221 this._eventNode.addEventListener("keypress", this, false);
222 </constructor>
223
224 <destructor>
225 this._eventNode.removeEventListener("keypress", this, false);
226 </destructor>
227 </implementation>
228 </binding>
229
230 <binding id="tabs" role="xul:tabs"
231 extends="chrome://global/content/bindings/general.xml#basecontrol">
232 <resources>
233 <stylesheet src="chrome://global/skin/tabbox.css"/>
234 </resources>
235
236 <content>
237 <xul:spacer class="tabs-left"/>
238 <children/>
239 <xul:spacer class="tabs-right" flex="1"/>
240 </content>
241
242 <implementation implements="nsIDOMXULSelectControlElement, nsIDOMXULRelatedElement">
243 <constructor>
244 <![CDATA[
245 // first and last tabs need to be able to have unique styles
246 // and also need to select first tab on startup.
247 if (this.firstChild)
248 this.firstChild.setAttribute("first-tab", "true");
249 if (this.lastChild)
250 this.lastChild.setAttribute("last-tab", "true");
251
252 if (!this.hasAttribute("orient"))
253 this.setAttribute("orient", "horizontal");
254
255 if (this.tabbox && this.tabbox.hasAttribute("selectedIndex")) {
256 let selectedIndex = parseInt(this.tabbox.getAttribute("selectedIndex"));
257 this.selectedIndex = selectedIndex > 0 ? selectedIndex : 0;
258 return;
259 }
260
261 var children = this.childNodes;
262 var length = children.length;
263 for (var i = 0; i < length; i++) {
264 if (children[i].getAttribute("selected") == "true") {
265 this.selectedIndex = i;
266 return;
267 }
268 }
269
270 var value = this.value;
271 if (value)
272 this.value = value;
273 else
274 this.selectedIndex = 0;
275 ]]>
276 </constructor>
277
278 <!-- nsIDOMXULRelatedElement -->
279 <method name="getRelatedElement">
280 <parameter name="aTabElm"/>
281 <body>
282 <![CDATA[
283 if (!aTabElm)
284 return null;
285
286 let tabboxElm = this.tabbox;
287 if (!tabboxElm)
288 return null;
289
290 let tabpanelsElm = tabboxElm.tabpanels;
291 if (!tabpanelsElm)
292 return null;
293
294 // Get linked tab panel by 'linkedpanel' attribute on the given tab
295 // element.
296 let linkedPanelElm = null;
297
298 let linkedPanelId = aTabElm.linkedPanel;
299 if (linkedPanelId) {
300 let ownerDoc = this.ownerDocument;
301
302 // XXX bug 565858: if XUL tab element is anonymous element then
303 // suppose linked tab panel is hosted within the same XBL binding
304 // and search it by ID attribute inside an anonymous content of
305 // the binding. This is not robust assumption since tab elements may
306 // live outside a tabbox element so that for example tab elements
307 // can be explicit content but tab panels can be anonymous.
308
309 let bindingParent = ownerDoc.getBindingParent(aTabElm);
310 if (bindingParent)
311 return ownerDoc.getAnonymousElementByAttribute(bindingParent,
312 "id",
313 linkedPanelId);
314
315 return ownerDoc.getElementById(linkedPanelId);
316 }
317
318 // otherwise linked tabpanel element has the same index as the given
319 // tab element.
320 let tabElmIdx = this.getIndexOfItem(aTabElm);
321 return tabpanelsElm.childNodes[tabElmIdx];
322 ]]>
323 </body>
324 </method>
325
326 <!-- nsIDOMXULSelectControlElement -->
327 <property name="itemCount" readonly="true"
328 onget="return this.childNodes.length"/>
329
330 <property name="value" onget="return this.getAttribute('value');">
331 <setter>
332 <![CDATA[
333 this.setAttribute("value", val);
334 var children = this.childNodes;
335 for (var c = children.length - 1; c >= 0; c--) {
336 if (children[c].value == val) {
337 this.selectedIndex = c;
338 break;
339 }
340 }
341 return val;
342 ]]>
343 </setter>
344 </property>
345
346 <field name="tabbox" readonly="true"><![CDATA[
347 var parent = this.parentNode;
348 while (parent) {
349 if (parent.localName == "tabbox")
350 break;
351 parent = parent.parentNode;
352 }
353 parent;
354 ]]></field>
355
356 <!-- _tabbox is deprecated, it exists only for backwards compatibility. -->
357 <field name="_tabbox" readonly="true"><![CDATA[
358 this.tabbox;
359 ]]></field>
360
361 <property name="selectedIndex">
362 <getter>
363 <![CDATA[
364 const tabs = this.childNodes;
365 for (var i = 0; i < tabs.length; i++) {
366 if (tabs[i].selected)
367 return i;
368 }
369 return -1;
370 ]]>
371 </getter>
372
373 <setter>
374 <![CDATA[
375 var tab = this.getItemAtIndex(val);
376 if (tab) {
377 var alreadySelected = tab.selected;
378
379 Array.forEach(this.childNodes, function (aTab) {
380 if (aTab.selected && aTab != tab)
381 aTab._selected = false;
382 });
383 tab._selected = true;
384
385 this.setAttribute("value", tab.value);
386
387 let linkedPanel = this.getRelatedElement(tab);
388 if (linkedPanel) {
389 this.tabbox.setAttribute("selectedIndex", val);
390
391 // This will cause an onselect event to fire for the tabpanel
392 // element.
393 this.tabbox.tabpanels.selectedPanel = linkedPanel;
394 }
395
396 if (!alreadySelected) {
397 // Fire an onselect event for the tabs element.
398 var event = document.createEvent('Events');
399 event.initEvent('select', true, true);
400 this.dispatchEvent(event);
401 }
402 }
403 return val;
404 ]]>
405 </setter>
406 </property>
407
408 <property name="selectedItem">
409 <getter>
410 <![CDATA[
411 const tabs = this.childNodes;
412 for (var i = 0; i < tabs.length; i++) {
413 if (tabs[i].selected)
414 return tabs[i];
415 }
416 return null;
417 ]]>
418 </getter>
419
420 <setter>
421 <![CDATA[
422 if (val && !val.selected)
423 // The selectedIndex setter ignores invalid values
424 // such as -1 if |val| isn't one of our child nodes.
425 this.selectedIndex = this.getIndexOfItem(val);
426 return val;
427 ]]>
428 </setter>
429 </property>
430
431 <method name="getIndexOfItem">
432 <parameter name="item"/>
433 <body>
434 <![CDATA[
435 return Array.indexOf(this.childNodes, item);
436 ]]>
437 </body>
438 </method>
439
440 <method name="getItemAtIndex">
441 <parameter name="index"/>
442 <body>
443 <![CDATA[
444 return this.childNodes.item(index);
445 ]]>
446 </body>
447 </method>
448
449 <method name="_selectNewTab">
450 <parameter name="aNewTab"/>
451 <parameter name="aFallbackDir"/>
452 <parameter name="aWrap"/>
453 <body>
454 <![CDATA[
455 var requestedTab = aNewTab;
456 while (aNewTab.hidden || aNewTab.disabled || !this._canAdvanceToTab(aNewTab)) {
457 aNewTab = aFallbackDir == -1 ? aNewTab.previousSibling : aNewTab.nextSibling;
458 if (!aNewTab && aWrap)
459 aNewTab = aFallbackDir == -1 ? this.childNodes[this.childNodes.length - 1] :
460 this.childNodes[0];
461 if (!aNewTab || aNewTab == requestedTab)
462 return;
463 }
464
465 var isTabFocused = false;
466 try {
467 isTabFocused =
468 (document.commandDispatcher.focusedElement == this.selectedItem);
469 } catch (e) {}
470 this.selectedItem = aNewTab;
471 if (isTabFocused) {
472 aNewTab.focus();
473 }
474 else if (this.getAttribute("setfocus") != "false") {
475 let selectedPanel = this.tabbox.selectedPanel;
476 document.commandDispatcher.advanceFocusIntoSubtree(selectedPanel);
477
478 // Make sure that the focus doesn't move outside the tabbox
479 if (this.tabbox) {
480 try {
481 let el = document.commandDispatcher.focusedElement;
482 while (el && el != this.tabbox.tabpanels) {
483 if (el == this.tabbox || el == selectedPanel)
484 return;
485 el = el.parentNode;
486 }
487 aNewTab.focus();
488 } catch(e) {
489 }
490 }
491 }
492 ]]>
493 </body>
494 </method>
495
496 <method name="_canAdvanceToTab">
497 <parameter name="aTab"/>
498 <body>
499 <![CDATA[
500 return true;
501 ]]>
502 </body>
503 </method>
504
505 <method name="advanceSelectedTab">
506 <parameter name="aDir"/>
507 <parameter name="aWrap"/>
508 <body>
509 <![CDATA[
510 var startTab = this.selectedItem;
511 var next = startTab[aDir == -1 ? "previousSibling" : "nextSibling"];
512 if (!next && aWrap) {
513 next = aDir == -1 ? this.childNodes[this.childNodes.length - 1] :
514 this.childNodes[0];
515 }
516 if (next && next != startTab) {
517 this._selectNewTab(next, aDir, aWrap);
518 }
519 ]]>
520 </body>
521 </method>
522
523 <method name="appendItem">
524 <parameter name="label"/>
525 <parameter name="value"/>
526 <body>
527 <![CDATA[
528 var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
529 var tab = document.createElementNS(XULNS, "tab");
530 tab.setAttribute("label", label);
531 tab.setAttribute("value", value);
532 this.appendChild(tab);
533 return tab;
534 ]]>
535 </body>
536 </method>
537
538 <method name="insertItemAt">
539 <parameter name="index"/>
540 <parameter name="label"/>
541 <parameter name="value"/>
542 <body>
543 <![CDATA[
544 var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
545 var tab = document.createElementNS(XULNS, "tab");
546 tab.setAttribute("label", label);
547 tab.setAttribute("value", value);
548 var before = this.getItemAtIndex(index);
549 if (before)
550 this.insertBefore(tab, before);
551 else
552 this.appendChild(tab);
553 return tab;
554 ]]>
555 </body>
556 </method>
557
558 <method name="removeItemAt">
559 <parameter name="index"/>
560 <body>
561 <![CDATA[
562 var remove = this.getItemAtIndex(index);
563 if (remove)
564 this.removeChild(remove);
565 return remove;
566 ]]>
567 </body>
568 </method>
569 </implementation>
570
571 #ifdef MOZ_WIDGET_GTK
572 <handlers>
573 <handler event="DOMMouseScroll">
574 <![CDATA[
575 if (event.detail > 0)
576 this.advanceSelectedTab(1, false);
577 else
578 this.advanceSelectedTab(-1, false);
579
580 event.stopPropagation();
581 ]]>
582 </handler>
583 </handlers>
584 #endif
585 </binding>
586
587 <binding id="tabpanels" role="xul:tabpanels"
588 extends="chrome://global/content/bindings/tabbox.xml#tab-base">
589 <implementation implements="nsIDOMXULRelatedElement">
590 <!-- nsIDOMXULRelatedElement -->
591 <method name="getRelatedElement">
592 <parameter name="aTabPanelElm"/>
593 <body>
594 <![CDATA[
595 if (!aTabPanelElm)
596 return null;
597
598 let tabboxElm = this.tabbox;
599 if (!tabboxElm)
600 return null;
601
602 let tabsElm = tabboxElm.tabs;
603 if (!tabsElm)
604 return null;
605
606 // Return tab element having 'linkedpanel' attribute equal to the id
607 // of the tab panel or the same index as the tab panel element.
608 let tabpanelIdx = Array.indexOf(this.childNodes, aTabPanelElm);
609 if (tabpanelIdx == -1)
610 return null;
611
612 let tabElms = tabsElm.childNodes;
613 let tabElmFromIndex = tabElms[tabpanelIdx];
614
615 let tabpanelId = aTabPanelElm.id;
616 if (tabpanelId) {
617 for (let idx = 0; idx < tabElms.length; idx++) {
618 var tabElm = tabElms[idx];
619 if (tabElm.linkedPanel == tabpanelId)
620 return tabElm;
621 }
622 }
623
624 return tabElmFromIndex;
625 ]]>
626 </body>
627 </method>
628
629 <!-- public -->
630 <field name="tabbox" readonly="true"><![CDATA[
631 var parent = this.parentNode;
632 while (parent) {
633 if (parent.localName == "tabbox")
634 break;
635 parent = parent.parentNode;
636 }
637 parent;
638 ]]></field>
639
640 <field name="_selectedPanel">this.childNodes.item(this.selectedIndex)</field>
641
642 <property name="selectedIndex">
643 <getter>
644 <![CDATA[
645 var indexStr = this.getAttribute("selectedIndex");
646 return indexStr ? parseInt(indexStr) : -1;
647 ]]>
648 </getter>
649
650 <setter>
651 <![CDATA[
652 if (val < 0 || val >= this.childNodes.length)
653 return val;
654 var panel = this._selectedPanel;
655 this._selectedPanel = this.childNodes[val];
656 this.setAttribute("selectedIndex", val);
657 if (this._selectedPanel != panel) {
658 var event = document.createEvent("Events");
659 event.initEvent("select", true, true);
660 this.dispatchEvent(event);
661 }
662 return val;
663 ]]>
664 </setter>
665 </property>
666
667 <property name="selectedPanel">
668 <getter>
669 <![CDATA[
670 return this._selectedPanel;
671 ]]>
672 </getter>
673
674 <setter>
675 <![CDATA[
676 var selectedIndex = -1;
677 for (var panel = val; panel != null; panel = panel.previousSibling)
678 ++selectedIndex;
679 this.selectedIndex = selectedIndex;
680 return val;
681 ]]>
682 </setter>
683 </property>
684 </implementation>
685 </binding>
686
687 <binding id="tab" display="xul:button" role="xul:tab"
688 extends="chrome://global/content/bindings/general.xml#control-item">
689 <resources>
690 <stylesheet src="chrome://global/skin/tabbox.css"/>
691 </resources>
692
693 <content>
694 <xul:hbox class="tab-middle box-inherit" xbl:inherits="align,dir,pack,orient,selected" flex="1">
695 <xul:image class="tab-icon"
696 xbl:inherits="validate,src=image"
697 role="presentation"/>
698 <xul:label class="tab-text"
699 xbl:inherits="value=label,accesskey,crop,disabled"
700 flex="1"
701 role="presentation"/>
702 </xul:hbox>
703 </content>
704
705 <implementation implements="nsIDOMXULSelectControlItemElement">
706 <property name="control" readonly="true">
707 <getter>
708 <![CDATA[
709 var parent = this.parentNode;
710 if (parent instanceof Components.interfaces.nsIDOMXULSelectControlElement)
711 return parent;
712 return null;
713 ]]>
714 </getter>
715 </property>
716
717 <property name="selected" readonly="true"
718 onget="return this.getAttribute('selected') == 'true';"/>
719
720 <property name="_selected">
721 <setter>
722 <![CDATA[
723 if (val)
724 this.setAttribute("selected", "true");
725 else
726 this.removeAttribute("selected");
727
728 if (this.previousSibling && this.previousSibling.localName == "tab") {
729 if (val)
730 this.previousSibling.setAttribute("beforeselected", "true");
731 else
732 this.previousSibling.removeAttribute("beforeselected");
733 this.removeAttribute("first-tab");
734 }
735 else
736 this.setAttribute("first-tab", "true");
737
738 if (this.nextSibling && this.nextSibling.localName == "tab") {
739 if (val)
740 this.nextSibling.setAttribute("afterselected", "true");
741 else
742 this.nextSibling.removeAttribute("afterselected");
743 this.removeAttribute("last-tab");
744 }
745 else
746 this.setAttribute("last-tab", "true");
747 return val;
748 ]]>
749 </setter>
750 </property>
751
752 <property name="linkedPanel" onget="return this.getAttribute('linkedpanel')"
753 onset="this.setAttribute('linkedpanel', val); return val;"/>
754
755 <field name="arrowKeysShouldWrap" readonly="true">
756 #ifdef XP_MACOSX
757 true
758 #else
759 false
760 #endif
761 </field>
762 <field name="TelemetryStopwatch" readonly="true">
763 let tmp = {};
764 Cu.import("resource://gre/modules/TelemetryStopwatch.jsm", tmp);
765 tmp.TelemetryStopwatch;
766 </field>
767 </implementation>
768
769 <handlers>
770 <handler event="mousedown" button="0">
771 <![CDATA[
772 if (this.disabled)
773 return;
774
775 if (this != this.parentNode.selectedItem) { // Not selected yet
776 let stopwatchid = this.parentNode.getAttribute("stopwatchid");
777 if (stopwatchid) {
778 this.TelemetryStopwatch.start(stopwatchid);
779 }
780
781 // Call this before setting the 'ignorefocus' attribute because this
782 // will pass on focus if the formerly selected tab was focused as well.
783 this.parentNode._selectNewTab(this);
784
785 var isTabFocused = false;
786 try {
787 isTabFocused = (document.commandDispatcher.focusedElement == this);
788 } catch (e) {}
789
790 // Set '-moz-user-focus' to 'ignore' so that PostHandleEvent() can't
791 // focus the tab; we only want tabs to be focusable by the mouse if
792 // they are already focused. After a short timeout we'll reset
793 // '-moz-user-focus' so that tabs can be focused by keyboard again.
794 if (!isTabFocused) {
795 this.setAttribute("ignorefocus", "true");
796 setTimeout(function (tab) tab.removeAttribute("ignorefocus"), 0, this);
797 }
798
799 if (stopwatchid) {
800 this.TelemetryStopwatch.finish(stopwatchid);
801 }
802 }
803 // Otherwise this tab is already selected and we will fall
804 // through to mousedown behavior which sets focus on the current tab,
805 // Only a click on an already selected tab should focus the tab itself.
806 ]]>
807 </handler>
808
809 <handler event="keypress" keycode="VK_LEFT">
810 <![CDATA[
811 var direction = window.getComputedStyle(this.parentNode, null).direction;
812 this.parentNode.advanceSelectedTab(direction == 'ltr' ? -1 : 1, this.arrowKeysShouldWrap);
813 ]]>
814 </handler>
815
816 <handler event="keypress" keycode="VK_RIGHT">
817 <![CDATA[
818 var direction = window.getComputedStyle(this.parentNode, null).direction;
819 this.parentNode.advanceSelectedTab(direction == 'ltr' ? 1 : -1, this.arrowKeysShouldWrap);
820 ]]>
821 </handler>
822
823 <handler event="keypress" keycode="VK_UP">
824 <![CDATA[
825 this.parentNode.advanceSelectedTab(-1, this.arrowKeysShouldWrap);
826 ]]>
827 </handler>
828
829 <handler event="keypress" keycode="VK_DOWN">
830 <![CDATA[
831 this.parentNode.advanceSelectedTab(1, this.arrowKeysShouldWrap);
832 ]]>
833 </handler>
834
835 <handler event="keypress" keycode="VK_HOME">
836 <![CDATA[
837 this.parentNode._selectNewTab(this.parentNode.childNodes[0]);
838 ]]>
839 </handler>
840
841 <handler event="keypress" keycode="VK_END">
842 <![CDATA[
843 var tabs = this.parentNode.childNodes;
844 this.parentNode._selectNewTab(tabs[tabs.length - 1], -1);
845 ]]>
846 </handler>
847 </handlers>
848 </binding>
849
850 </bindings>
851

mercurial