Web Inspector: TabBar redesign: remove top-level search field and pin the Search tab
authormattbaker@apple.com <mattbaker@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Feb 2018 22:06:01 +0000 (22:06 +0000)
committermattbaker@apple.com <mattbaker@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Feb 2018 22:06:01 +0000 (22:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=182353
<rdar://problem/37088644>

Reviewed by Devin Rousso.

* Localizations/en.lproj/localizedStrings.js:

* UserInterface/Base/Main.js:
(WI.contentLoaded):
Create Search UI based on experimental setting. When the new TabBar is
enabled, the Search tab is a pinned tab. Since it is also saveable, it
needs to be added to the TabBrowser (the browser adds the item to the bar).

When restoring saved tabs, make an additional check to prevent a tab
from being added twice. This can occur now that the Search tab is pinned.

* UserInterface/Images/Search.svg:
Update art to better match Safari/macOS. Slightly increase the radius of
the lens, and shorten the length of the handle.

* UserInterface/Views/GoToLineDialog.css:
(.go-to-line-dialog > div::before):
Update styles for new Search icon.

* UserInterface/Views/LegacyTabBar.js:
(WI.LegacyTabBar.prototype.get saveableTabCount):
Backported new TabBar method which is called by TabBrowser.

* UserInterface/Views/OpenResourceDialog.css:
(.open-resource-dialog > .field::before):
Update styles for new Search icon.

* UserInterface/Views/PinnedTabBarItem.js:
(WI.PinnedTabBarItem.prototype.fromTabInfo):
Match GeneralTabBarItem.fromTabInfo.

* UserInterface/Views/SearchTabContentView.js:
(WI.SearchTabContentView):
(WI.SearchTabContentView.tabInfo):
New image (magnifying glass without border) when new TabBar is enabled.

* UserInterface/Views/SettingsTabContentView.js:
(WI.SettingsTabContentView):

* UserInterface/Views/TabBar.js:
(WI.TabBar):
Move creation of the Settings item out of TabBar. The TabBar should
only be concerned with managing tabs.

(WI.TabBar.prototype.get saveableTabCount):
(WI.TabBar.prototype._handleContextMenu):
(WI.TabBar.prototype.get normalNonEphemeralTabCount): Deleted.
Now that the Search tab is pinned, there aren't any normal tabs that
are also ephemeral. For the LegacyTabBar, both the Search and New Tab
tabs are still in this category.

* UserInterface/Views/TabBrowser.js:
(WI.TabBrowser.prototype.addTabForContentView):
(WI.TabBrowser.prototype.closeTabForContentView):
(WI.TabBrowser.prototype._tabBarItemSelected):
(WI.TabBrowser._tabBarItemRemoved):
Recent tab list should be validated against the list of saveable tabs,
since the Search tab is no longer a normal tab (a GeneralTabBarItem),
but is still persisted across Inspector sessions.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@228581 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Base/Main.js
Source/WebInspectorUI/UserInterface/Images/Search.svg
Source/WebInspectorUI/UserInterface/Views/GoToLineDialog.css
Source/WebInspectorUI/UserInterface/Views/LegacyTabBar.js
Source/WebInspectorUI/UserInterface/Views/OpenResourceDialog.css
Source/WebInspectorUI/UserInterface/Views/PinnedTabBarItem.js
Source/WebInspectorUI/UserInterface/Views/SearchTabContentView.js
Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js
Source/WebInspectorUI/UserInterface/Views/TabBar.js
Source/WebInspectorUI/UserInterface/Views/TabBrowser.js

index ab4ec13..37d0e2b 100644 (file)
@@ -1,5 +1,73 @@
 2018-02-16  Matt Baker  <mattbaker@apple.com>
 
+        Web Inspector: TabBar redesign: remove top-level search field and pin the Search tab
+        https://bugs.webkit.org/show_bug.cgi?id=182353
+        <rdar://problem/37088644>
+
+        Reviewed by Devin Rousso.
+
+        * Localizations/en.lproj/localizedStrings.js:
+
+        * UserInterface/Base/Main.js:
+        (WI.contentLoaded):
+        Create Search UI based on experimental setting. When the new TabBar is
+        enabled, the Search tab is a pinned tab. Since it is also saveable, it
+        needs to be added to the TabBrowser (the browser adds the item to the bar).
+
+        When restoring saved tabs, make an additional check to prevent a tab
+        from being added twice. This can occur now that the Search tab is pinned.
+
+        * UserInterface/Images/Search.svg:
+        Update art to better match Safari/macOS. Slightly increase the radius of
+        the lens, and shorten the length of the handle.
+
+        * UserInterface/Views/GoToLineDialog.css:
+        (.go-to-line-dialog > div::before):
+        Update styles for new Search icon.
+
+        * UserInterface/Views/LegacyTabBar.js:
+        (WI.LegacyTabBar.prototype.get saveableTabCount):
+        Backported new TabBar method which is called by TabBrowser.
+
+        * UserInterface/Views/OpenResourceDialog.css:
+        (.open-resource-dialog > .field::before):
+        Update styles for new Search icon.
+
+        * UserInterface/Views/PinnedTabBarItem.js:
+        (WI.PinnedTabBarItem.prototype.fromTabInfo):
+        Match GeneralTabBarItem.fromTabInfo.
+
+        * UserInterface/Views/SearchTabContentView.js:
+        (WI.SearchTabContentView):
+        (WI.SearchTabContentView.tabInfo):
+        New image (magnifying glass without border) when new TabBar is enabled.
+
+        * UserInterface/Views/SettingsTabContentView.js:
+        (WI.SettingsTabContentView):
+
+        * UserInterface/Views/TabBar.js:
+        (WI.TabBar):
+        Move creation of the Settings item out of TabBar. The TabBar should
+        only be concerned with managing tabs.
+
+        (WI.TabBar.prototype.get saveableTabCount):
+        (WI.TabBar.prototype._handleContextMenu):
+        (WI.TabBar.prototype.get normalNonEphemeralTabCount): Deleted.
+        Now that the Search tab is pinned, there aren't any normal tabs that
+        are also ephemeral. For the LegacyTabBar, both the Search and New Tab
+        tabs are still in this category.
+
+        * UserInterface/Views/TabBrowser.js:
+        (WI.TabBrowser.prototype.addTabForContentView):
+        (WI.TabBrowser.prototype.closeTabForContentView):
+        (WI.TabBrowser.prototype._tabBarItemSelected):
+        (WI.TabBrowser._tabBarItemRemoved):
+        Recent tab list should be validated against the list of saveable tabs,
+        since the Search tab is no longer a normal tab (a GeneralTabBarItem),
+        but is still persisted across Inspector sessions.
+
+2018-02-16  Matt Baker  <mattbaker@apple.com>
+
         Web Inspector: TabBar redesign: TabBarItem close button is incorrectly positioned
         https://bugs.webkit.org/show_bug.cgi?id=182844
         <rdar://problem/37586749>
index ae452ba..9b7222d 100644 (file)
@@ -659,7 +659,6 @@ localizedStrings["Only show resources with issues"] = "Only show resources with
 localizedStrings["Only show visual actions"] = "Only show visual actions";
 localizedStrings["Opacity"] = "Opacity";
 localizedStrings["Open"] = "Open";
-localizedStrings["Open Settings"] = "Open Settings";
 localizedStrings["Open in New Tab"] = "Open in New Tab";
 localizedStrings["Option-click to show all units"] = "Option-click to show all units";
 localizedStrings["Option-click to show all values"] = "Option-click to show all values";
index 2eb8d72..6050cc2 100644 (file)
@@ -399,10 +399,6 @@ WI.contentLoaded = function()
     this._dashboardContainer = new WI.DashboardContainerView;
     this._dashboardContainer.showDashboardViewForRepresentedObject(this.dashboardManager.dashboards.default);
 
-    const incremental = false;
-    this._searchToolbarItem = new WI.SearchBar("inspector-search", WI.UIString("Search"), incremental);
-    this._searchToolbarItem.addEventListener(WI.SearchBar.Event.TextChanged, this._searchTextDidChange, this);
-
     this.toolbar.addToolbarItem(this._closeToolbarButton, WI.Toolbar.Section.Control);
 
     this.toolbar.addToolbarItem(this._undockToolbarButton, WI.Toolbar.Section.Left);
@@ -416,7 +412,17 @@ WI.contentLoaded = function()
 
     this.toolbar.addToolbarItem(this._inspectModeToolbarButton, WI.Toolbar.Section.CenterRight);
 
-    this.toolbar.addToolbarItem(this._searchToolbarItem, WI.Toolbar.Section.Right);
+    this._searchTabContentView = new WI.SearchTabContentView;
+
+    if (WI.settings.experimentalEnableNewTabBar.value) {
+        this.tabBrowser.addTabForContentView(this._searchTabContentView, {suppressAnimations: true});
+        this.tabBar.addTabBarItem(this.settingsTabContentView.tabBarItem, {suppressAnimations: true});
+    } else {
+        const incremental = false;
+        this._searchToolbarItem = new WI.SearchBar("inspector-search", WI.UIString("Search"), incremental);
+        this._searchToolbarItem.addEventListener(WI.SearchBar.Event.TextChanged, this._searchTextDidChange, this);
+        this.toolbar.addToolbarItem(this._searchToolbarItem, WI.Toolbar.Section.Right);
+    }
 
     this.modifierKeys = {altKey: false, metaKey: false, shiftKey: false};
 
@@ -470,6 +476,9 @@ WI.contentLoaded = function()
             continue;
         }
 
