Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(795)

Unified Diff: third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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) {}
};

Powered by Google App Engine
This is Rietveld 408576698