Index: third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js b/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js |
index 5f6d835006eb23b7bd4c962b50023784ba7ec52e..f072f058c375c89487ad1f81ab1c93f5e039dc02 100644 |
--- a/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js |
+++ b/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js |
@@ -27,27 +27,25 @@ |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
- |
/** |
- * @extends {WebInspector.VBox} |
- * @constructor |
+ * @unrestricted |
*/ |
-WebInspector.TabbedPane = function() |
-{ |
- WebInspector.VBox.call(this, true); |
- this.registerRequiredCSS("ui/tabbedPane.css"); |
- this.element.classList.add("tabbed-pane"); |
- this.contentElement.classList.add("tabbed-pane-shadow"); |
+WebInspector.TabbedPane = class extends WebInspector.VBox { |
+ constructor() { |
+ super(true); |
+ this.registerRequiredCSS('ui/tabbedPane.css'); |
+ this.element.classList.add('tabbed-pane'); |
+ this.contentElement.classList.add('tabbed-pane-shadow'); |
this.contentElement.tabIndex = -1; |
- this._headerElement = this.contentElement.createChild("div", "tabbed-pane-header"); |
- this._headerContentsElement = this._headerElement.createChild("div", "tabbed-pane-header-contents"); |
- this._headerContentsElement.setAttribute("aria-label", WebInspector.UIString("Panels")); |
- this._tabSlider = createElementWithClass("div", "tabbed-pane-tab-slider"); |
- this._tabsElement = this._headerContentsElement.createChild("div", "tabbed-pane-header-tabs"); |
- this._tabsElement.setAttribute("role", "tablist"); |
- this._contentElement = this.contentElement.createChild("div", "tabbed-pane-content"); |
- this._contentElement.setAttribute("role", "tabpanel"); |
- this._contentElement.createChild("content"); |
+ this._headerElement = this.contentElement.createChild('div', 'tabbed-pane-header'); |
+ this._headerContentsElement = this._headerElement.createChild('div', 'tabbed-pane-header-contents'); |
+ this._headerContentsElement.setAttribute('aria-label', WebInspector.UIString('Panels')); |
+ this._tabSlider = createElementWithClass('div', 'tabbed-pane-tab-slider'); |
+ this._tabsElement = this._headerContentsElement.createChild('div', 'tabbed-pane-header-tabs'); |
+ this._tabsElement.setAttribute('role', 'tablist'); |
+ this._contentElement = this.contentElement.createChild('div', 'tabbed-pane-content'); |
+ this._contentElement.setAttribute('role', 'tabpanel'); |
+ this._contentElement.createChild('content'); |
/** @type {!Array.<!WebInspector.TabbedPaneTab>} */ |
this._tabs = []; |
/** @type {!Array.<!WebInspector.TabbedPaneTab>} */ |
@@ -59,847 +57,801 @@ WebInspector.TabbedPane = function() |
this._dropDownButton = this._createDropDownButton(); |
WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._zoomChanged, this); |
-}; |
- |
-/** @enum {symbol} */ |
-WebInspector.TabbedPane.Events = { |
- TabSelected: Symbol("TabSelected"), |
- TabClosed: Symbol("TabClosed"), |
- TabOrderChanged: Symbol("TabOrderChanged") |
-}; |
- |
-WebInspector.TabbedPane.prototype = { |
- /** |
- * @param {boolean} locked |
- */ |
- setCurrentTabLocked: function(locked) |
- { |
- this._currentTabLocked = locked; |
- this._headerElement.classList.toggle("locked", this._currentTabLocked); |
- }, |
- |
- /** |
- * @param {boolean} autoSelect |
- */ |
- setAutoSelectFirstItemOnShow: function(autoSelect) |
- { |
- this._autoSelectFirstItemOnShow = autoSelect; |
- }, |
- |
- /** |
- * @return {?WebInspector.Widget} |
- */ |
- get visibleView() |
- { |
- return this._currentTab ? this._currentTab.view : null; |
- }, |
- |
- /** |
- * @return {!Array.<string>} |
- */ |
- tabIds: function() |
- { |
- return this._tabs.map(tab => tab._id); |
- }, |
- |
- /** |
- * @param {string} tabId |
- * @return {number} |
- */ |
- tabIndex: function(tabId) |
- { |
- return this._tabs.findIndex(tab => tab.id === tabId); |
- }, |
- |
- /** |
- * @return {!Array.<!WebInspector.Widget>} |
- */ |
- tabViews: function() |
- { |
- return this._tabs.map(tab => tab.view); |
- }, |
- |
- /** |
- * @param {string} tabId |
- * @return {?WebInspector.Widget} |
- */ |
- tabView: function(tabId) |
- { |
- return this._tabsById[tabId] ? this._tabsById[tabId].view : null; |
- }, |
- |
- /** |
- * @return {?string} |
- */ |
- get selectedTabId() |
- { |
- return this._currentTab ? this._currentTab.id : null; |
- }, |
- |
- /** |
- * @param {boolean} shrinkableTabs |
- */ |
- setShrinkableTabs: function(shrinkableTabs) |
- { |
- this._shrinkableTabs = shrinkableTabs; |
- }, |
- |
- /** |
- * @param {boolean} verticalTabLayout |
- */ |
- setVerticalTabLayout: function(verticalTabLayout) |
- { |
- this._verticalTabLayout = verticalTabLayout; |
- this.contentElement.classList.add("vertical-tab-layout"); |
- this.invalidateConstraints(); |
- }, |
- |
- /** |
- * @param {boolean} closeableTabs |
- */ |
- setCloseableTabs: function(closeableTabs) |
- { |
- this._closeableTabs = closeableTabs; |
- }, |
- |
- /** |
- * @override |
- */ |
- focus: function() |
- { |
- if (this.visibleView) |
- this.visibleView.focus(); |
- else |
- this.contentElement.focus(); |
- }, |
- |
- /** |
- * @return {!Element} |
- */ |
- headerElement: function() |
- { |
- return this._headerElement; |
- }, |
- |
- /** |
- * @param {string} id |
- * @return {boolean} |
- */ |
- isTabCloseable: function(id) |
- { |
- var tab = this._tabsById[id]; |
- return tab ? tab.isCloseable() : false; |
- }, |
- |
- /** |
- * @param {!WebInspector.TabbedPaneTabDelegate} delegate |
- */ |
- setTabDelegate: function(delegate) |
- { |
- var tabs = this._tabs.slice(); |
- for (var i = 0; i < tabs.length; ++i) |
- tabs[i].setDelegate(delegate); |
- this._delegate = delegate; |
- }, |
- |
- /** |
- * @param {string} id |
- * @param {string} tabTitle |
- * @param {!WebInspector.Widget} view |
- * @param {string=} tabTooltip |
- * @param {boolean=} userGesture |
- * @param {boolean=} isCloseable |
- * @param {number=} index |
- */ |
- appendTab: function(id, tabTitle, view, tabTooltip, userGesture, isCloseable, index) |
- { |
- isCloseable = typeof isCloseable === "boolean" ? isCloseable : this._closeableTabs; |
- var tab = new WebInspector.TabbedPaneTab(this, id, tabTitle, isCloseable, view, tabTooltip); |
- tab.setDelegate(this._delegate); |
- this._tabsById[id] = tab; |
- if (index !== undefined) |
- this._tabs.splice(index, 0, tab); |
- else |
- this._tabs.push(tab); |
- this._tabsHistory.push(tab); |
- view.attach(this); |
- if (this._tabsHistory[0] === tab && this.isShowing()) |
- this.selectTab(tab.id, userGesture); |
- this._updateTabElements(); |
- }, |
- |
- /** |
- * @param {string} id |
- * @param {boolean=} userGesture |
- */ |
- closeTab: function(id, userGesture) |
- { |
- this.closeTabs([id], userGesture); |
- }, |
- |
- /** |
- * @param {!Array.<string>} ids |
- * @param {boolean=} userGesture |
- */ |
- closeTabs: function(ids, userGesture) |
- { |
- var focused = this.hasFocus(); |
- for (var i = 0; i < ids.length; ++i) |
- this._innerCloseTab(ids[i], userGesture); |
- this._updateTabElements(); |
- if (this._tabsHistory.length) |
- this.selectTab(this._tabsHistory[0].id, false); |
- if (focused) |
- this.focus(); |
- }, |
- |
- /** |
- * @param {string} id |
- * @param {boolean=} userGesture |
- */ |
- _innerCloseTab: function(id, userGesture) |
- { |
- if (!this._tabsById[id]) |
- return; |
- if (userGesture && !this._tabsById[id]._closeable) |
- return; |
- if (this._currentTab && this._currentTab.id === id) |
- this._hideCurrentTab(); |
- |
- var tab = this._tabsById[id]; |
- delete this._tabsById[id]; |
- |
- this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1); |
- this._tabs.splice(this._tabs.indexOf(tab), 1); |
- if (tab._shown) |
- this._hideTabElement(tab); |
- tab.view.detach(); |
- |
- var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture }; |
- this.dispatchEventToListeners(WebInspector.TabbedPane.Events.TabClosed, eventData); |
- return true; |
- }, |
- |
- /** |
- * @param {string} tabId |
- * @return {boolean} |
- */ |
- hasTab: function(tabId) |
- { |
- return !!this._tabsById[tabId]; |
- }, |
- |
- /** |
- * @return {!Array.<string>} |
- */ |
- allTabs: function() |
- { |
- return this._tabs.map(function(tab) { return tab.id; }); |
- }, |
- |
- /** |
- * @param {string} id |
- * @return {!Array.<string>} |
- */ |
- otherTabs: function(id) |
- { |
- var result = []; |
- for (var i = 0; i < this._tabs.length; ++i) { |
- if (this._tabs[i].id !== id) |
- result.push(this._tabs[i].id); |
- } |
- return result; |
- }, |
- |
- /** |
- * @param {string} id |
- * @return {!Array.<string>} |
- */ |
- _tabsToTheRight: function(id) |
- { |
- var index = -1; |
- for (var i = 0; i < this._tabs.length; ++i) { |
- if (this._tabs[i].id === id) { |
- index = i; |
- break; |
- } |
- } |
- if (index === -1) |
- return []; |
- return this._tabs.slice(index + 1).map(function(tab) { return tab.id; }); |
- }, |
- |
- /** |
- * @param {string} id |
- * @param {boolean=} userGesture |
- * @return {boolean} |
- */ |
- selectTab: function(id, userGesture) |
- { |
- if (this._currentTabLocked) |
- return false; |
- var focused = this.hasFocus(); |
- var tab = this._tabsById[id]; |
- if (!tab) |
- return false; |
- if (this._currentTab && this._currentTab.id === id) |
- return true; |
- |
- this.suspendInvalidations(); |
- this._hideCurrentTab(); |
- this._showTab(tab); |
- this.resumeInvalidations(); |
- this._currentTab = tab; |
- |
- this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1); |
- this._tabsHistory.splice(0, 0, tab); |
- |
- this._updateTabElements(); |
- if (focused) |
- this.focus(); |
- |
- var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture }; |
- this.dispatchEventToListeners(WebInspector.TabbedPane.Events.TabSelected, eventData); |
- return true; |
- }, |
- |
- /** |
- * @param {number} tabsCount |
- * @return {!Array.<string>} |
- */ |
- lastOpenedTabIds: function(tabsCount) |
- { |
- function tabToTabId(tab) { |
- return tab.id; |
- } |
- |
- return this._tabsHistory.slice(0, tabsCount).map(tabToTabId); |
- }, |
- |
- /** |
- * @param {string} id |
- * @param {string} iconType |
- * @param {string=} iconTooltip |
- */ |
- setTabIcon: function(id, iconType, iconTooltip) |
- { |
- var tab = this._tabsById[id]; |
- if (tab._setIconType(iconType, iconTooltip)) |
- this._updateTabElements(); |
- }, |
- |
- /** |
- * @param {string} id |
- * @param {boolean} enabled |
- */ |
- setTabEnabled: function(id, enabled) |
- { |
- var tab = this._tabsById[id]; |
- tab.tabElement.classList.toggle("disabled", !enabled); |
- }, |
- |
- /** |
- * @param {string} id |
- * @param {string} className |
- * @param {boolean=} force |
- */ |
- toggleTabClass: function(id, className, force) |
- { |
- var tab = this._tabsById[id]; |
- if (tab._toggleClass(className, force)) |
- this._updateTabElements(); |
- }, |
- |
- /** |
- * @param {!WebInspector.Event} event |
- */ |
- _zoomChanged: function(event) |
- { |
- for (var i = 0; i < this._tabs.length; ++i) |
- delete this._tabs[i]._measuredWidth; |
- if (this.isShowing()) |
- this._updateTabElements(); |
- }, |
- |
- /** |
- * @param {string} id |
- * @param {string} tabTitle |
- * @param {string=} tabTooltip |
- */ |
- changeTabTitle: function(id, tabTitle, tabTooltip) |
- { |
- var tab = this._tabsById[id]; |
- if (tabTooltip !== undefined) |
- tab.tooltip = tabTooltip; |
- if (tab.title !== tabTitle) { |
- tab.title = tabTitle; |
- this._updateTabElements(); |
- } |
- }, |
- |
- /** |
- * @param {string} id |
- * @param {!WebInspector.Widget} view |
- */ |
- changeTabView: function(id, view) |
- { |
- var tab = this._tabsById[id]; |
- if (tab.view === view) |
- return; |
- |
- var shouldFocus = tab.view.hasFocus(); |
- |
- this.suspendInvalidations(); |
- |
- var isSelected = this._currentTab && this._currentTab.id === id; |
- if (isSelected) |
- this._hideTab(tab); |
- tab.view.detach(); |
- tab.view = view; |
- tab.view.attach(this); |
- if (isSelected) |
- this._showTab(tab); |
- if (shouldFocus) |
- tab.view.focus(); |
- |
- this.resumeInvalidations(); |
- }, |
- |
- onResize: function() |
- { |
- this._updateTabElements(); |
- }, |
- |
- headerResized: function() |
- { |
- this._updateTabElements(); |
- }, |
- |
- wasShown: function() |
- { |
- var effectiveTab = this._currentTab || this._tabsHistory[0]; |
- if (effectiveTab && this._autoSelectFirstItemOnShow) |
- this.selectTab(effectiveTab.id); |
- }, |
- |
- /** |
- * @param {boolean} enable |
- */ |
- setTabSlider: function(enable) |
- { |
- this._sliderEnabled = enable; |
- this._tabSlider.classList.toggle("enabled", enable); |
- }, |
- |
- /** |
- * @override |
- * @return {!Constraints} |
- */ |
- calculateConstraints: function() |
- { |
- var constraints = WebInspector.VBox.prototype.calculateConstraints.call(this); |
- var minContentConstraints = new Constraints(new Size(0, 0), new Size(50, 50)); |
- constraints = constraints.widthToMax(minContentConstraints).heightToMax(minContentConstraints); |
- if (this._verticalTabLayout) |
- constraints = constraints.addWidth(new Constraints(new Size(120, 0))); |
- else |
- constraints = constraints.addHeight(new Constraints(new Size(0, 30))); |
- return constraints; |
- }, |
- |
- _updateTabElements: function() |
- { |
- WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateTabElements); |
- }, |
- |
- /** |
- * @param {string} text |
- */ |
- setPlaceholderText: function(text) |
- { |
- this._noTabsMessage = text; |
- }, |
- |
- _innerUpdateTabElements: function() |
- { |
- if (!this.isShowing()) |
- return; |
- |
- if (!this._tabs.length) { |
- this._contentElement.classList.add("has-no-tabs"); |
- if (this._noTabsMessage && !this._noTabsMessageElement) { |
- this._noTabsMessageElement = this._contentElement.createChild("div", "tabbed-pane-placeholder fill"); |
- this._noTabsMessageElement.textContent = this._noTabsMessage; |
- } |
- } else { |
- this._contentElement.classList.remove("has-no-tabs"); |
- if (this._noTabsMessageElement) { |
- this._noTabsMessageElement.remove(); |
- delete this._noTabsMessageElement; |
- } |
- } |
- |
- this._measureDropDownButton(); |
- this._updateWidths(); |
- this._updateTabsDropDown(); |
- this._updateTabSlider(); |
- }, |
- |
- /** |
- * @param {number} index |
- * @param {!WebInspector.TabbedPaneTab} tab |
- */ |
- _showTabElement: function(index, tab) |
- { |
- if (index >= this._tabsElement.children.length) |
- this._tabsElement.appendChild(tab.tabElement); |
- else |
- this._tabsElement.insertBefore(tab.tabElement, this._tabsElement.children[index]); |
- tab._shown = true; |
- }, |
- |
- /** |
- * @param {!WebInspector.TabbedPaneTab} tab |
- */ |
- _hideTabElement: function(tab) |
- { |
- this._tabsElement.removeChild(tab.tabElement); |
- tab._shown = false; |
- }, |
- |
- _createDropDownButton: function() |
- { |
- var dropDownContainer = createElementWithClass("div", "tabbed-pane-header-tabs-drop-down-container"); |
- dropDownContainer.createChild("div", "glyph"); |
- this._dropDownMenu = new WebInspector.DropDownMenu(dropDownContainer); |
- this._dropDownMenu.addEventListener(WebInspector.DropDownMenu.Events.ItemSelected, this._dropDownMenuItemSelected, this); |
- |
- return dropDownContainer; |
- }, |
- |
- /** |
- * @param {!WebInspector.Event} event |
- */ |
- _dropDownMenuItemSelected: function(event) |
- { |
- var tabId = /** @type {string} */ (event.data); |
- this._lastSelectedOverflowTab = this._tabsById[tabId]; |
- this.selectTab(tabId, true); |
- }, |
- |
- _totalWidth: function() |
- { |
- return this._headerContentsElement.getBoundingClientRect().width; |
- }, |
- |
- /** |
- * @return {number} |
- */ |
- _numberOfTabsShown: function() |
- { |
- var numTabsShown = 0; |
- for (var tab of this._tabs) { |
- if (tab._shown) |
- numTabsShown++; |
- } |
- return numTabsShown; |
- }, |
- |
- disableOverflowMenu: function() |
- { |
- this._overflowDisabled = true; |
- }, |
- |
- _updateTabsDropDown: function() |
- { |
- var tabsToShowIndexes = this._tabsToShowIndexes(this._tabs, this._tabsHistory, this._totalWidth(), this._measuredDropDownButtonWidth || 0); |
- if (this._lastSelectedOverflowTab && this._numberOfTabsShown() !== tabsToShowIndexes.length) { |
- delete this._lastSelectedOverflowTab; |
- this._updateTabsDropDown(); |
- return; |
- } |
- |
- for (var i = 0; i < this._tabs.length; ++i) { |
- if (this._tabs[i]._shown && tabsToShowIndexes.indexOf(i) === -1) |
- this._hideTabElement(this._tabs[i]); |
- } |
- for (var i = 0; i < tabsToShowIndexes.length; ++i) { |
- var tab = this._tabs[tabsToShowIndexes[i]]; |
- if (!tab._shown) |
- this._showTabElement(i, tab); |
- } |
- |
- if (!this._overflowDisabled) |
- this._populateDropDownFromIndex(); |
- }, |
- |
- _populateDropDownFromIndex: function() |
- { |
- if (this._dropDownButton.parentElement) |
- this._headerContentsElement.removeChild(this._dropDownButton); |
- |
- this._dropDownMenu.clear(); |
- |
- var tabsToShow = []; |
- for (var i = 0; i < this._tabs.length; ++i) { |
- if (!this._tabs[i]._shown) |
- tabsToShow.push(this._tabs[i]); |
- } |
- |
- var selectedId = null; |
- for (var i = 0; i < tabsToShow.length; ++i) { |
- var tab = tabsToShow[i]; |
- this._dropDownMenu.addItem(tab.id, tab.title); |
- if (this._tabsHistory[0] === tab) |
- selectedId = tab.id; |
- } |
- if (tabsToShow.length) { |
- this._headerContentsElement.appendChild(this._dropDownButton); |
- this._dropDownMenu.selectItem(selectedId); |
- } |
- }, |
- |
- _measureDropDownButton: function() |
- { |
- if (this._overflowDisabled || this._measuredDropDownButtonWidth) |
- return; |
- this._dropDownButton.classList.add("measuring"); |
- this._headerContentsElement.appendChild(this._dropDownButton); |
- this._measuredDropDownButtonWidth = this._dropDownButton.getBoundingClientRect().width; |
- this._headerContentsElement.removeChild(this._dropDownButton); |
- this._dropDownButton.classList.remove("measuring"); |
- }, |
- |
- _updateWidths: function() |
- { |
- var measuredWidths = this._measureWidths(); |
- var maxWidth = this._shrinkableTabs ? this._calculateMaxWidth(measuredWidths.slice(), this._totalWidth()) : Number.MAX_VALUE; |
- |
- var i = 0; |
- for (var tab of this._tabs) |
- tab.setWidth(this._verticalTabLayout ? -1 : Math.min(maxWidth, measuredWidths[i++])); |
- }, |
- |
- _measureWidths: function() |
- { |
- // Add all elements to measure into this._tabsElement |
- this._tabsElement.style.setProperty("width", "2000px"); |
- var measuringTabElements = []; |
- for (var tab of this._tabs) { |
- if (typeof tab._measuredWidth === "number") |
- continue; |
- var measuringTabElement = tab._createTabElement(true); |
- measuringTabElement.__tab = tab; |
- measuringTabElements.push(measuringTabElement); |
- this._tabsElement.appendChild(measuringTabElement); |
- } |
- |
- // Perform measurement |
- for (var i = 0; i < measuringTabElements.length; ++i) { |
- var width = measuringTabElements[i].getBoundingClientRect().width; |
- measuringTabElements[i].__tab._measuredWidth = Math.ceil(width); |
- } |
- |
- // Nuke elements from the UI |
- for (var i = 0; i < measuringTabElements.length; ++i) |
- measuringTabElements[i].remove(); |
- |
- // Combine the results. |
- var measuredWidths = []; |
- for (var tab of this._tabs) |
- measuredWidths.push(tab._measuredWidth); |
- this._tabsElement.style.removeProperty("width"); |
- |
- return measuredWidths; |
- }, |
- |
- /** |
- * @param {!Array.<number>} measuredWidths |
- * @param {number} totalWidth |
- */ |
- _calculateMaxWidth: function(measuredWidths, totalWidth) |
- { |
- if (!measuredWidths.length) |
- return 0; |
- |
- measuredWidths.sort(function(x, y) { return x - y; }); |
- |
- var totalMeasuredWidth = 0; |
- for (var i = 0; i < measuredWidths.length; ++i) |
- totalMeasuredWidth += measuredWidths[i]; |
+ } |
+ |
+ /** |
+ * @param {boolean} locked |
+ */ |
+ setCurrentTabLocked(locked) { |
+ this._currentTabLocked = locked; |
+ this._headerElement.classList.toggle('locked', this._currentTabLocked); |
+ } |
+ |
+ /** |
+ * @param {boolean} autoSelect |
+ */ |
+ setAutoSelectFirstItemOnShow(autoSelect) { |
+ this._autoSelectFirstItemOnShow = autoSelect; |
+ } |
+ |
+ /** |
+ * @return {?WebInspector.Widget} |
+ */ |
+ get visibleView() { |
+ return this._currentTab ? this._currentTab.view : null; |
+ } |
+ |
+ /** |
+ * @return {!Array.<string>} |
+ */ |
+ tabIds() { |
+ return this._tabs.map(tab => tab._id); |
+ } |
+ |
+ /** |
+ * @param {string} tabId |
+ * @return {number} |
+ */ |
+ tabIndex(tabId) { |
+ return this._tabs.findIndex(tab => tab.id === tabId); |
+ } |
+ |
+ /** |
+ * @return {!Array.<!WebInspector.Widget>} |
+ */ |
+ tabViews() { |
+ return this._tabs.map(tab => tab.view); |
+ } |
+ |
+ /** |
+ * @param {string} tabId |
+ * @return {?WebInspector.Widget} |
+ */ |
+ tabView(tabId) { |
+ return this._tabsById[tabId] ? this._tabsById[tabId].view : null; |
+ } |
+ |
+ /** |
+ * @return {?string} |
+ */ |
+ get selectedTabId() { |
+ return this._currentTab ? this._currentTab.id : null; |
+ } |
+ |
+ /** |
+ * @param {boolean} shrinkableTabs |
+ */ |
+ setShrinkableTabs(shrinkableTabs) { |
+ this._shrinkableTabs = shrinkableTabs; |
+ } |
+ |
+ /** |
+ * @param {boolean} verticalTabLayout |
+ */ |
+ setVerticalTabLayout(verticalTabLayout) { |
+ this._verticalTabLayout = verticalTabLayout; |
+ this.contentElement.classList.add('vertical-tab-layout'); |
+ this.invalidateConstraints(); |
+ } |
+ |
+ /** |
+ * @param {boolean} closeableTabs |
+ */ |
+ setCloseableTabs(closeableTabs) { |
+ this._closeableTabs = closeableTabs; |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ focus() { |
+ if (this.visibleView) |
+ this.visibleView.focus(); |
+ else |
+ this.contentElement.focus(); |
+ } |
+ |
+ /** |
+ * @return {!Element} |
+ */ |
+ headerElement() { |
+ return this._headerElement; |
+ } |
+ |
+ /** |
+ * @param {string} id |
+ * @return {boolean} |
+ */ |
+ isTabCloseable(id) { |
+ var tab = this._tabsById[id]; |
+ return tab ? tab.isCloseable() : false; |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.TabbedPaneTabDelegate} delegate |
+ */ |
+ setTabDelegate(delegate) { |
+ var tabs = this._tabs.slice(); |
+ for (var i = 0; i < tabs.length; ++i) |
+ tabs[i].setDelegate(delegate); |
+ this._delegate = delegate; |
+ } |
+ |
+ /** |
+ * @param {string} id |
+ * @param {string} tabTitle |
+ * @param {!WebInspector.Widget} view |
+ * @param {string=} tabTooltip |
+ * @param {boolean=} userGesture |
+ * @param {boolean=} isCloseable |
+ * @param {number=} index |
+ */ |
+ appendTab(id, tabTitle, view, tabTooltip, userGesture, isCloseable, index) { |
+ isCloseable = typeof isCloseable === 'boolean' ? isCloseable : this._closeableTabs; |
+ var tab = new WebInspector.TabbedPaneTab(this, id, tabTitle, isCloseable, view, tabTooltip); |
+ tab.setDelegate(this._delegate); |
+ this._tabsById[id] = tab; |
+ if (index !== undefined) |
+ this._tabs.splice(index, 0, tab); |
+ else |
+ this._tabs.push(tab); |
+ this._tabsHistory.push(tab); |
+ view.attach(this); |
+ if (this._tabsHistory[0] === tab && this.isShowing()) |
+ this.selectTab(tab.id, userGesture); |
+ this._updateTabElements(); |
+ } |
+ |
+ /** |
+ * @param {string} id |
+ * @param {boolean=} userGesture |
+ */ |
+ closeTab(id, userGesture) { |
+ this.closeTabs([id], userGesture); |
+ } |
+ |
+ /** |
+ * @param {!Array.<string>} ids |
+ * @param {boolean=} userGesture |
+ */ |
+ closeTabs(ids, userGesture) { |
+ var focused = this.hasFocus(); |
+ for (var i = 0; i < ids.length; ++i) |
+ this._innerCloseTab(ids[i], userGesture); |
+ this._updateTabElements(); |
+ if (this._tabsHistory.length) |
+ this.selectTab(this._tabsHistory[0].id, false); |
+ if (focused) |
+ this.focus(); |
+ } |
+ |
+ /** |
+ * @param {string} id |
+ * @param {boolean=} userGesture |
+ */ |
+ _innerCloseTab(id, userGesture) { |
+ if (!this._tabsById[id]) |
+ return; |
+ if (userGesture && !this._tabsById[id]._closeable) |
+ return; |
+ if (this._currentTab && this._currentTab.id === id) |
+ this._hideCurrentTab(); |
+ |
+ var tab = this._tabsById[id]; |
+ delete this._tabsById[id]; |
+ |
+ this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1); |
+ this._tabs.splice(this._tabs.indexOf(tab), 1); |
+ if (tab._shown) |
+ this._hideTabElement(tab); |
+ tab.view.detach(); |
+ |
+ var eventData = {tabId: id, view: tab.view, isUserGesture: userGesture}; |
+ this.dispatchEventToListeners(WebInspector.TabbedPane.Events.TabClosed, eventData); |
+ return true; |
+ } |
+ |
+ /** |
+ * @param {string} tabId |
+ * @return {boolean} |
+ */ |
+ hasTab(tabId) { |
+ return !!this._tabsById[tabId]; |
+ } |
+ |
+ /** |
+ * @return {!Array.<string>} |
+ */ |
+ allTabs() { |
+ return this._tabs.map(function(tab) { |
+ return tab.id; |
+ }); |
+ } |
+ |
+ /** |
+ * @param {string} id |
+ * @return {!Array.<string>} |
+ */ |
+ otherTabs(id) { |
+ var result = []; |
+ for (var i = 0; i < this._tabs.length; ++i) { |
+ if (this._tabs[i].id !== id) |
+ result.push(this._tabs[i].id); |
+ } |
+ return result; |
+ } |
+ |
+ /** |
+ * @param {string} id |
+ * @return {!Array.<string>} |
+ */ |
+ _tabsToTheRight(id) { |
+ var index = -1; |
+ for (var i = 0; i < this._tabs.length; ++i) { |
+ if (this._tabs[i].id === id) { |
+ index = i; |
+ break; |
+ } |
+ } |
+ if (index === -1) |
+ return []; |
+ return this._tabs.slice(index + 1).map(function(tab) { |
+ return tab.id; |
+ }); |
+ } |
+ |
+ /** |
+ * @param {string} id |
+ * @param {boolean=} userGesture |
+ * @return {boolean} |
+ */ |
+ selectTab(id, userGesture) { |
+ if (this._currentTabLocked) |
+ return false; |
+ var focused = this.hasFocus(); |
+ var tab = this._tabsById[id]; |
+ if (!tab) |
+ return false; |
+ if (this._currentTab && this._currentTab.id === id) |
+ return true; |
+ |
+ this.suspendInvalidations(); |
+ this._hideCurrentTab(); |
+ this._showTab(tab); |
+ this.resumeInvalidations(); |
+ this._currentTab = tab; |
+ |
+ this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1); |
+ this._tabsHistory.splice(0, 0, tab); |
+ |
+ this._updateTabElements(); |
+ if (focused) |
+ this.focus(); |
+ |
+ var eventData = {tabId: id, view: tab.view, isUserGesture: userGesture}; |
+ this.dispatchEventToListeners(WebInspector.TabbedPane.Events.TabSelected, eventData); |
+ return true; |
+ } |
+ |
+ /** |
+ * @param {number} tabsCount |
+ * @return {!Array.<string>} |
+ */ |
+ lastOpenedTabIds(tabsCount) { |
+ function tabToTabId(tab) { |
+ return tab.id; |
+ } |
- if (totalWidth >= totalMeasuredWidth) |
- return measuredWidths[measuredWidths.length - 1]; |
+ return this._tabsHistory.slice(0, tabsCount).map(tabToTabId); |
+ } |
+ |
+ /** |
+ * @param {string} id |
+ * @param {string} iconType |
+ * @param {string=} iconTooltip |
+ */ |
+ setTabIcon(id, iconType, iconTooltip) { |
+ var tab = this._tabsById[id]; |
+ if (tab._setIconType(iconType, iconTooltip)) |
+ this._updateTabElements(); |
+ } |
+ |
+ /** |
+ * @param {string} id |
+ * @param {boolean} enabled |
+ */ |
+ setTabEnabled(id, enabled) { |
+ var tab = this._tabsById[id]; |
+ tab.tabElement.classList.toggle('disabled', !enabled); |
+ } |
+ |
+ /** |
+ * @param {string} id |
+ * @param {string} className |
+ * @param {boolean=} force |
+ */ |
+ toggleTabClass(id, className, force) { |
+ var tab = this._tabsById[id]; |
+ if (tab._toggleClass(className, force)) |
+ this._updateTabElements(); |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _zoomChanged(event) { |
+ for (var i = 0; i < this._tabs.length; ++i) |
+ delete this._tabs[i]._measuredWidth; |
+ if (this.isShowing()) |
+ this._updateTabElements(); |
+ } |
+ |
+ /** |
+ * @param {string} id |
+ * @param {string} tabTitle |
+ * @param {string=} tabTooltip |
+ */ |
+ changeTabTitle(id, tabTitle, tabTooltip) { |
+ var tab = this._tabsById[id]; |
+ if (tabTooltip !== undefined) |
+ tab.tooltip = tabTooltip; |
+ if (tab.title !== tabTitle) { |
+ tab.title = tabTitle; |
+ this._updateTabElements(); |
+ } |
+ } |
+ |
+ /** |
+ * @param {string} id |
+ * @param {!WebInspector.Widget} view |
+ */ |
+ changeTabView(id, view) { |
+ var tab = this._tabsById[id]; |
+ if (tab.view === view) |
+ return; |
+ |
+ var shouldFocus = tab.view.hasFocus(); |
+ |
+ this.suspendInvalidations(); |
+ |
+ var isSelected = this._currentTab && this._currentTab.id === id; |
+ if (isSelected) |
+ this._hideTab(tab); |
+ tab.view.detach(); |
+ tab.view = view; |
+ tab.view.attach(this); |
+ if (isSelected) |
+ this._showTab(tab); |
+ if (shouldFocus) |
+ tab.view.focus(); |
+ |
+ this.resumeInvalidations(); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ onResize() { |
+ this._updateTabElements(); |
+ } |
+ |
+ headerResized() { |
+ this._updateTabElements(); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ wasShown() { |
+ var effectiveTab = this._currentTab || this._tabsHistory[0]; |
+ if (effectiveTab && this._autoSelectFirstItemOnShow) |
+ this.selectTab(effectiveTab.id); |
+ } |
+ |
+ /** |
+ * @param {boolean} enable |
+ */ |
+ setTabSlider(enable) { |
+ this._sliderEnabled = enable; |
+ this._tabSlider.classList.toggle('enabled', enable); |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {!Constraints} |
+ */ |
+ calculateConstraints() { |
+ var constraints = super.calculateConstraints(); |
+ var minContentConstraints = new Constraints(new Size(0, 0), new Size(50, 50)); |
+ constraints = constraints.widthToMax(minContentConstraints).heightToMax(minContentConstraints); |
+ if (this._verticalTabLayout) |
+ constraints = constraints.addWidth(new Constraints(new Size(120, 0))); |
+ else |
+ constraints = constraints.addHeight(new Constraints(new Size(0, 30))); |
+ return constraints; |
+ } |
+ |
+ _updateTabElements() { |
+ WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateTabElements); |
+ } |
+ |
+ /** |
+ * @param {string} text |
+ */ |
+ setPlaceholderText(text) { |
+ this._noTabsMessage = text; |
+ } |
+ |
+ _innerUpdateTabElements() { |
+ if (!this.isShowing()) |
+ return; |
+ |
+ if (!this._tabs.length) { |
+ this._contentElement.classList.add('has-no-tabs'); |
+ if (this._noTabsMessage && !this._noTabsMessageElement) { |
+ this._noTabsMessageElement = this._contentElement.createChild('div', 'tabbed-pane-placeholder fill'); |
+ this._noTabsMessageElement.textContent = this._noTabsMessage; |
+ } |
+ } else { |
+ this._contentElement.classList.remove('has-no-tabs'); |
+ if (this._noTabsMessageElement) { |
+ this._noTabsMessageElement.remove(); |
+ delete this._noTabsMessageElement; |
+ } |
+ } |
- var totalExtraWidth = 0; |
- for (var i = measuredWidths.length - 1; i > 0; --i) { |
- var extraWidth = measuredWidths[i] - measuredWidths[i - 1]; |
- totalExtraWidth += (measuredWidths.length - i) * extraWidth; |
+ this._measureDropDownButton(); |
+ this._updateWidths(); |
+ this._updateTabsDropDown(); |
+ this._updateTabSlider(); |
+ } |
+ |
+ /** |
+ * @param {number} index |
+ * @param {!WebInspector.TabbedPaneTab} tab |
+ */ |
+ _showTabElement(index, tab) { |
+ if (index >= this._tabsElement.children.length) |
+ this._tabsElement.appendChild(tab.tabElement); |
+ else |
+ this._tabsElement.insertBefore(tab.tabElement, this._tabsElement.children[index]); |
+ tab._shown = true; |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.TabbedPaneTab} tab |
+ */ |
+ _hideTabElement(tab) { |
+ this._tabsElement.removeChild(tab.tabElement); |
+ tab._shown = false; |
+ } |
+ |
+ _createDropDownButton() { |
+ var dropDownContainer = createElementWithClass('div', 'tabbed-pane-header-tabs-drop-down-container'); |
+ dropDownContainer.createChild('div', 'glyph'); |
+ this._dropDownMenu = new WebInspector.DropDownMenu(dropDownContainer); |
+ this._dropDownMenu.addEventListener( |
+ WebInspector.DropDownMenu.Events.ItemSelected, this._dropDownMenuItemSelected, this); |
+ |
+ return dropDownContainer; |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _dropDownMenuItemSelected(event) { |
+ var tabId = /** @type {string} */ (event.data); |
+ this._lastSelectedOverflowTab = this._tabsById[tabId]; |
+ this.selectTab(tabId, true); |
+ } |
+ |
+ _totalWidth() { |
+ return this._headerContentsElement.getBoundingClientRect().width; |
+ } |
+ |
+ /** |
+ * @return {number} |
+ */ |
+ _numberOfTabsShown() { |
+ var numTabsShown = 0; |
+ for (var tab of this._tabs) { |
+ if (tab._shown) |
+ numTabsShown++; |
+ } |
+ return numTabsShown; |
+ } |
+ |
+ disableOverflowMenu() { |
+ this._overflowDisabled = true; |
+ } |
+ |
+ _updateTabsDropDown() { |
+ var tabsToShowIndexes = this._tabsToShowIndexes( |
+ this._tabs, this._tabsHistory, this._totalWidth(), this._measuredDropDownButtonWidth || 0); |
+ if (this._lastSelectedOverflowTab && this._numberOfTabsShown() !== tabsToShowIndexes.length) { |
+ delete this._lastSelectedOverflowTab; |
+ this._updateTabsDropDown(); |
+ return; |
+ } |
- if (totalWidth + totalExtraWidth >= totalMeasuredWidth) |
- return measuredWidths[i - 1] + (totalWidth + totalExtraWidth - totalMeasuredWidth) / (measuredWidths.length - i); |
- } |
+ for (var i = 0; i < this._tabs.length; ++i) { |
+ if (this._tabs[i]._shown && tabsToShowIndexes.indexOf(i) === -1) |
+ this._hideTabElement(this._tabs[i]); |
+ } |
+ for (var i = 0; i < tabsToShowIndexes.length; ++i) { |
+ var tab = this._tabs[tabsToShowIndexes[i]]; |
+ if (!tab._shown) |
+ this._showTabElement(i, tab); |
+ } |
- return totalWidth / measuredWidths.length; |
- }, |
+ if (!this._overflowDisabled) |
+ this._populateDropDownFromIndex(); |
+ } |
- /** |
- * @param {!Array.<!WebInspector.TabbedPaneTab>} tabsOrdered |
- * @param {!Array.<!WebInspector.TabbedPaneTab>} tabsHistory |
- * @param {number} totalWidth |
- * @param {number} measuredDropDownButtonWidth |
- * @return {!Array.<number>} |
- */ |
- _tabsToShowIndexes: function(tabsOrdered, tabsHistory, totalWidth, measuredDropDownButtonWidth) |
- { |
- var tabsToShowIndexes = []; |
- |
- var totalTabsWidth = 0; |
- var tabCount = tabsOrdered.length; |
- var tabsToLookAt = tabsOrdered.slice(0); |
- if (this._currentTab !== undefined) |
- tabsToLookAt.unshift(tabsToLookAt.splice(tabsToLookAt.indexOf(this._currentTab), 1)[0]); |
- if (this._lastSelectedOverflowTab !== undefined) |
- tabsToLookAt.unshift(tabsToLookAt.splice(tabsToLookAt.indexOf(this._lastSelectedOverflowTab), 1)[0]); |
- for (var i = 0; i < tabCount; ++i) { |
- var tab = this._automaticReorder ? tabsHistory[i] : tabsToLookAt[i]; |
- totalTabsWidth += tab.width(); |
- var minimalRequiredWidth = totalTabsWidth; |
- if (i !== tabCount - 1) |
- minimalRequiredWidth += measuredDropDownButtonWidth; |
- if (!this._verticalTabLayout && minimalRequiredWidth > totalWidth) |
- break; |
- tabsToShowIndexes.push(tabsOrdered.indexOf(tab)); |
- } |
- |
- tabsToShowIndexes.sort(function(x, y) { return x - y; }); |
- |
- return tabsToShowIndexes; |
- }, |
- |
- _hideCurrentTab: function() |
- { |
- if (!this._currentTab) |
- return; |
- |
- this._hideTab(this._currentTab); |
- delete this._currentTab; |
- }, |
+ _populateDropDownFromIndex() { |
+ if (this._dropDownButton.parentElement) |
+ this._headerContentsElement.removeChild(this._dropDownButton); |
- /** |
- * @param {!WebInspector.TabbedPaneTab} tab |
- */ |
- _showTab: function(tab) |
- { |
- tab.tabElement.classList.add("selected"); |
- tab.tabElement.setAttribute("aria-selected", "true"); |
- tab.view.showWidget(this.element); |
- this._updateTabSlider(); |
- }, |
- |
- _updateTabSlider: function() |
- { |
- if (!this._currentTab || !this._sliderEnabled) |
- return; |
- var left = 0; |
- for (var i = 0; i < this._tabs.length && this._currentTab !== this._tabs[i] && this._tabs[i]._shown; i++) |
- left += this._tabs[i]._measuredWidth; |
- var sliderWidth = this._currentTab._shown ? this._currentTab._measuredWidth : this._dropDownButton.offsetWidth; |
- var scaleFactor = window.devicePixelRatio >= 1.5 ? " scaleY(0.75)" : ""; |
- this._tabSlider.style.transform = "translateX(" + left + "px)" + scaleFactor; |
- this._tabSlider.style.width = sliderWidth + "px"; |
- |
- if (this._tabSlider.parentElement !== this._headerContentsElement) |
- this._headerContentsElement.appendChild(this._tabSlider); |
- }, |
+ this._dropDownMenu.clear(); |
- /** |
- * @param {!WebInspector.TabbedPaneTab} tab |
- */ |
- _hideTab: function(tab) |
- { |
- tab.tabElement.classList.remove("selected"); |
- tab.tabElement.setAttribute("aria-selected", "false"); |
- tab.view.hideWidget(); |
- }, |
+ var tabsToShow = []; |
+ for (var i = 0; i < this._tabs.length; ++i) { |
+ if (!this._tabs[i]._shown) |
+ tabsToShow.push(this._tabs[i]); |
+ } |
- /** |
- * @override |
- * @return {!Array.<!Element>} |
- */ |
- elementsToRestoreScrollPositionsFor: function() |
- { |
- return [ this._contentElement ]; |
- }, |
+ var selectedId = null; |
+ for (var i = 0; i < tabsToShow.length; ++i) { |
+ var tab = tabsToShow[i]; |
+ this._dropDownMenu.addItem(tab.id, tab.title); |
+ if (this._tabsHistory[0] === tab) |
+ selectedId = tab.id; |
+ } |
+ if (tabsToShow.length) { |
+ this._headerContentsElement.appendChild(this._dropDownButton); |
+ this._dropDownMenu.selectItem(selectedId); |
+ } |
+ } |
+ |
+ _measureDropDownButton() { |
+ if (this._overflowDisabled || this._measuredDropDownButtonWidth) |
+ return; |
+ this._dropDownButton.classList.add('measuring'); |
+ this._headerContentsElement.appendChild(this._dropDownButton); |
+ this._measuredDropDownButtonWidth = this._dropDownButton.getBoundingClientRect().width; |
+ this._headerContentsElement.removeChild(this._dropDownButton); |
+ this._dropDownButton.classList.remove('measuring'); |
+ } |
+ |
+ _updateWidths() { |
+ var measuredWidths = this._measureWidths(); |
+ var maxWidth = |
+ this._shrinkableTabs ? this._calculateMaxWidth(measuredWidths.slice(), this._totalWidth()) : Number.MAX_VALUE; |
+ |
+ var i = 0; |
+ for (var tab of this._tabs) |
+ tab.setWidth(this._verticalTabLayout ? -1 : Math.min(maxWidth, measuredWidths[i++])); |
+ } |
+ |
+ _measureWidths() { |
+ // Add all elements to measure into this._tabsElement |
+ this._tabsElement.style.setProperty('width', '2000px'); |
+ var measuringTabElements = []; |
+ for (var tab of this._tabs) { |
+ if (typeof tab._measuredWidth === 'number') |
+ continue; |
+ var measuringTabElement = tab._createTabElement(true); |
+ measuringTabElement.__tab = tab; |
+ measuringTabElements.push(measuringTabElement); |
+ this._tabsElement.appendChild(measuringTabElement); |
+ } |
- /** |
- * @param {!WebInspector.TabbedPaneTab} tab |
- * @param {number} index |
- */ |
- _insertBefore: function(tab, index) |
- { |
- this._tabsElement.insertBefore(tab._tabElement || null, this._tabsElement.childNodes[index]); |
- var oldIndex = this._tabs.indexOf(tab); |
- this._tabs.splice(oldIndex, 1); |
- if (oldIndex < index) |
- --index; |
- this._tabs.splice(index, 0, tab); |
- this.dispatchEventToListeners(WebInspector.TabbedPane.Events.TabOrderChanged, this._tabs); |
- }, |
+ // Perform measurement |
+ for (var i = 0; i < measuringTabElements.length; ++i) { |
+ var width = measuringTabElements[i].getBoundingClientRect().width; |
+ measuringTabElements[i].__tab._measuredWidth = Math.ceil(width); |
+ } |
- /** |
- * @return {!WebInspector.Toolbar} |
- */ |
- leftToolbar: function() |
- { |
- if (!this._leftToolbar) { |
- this._leftToolbar = new WebInspector.Toolbar("tabbed-pane-left-toolbar"); |
- this._headerElement.insertBefore(this._leftToolbar.element, this._headerElement.firstChild); |
- } |
- return this._leftToolbar; |
- }, |
+ // Nuke elements from the UI |
+ for (var i = 0; i < measuringTabElements.length; ++i) |
+ measuringTabElements[i].remove(); |
+ |
+ // Combine the results. |
+ var measuredWidths = []; |
+ for (var tab of this._tabs) |
+ measuredWidths.push(tab._measuredWidth); |
+ this._tabsElement.style.removeProperty('width'); |
+ |
+ return measuredWidths; |
+ } |
+ |
+ /** |
+ * @param {!Array.<number>} measuredWidths |
+ * @param {number} totalWidth |
+ */ |
+ _calculateMaxWidth(measuredWidths, totalWidth) { |
+ if (!measuredWidths.length) |
+ return 0; |
+ |
+ measuredWidths.sort(function(x, y) { |
+ return x - y; |
+ }); |
+ |
+ var totalMeasuredWidth = 0; |
+ for (var i = 0; i < measuredWidths.length; ++i) |
+ totalMeasuredWidth += measuredWidths[i]; |
+ |
+ if (totalWidth >= totalMeasuredWidth) |
+ return measuredWidths[measuredWidths.length - 1]; |
+ |
+ var totalExtraWidth = 0; |
+ for (var i = measuredWidths.length - 1; i > 0; --i) { |
+ var extraWidth = measuredWidths[i] - measuredWidths[i - 1]; |
+ totalExtraWidth += (measuredWidths.length - i) * extraWidth; |
+ |
+ if (totalWidth + totalExtraWidth >= totalMeasuredWidth) |
+ return measuredWidths[i - 1] + |
+ (totalWidth + totalExtraWidth - totalMeasuredWidth) / (measuredWidths.length - i); |
+ } |
- /** |
- * @return {!WebInspector.Toolbar} |
- */ |
- rightToolbar: function() |
- { |
- if (!this._rightToolbar) { |
- this._rightToolbar = new WebInspector.Toolbar("tabbed-pane-right-toolbar"); |
- this._headerElement.appendChild(this._rightToolbar.element); |
- } |
- return this._rightToolbar; |
- }, |
- |
- renderWithNoHeaderBackground: function() |
- { |
- this._headerElement.classList.add("tabbed-pane-no-header-background"); |
- }, |
+ return totalWidth / measuredWidths.length; |
+ } |
+ |
+ /** |
+ * @param {!Array.<!WebInspector.TabbedPaneTab>} tabsOrdered |
+ * @param {!Array.<!WebInspector.TabbedPaneTab>} tabsHistory |
+ * @param {number} totalWidth |
+ * @param {number} measuredDropDownButtonWidth |
+ * @return {!Array.<number>} |
+ */ |
+ _tabsToShowIndexes(tabsOrdered, tabsHistory, totalWidth, measuredDropDownButtonWidth) { |
+ var tabsToShowIndexes = []; |
+ |
+ var totalTabsWidth = 0; |
+ var tabCount = tabsOrdered.length; |
+ var tabsToLookAt = tabsOrdered.slice(0); |
+ if (this._currentTab !== undefined) |
+ tabsToLookAt.unshift(tabsToLookAt.splice(tabsToLookAt.indexOf(this._currentTab), 1)[0]); |
+ if (this._lastSelectedOverflowTab !== undefined) |
+ tabsToLookAt.unshift(tabsToLookAt.splice(tabsToLookAt.indexOf(this._lastSelectedOverflowTab), 1)[0]); |
+ for (var i = 0; i < tabCount; ++i) { |
+ var tab = this._automaticReorder ? tabsHistory[i] : tabsToLookAt[i]; |
+ totalTabsWidth += tab.width(); |
+ var minimalRequiredWidth = totalTabsWidth; |
+ if (i !== tabCount - 1) |
+ minimalRequiredWidth += measuredDropDownButtonWidth; |
+ if (!this._verticalTabLayout && minimalRequiredWidth > totalWidth) |
+ break; |
+ tabsToShowIndexes.push(tabsOrdered.indexOf(tab)); |
+ } |
- /** |
- * @param {boolean} allow |
- * @param {boolean=} automatic |
- */ |
- setAllowTabReorder: function(allow, automatic) |
- { |
- this._allowTabReorder = allow; |
- this._automaticReorder = automatic; |
- }, |
+ tabsToShowIndexes.sort(function(x, y) { |
+ return x - y; |
+ }); |
+ |
+ return tabsToShowIndexes; |
+ } |
+ |
+ _hideCurrentTab() { |
+ if (!this._currentTab) |
+ return; |
+ |
+ this._hideTab(this._currentTab); |
+ delete this._currentTab; |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.TabbedPaneTab} tab |
+ */ |
+ _showTab(tab) { |
+ tab.tabElement.classList.add('selected'); |
+ tab.tabElement.setAttribute('aria-selected', 'true'); |
+ tab.view.showWidget(this.element); |
+ this._updateTabSlider(); |
+ } |
+ |
+ _updateTabSlider() { |
+ if (!this._currentTab || !this._sliderEnabled) |
+ return; |
+ var left = 0; |
+ for (var i = 0; i < this._tabs.length && this._currentTab !== this._tabs[i] && this._tabs[i]._shown; i++) |
+ left += this._tabs[i]._measuredWidth; |
+ var sliderWidth = this._currentTab._shown ? this._currentTab._measuredWidth : this._dropDownButton.offsetWidth; |
+ var scaleFactor = window.devicePixelRatio >= 1.5 ? ' scaleY(0.75)' : ''; |
+ this._tabSlider.style.transform = 'translateX(' + left + 'px)' + scaleFactor; |
+ this._tabSlider.style.width = sliderWidth + 'px'; |
+ |
+ if (this._tabSlider.parentElement !== this._headerContentsElement) |
+ this._headerContentsElement.appendChild(this._tabSlider); |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.TabbedPaneTab} tab |
+ */ |
+ _hideTab(tab) { |
+ tab.tabElement.classList.remove('selected'); |
+ tab.tabElement.setAttribute('aria-selected', 'false'); |
+ tab.view.hideWidget(); |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {!Array.<!Element>} |
+ */ |
+ elementsToRestoreScrollPositionsFor() { |
+ return [this._contentElement]; |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.TabbedPaneTab} tab |
+ * @param {number} index |
+ */ |
+ _insertBefore(tab, index) { |
+ this._tabsElement.insertBefore(tab._tabElement || null, this._tabsElement.childNodes[index]); |
+ var oldIndex = this._tabs.indexOf(tab); |
+ this._tabs.splice(oldIndex, 1); |
+ if (oldIndex < index) |
+ --index; |
+ this._tabs.splice(index, 0, tab); |
+ this.dispatchEventToListeners(WebInspector.TabbedPane.Events.TabOrderChanged, this._tabs); |
+ } |
+ |
+ /** |
+ * @return {!WebInspector.Toolbar} |
+ */ |
+ leftToolbar() { |
+ if (!this._leftToolbar) { |
+ this._leftToolbar = new WebInspector.Toolbar('tabbed-pane-left-toolbar'); |
+ this._headerElement.insertBefore(this._leftToolbar.element, this._headerElement.firstChild); |
+ } |
+ return this._leftToolbar; |
+ } |
+ |
+ /** |
+ * @return {!WebInspector.Toolbar} |
+ */ |
+ rightToolbar() { |
+ if (!this._rightToolbar) { |
+ this._rightToolbar = new WebInspector.Toolbar('tabbed-pane-right-toolbar'); |
+ this._headerElement.appendChild(this._rightToolbar.element); |
+ } |
+ return this._rightToolbar; |
+ } |
+ |
+ renderWithNoHeaderBackground() { |
+ this._headerElement.classList.add('tabbed-pane-no-header-background'); |
+ } |
+ |
+ /** |
+ * @param {boolean} allow |
+ * @param {boolean=} automatic |
+ */ |
+ setAllowTabReorder(allow, automatic) { |
+ this._allowTabReorder = allow; |
+ this._automaticReorder = automatic; |
+ } |
+}; |
- __proto__: WebInspector.VBox.prototype |
+/** @enum {symbol} */ |
+WebInspector.TabbedPane.Events = { |
+ TabSelected: Symbol('TabSelected'), |
+ TabClosed: Symbol('TabClosed'), |
+ TabOrderChanged: Symbol('TabOrderChanged') |
}; |
/** |
- * @constructor |
- * @param {!WebInspector.TabbedPane} tabbedPane |
- * @param {string} id |
- * @param {string} title |
- * @param {boolean} closeable |
- * @param {!WebInspector.Widget} view |
- * @param {string=} tooltip |
+ * @unrestricted |
*/ |
-WebInspector.TabbedPaneTab = function(tabbedPane, id, title, closeable, view, tooltip) |
-{ |
+WebInspector.TabbedPaneTab = class { |
+ /** |
+ * @param {!WebInspector.TabbedPane} tabbedPane |
+ * @param {string} id |
+ * @param {string} title |
+ * @param {boolean} closeable |
+ * @param {!WebInspector.Widget} view |
+ * @param {string=} tooltip |
+ */ |
+ constructor(tabbedPane, id, title, closeable, view, tooltip) { |
this._closeable = closeable; |
this._tabbedPane = tabbedPane; |
this._id = id; |
@@ -909,376 +861,356 @@ WebInspector.TabbedPaneTab = function(tabbedPane, id, title, closeable, view, to |
this._shown = false; |
/** @type {number} */ this._measuredWidth; |
/** @type {!Element|undefined} */ this._tabElement; |
-}; |
- |
-WebInspector.TabbedPaneTab.prototype = { |
- /** |
- * @return {string} |
- */ |
- get id() |
- { |
- return this._id; |
- }, |
- |
- /** |
- * @return {string} |
- */ |
- get title() |
- { |
- return this._title; |
- }, |
- |
- set title(title) |
- { |
- if (title === this._title) |
- return; |
- this._title = title; |
- if (this._titleElement) |
- this._titleElement.textContent = title; |
- delete this._measuredWidth; |
- }, |
- |
- /** |
- * @return {boolean} |
- */ |
- isCloseable: function() |
- { |
- return this._closeable; |
- }, |
- |
- /** |
- * @param {string} iconType |
- * @param {string=} iconTooltip |
- * @return {boolean} |
- */ |
- _setIconType: function(iconType, iconTooltip) |
- { |
- if (iconType === this._iconType && iconTooltip === this._iconTooltip) |
- return false; |
- this._iconType = iconType; |
- this._iconTooltip = iconTooltip; |
- if (this._tabElement) |
- this._createIconElement(this._tabElement, this._titleElement); |
- delete this._measuredWidth; |
- return true; |
- }, |
- |
- /** |
- * @param {string} className |
- * @param {boolean=} force |
- * @return {boolean} |
- */ |
- _toggleClass: function(className, force) |
- { |
- var element = this.tabElement; |
- var hasClass = element.classList.contains(className); |
- if (hasClass === force) |
- return false; |
- element.classList.toggle(className, force); |
- delete this._measuredWidth; |
- return true; |
- }, |
- |
- /** |
- * @return {!WebInspector.Widget} |
- */ |
- get view() |
- { |
- return this._view; |
- }, |
- |
- set view(view) |
- { |
- this._view = view; |
- }, |
- |
- /** |
- * @return {string|undefined} |
- */ |
- get tooltip() |
- { |
- return this._tooltip; |
- }, |
- |
- set tooltip(tooltip) |
- { |
- this._tooltip = tooltip; |
- if (this._titleElement) |
- this._titleElement.title = tooltip || ""; |
- }, |
- |
- /** |
- * @return {!Element} |
- */ |
- get tabElement() |
- { |
- if (!this._tabElement) |
- this._tabElement = this._createTabElement(false); |
- |
- return this._tabElement; |
- }, |
- |
- /** |
- * @return {number} |
- */ |
- width: function() |
- { |
- return this._width; |
- }, |
- |
- /** |
- * @param {number} width |
- */ |
- setWidth: function(width) |
- { |
- this.tabElement.style.width = width === -1 ? "" : (width + "px"); |
- this._width = width; |
- }, |
- |
- /** |
- * @param {!WebInspector.TabbedPaneTabDelegate} delegate |
- */ |
- setDelegate: function(delegate) |
- { |
- this._delegate = delegate; |
- }, |
- |
- /** |
- * @param {!Element} tabElement |
- * @param {!Element} titleElement |
- */ |
- _createIconElement: function(tabElement, titleElement) |
- { |
- if (tabElement.__iconElement) |
- tabElement.__iconElement.remove(); |
- if (!this._iconType) |
- return; |
- |
- var iconElement = createElementWithClass("label", "tabbed-pane-header-tab-icon", "dt-icon-label"); |
- iconElement.type = this._iconType; |
- if (this._iconTooltip) |
- iconElement.title = this._iconTooltip; |
- tabElement.insertBefore(iconElement, titleElement); |
- tabElement.__iconElement = iconElement; |
- }, |
- |
- /** |
- * @param {boolean} measuring |
- * @return {!Element} |
- */ |
- _createTabElement: function(measuring) |
- { |
- var tabElement = createElementWithClass("div", "tabbed-pane-header-tab"); |
- tabElement.id = "tab-" + this._id; |
- tabElement.tabIndex = -1; |
- tabElement.setAttribute("role", "tab"); |
- tabElement.setAttribute("aria-selected", "false"); |
- tabElement.selectTabForTest = this._tabbedPane.selectTab.bind(this._tabbedPane, this.id, true); |
- |
- var titleElement = tabElement.createChild("span", "tabbed-pane-header-tab-title"); |
- titleElement.textContent = this.title; |
- titleElement.title = this.tooltip || ""; |
- this._createIconElement(tabElement, titleElement); |
- if (!measuring) |
- this._titleElement = titleElement; |
- |
- if (this._closeable) |
- tabElement.createChild("div", "tabbed-pane-close-button", "dt-close-button").gray = true; |
- |
- if (measuring) { |
- tabElement.classList.add("measuring"); |
- } else { |
- tabElement.addEventListener("click", this._tabClicked.bind(this), false); |
- tabElement.addEventListener("auxclick", this._tabClicked.bind(this), false); |
- tabElement.addEventListener("mousedown", this._tabMouseDown.bind(this), false); |
- tabElement.addEventListener("mouseup", this._tabMouseUp.bind(this), false); |
- |
- tabElement.addEventListener("contextmenu", this._tabContextMenu.bind(this), false); |
- if (this._tabbedPane._allowTabReorder) |
- WebInspector.installDragHandle(tabElement, this._startTabDragging.bind(this), this._tabDragging.bind(this), this._endTabDragging.bind(this), "-webkit-grabbing", "pointer", 200); |
- } |
- |
- return tabElement; |
- }, |
+ } |
+ |
+ /** |
+ * @return {string} |
+ */ |
+ get id() { |
+ return this._id; |
+ } |
+ |
+ /** |
+ * @return {string} |
+ */ |
+ get title() { |
+ return this._title; |
+ } |
+ |
+ /** |
+ * @param {string} title |
+ */ |
+ set title(title) { |
+ if (title === this._title) |
+ return; |
+ this._title = title; |
+ if (this._titleElement) |
+ this._titleElement.textContent = title; |
+ delete this._measuredWidth; |
+ } |
+ |
+ /** |
+ * @return {boolean} |
+ */ |
+ isCloseable() { |
+ return this._closeable; |
+ } |
+ |
+ /** |
+ * @param {string} iconType |
+ * @param {string=} iconTooltip |
+ * @return {boolean} |
+ */ |
+ _setIconType(iconType, iconTooltip) { |
+ if (iconType === this._iconType && iconTooltip === this._iconTooltip) |
+ return false; |
+ this._iconType = iconType; |
+ this._iconTooltip = iconTooltip; |
+ if (this._tabElement) |
+ this._createIconElement(this._tabElement, this._titleElement); |
+ delete this._measuredWidth; |
+ return true; |
+ } |
+ |
+ /** |
+ * @param {string} className |
+ * @param {boolean=} force |
+ * @return {boolean} |
+ */ |
+ _toggleClass(className, force) { |
+ var element = this.tabElement; |
+ var hasClass = element.classList.contains(className); |
+ if (hasClass === force) |
+ return false; |
+ element.classList.toggle(className, force); |
+ delete this._measuredWidth; |
+ return true; |
+ } |
+ |
+ /** |
+ * @return {!WebInspector.Widget} |
+ */ |
+ get view() { |
+ return this._view; |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.Widget} view |
+ */ |
+ set view(view) { |
+ this._view = view; |
+ } |
+ |
+ /** |
+ * @return {string|undefined} |
+ */ |
+ get tooltip() { |
+ return this._tooltip; |
+ } |
+ |
+ /** |
+ * @param {string|undefined} tooltip |
+ */ |
+ set tooltip(tooltip) { |
+ this._tooltip = tooltip; |
+ if (this._titleElement) |
+ this._titleElement.title = tooltip || ''; |
+ } |
+ |
+ /** |
+ * @return {!Element} |
+ */ |
+ get tabElement() { |
+ if (!this._tabElement) |
+ this._tabElement = this._createTabElement(false); |
+ |
+ return this._tabElement; |
+ } |
+ |
+ /** |
+ * @return {number} |
+ */ |
+ width() { |
+ return this._width; |
+ } |
+ |
+ /** |
+ * @param {number} width |
+ */ |
+ setWidth(width) { |
+ this.tabElement.style.width = width === -1 ? '' : (width + 'px'); |
+ this._width = width; |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.TabbedPaneTabDelegate} delegate |
+ */ |
+ setDelegate(delegate) { |
+ this._delegate = delegate; |
+ } |
+ |
+ /** |
+ * @param {!Element} tabElement |
+ * @param {!Element} titleElement |
+ */ |
+ _createIconElement(tabElement, titleElement) { |
+ if (tabElement.__iconElement) |
+ tabElement.__iconElement.remove(); |
+ if (!this._iconType) |
+ return; |
+ |
+ var iconElement = createElementWithClass('label', 'tabbed-pane-header-tab-icon', 'dt-icon-label'); |
+ iconElement.type = this._iconType; |
+ if (this._iconTooltip) |
+ iconElement.title = this._iconTooltip; |
+ tabElement.insertBefore(iconElement, titleElement); |
+ tabElement.__iconElement = iconElement; |
+ } |
+ |
+ /** |
+ * @param {boolean} measuring |
+ * @return {!Element} |
+ */ |
+ _createTabElement(measuring) { |
+ var tabElement = createElementWithClass('div', 'tabbed-pane-header-tab'); |
+ tabElement.id = 'tab-' + this._id; |
+ tabElement.tabIndex = -1; |
+ tabElement.setAttribute('role', 'tab'); |
+ tabElement.setAttribute('aria-selected', 'false'); |
+ tabElement.selectTabForTest = this._tabbedPane.selectTab.bind(this._tabbedPane, this.id, true); |
+ |
+ var titleElement = tabElement.createChild('span', 'tabbed-pane-header-tab-title'); |
+ titleElement.textContent = this.title; |
+ titleElement.title = this.tooltip || ''; |
+ this._createIconElement(tabElement, titleElement); |
+ if (!measuring) |
+ this._titleElement = titleElement; |
+ |
+ if (this._closeable) |
+ tabElement.createChild('div', 'tabbed-pane-close-button', 'dt-close-button').gray = true; |
+ |
+ if (measuring) { |
+ tabElement.classList.add('measuring'); |
+ } else { |
+ tabElement.addEventListener('click', this._tabClicked.bind(this), false); |
+ tabElement.addEventListener('auxclick', this._tabClicked.bind(this), false); |
+ tabElement.addEventListener('mousedown', this._tabMouseDown.bind(this), false); |
+ tabElement.addEventListener('mouseup', this._tabMouseUp.bind(this), false); |
+ |
+ tabElement.addEventListener('contextmenu', this._tabContextMenu.bind(this), false); |
+ if (this._tabbedPane._allowTabReorder) |
+ WebInspector.installDragHandle( |
+ tabElement, this._startTabDragging.bind(this), this._tabDragging.bind(this), |
+ this._endTabDragging.bind(this), '-webkit-grabbing', 'pointer', 200); |
+ } |
- /** |
- * @param {!Event} event |
- */ |
- _tabClicked: function(event) |
- { |
- var middleButton = event.button === 1; |
- var shouldClose = this._closeable && (middleButton || event.target.classList.contains("tabbed-pane-close-button")); |
- if (!shouldClose) { |
- this._tabbedPane.focus(); |
- return; |
- } |
- this._closeTabs([this.id]); |
- event.consume(true); |
- }, |
+ return tabElement; |
+ } |
+ |
+ /** |
+ * @param {!Event} event |
+ */ |
+ _tabClicked(event) { |
+ var middleButton = event.button === 1; |
+ var shouldClose = this._closeable && (middleButton || event.target.classList.contains('tabbed-pane-close-button')); |
+ if (!shouldClose) { |
+ this._tabbedPane.focus(); |
+ return; |
+ } |
+ this._closeTabs([this.id]); |
+ event.consume(true); |
+ } |
+ |
+ /** |
+ * @param {!Event} event |
+ */ |
+ _tabMouseDown(event) { |
+ if (event.target.classList.contains('tabbed-pane-close-button') || event.button === 1) |
+ return; |
+ this._tabbedPane.selectTab(this.id, true); |
+ } |
+ |
+ /** |
+ * @param {!Event} event |
+ */ |
+ _tabMouseUp(event) { |
+ // This is needed to prevent middle-click pasting on linux when tabs are clicked. |
+ if (event.button === 1) |
+ event.consume(true); |
+ } |
+ |
+ /** |
+ * @param {!Array.<string>} ids |
+ */ |
+ _closeTabs(ids) { |
+ if (this._delegate) { |
+ this._delegate.closeTabs(this._tabbedPane, ids); |
+ return; |
+ } |
+ this._tabbedPane.closeTabs(ids, true); |
+ } |
+ _tabContextMenu(event) { |
/** |
- * @param {!Event} event |
+ * @this {WebInspector.TabbedPaneTab} |
*/ |
- _tabMouseDown: function(event) |
- { |
- if (event.target.classList.contains("tabbed-pane-close-button") || event.button === 1) |
- return; |
- this._tabbedPane.selectTab(this.id, true); |
- }, |
+ function close() { |
+ this._closeTabs([this.id]); |
+ } |
/** |
- * @param {!Event} event |
+ * @this {WebInspector.TabbedPaneTab} |
*/ |
- _tabMouseUp: function(event) |
- { |
- // This is needed to prevent middle-click pasting on linux when tabs are clicked. |
- if (event.button === 1) |
- event.consume(true); |
- }, |
+ function closeOthers() { |
+ this._closeTabs(this._tabbedPane.otherTabs(this.id)); |
+ } |
/** |
- * @param {!Array.<string>} ids |
+ * @this {WebInspector.TabbedPaneTab} |
*/ |
- _closeTabs: function(ids) |
- { |
- if (this._delegate) { |
- this._delegate.closeTabs(this._tabbedPane, ids); |
- return; |
- } |
- this._tabbedPane.closeTabs(ids, true); |
- }, |
- |
- _tabContextMenu: function(event) |
- { |
- /** |
- * @this {WebInspector.TabbedPaneTab} |
- */ |
- function close() |
- { |
- this._closeTabs([this.id]); |
- } |
- |
- /** |
- * @this {WebInspector.TabbedPaneTab} |
- */ |
- function closeOthers() |
- { |
- this._closeTabs(this._tabbedPane.otherTabs(this.id)); |
- } |
- |
- /** |
- * @this {WebInspector.TabbedPaneTab} |
- */ |
- function closeAll() |
- { |
- this._closeTabs(this._tabbedPane.allTabs()); |
- } |
- |
- /** |
- * @this {WebInspector.TabbedPaneTab} |
- */ |
- function closeToTheRight() |
- { |
- this._closeTabs(this._tabbedPane._tabsToTheRight(this.id)); |
- } |
- |
- var contextMenu = new WebInspector.ContextMenu(event); |
- if (this._closeable) { |
- contextMenu.appendItem(WebInspector.UIString.capitalize("Close"), close.bind(this)); |
- contextMenu.appendItem(WebInspector.UIString.capitalize("Close ^others"), closeOthers.bind(this)); |
- contextMenu.appendItem(WebInspector.UIString.capitalize("Close ^tabs to the ^right"), closeToTheRight.bind(this)); |
- contextMenu.appendItem(WebInspector.UIString.capitalize("Close ^all"), closeAll.bind(this)); |
- } |
- if (this._delegate) |
- this._delegate.onContextMenu(this.id, contextMenu); |
- contextMenu.show(); |
- }, |
+ function closeAll() { |
+ this._closeTabs(this._tabbedPane.allTabs()); |
+ } |
/** |
- * @param {!Event} event |
- * @return {boolean} |
+ * @this {WebInspector.TabbedPaneTab} |
*/ |
- _startTabDragging: function(event) |
- { |
- if (event.target.classList.contains("tabbed-pane-close-button")) |
- return false; |
- this._dragStartX = event.pageX; |
- this._tabElement.classList.add("dragging"); |
- this._tabbedPane._tabSlider.remove(); |
- return true; |
- }, |
+ function closeToTheRight() { |
+ this._closeTabs(this._tabbedPane._tabsToTheRight(this.id)); |
+ } |
- /** |
- * @param {!Event} event |
- */ |
- _tabDragging: function(event) |
- { |
- var tabElements = this._tabbedPane._tabsElement.childNodes; |
- for (var i = 0; i < tabElements.length; ++i) { |
- var tabElement = tabElements[i]; |
- if (tabElement === this._tabElement) |
- continue; |
- |
- var intersects = tabElement.offsetLeft + tabElement.clientWidth > this._tabElement.offsetLeft && |
- this._tabElement.offsetLeft + this._tabElement.clientWidth > tabElement.offsetLeft; |
- if (!intersects) |
- continue; |
- |
- if (Math.abs(event.pageX - this._dragStartX) < tabElement.clientWidth / 2 + 5) |
- break; |
- |
- if (event.pageX - this._dragStartX > 0) { |
- tabElement = tabElement.nextSibling; |
- ++i; |
- } |
- |
- var oldOffsetLeft = this._tabElement.offsetLeft; |
- this._tabbedPane._insertBefore(this, i); |
- this._dragStartX += this._tabElement.offsetLeft - oldOffsetLeft; |
- break; |
- } |
- |
- if (!this._tabElement.previousSibling && event.pageX - this._dragStartX < 0) { |
- this._tabElement.style.setProperty("left", "0px"); |
- return; |
- } |
- if (!this._tabElement.nextSibling && event.pageX - this._dragStartX > 0) { |
- this._tabElement.style.setProperty("left", "0px"); |
- return; |
- } |
- |
- this._tabElement.style.setProperty("left", (event.pageX - this._dragStartX) + "px"); |
- }, |
+ var contextMenu = new WebInspector.ContextMenu(event); |
+ if (this._closeable) { |
+ contextMenu.appendItem(WebInspector.UIString.capitalize('Close'), close.bind(this)); |
+ contextMenu.appendItem(WebInspector.UIString.capitalize('Close ^others'), closeOthers.bind(this)); |
+ contextMenu.appendItem(WebInspector.UIString.capitalize('Close ^tabs to the ^right'), closeToTheRight.bind(this)); |
+ contextMenu.appendItem(WebInspector.UIString.capitalize('Close ^all'), closeAll.bind(this)); |
+ } |
+ if (this._delegate) |
+ this._delegate.onContextMenu(this.id, contextMenu); |
+ contextMenu.show(); |
+ } |
+ |
+ /** |
+ * @param {!Event} event |
+ * @return {boolean} |
+ */ |
+ _startTabDragging(event) { |
+ if (event.target.classList.contains('tabbed-pane-close-button')) |
+ return false; |
+ this._dragStartX = event.pageX; |
+ this._tabElement.classList.add('dragging'); |
+ this._tabbedPane._tabSlider.remove(); |
+ return true; |
+ } |
+ |
+ /** |
+ * @param {!Event} event |
+ */ |
+ _tabDragging(event) { |
+ var tabElements = this._tabbedPane._tabsElement.childNodes; |
+ for (var i = 0; i < tabElements.length; ++i) { |
+ var tabElement = tabElements[i]; |
+ if (tabElement === this._tabElement) |
+ continue; |
+ |
+ var intersects = tabElement.offsetLeft + tabElement.clientWidth > this._tabElement.offsetLeft && |
+ this._tabElement.offsetLeft + this._tabElement.clientWidth > tabElement.offsetLeft; |
+ if (!intersects) |
+ continue; |
+ |
+ if (Math.abs(event.pageX - this._dragStartX) < tabElement.clientWidth / 2 + 5) |
+ break; |
+ |
+ if (event.pageX - this._dragStartX > 0) { |
+ tabElement = tabElement.nextSibling; |
+ ++i; |
+ } |
+ |
+ var oldOffsetLeft = this._tabElement.offsetLeft; |
+ this._tabbedPane._insertBefore(this, i); |
+ this._dragStartX += this._tabElement.offsetLeft - oldOffsetLeft; |
+ break; |
+ } |
- /** |
- * @param {!Event} event |
- */ |
- _endTabDragging: function(event) |
- { |
- this._tabElement.classList.remove("dragging"); |
- this._tabElement.style.removeProperty("left"); |
- delete this._dragStartX; |
- this._tabbedPane._updateTabSlider(); |
+ if (!this._tabElement.previousSibling && event.pageX - this._dragStartX < 0) { |
+ this._tabElement.style.setProperty('left', '0px'); |
+ return; |
+ } |
+ if (!this._tabElement.nextSibling && event.pageX - this._dragStartX > 0) { |
+ this._tabElement.style.setProperty('left', '0px'); |
+ return; |
} |
+ |
+ this._tabElement.style.setProperty('left', (event.pageX - this._dragStartX) + 'px'); |
+ } |
+ |
+ /** |
+ * @param {!Event} event |
+ */ |
+ _endTabDragging(event) { |
+ this._tabElement.classList.remove('dragging'); |
+ this._tabElement.style.removeProperty('left'); |
+ delete this._dragStartX; |
+ this._tabbedPane._updateTabSlider(); |
+ } |
}; |
/** |
* @interface |
*/ |
-WebInspector.TabbedPaneTabDelegate = function() |
-{ |
-}; |
+WebInspector.TabbedPaneTabDelegate = function() {}; |
WebInspector.TabbedPaneTabDelegate.prototype = { |
- /** |
- * @param {!WebInspector.TabbedPane} tabbedPane |
- * @param {!Array.<string>} ids |
- */ |
- closeTabs: function(tabbedPane, ids) { }, |
- |
- /** |
- * @param {string} tabId |
- * @param {!WebInspector.ContextMenu} contextMenu |
- */ |
- onContextMenu: function(tabId, contextMenu) { } |
+ /** |
+ * @param {!WebInspector.TabbedPane} tabbedPane |
+ * @param {!Array.<string>} ids |
+ */ |
+ closeTabs: function(tabbedPane, ids) {}, |
+ |
+ /** |
+ * @param {string} tabId |
+ * @param {!WebInspector.ContextMenu} contextMenu |
+ */ |
+ onContextMenu: function(tabId, contextMenu) {} |
}; |