+        if (!this.isNewTabWithTypeAllowed(tabType))
+            continue;
+
         let tabContentView = this._createTabContentViewForType(tabType);
         if (!tabContentView)
             continue;
@@ -1263,12 +1272,16 @@ WI._searchTextDidChange = function(event)
 
 WI._focusSearchField = function(event)
 {
+    if (WI.settings.experimentalEnableNewTabBar.value)
+        this.tabBrowser.showTabForContentView(this._searchTabContentView);
+
     if (this.tabBrowser.selectedTabContentView instanceof WI.SearchTabContentView) {
         this.tabBrowser.selectedTabContentView.focusSearchField();
         return;
     }
 
-    this._searchToolbarItem.focus();
+    if (this._searchToolbarItem)
+        this._searchToolbarItem.focus();
 };
 
 WI._focusChanged = function(event)
index 3201783..f633ca0 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright © 2016 Apple Inc. All rights reserved. -->
+<!-- Copyright © 2018 Apple Inc. All rights reserved. -->
 <svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" viewBox="0 0 16 16">
-    <circle fill="none" stroke="currentColor" cx="7" cy="7" r="3"/>
+    <circle fill="none" stroke="currentColor" cx="6" cy="6" r="4"/>
     <path fill="none" stroke="currentColor" d="M 9 9 L 13.5 13.5"/>
 </svg>
