Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (193431 => 193432)
--- trunk/Source/WebInspectorUI/ChangeLog 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/ChangeLog 2015-12-04 19:53:05 UTC (rev 193432)
@@ -1,3 +1,101 @@
+2015-12-04 Brian Burg <bb...@apple.com>
+
+ Web Inspector: support runtime registration of tab type associations
+ https://bugs.webkit.org/show_bug.cgi?id=151594
+
+ Reviewed by Joseph Pecoraro.
+
+ We want to add special tabs that only exist in engineering builds
+ for debugging purposes. Though the relevant models and views can be
+ put in the Debug/ directory to exclude them from production builds,
+ there's no way to register tabs conditionally at runtime; tabs are
+ hardcoded.
+
+ This patch makes it possible to register new tab types at runtime.
+ First, WebInspector keeps a map of known, registered tab classes.
+ Details that were hardcoded before---whether to show in New Tab,
+ whether a tab can be instantiated given the active domains, UI text,
+ etc.---are now static methods on the base TabContentView or overidden
+ in its subclasses. Lastly, a public method allows code in Bootstrap.js
+ to register tabs at runtime. Doing so sends a notification so the
+ NewTabContentView can show the newly available tab item.
+
+ * UserInterface/Base/Main.js:
+ (WebInspector.contentLoaded):
+ (WebInspector.isTabTypeAllowed):
+ (WebInspector.knownTabClasses): Added, used by NewTabContentView.
+ (WebInspector._createTabContentViewForType): Renamed from _tabContentViewForType.
+ (WebInspector._rememberOpenTabs):
+ (WebInspector._updateNewTabButtonState):
+ (WebInspector._tryToRestorePendingTabs): Added.
+
+ Whenever a new tab is registered, try to restore pending tabs, since
+ an extra tab won't be added initially when production tabs are added.
+ But, it could have been saved in the Setting for opened tabs.
+
+ (WebInspector.showNewTabTab):
+ (WebInspector.isNewTabWithTypeAllowed):
+ (WebInspector.createNewTabWithType):
+ (WebInspector._tabContentViewForType): Deleted.
+ * UserInterface/Base/Object.js:
+ * UserInterface/Views/ConsoleTabContentView.js:
+ (WebInspector.ConsoleTabContentView):
+ (WebInspector.ConsoleTabContentView.tabInfo): Added.
+ * UserInterface/Views/DebuggerTabContentView.js:
+ (WebInspector.DebuggerTabContentView):
+ (WebInspector.DebuggerTabContentView.tabInfo): Added.
+ * UserInterface/Views/ElementsTabContentView.js:
+ (WebInspector.ElementsTabContentView):
+ (WebInspector.ElementsTabContentView.tabInfo): Added.
+ (WebInspector.ElementsTabContentView.isTabAllowed): Added.
+ * UserInterface/Views/NetworkTabContentView.js:
+ (WebInspector.NetworkTabContentView):
+ (WebInspector.NetworkTabContentView.tabInfo): Added.
+ (WebInspector.NetworkTabContentView.isTabAllowed): Added.
+ * UserInterface/Views/NewTabContentView.js:
+
+ Keep a list of shown tab items, so we don't have to query the DOM
+ to update enabled/disabled state. Put tree construction inside a
+ layout() override and dirty the view whenever known tab types change.
+
+ (WebInspector.NewTabContentView):
+ (WebInspector.NewTabContentView.tabInfo): Added.
+ (WebInspector.NewTabContentView.isEphemeral): Added.
+ (WebInspector.NewTabContentView.shouldSaveTab): Added.
+ (WebInspector.NewTabContentView.prototype.layout): Added.
+ (WebInspector.NewTabContentView.prototype._updateShownTabs): Added.
+ (WebInspector.NewTabContentView.prototype._allowableTabTypes):
+ (WebInspector.NewTabContentView.prototype._updateTabItems):
+ (WebInspector.NewTabContentView.prototype.get tabItemElements): Deleted.
+ * UserInterface/Views/ResourcesTabContentView.js:
+ (WebInspector.ResourcesTabContentView):
+ (WebInspector.ResourcesTabContentView.tabInfo): Added.
+ * UserInterface/Views/SearchTabContentView.js:
+ (WebInspector.SearchTabContentView):
+ (WebInspector.SearchTabContentView.tabInfo): Added.
+ (WebInspector.SearchTabContentView.isEphemeral): Added.
+ * UserInterface/Views/SettingsTabContentView.js:
+ (WebInspector.SettingsTabContentView.isTabAllowed): Added.
+ (WebInspector.SettingsTabContentView.shouldSaveTab): Added.
+ * UserInterface/Views/StorageTabContentView.js:
+ (WebInspector.StorageTabContentView):
+ (WebInspector.StorageTabContentView.tabInfo): Added.
+ (WebInspector.StorageTabContentView.isTabAllowed): Added.
+ * UserInterface/Views/TabBrowser.js:
+ (WebInspector.TabBrowser.showTabForContentView):
+
+ Add a workaround for <https://webkit.org/b/151876>. This bug is
+ revealed by the changes to NewTabContentView in this patch.
+
+ * UserInterface/Views/TabContentView.js:
+ (WebInspector.TabContentView.isTabAllowed): Added.
+ (WebInspector.TabContentView.isEphemeral): Added.
+ (WebInspector.TabContentView.shouldSaveTab): Added.
+ * UserInterface/Views/TimelineTabContentView.js:
+ (WebInspector.TimelineTabContentView):
+ (WebInspector.TimelineTabContentView.tabInfo): Added.
+ (WebInspector.TimelineTabContentView.isTabAllowed): Added.
+
2015-12-04 Joseph Pecoraro <pecor...@apple.com>
Web Inspector: Remove untested and unused Worker inspection
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Main.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Main.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Main.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -365,6 +365,26 @@
this._updateToolbarHeight();
this._setupViewHierarchy();
+ // These tabs are always available for selecting, modulo isTabAllowed().
+ // Other tabs may be engineering-only or toggled at runtime if incomplete.
+ let productionTabClasses = [
+ WebInspector.ConsoleTabContentView,
+ WebInspector.DebuggerTabContentView,
+ WebInspector.ElementsTabContentView,
+ WebInspector.NetworkTabContentView,
+ WebInspector.NewTabContentView,
+ WebInspector.ResourcesTabContentView,
+ WebInspector.SearchTabContentView,
+ WebInspector.StorageTabContentView,
+ WebInspector.TimelineTabContentView,
+ ];
+
+ this._knownTabClassesByType = new Map;
+ // Set tab classes directly. The public API triggers other updates and
+ // notifications that won't work or have no listeners at this point.
+ for (let tabClass of productionTabClasses)
+ this._knownTabClassesByType.set(tabClass.Type, tabClass);
+
this._pendingOpenTabs = [];
let openTabTypes = this._openTabsSetting.value;
@@ -376,7 +396,7 @@
continue;
}
- let tabContentView = this._tabContentViewForType(tabType);
+ let tabContentView = this._createTabContentViewForType(tabType);
if (!tabContentView)
continue;
this.tabBrowser.addTabForContentView(tabContentView, true);
@@ -417,57 +437,39 @@
WebInspector.isTabTypeAllowed = function(tabType)
{
- switch (tabType) {
- case WebInspector.ElementsTabContentView.Type:
- return !!window.DOMAgent;
- case WebInspector.NetworkTabContentView.Type:
- return !!window.NetworkAgent && !!window.PageAgent;
- case WebInspector.StorageTabContentView.Type:
- return !!window.DOMStorageAgent || !!window.DatabaseAgent || !!window.IndexedDBAgent;
- case WebInspector.TimelineTabContentView.Type:
- return !!window.TimelineAgent;
- }
+ let tabClass = this._knownTabClassesByType.get(tabType);
+ if (!tabClass)
+ return false;
- return true;
+ return tabClass.isTabAllowed();
};
-WebInspector._tabContentViewForType = function(tabType)
+WebInspector.knownTabClasses = function()
{
- switch (tabType) {
- case WebInspector.ConsoleTabContentView.Type:
- return new WebInspector.ConsoleTabContentView;
- case WebInspector.DebuggerTabContentView.Type:
- return new WebInspector.DebuggerTabContentView;
- case WebInspector.ElementsTabContentView.Type:
- return new WebInspector.ElementsTabContentView;
- case WebInspector.NetworkTabContentView.Type:
- return new WebInspector.NetworkTabContentView;
- case WebInspector.NewTabContentView.Type:
- return new WebInspector.NewTabContentView;
- case WebInspector.ResourcesTabContentView.Type:
- return new WebInspector.ResourcesTabContentView;
- case WebInspector.SearchTabContentView.Type:
- return new WebInspector.SearchTabContentView;
- case WebInspector.StorageTabContentView.Type:
- return new WebInspector.StorageTabContentView;
- case WebInspector.TimelineTabContentView.Type:
- return new WebInspector.TimelineTabContentView;
- default:
+ return new Set(this._knownTabClassesByType.values());
+}
+
+WebInspector._createTabContentViewForType = function(tabType)
+{
+ let tabClass = this._knownTabClassesByType.get(tabType);
+ if (!tabClass) {
console.error("Unknown tab type", tabType);
+ return null;
}
- return null;
+ console.assert(WebInspector.TabContentView.isPrototypeOf(tabClass));
+ return new tabClass;
};
WebInspector._rememberOpenTabs = function()
{
- var openTabs = [];
+ let openTabs = [];
- for (var tabBarItem of this.tabBar.tabBarItems) {
- var tabContentView = tabBarItem.representedObject;
+ for (let tabBarItem of this.tabBar.tabBarItems) {
+ let tabContentView = tabBarItem.representedObject;
if (!(tabContentView instanceof WebInspector.TabContentView))
continue;
- if (tabContentView instanceof WebInspector.SettingsTabContentView || tabContentView instanceof WebInspector.NewTabContentView)
+ if (!tabContentView.constructor.shouldSaveTab())
continue;
console.assert(tabContentView.type, "Tab type can't be null, undefined, or empty string", tabContentView.type, tabContentView);
openTabs.push(tabContentView.type);
@@ -482,11 +484,10 @@
WebInspector._updateNewTabButtonState = function(event)
{
- var newTabAllowed = this.isNewTabWithTypeAllowed(WebInspector.ConsoleTabContentView.Type) || this.isNewTabWithTypeAllowed(WebInspector.ElementsTabContentView.Type)
- || this.isNewTabWithTypeAllowed(WebInspector.ResourcesTabContentView.Type) || this.isNewTabWithTypeAllowed(WebInspector.StorageTabContentView.Type)
- || this.isNewTabWithTypeAllowed(WebInspector.TimelineTabContentView.Type) || this.isNewTabWithTypeAllowed(WebInspector.DebuggerTabContentView.Type)
- || this.isNewTabWithTypeAllowed(WebInspector.NetworkTabContentView.Type);
- this.tabBar.newTabItem.disabled = !newTabAllowed;
+ let allTabs = [...this._knownTabClassesByType.values()];
+ let addableTabs = allTabs.filter((tabClass) => !tabClass.isEphemeral());
+ let canMakeNewTab = addableTabs.some((tabClass) => this.isNewTabWithTypeAllowed(tabClass.Type));
+ this.tabBar.newTabItem.disabled = !canMakeNewTab;
};
WebInspector._newTabItemClicked = function(event)
@@ -500,9 +501,32 @@
this.showNewTabTab();
};
+WebInspector._tryToRestorePendingTabs = function()
+{
+ let stillPendingOpenTabs = [];
+ for (let {tabType, index} of this._pendingOpenTabs) {
+ if (!this.isTabTypeAllowed(tabType)) {
+ stillPendingOpenTabs.push({tabType, index});
+ continue;
+ }
+
+ let tabContentView = this._createTabContentViewForType(tabType);
+ if (!tabContentView)
+ continue;
+
+ this.tabBrowser.addTabForContentView(tabContentView, true, index);
+
+ tabContentView.restoreStateFromCookie(WebInspector.StateRestorationType.Load);
+ }
+
+ this._pendingOpenTabs = stillPendingOpenTabs;
+
+ this._updateNewTabButtonState();
+}
+
WebInspector.showNewTabTab = function(shouldAnimate)
{
- var tabContentView = this.tabBrowser.bestTabContentViewForClass(WebInspector.NewTabContentView);
+ let tabContentView = this.tabBrowser.bestTabContentViewForClass(WebInspector.NewTabContentView);
if (!tabContentView)
tabContentView = new WebInspector.NewTabContentView;
this.tabBrowser.showTabForContentView(tabContentView, !shouldAnimate);
@@ -510,15 +534,16 @@
WebInspector.isNewTabWithTypeAllowed = function(tabType)
{
- if (!this.isTabTypeAllowed(tabType))
+ let tabClass = this._knownTabClassesByType.get(tabType);
+ if (!tabClass || !tabClass.isTabAllowed())
return false;
// Only allow one tab per class for now.
- for (var tabBarItem of this.tabBar.tabBarItems) {
- var tabContentView = tabBarItem.representedObject;
+ for (let tabBarItem of this.tabBar.tabBarItems) {
+ let tabContentView = tabBarItem.representedObject;
if (!(tabContentView instanceof WebInspector.TabContentView))
continue;
- if (tabContentView.type === tabType)
+ if (tabContentView.constructor === tabClass)
return false;
}
@@ -533,7 +558,7 @@
console.assert(!referencedView || referencedView instanceof WebInspector.TabContentView, referencedView);
console.assert(!shouldReplaceTab || referencedView, "Must provide a reference view to replace a tab.");
- let tabContentView = this._tabContentViewForType(tabType);
+ let tabContentView = this._createTabContentViewForType(tabType);
const suppressAnimations = true;
let insertionIndex = referencedView ? this.tabBar.tabBarItems.indexOf(referencedView.tabBarItem) : undefined;
this.tabBrowser.addTabForContentView(tabContentView, suppressAnimations, insertionIndex);
@@ -545,6 +570,21 @@
this.tabBrowser.showTabForContentView(tabContentView);
};
+WebInspector.registerTabClass = function(tabClass)
+{
+ console.assert(WebInspector.TabContentView.isPrototypeOf(tabClass));
+ if (!WebInspector.TabContentView.isPrototypeOf(tabClass))
+ return;
+
+ if (this._knownTabClassesByType.has(tabClass.Type))
+ return;
+
+ this._knownTabClassesByType.set(tabClass.Type, tabClass);
+
+ this._tryToRestorePendingTabs();
+ this.notifications.dispatchEventToListeners(WebInspector.Notification.TabTypesChanged);
+}
+
WebInspector.activateExtraDomains = function(domains)
{
this.hasExtraDomains = true;
@@ -561,26 +601,7 @@
this._updateReloadToolbarButton();
this._updateDownloadToolbarButton();
-
- let stillPendingOpenTabs = [];
- for (let {tabType, index} of this._pendingOpenTabs) {
- if (!this.isTabTypeAllowed(tabType)) {
- stillPendingOpenTabs.push({tabType, index});
- continue;
- }
-
- let tabContentView = this._tabContentViewForType(tabType);
- if (!tabContentView)
- continue;
-
- this.tabBrowser.addTabForContentView(tabContentView, true, index);
-
- tabContentView.restoreStateFromCookie(WebInspector.StateRestorationType.Load);
- }
-
- this._pendingOpenTabs = stillPendingOpenTabs;
-
- this._updateNewTabButtonState();
+ this._tryToRestorePendingTabs();
};
WebInspector.contentBrowserTreeElementForRepresentedObject = function(contentBrowser, representedObject)
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Object.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Object.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Object.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -208,4 +208,5 @@
PageArchiveStarted: "page-archive-started",
PageArchiveEnded: "page-archive-ended",
ExtraDomainsActivated: "extra-domains-activated",
+ TabTypesChanged: "tab-types-changed",
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleTabContentView.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleTabContentView.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleTabContentView.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -27,11 +27,20 @@
{
constructor(identifier)
{
- var tabBarItem = new WebInspector.TabBarItem("Images/Console.svg", WebInspector.UIString("Console"));
+ let {image, title} = WebInspector.ConsoleTabContentView.tabInfo();
+ let tabBarItem = new WebInspector.TabBarItem(image, title);
super(identifier || "console", "console", tabBarItem, null, null, true);
}
+ static tabInfo()
+ {
+ return {
+ image: "Images/Console.svg",
+ title: WebInspector.UIString("Console"),
+ };
+ }
+
// Public
get type()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerTabContentView.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerTabContentView.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerTabContentView.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -27,12 +27,21 @@
{
constructor(identifier)
{
- var tabBarItem = new WebInspector.TabBarItem("Images/Debugger.svg", WebInspector.UIString("Debugger"));
- var detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.scopeChainDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
+ let {image, title} = WebInspector.DebuggerTabContentView.tabInfo();
+ let tabBarItem = new WebInspector.TabBarItem(image, title);
+ let detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.scopeChainDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
super(identifier || "debugger", "debugger", tabBarItem, WebInspector.DebuggerSidebarPanel, detailsSidebarPanels);
}
+ static tabInfo()
+ {
+ return {
+ image: "Images/Debugger.svg",
+ title: WebInspector.UIString("Debugger"),
+ };
+ }
+
// Public
get type()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ElementsTabContentView.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ElementsTabContentView.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ElementsTabContentView.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -27,8 +27,9 @@
{
constructor(identifier)
{
- var tabBarItem = new WebInspector.TabBarItem("Images/Elements.svg", WebInspector.UIString("Elements"));
- var detailsSidebarPanels = [WebInspector.domNodeDetailsSidebarPanel, WebInspector.cssStyleDetailsSidebarPanel];
+ let {image, title} = WebInspector.ElementsTabContentView.tabInfo();
+ let tabBarItem = new WebInspector.TabBarItem(image, title);
+ let detailsSidebarPanels = [WebInspector.domNodeDetailsSidebarPanel, WebInspector.cssStyleDetailsSidebarPanel];
if (WebInspector.layerTreeDetailsSidebarPanel)
detailsSidebarPanels.push(WebInspector.layerTreeDetailsSidebarPanel);
@@ -41,6 +42,19 @@
this._showDOMTreeContentView();
}
+ static tabInfo()
+ {
+ return {
+ image: "Images/Elements.svg",
+ title: WebInspector.UIString("Elements"),
+ };
+ }
+
+ static isTabAllowed()
+ {
+ return !!window.DOMAgent;
+ }
+
// Public
get type()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTabContentView.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTabContentView.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTabContentView.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -27,12 +27,26 @@
{
constructor(identifier)
{
- var tabBarItem = new WebInspector.TabBarItem("Images/Network.svg", WebInspector.UIString("Network"));
- var detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
+ let {image, title} = WebInspector.NetworkTabContentView.tabInfo();
+ let tabBarItem = new WebInspector.TabBarItem(image, title);
+ let detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
super(identifier || "network", "network", tabBarItem, WebInspector.NetworkSidebarPanel, detailsSidebarPanels);
}
+ static tabInfo()
+ {
+ return {
+ image: "Images/Network.svg",
+ title: WebInspector.UIString("Network"),
+ };
+ }
+
+ static isTabAllowed()
+ {
+ return !!window.NetworkAgent && !!window.PageAgent;
+ }
+
// Public
get type()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NewTabContentView.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NewTabContentView.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NewTabContentView.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -27,43 +27,34 @@
{
constructor(identifier)
{
- var tabBarItem = new WebInspector.TabBarItem("Images/NewTab.svg", WebInspector.UIString("New Tab"));
+ let {image, title} = WebInspector.NewTabContentView.tabInfo();
+ let tabBarItem = new WebInspector.TabBarItem(image, title);
tabBarItem.isDefaultTab = true;
super(identifier || "new-tab", "new-tab", tabBarItem);
- var allowedNewTabs = [
- {image: "Images/Console.svg", title: WebInspector.UIString("Console"), type: WebInspector.ConsoleTabContentView.Type},
- {image: "Images/Debugger.svg", title: WebInspector.UIString("Debugger"), type: WebInspector.DebuggerTabContentView.Type},
- {image: "Images/Elements.svg", title: WebInspector.UIString("Elements"), type: WebInspector.ElementsTabContentView.Type},
- {image: "Images/Network.svg", title: WebInspector.UIString("Network"), type: WebInspector.NetworkTabContentView.Type},
- {image: "Images/Resources.svg", title: WebInspector.UIString("Resources"), type: WebInspector.ResourcesTabContentView.Type},
- {image: "Images/Storage.svg", title: WebInspector.UIString("Storage"), type: WebInspector.StorageTabContentView.Type},
- {image: "Images/Timeline.svg", title: WebInspector.UIString("Timelines"), type: WebInspector.TimelineTabContentView.Type}
- ];
+ WebInspector.notifications.addEventListener(WebInspector.Notification.TabTypesChanged, this._updateShownTabs.bind(this));
- allowedNewTabs.sort(function(a, b) { return a.title.localeCompare(b.title); });
+ this._tabElementsByTabClass = new Map;
+ this._updateShownTabs();
+ }
- for (var info of allowedNewTabs) {
- if (!WebInspector.isTabTypeAllowed(info.type))
- continue;
+ static tabInfo()
+ {
+ return {
+ image: "Images/NewTab.svg",
+ title: WebInspector.UIString("New Tab"),
+ };
+ }
- var tabItemElement = document.createElement("div");
- tabItemElement.classList.add(WebInspector.NewTabContentView.TabItemStyleClassName);
- tabItemElement.addEventListener("click", this._createNewTabWithType.bind(this, info.type));
- tabItemElement[WebInspector.NewTabContentView.TypeSymbol] = info.type;
+ static isEphemeral()
+ {
+ return true;
+ }
- var boxElement = tabItemElement.appendChild(document.createElement("div"));
- boxElement.classList.add("box");
-
- var imageElement = boxElement.appendChild(document.createElement("img"));
- imageElement.src = ""
-
- var labelElement = tabItemElement.appendChild(document.createElement("label"));
- labelElement.textContent = info.title;
-
- this.element.appendChild(tabItemElement);
- }
+ static shouldSaveTab()
+ {
+ return false;
}
// Public
@@ -93,9 +84,32 @@
return false;
}
- get tabItemElements()
+ layout()
{
- return Array.from(this.element.querySelectorAll("." + WebInspector.NewTabContentView.TabItemStyleClassName));
+ this._tabElementsByTabClass.clear();
+ this.element.removeChildren();
+
+ for (let tabClass of this._shownTabClasses) {
+ let tabItemElement = document.createElement("div");
+ tabItemElement.classList.add("tab-item");
+ tabItemElement.addEventListener("click", this._createNewTabWithType.bind(this, tabClass.Type));
+ tabItemElement[WebInspector.NewTabContentView.TypeSymbol] = tabClass.Type;
+
+ let boxElement = tabItemElement.appendChild(document.createElement("div"));
+ boxElement.classList.add("box");
+
+ let info = tabClass.tabInfo();
+ let imageElement = boxElement.appendChild(document.createElement("img"));
+ imageElement.src = ""
+
+ let labelElement = tabItemElement.appendChild(document.createElement("label"));
+ labelElement.textContent = info.title;
+
+ this.element.appendChild(tabItemElement);
+ this._tabElementsByTabClass.set(tabClass, tabItemElement);
+ }
+
+ this._updateTabItems();
}
// Private
@@ -114,19 +128,29 @@
WebInspector.createNewTabWithType(tabType, options);
}
+ _updateShownTabs()
+ {
+ let allTabClasses = [...WebInspector.knownTabClasses()];
+ let allowedTabClasses = allTabClasses.filter((tabClass) => tabClass.isTabAllowed() && !tabClass.isEphemeral());
+ allowedTabClasses.sort((a, b) => a.tabInfo().title.localeCompare(b.tabInfo().title));
+
+ if (Object.shallowEqual(this._shownTabClasses, allowedTabClasses))
+ return;
+
+ this._shownTabClasses = allowedTabClasses;
+ this.needsLayout();
+ }
+
_allowableTabTypes()
{
- let tabItemElements = this.tabItemElements;
- let tabTypes = tabItemElements.map((tabItemElement) => tabItemElement[WebInspector.NewTabContentView.TypeSymbol]);
+ let tabTypes = this._shownTabClasses.map((tabClass) => tabClass.Type);
return tabTypes.filter((type) => WebInspector.isNewTabWithTypeAllowed(type));
}
_updateTabItems()
{
- let tabItemElements = this.tabItemElements;
- for (let tabItemElement of tabItemElements) {
- let type = tabItemElement[WebInspector.NewTabContentView.TypeSymbol];
- let allowed = WebInspector.isNewTabWithTypeAllowed(type);
+ for (let [tabClass, tabItemElement] of this._tabElementsByTabClass.entries()) {
+ let allowed = WebInspector.isNewTabWithTypeAllowed(tabClass.Type);
tabItemElement.classList.toggle(WebInspector.NewTabContentView.DisabledStyleClassName, !allowed);
}
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ResourcesTabContentView.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourcesTabContentView.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourcesTabContentView.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -27,8 +27,9 @@
{
constructor(identifier)
{
- var tabBarItem = new WebInspector.TabBarItem("Images/Resources.svg", WebInspector.UIString("Resources"));
- var detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
+ let {image, title} = WebInspector.ResourcesTabContentView.tabInfo();
+ let tabBarItem = new WebInspector.TabBarItem(image, title);
+ let detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
// FIXME: Until ContentFlows are moved to the Elements tab, these details sidebar panels need to be included.
detailsSidebarPanels = detailsSidebarPanels.concat([WebInspector.domNodeDetailsSidebarPanel, WebInspector.cssStyleDetailsSidebarPanel]);
@@ -38,6 +39,14 @@
super(identifier || "resources", "resources", tabBarItem, WebInspector.ResourceSidebarPanel, detailsSidebarPanels);
}
+ static tabInfo()
+ {
+ return {
+ image: "Images/Resources.svg",
+ title: WebInspector.UIString("Resources"),
+ };
+ }
+
// Public
get type()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SearchTabContentView.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SearchTabContentView.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SearchTabContentView.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -27,8 +27,9 @@
{
constructor(identifier)
{
- var tabBarItem = new WebInspector.TabBarItem("Images/SearchResults.svg", WebInspector.UIString("Search"));
- var detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel,
+ let {image, title} = WebInspector.SearchTabContentView.tabInfo();
+ let tabBarItem = new WebInspector.TabBarItem(image, title);
+ let detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel,
WebInspector.domNodeDetailsSidebarPanel, WebInspector.cssStyleDetailsSidebarPanel];
if (WebInspector.layerTreeDetailsSidebarPanel)
@@ -37,6 +38,19 @@
super(identifier || "search", "search", tabBarItem, WebInspector.SearchSidebarPanel, detailsSidebarPanels);
}
+ static tabInfo()
+ {
+ return {
+ image: "Images/SearchResults.svg",
+ title: WebInspector.UIString("Search"),
+ };
+ }
+
+ static isEphemeral()
+ {
+ return true;
+ }
+
// Public
get type()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -32,6 +32,17 @@
super(identifier || "settings", "settings", tabBarItem);
}
+ static isTabAllowed()
+ {
+ // FIXME (149284): This tab isn't ready to be shown yet.
+ return false;
+ }
+
+ static shouldSaveTab()
+ {
+ return false;
+ }
+
// Public
get type()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/StorageTabContentView.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Views/StorageTabContentView.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/StorageTabContentView.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -27,12 +27,26 @@
{
constructor(identifier)
{
- var tabBarItem = new WebInspector.TabBarItem("Images/Storage.svg", WebInspector.UIString("Storage"));
- var detailsSidebarPanels = [WebInspector.applicationCacheDetailsSidebarPanel];
+ let {image, title} = WebInspector.StorageTabContentView.tabInfo();
+ let tabBarItem = new WebInspector.TabBarItem(image, title);
+ let detailsSidebarPanels = [WebInspector.applicationCacheDetailsSidebarPanel];
super(identifier || "storage", "storage", tabBarItem, WebInspector.StorageSidebarPanel, detailsSidebarPanels);
}
+ static tabInfo()
+ {
+ return {
+ image: "Images/Storage.svg",
+ title: WebInspector.UIString("Storage"),
+ };
+ }
+
+ static isTabAllowed()
+ {
+ return !!window.DOMStorageAgent || !!window.DatabaseAgent || !!window.IndexedDBAgent;
+ }
+
// Public
get type()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TabBrowser.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TabBrowser.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TabBrowser.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -160,6 +160,13 @@
this._tabBar.selectedTabBarItem = tabContentView.tabBarItem;
+ // FIXME: this is a workaround for <https://webkit.org/b/151876>.
+ // Without this extra call, we might never lay out the child tab
+ // if it has already marked itself as dirty in the same run loop
+ // as it is attached. It will schedule a layout, but when the rAF
+ // fires the parent will abort the layout because the counter is
+ // out of sync.
+ this.needsLayout();
return true;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TabContentView.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TabContentView.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TabContentView.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -55,6 +55,24 @@
this._cookieSetting = new WebInspector.Setting(identifier + "-tab-cookie", {});
}
+ static isTabAllowed()
+ {
+ // Returns false if a necessary domain or other features are unavailable.
+ return true;
+ }
+
+ static isEphemeral()
+ {
+ // Returns true if the tab should not be shown in the new tab content view.
+ return false;
+ }
+
+ static shouldSaveTab()
+ {
+ // Returns false if the tab should not be restored when re-opening the Inspector.
+ return true;
+ }
+
// Public
get type()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineTabContentView.js (193431 => 193432)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineTabContentView.js 2015-12-04 19:41:52 UTC (rev 193431)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineTabContentView.js 2015-12-04 19:53:05 UTC (rev 193432)
@@ -27,12 +27,26 @@
{
constructor(identifier)
{
- var tabBarItem = new WebInspector.TabBarItem("Images/Timeline.svg", WebInspector.UIString("Timelines"));
- var detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
+ let {image, title} = WebInspector.TimelineTabContentView.tabInfo();
+ let tabBarItem = new WebInspector.TabBarItem(image, title);
+ let detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
super(identifier || "timeline", "timeline", tabBarItem, WebInspector.TimelineSidebarPanel, detailsSidebarPanels);
}
+ static tabInfo()
+ {
+ return {
+ image: "Images/Timeline.svg",
+ title: WebInspector.UIString("Timelines"),
+ };
+ }
+
+ static isTabAllowed()
+ {
+ return !!window.TimelineAgent;
+ }
+
// Public
get type()