OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 25 matching lines...) Expand all Loading... | |
36 super(true); | 36 super(true); |
37 this.registerRequiredCSS('ui/tabbedPane.css'); | 37 this.registerRequiredCSS('ui/tabbedPane.css'); |
38 this.element.classList.add('tabbed-pane'); | 38 this.element.classList.add('tabbed-pane'); |
39 this.contentElement.classList.add('tabbed-pane-shadow'); | 39 this.contentElement.classList.add('tabbed-pane-shadow'); |
40 this.contentElement.tabIndex = -1; | 40 this.contentElement.tabIndex = -1; |
41 this._headerElement = this.contentElement.createChild('div', 'tabbed-pane-he ader'); | 41 this._headerElement = this.contentElement.createChild('div', 'tabbed-pane-he ader'); |
42 this._headerContentsElement = this._headerElement.createChild('div', 'tabbed -pane-header-contents'); | 42 this._headerContentsElement = this._headerElement.createChild('div', 'tabbed -pane-header-contents'); |
43 this._tabSlider = createElementWithClass('div', 'tabbed-pane-tab-slider'); | 43 this._tabSlider = createElementWithClass('div', 'tabbed-pane-tab-slider'); |
44 this._tabsElement = this._headerContentsElement.createChild('div', 'tabbed-p ane-header-tabs'); | 44 this._tabsElement = this._headerContentsElement.createChild('div', 'tabbed-p ane-header-tabs'); |
45 this._tabsElement.setAttribute('role', 'tablist'); | 45 this._tabsElement.setAttribute('role', 'tablist'); |
46 this._tabsElement.addEventListener('keydown', this._keyDown.bind(this), fals e); | |
46 this._contentElement = this.contentElement.createChild('div', 'tabbed-pane-c ontent'); | 47 this._contentElement = this.contentElement.createChild('div', 'tabbed-pane-c ontent'); |
47 this._contentElement.setAttribute('role', 'tabpanel'); | 48 this._contentElement.setAttribute('role', 'tabpanel'); |
48 this._contentElement.createChild('content'); | 49 this._contentElement.createChild('content'); |
49 /** @type {!Array.<!UI.TabbedPaneTab>} */ | 50 /** @type {!Array.<!UI.TabbedPaneTab>} */ |
50 this._tabs = []; | 51 this._tabs = []; |
51 /** @type {!Array.<!UI.TabbedPaneTab>} */ | 52 /** @type {!Array.<!UI.TabbedPaneTab>} */ |
52 this._tabsHistory = []; | 53 this._tabsHistory = []; |
53 /** @type {!Map<string, !UI.TabbedPaneTab>} */ | 54 /** @type {!Map<string, !UI.TabbedPaneTab>} */ |
54 this._tabsById = new Map(); | 55 this._tabsById = new Map(); |
55 this._currentTabLocked = false; | 56 this._currentTabLocked = false; |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
536 */ | 537 */ |
537 _hideTabElement(tab) { | 538 _hideTabElement(tab) { |
538 this._tabsElement.removeChild(tab.tabElement); | 539 this._tabsElement.removeChild(tab.tabElement); |
539 tab._shown = false; | 540 tab._shown = false; |
540 } | 541 } |
541 | 542 |
542 _createDropDownButton() { | 543 _createDropDownButton() { |
543 var dropDownContainer = createElementWithClass('div', 'tabbed-pane-header-ta bs-drop-down-container'); | 544 var dropDownContainer = createElementWithClass('div', 'tabbed-pane-header-ta bs-drop-down-container'); |
544 var chevronIcon = UI.Icon.create('largeicon-chevron', 'chevron-icon'); | 545 var chevronIcon = UI.Icon.create('largeicon-chevron', 'chevron-icon'); |
545 dropDownContainer.appendChild(chevronIcon); | 546 dropDownContainer.appendChild(chevronIcon); |
547 dropDownContainer.addEventListener('click', this._onDropDownMouseDown.bind(t his)); | |
aboxhall
2017/04/12 07:25:06
Do we need to make sure we don't run all this code
einbinder
2017/04/17 21:46:39
The ContextMenu consumes the mousedown event if it
aboxhall
2017/04/17 23:03:36
Oh right :)
| |
546 dropDownContainer.addEventListener('mousedown', this._onDropDownMouseDown.bi nd(this)); | 548 dropDownContainer.addEventListener('mousedown', this._onDropDownMouseDown.bi nd(this)); |
547 return dropDownContainer; | 549 return dropDownContainer; |
548 } | 550 } |
549 | 551 |
550 /** | 552 /** |
551 * @param {!Event} event | 553 * @param {!Event} event |
552 */ | 554 */ |
553 _onDropDownMouseDown(event) { | 555 _onDropDownMouseDown(event) { |
554 if (event.which !== 1) | 556 if (event.which !== 1) |
555 return; | 557 return; |
556 var menu = new UI.ContextMenu(event); | 558 var x = event.x; |
559 var y = event.y; | |
560 // This wasn't a mouse event, manually set the position | |
aboxhall
2017/04/12 07:25:06
Can we just do this normally? It doesn't seem like
einbinder
2017/04/17 21:46:39
Done.
| |
561 if (!x && !y) { | |
562 var rect = this._dropDownButton.getBoundingClientRect(); | |
563 x = (rect.left + rect.right) / 2; | |
564 y = (rect.top + rect.bottom) / 2; | |
565 } | |
566 var menu = new UI.ContextMenu(event, false, x, y); | |
557 for (var i = 0; i < this._tabs.length; ++i) { | 567 for (var i = 0; i < this._tabs.length; ++i) { |
558 var tab = this._tabs[i]; | 568 var tab = this._tabs[i]; |
559 if (tab._shown) | 569 if (tab._shown) |
560 continue; | 570 continue; |
561 menu.appendCheckboxItem(tab.title, this._dropDownMenuItemSelected.bind(thi s, tab), this._tabsHistory[0] === tab); | 571 menu.appendCheckboxItem(tab.title, this._dropDownMenuItemSelected.bind(thi s, tab), this._tabsHistory[0] === tab); |
562 } | 572 } |
563 menu.show(); | 573 menu.show(); |
564 } | 574 } |
565 | 575 |
566 /** | 576 /** |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
749 return; | 759 return; |
750 | 760 |
751 this._hideTab(this._currentTab); | 761 this._hideTab(this._currentTab); |
752 delete this._currentTab; | 762 delete this._currentTab; |
753 } | 763 } |
754 | 764 |
755 /** | 765 /** |
756 * @param {!UI.TabbedPaneTab} tab | 766 * @param {!UI.TabbedPaneTab} tab |
757 */ | 767 */ |
758 _showTab(tab) { | 768 _showTab(tab) { |
769 tab.tabElement.tabIndex = 0; | |
759 tab.tabElement.classList.add('selected'); | 770 tab.tabElement.classList.add('selected'); |
760 UI.ARIAUtils.setSelected(tab.tabElement, true); | 771 UI.ARIAUtils.setSelected(tab.tabElement, true); |
761 tab.view.show(this.element); | 772 tab.view.show(this.element); |
762 this._updateTabSlider(); | 773 this._updateTabSlider(); |
763 } | 774 } |
764 | 775 |
765 _updateTabSlider() { | 776 _updateTabSlider() { |
766 if (!this._currentTab || !this._sliderEnabled) | 777 if (!this._currentTab || !this._sliderEnabled) |
767 return; | 778 return; |
768 var left = 0; | 779 var left = 0; |
769 for (var i = 0; i < this._tabs.length && this._currentTab !== this._tabs[i] && this._tabs[i]._shown; i++) | 780 for (var i = 0; i < this._tabs.length && this._currentTab !== this._tabs[i] && this._tabs[i]._shown; i++) |
770 left += this._tabs[i]._measuredWidth; | 781 left += this._tabs[i]._measuredWidth; |
771 var sliderWidth = this._currentTab._shown ? this._currentTab._measuredWidth : this._dropDownButton.offsetWidth; | 782 var sliderWidth = this._currentTab._shown ? this._currentTab._measuredWidth : this._dropDownButton.offsetWidth; |
772 var scaleFactor = window.devicePixelRatio >= 1.5 ? ' scaleY(0.75)' : ''; | 783 var scaleFactor = window.devicePixelRatio >= 1.5 ? ' scaleY(0.75)' : ''; |
773 this._tabSlider.style.transform = 'translateX(' + left + 'px)' + scaleFactor ; | 784 this._tabSlider.style.transform = 'translateX(' + left + 'px)' + scaleFactor ; |
774 this._tabSlider.style.width = sliderWidth + 'px'; | 785 this._tabSlider.style.width = sliderWidth + 'px'; |
775 | 786 |
776 if (this._tabSlider.parentElement !== this._headerContentsElement) | 787 if (this._tabSlider.parentElement !== this._headerContentsElement) |
777 this._headerContentsElement.appendChild(this._tabSlider); | 788 this._headerContentsElement.appendChild(this._tabSlider); |
778 } | 789 } |
779 | 790 |
780 /** | 791 /** |
781 * @param {!UI.TabbedPaneTab} tab | 792 * @param {!UI.TabbedPaneTab} tab |
782 */ | 793 */ |
783 _hideTab(tab) { | 794 _hideTab(tab) { |
795 tab.tabElement.tabIndex = -1; | |
aboxhall
2017/04/12 07:25:06
Can just remove the tabIndex attribute instead (pr
einbinder
2017/04/17 21:46:39
Done.
| |
784 tab.tabElement.classList.remove('selected'); | 796 tab.tabElement.classList.remove('selected'); |
785 tab.tabElement.setAttribute('aria-selected', 'false'); | 797 tab.tabElement.setAttribute('aria-selected', 'false'); |
786 tab.view.detach(); | 798 tab.view.detach(); |
787 } | 799 } |
788 | 800 |
789 /** | 801 /** |
790 * @override | 802 * @override |
791 * @return {!Array.<!Element>} | 803 * @return {!Array.<!Element>} |
792 */ | 804 */ |
793 elementsToRestoreScrollPositionsFor() { | 805 elementsToRestoreScrollPositionsFor() { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
835 } | 847 } |
836 | 848 |
837 /** | 849 /** |
838 * @param {boolean} allow | 850 * @param {boolean} allow |
839 * @param {boolean=} automatic | 851 * @param {boolean=} automatic |
840 */ | 852 */ |
841 setAllowTabReorder(allow, automatic) { | 853 setAllowTabReorder(allow, automatic) { |
842 this._allowTabReorder = allow; | 854 this._allowTabReorder = allow; |
843 this._automaticReorder = automatic; | 855 this._automaticReorder = automatic; |
844 } | 856 } |
857 | |
858 /** | |
859 * @param {!Event} event | |
860 */ | |
861 _keyDown(event) { | |
862 if (!this._currentTab) | |
863 return; | |
864 var nextTab = null; | |
aboxhall
2017/04/12 07:25:06
s/nextTab/nextTabElement/ ?
einbinder
2017/04/17 21:46:39
Done.
| |
865 switch (event.keyCode) { | |
866 case UI.KeyboardShortcut.Keys.Up.code: | |
867 case UI.KeyboardShortcut.Keys.Left.code: | |
868 nextTab = this._currentTab.tabElement.previousElementSibling; | |
869 if (!nextTab && !this._dropDownButton.parentElement) | |
870 nextTab = this._currentTab.tabElement.parentElement.lastElementChild; | |
871 break; | |
872 case UI.KeyboardShortcut.Keys.Down.code: | |
873 case UI.KeyboardShortcut.Keys.Right.code: | |
874 nextTab = this._currentTab.tabElement.nextElementSibling; | |
875 if (!nextTab && !this._dropDownButton.parentElement) | |
876 nextTab = this._currentTab.tabElement.parentElement.firstElementChild; | |
877 break; | |
878 default: | |
879 return; | |
880 } | |
881 if (!nextTab) { | |
882 this._dropDownButton.click(); | |
aboxhall
2017/04/12 07:25:06
This is pretty counter-intuitive - maybe extract t
einbinder
2017/04/17 21:46:39
I need the event to construct the ContextMenu. I t
aboxhall
2017/04/17 23:03:36
Ah, I see. Yeah it's a bit of a hack using a conte
| |
883 return; | |
884 } | |
885 var tab = this._tabs.find(tab => tab.tabElement === nextTab); | |
886 this.selectTab(tab.id, true); | |
887 nextTab.focus(); | |
888 } | |
845 }; | 889 }; |
846 | 890 |
847 /** @enum {symbol} */ | 891 /** @enum {symbol} */ |
848 UI.TabbedPane.Events = { | 892 UI.TabbedPane.Events = { |
849 TabSelected: Symbol('TabSelected'), | 893 TabSelected: Symbol('TabSelected'), |
850 TabClosed: Symbol('TabClosed'), | 894 TabClosed: Symbol('TabClosed'), |
851 TabOrderChanged: Symbol('TabOrderChanged') | 895 TabOrderChanged: Symbol('TabOrderChanged') |
852 }; | 896 }; |
853 | 897 |
854 /** | 898 /** |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1220 * @param {!Array.<string>} ids | 1264 * @param {!Array.<string>} ids |
1221 */ | 1265 */ |
1222 closeTabs(tabbedPane, ids) {}, | 1266 closeTabs(tabbedPane, ids) {}, |
1223 | 1267 |
1224 /** | 1268 /** |
1225 * @param {string} tabId | 1269 * @param {string} tabId |
1226 * @param {!UI.ContextMenu} contextMenu | 1270 * @param {!UI.ContextMenu} contextMenu |
1227 */ | 1271 */ |
1228 onContextMenu(tabId, contextMenu) {} | 1272 onContextMenu(tabId, contextMenu) {} |
1229 }; | 1273 }; |
OLD | NEW |