index b34d376..131945a 100644 (file)
@@ -50,9 +50,9 @@
 
 .go-to-line-dialog > div::before {
     position: absolute;
-    left: 6px;
-    top: 6px;
-    width: 30px;
+    left: 10px;
+    top: 10px;
+    width: 24px;
     opacity: 0.5;
     content: url(../Images/Search.svg);
 }
index 8f36832..b66c3db 100644 (file)
@@ -396,6 +396,11 @@ WI.LegacyTabBar = class LegacyTabBar extends WI.View
         return this._tabBarItems.filter((item) => !(item instanceof WI.PinnedTabBarItem)).length;
     }
 
+    get saveableTabCount()
+    {
+        return this._tabBarItems.filter((item) => item.representedObject && item.representedObject.constructor.shouldSaveTab()).length;
+    }
+
     // Protected
 
     layout()
index 94cf9cb..529c0fc 100644 (file)
@@ -67,12 +67,12 @@ body[dir=rtl] .open-resource-dialog > .field {
 
 .open-resource-dialog > .field::before {
     position: absolute;
-    top: 6px;
-    width: 30px;
+    top: 10px;
+    width: 24px;
     opacity: 0.5;
     content: url(../Images/Search.svg);
 
-    --open-resource-dialog-search-icon-offset-start: 6px;
+    --open-resource-dialog-search-icon-offset-start: 10px;
 }
 
 body[dir=ltr] .open-resource-dialog > .field::before {
index 8d397ea..f35e430 100644 (file)
@@ -34,6 +34,11 @@ WI.PinnedTabBarItem = class PinnedTabBarItem extends WI.TabBarItem
         this.element.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this));
     }
 
