Chromium Code Reviews| 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 |