+    static fromTabInfo({image, title})
+    {
+        return new WI.PinnedTabBarItem(image, title);
+    }
+
     // Private
 
     _handleContextMenuEvent(event)
index 325662b..db771ac 100644 (file)
@@ -27,7 +27,12 @@ WI.SearchTabContentView = class SearchTabContentView extends WI.ContentBrowserTa
 {
     constructor(identifier)
     {
-        let tabBarItem = WI.GeneralTabBarItem.fromTabInfo(WI.SearchTabContentView.tabInfo());
+        let tabBarItem;
+        if (WI.settings.experimentalEnableNewTabBar.value)
+            tabBarItem = WI.PinnedTabBarItem.fromTabInfo(WI.SearchTabContentView.tabInfo());
+        else
+            tabBarItem = WI.GeneralTabBarItem.fromTabInfo(WI.SearchTabContentView.tabInfo());
+
         let detailsSidebarPanelConstructors = [WI.ResourceDetailsSidebarPanel, WI.ProbeDetailsSidebarPanel,
             WI.DOMNodeDetailsSidebarPanel, WI.ComputedStyleDetailsSidebarPanel, WI.RulesStyleDetailsSidebarPanel];
 
@@ -36,13 +41,17 @@ WI.SearchTabContentView = class SearchTabContentView extends WI.ContentBrowserTa
 
         super(identifier || "search", "search", tabBarItem, WI.SearchSidebarPanel, detailsSidebarPanelConstructors);
 
+        // Ensures that the Search tab is displayable from a pinned tab bar item.
+        tabBarItem.representedObject = this;
+
         this._forcePerformSearch = false;
     }
 
     static tabInfo()
     {
+        let image = WI.settings.experimentalEnableNewTabBar.value ? "Images/Search.svg" : "Images/SearchResults.svg";
         return {
-            image: "Images/SearchResults.svg",
+            image,
             title: WI.UIString("Search"),
             isEphemeral: true,
         };
index 8fed8d4..f0b32ad 100644 (file)
@@ -28,7 +28,7 @@ WI.SettingsTabContentView = class SettingsTabContentView extends WI.TabContentVi
 {
     constructor(identifier)
     {
-        let tabBarItem = new WI.PinnedTabBarItem("Images/Gear.svg", WI.UIString("Open Settings"));
+        let tabBarItem = WI.PinnedTabBarItem.fromTabInfo(WI.SettingsTabContentView.tabInfo());
 
         super(identifier || "settings", "settings", tabBarItem);
 
index 4bf6326..48e7c9f 100644 (file)
@@ -46,8 +46,6 @@ WI.TabBar = class TabBar extends WI.View
                 this.addTabBarItem(tabBarItem);
         }
 
-        this.addTabBarItem(WI.settingsTabContentView.tabBarItem, {suppressAnimations: true});
-
         this._tabPickerTabBarItem = new WI.PinnedTabBarItem("Images/TabPicker.svg", WI.UIString("Show hidden tabs"));
         this._tabPickerTabBarItem.element.classList.add("tab-picker");
         this._tabPickerTabBarItem.element.addEventListener("contextmenu", this._handleTabPickerTabContextMenu.bind(this));
@@ -83,7 +81,10 @@ WI.TabBar = class TabBar extends WI.View
 
         tabBarItem.parentTabBar = this;
 
-        index = Number.constrain(index, 0, this.normalTabCount);
+        if (tabBarItem instanceof WI.GeneralTabBarItem)
+            index = Number.constrain(index, 0, this.normalTabCount);
+        else
+            index = Number.constrain(index, this.normalTabCount, this._tabBarItems.length);
 
         if (this.element.classList.contains("animating")) {
             requestAnimationFrame(removeStyles.bind(this));
@@ -168,7 +169,7 @@ WI.TabBar = class TabBar extends WI.View
         if (!tabBarItem || tabBarItem instanceof WI.PinnedTabBarItem)
             return null;
 
-        if (!tabBarItem.isEphemeral && this.normalNonEphemeralTabCount === 1)
+        if (!tabBarItem.isEphemeral && this.normalTabCount === 1)
             return null;
 
         tabBarItem.parentTabBar = null;
@@ -368,9 +369,9 @@ WI.TabBar = class TabBar extends WI.View
         return this._tabBarItems.filter((item) => !(item instanceof WI.PinnedTabBarItem)).length;
     }
 
-    get normalNonEphemeralTabCount()
+    get saveableTabCount()
     {
-        return this._tabBarItems.filter((item) => !item.isEphemeral && !(item instanceof WI.PinnedTabBarItem)).length;
+        return this._tabBarItems.filter((item) => item.representedObject && item.representedObject.constructor.shouldSaveTab()).length;
     }
 
     // Protected
@@ -788,7 +789,7 @@ WI.TabBar = class TabBar extends WI.View
             }
 
             let checked = !!openTabBarItem;
-            let disabled = checked && this.normalNonEphemeralTabCount === 1;
+            let disabled = checked && this.normalTabCount === 1;
             contextMenu.appendCheckboxItem(tabClass.tabInfo().title, () => {
                 if (openTabBarItem)
                     this.removeTabBarItem(openTabBarItem);
index a68fd92..abd73f9 100644 (file)
@@ -170,7 +170,7 @@ WI.TabBrowser = class TabBrowser extends WI.View
         else
             this._tabBar.addTabBarItem(tabBarItem, options);
 
-        console.assert(this._recentTabContentViews.length === this._tabBar.normalTabCount);
+        console.assert(this._recentTabContentViews.length === this._tabBar.saveableTabCount);
         console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0]);
 
         return true;
@@ -209,7 +209,7 @@ WI.TabBrowser = class TabBrowser extends WI.View
 
         this._tabBar.removeTabBarItem(tabContentView.tabBarItem, options);
 
-        console.assert(this._recentTabContentViews.length === this._tabBar.normalTabCount);
+        console.assert(this._recentTabContentViews.length === this._tabBar.saveableTabCount);
         console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0]);
 
         return true;
@@ -233,8 +233,8 @@ WI.TabBrowser = class TabBrowser extends WI.View
         let tabContentView = this._tabBar.selectedTabBarItem ? this._tabBar.selectedTabBarItem.representedObject : null;
 
         if (tabContentView) {
-            let isSettingsTab = tabContentView instanceof WI.SettingsTabContentView;
-            if (!isSettingsTab) {
+            let shouldSaveTab = tabContentView.constructor.shouldSaveTab();
+            if (shouldSaveTab) {
                 this._recentTabContentViews.remove(tabContentView);
                 this._recentTabContentViews.unshift(tabContentView);
             }
@@ -242,8 +242,8 @@ WI.TabBrowser = class TabBrowser extends WI.View
             this._contentViewContainer.showContentView(tabContentView);
 
             console.assert(this.selectedTabContentView);
-            console.assert(this._recentTabContentViews.length === this._tabBar.normalTabCount);
-            console.assert(this.selectedTabContentView === this._recentTabContentViews[0] || isSettingsTab);
+            console.assert(this._recentTabContentViews.length === this._tabBar.saveableTabCount);
+            console.assert(this.selectedTabContentView === this._recentTabContentViews[0] || !shouldSaveTab);
         } else {
             this._contentViewContainer.closeAllContentViews();
 
@@ -290,7 +290,7 @@ WI.TabBrowser = class TabBrowser extends WI.View
 
         tabContentView.parentTabBrowser = null;
 
-        console.assert(this._recentTabContentViews.length === this._tabBar.normalTabCount);
+        console.assert(this._recentTabContentViews.length === this._tabBar.saveableTabCount);
         console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0]);
     }