Web Inspector: "No Filter Results" message overlaps Debugger sidebar sections
authormattbaker@apple.com <mattbaker@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Dec 2015 19:17:23 +0000 (19:17 +0000)
committermattbaker@apple.com <mattbaker@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Dec 2015 19:17:23 +0000 (19:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150608

Reviewed by Brian Burg.

* UserInterface/Views/DebuggerSidebarPanel.js:
(WebInspector.DebuggerSidebarPanel.showResourcesWithIssuesOnlyFilterFunction):
Style cleanup.
(WebInspector.DebuggerSidebarPanel):
Add breakpoints tree to the details section before adding Global Breakpoint
elements, since adding them will trigger filtering.
(WebInspector.DebuggerSidebarPanel.prototype._treeSelectionDidChange):
Simplified selection management between the various tree outlines.
(WebInspector.DebuggerSidebarPanel.prototype._updatePauseReasonSection):
Style cleanup.
(WebInspector.DebuggerSidebarPanel.prototype.get hasSelectedElement): Deleted.
Defer to the base class implementation.
(WebInspector.DebuggerSidebarPanel.prototype._treeSelectionDidChange.deselectCallStackContentTreeElements): Deleted.
(WebInspector.DebuggerSidebarPanel.prototype._treeSelectionDidChange.deselectBreakpointContentTreeElements): Deleted.
(WebInspector.DebuggerSidebarPanel.prototype._treeSelectionDidChange.deselectPauseReasonContentTreeElements): Deleted.
These are no longer needed, since the list of visible tree elements list can be used
to manage tree element selection is a more general way.

* UserInterface/Views/NavigationSidebarPanel.css:
Empty content placeholders are now inserted into the DOM as a sibling of the
tree that was filtered. As such, they can be a child of a details section, or
the sidebar's content element.
(.sidebar > .panel.navigation > .content .empty-content-placeholder):
Styles for all empty content placeholders.
(.sidebar > .panel.navigation > .content > .empty-content-placeholder):
Styles for empty content placeholders that fill the sidebar's content element.
(.sidebar > .panel.navigation > .content .message):
Styles for all empty content placeholders.
(.sidebar > .panel.navigation > .empty-content-placeholder): Deleted.
(.sidebar > .panel.navigation > .empty-content-placeholder > .message): Deleted.

* UserInterface/Views/NavigationSidebarPanel.js:
(WebInspector.NavigationSidebarPanel):
Track the tree outline which currently has a selection.
Manage a map of content placeholders
(WebInspector.NavigationSidebarPanel.prototype.set contentTreeOutline):
(WebInspector.NavigationSidebarPanel.prototype.get hasSelectedElement):
Check all visible content trees for a selected element.
(WebInspector.NavigationSidebarPanel.prototype.createContentTreeOutline):
(WebInspector.NavigationSidebarPanel.prototype.treeElementForRepresentedObject):
Check all visible content trees for the represented object.
(WebInspector.NavigationSidebarPanel.prototype.showEmptyContentPlaceholder):
(WebInspector.NavigationSidebarPanel.prototype.hideEmptyContentPlaceholder):
(WebInspector.NavigationSidebarPanel.prototype.updateEmptyContentPlaceholder):
No sidebars currently have more than one filterable content tree outline, but in
the future we will want to support this. Empty content placeholder visibility
is now done per tree outline.
(WebInspector.NavigationSidebarPanel.prototype.show):
Focus the tree outline that most recently had the selection, or the
first tree outline in the visible tree list, if it exists.
(WebInspector.NavigationSidebarPanel.prototype._checkForEmptyFilterResults.checkTreeOutlineForEmptyFilterResults):
Tree is considered filtered if no visible filterable tree elements are found.
(WebInspector.NavigationSidebarPanel.prototype._checkForEmptyFilterResults):
Check all visible trees that support filtering.
(WebInspector.NavigationSidebarPanel.prototype._updateFilter):
Support for filtering multiple content trees.
(WebInspector.NavigationSidebarPanel.prototype._treeElementAddedOrChanged):
Check if the element's tree outline supports filtering, before applying filters.
(WebInspector.NavigationSidebarPanel.prototype._treeSelectionDidChange):
Update the selected tree outline.
(WebInspector.NavigationSidebarPanel.prototype._createEmptyContentPlaceholderIfNeeded):
Create a new empty content placeholder element for the tree.
(WebInspector.NavigationSidebarPanel.prototype.get contentTreeOutlineElement): Deleted.
No longer used.

* UserInterface/Views/TimelineSidebarPanel.js:
(WebInspector.TimelineSidebarPanel.prototype.get hasSelectedElement): Deleted.
Defer to the base class implementation.

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

Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.css
Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/TimelineSidebarPanel.js

index 76d7aa0..ff13733 100644 (file)
@@ -1,3 +1,79 @@
+2015-12-31  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: "No Filter Results" message overlaps Debugger sidebar sections
+        https://bugs.webkit.org/show_bug.cgi?id=150608
+
+        Reviewed by Brian Burg.
+
+        * UserInterface/Views/DebuggerSidebarPanel.js:
+        (WebInspector.DebuggerSidebarPanel.showResourcesWithIssuesOnlyFilterFunction):
+        Style cleanup.
+        (WebInspector.DebuggerSidebarPanel):
+        Add breakpoints tree to the details section before adding Global Breakpoint
+        elements, since adding them will trigger filtering.
+        (WebInspector.DebuggerSidebarPanel.prototype._treeSelectionDidChange):
+        Simplified selection management between the various tree outlines.
+        (WebInspector.DebuggerSidebarPanel.prototype._updatePauseReasonSection):
+        Style cleanup.
+        (WebInspector.DebuggerSidebarPanel.prototype.get hasSelectedElement): Deleted.
+        Defer to the base class implementation.
+        (WebInspector.DebuggerSidebarPanel.prototype._treeSelectionDidChange.deselectCallStackContentTreeElements): Deleted.
+        (WebInspector.DebuggerSidebarPanel.prototype._treeSelectionDidChange.deselectBreakpointContentTreeElements): Deleted.
+        (WebInspector.DebuggerSidebarPanel.prototype._treeSelectionDidChange.deselectPauseReasonContentTreeElements): Deleted.
+        These are no longer needed, since the list of visible tree elements list can be used
+        to manage tree element selection is a more general way.
+
+        * UserInterface/Views/NavigationSidebarPanel.css:
+        Empty content placeholders are now inserted into the DOM as a sibling of the
+        tree that was filtered. As such, they can be a child of a details section, or
+        the sidebar's content element.
+        (.sidebar > .panel.navigation > .content .empty-content-placeholder):
+        Styles for all empty content placeholders.
+        (.sidebar > .panel.navigation > .content > .empty-content-placeholder):
+        Styles for empty content placeholders that fill the sidebar's content element.
+        (.sidebar > .panel.navigation > .content .message):
+        Styles for all empty content placeholders.
+        (.sidebar > .panel.navigation > .empty-content-placeholder): Deleted.
+        (.sidebar > .panel.navigation > .empty-content-placeholder > .message): Deleted.
+
+        * UserInterface/Views/NavigationSidebarPanel.js:
+        (WebInspector.NavigationSidebarPanel):
+        Track the tree outline which currently has a selection.
+        Manage a map of content placeholders
+        (WebInspector.NavigationSidebarPanel.prototype.set contentTreeOutline):
+        (WebInspector.NavigationSidebarPanel.prototype.get hasSelectedElement):
+        Check all visible content trees for a selected element.
+        (WebInspector.NavigationSidebarPanel.prototype.createContentTreeOutline):
+        (WebInspector.NavigationSidebarPanel.prototype.treeElementForRepresentedObject):
+        Check all visible content trees for the represented object.
+        (WebInspector.NavigationSidebarPanel.prototype.showEmptyContentPlaceholder):
+        (WebInspector.NavigationSidebarPanel.prototype.hideEmptyContentPlaceholder):
+        (WebInspector.NavigationSidebarPanel.prototype.updateEmptyContentPlaceholder):
+        No sidebars currently have more than one filterable content tree outline, but in
+        the future we will want to support this. Empty content placeholder visibility
+        is now done per tree outline.
+        (WebInspector.NavigationSidebarPanel.prototype.show):
+        Focus the tree outline that most recently had the selection, or the
+        first tree outline in the visible tree list, if it exists.
+        (WebInspector.NavigationSidebarPanel.prototype._checkForEmptyFilterResults.checkTreeOutlineForEmptyFilterResults):
+        Tree is considered filtered if no visible filterable tree elements are found.
+        (WebInspector.NavigationSidebarPanel.prototype._checkForEmptyFilterResults):
+        Check all visible trees that support filtering.
+        (WebInspector.NavigationSidebarPanel.prototype._updateFilter):
+        Support for filtering multiple content trees.
+        (WebInspector.NavigationSidebarPanel.prototype._treeElementAddedOrChanged):
+        Check if the element's tree outline supports filtering, before applying filters.
+        (WebInspector.NavigationSidebarPanel.prototype._treeSelectionDidChange):
+        Update the selected tree outline.
+        (WebInspector.NavigationSidebarPanel.prototype._createEmptyContentPlaceholderIfNeeded):
+        Create a new empty content placeholder element for the tree.
+        (WebInspector.NavigationSidebarPanel.prototype.get contentTreeOutlineElement): Deleted.
+        No longer used.
+
+        * UserInterface/Views/TimelineSidebarPanel.js:
+        (WebInspector.TimelineSidebarPanel.prototype.get hasSelectedElement): Deleted.
+        Defer to the base class implementation.
+
 2015-12-29  Devin Rousso  <dcrousso+webkit@gmail.com>
 
         Web Inspector: Styling of invalid selector persists when changing the selected node
index ea5e913..5c54c75 100644 (file)
@@ -92,10 +92,11 @@ WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspec
         this._globalBreakpointsFolderTreeElement = new WebInspector.FolderTreeElement(WebInspector.UIString("Global Breakpoints"), null, WebInspector.DebuggerSidebarPanel.GlobalIconStyleClassName);
         this._allExceptionsBreakpointTreeElement = new WebInspector.BreakpointTreeElement(WebInspector.debuggerManager.allExceptionsBreakpoint, WebInspector.DebuggerSidebarPanel.ExceptionIconStyleClassName, WebInspector.UIString("All Exceptions"));
         this._allUncaughtExceptionsBreakpointTreeElement = new WebInspector.BreakpointTreeElement(WebInspector.debuggerManager.allUncaughtExceptionsBreakpoint, WebInspector.DebuggerSidebarPanel.ExceptionIconStyleClassName, WebInspector.UIString("All Uncaught Exceptions"));
+        this.suppressFilteringOnTreeElements([this._globalBreakpointsFolderTreeElement, this._allExceptionsBreakpointTreeElement, this._allUncaughtExceptionsBreakpointTreeElement]);
 
         this.filterBar.placeholder = WebInspector.UIString("Filter Breakpoint List");
 
-        var showResourcesWithIssuesOnlyFilterFunction = function(treeElement)
+        function showResourcesWithIssuesOnlyFilterFunction(treeElement)
         {
             // Keep issues.
             if (treeElement instanceof WebInspector.IssueTreeElement)
@@ -103,7 +104,7 @@ WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspec
 
             // Keep resources with issues.
             if (treeElement.hasChildren) {
-                for (var child of treeElement.children) {
+                for (let child of treeElement.children) {
                     if (child instanceof WebInspector.IssueTreeElement)
                         return true;
                 }
@@ -114,6 +115,15 @@ WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspec
         this.filterBar.addFilterBarButton("debugger-show-resources-with-issues-only", showResourcesWithIssuesOnlyFilterFunction, true, WebInspector.UIString("Show only resources with issues."), WebInspector.UIString("Show resources with and without issues."), "Images/Errors.svg", 15, 15);
 
         this._breakpointsContentTreeOutline = this.contentTreeOutline;
+
+        let breakpointsRow = new WebInspector.DetailsSectionRow;
+        breakpointsRow.element.appendChild(this._breakpointsContentTreeOutline.element);
+
+        let breakpointsGroup = new WebInspector.DetailsSectionGroup([breakpointsRow]);
+        let breakpointsSection = new WebInspector.DetailsSection("scripts", WebInspector.UIString("Scripts"), [breakpointsGroup]);
+        this.contentView.element.appendChild(breakpointsSection.element);
+
+        this._breakpointsContentTreeOutline.element.classList.add("breakpoints");
         this._breakpointsContentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
         this._breakpointsContentTreeOutline.ondelete = this._breakpointTreeOutlineDeleteTreeElement.bind(this);
         this._breakpointsContentTreeOutline.oncontextmenu = this._breakpointTreeOutlineContextMenuTreeElement.bind(this);
@@ -123,22 +133,13 @@ WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspec
         this._globalBreakpointsFolderTreeElement.appendChild(this._allUncaughtExceptionsBreakpointTreeElement);
         this._globalBreakpointsFolderTreeElement.expand();
 
-        this.suppressFilteringOnTreeElements([this._globalBreakpointsFolderTreeElement, this._allExceptionsBreakpointTreeElement, this._allUncaughtExceptionsBreakpointTreeElement]);
-
-        var breakpointsRow = new WebInspector.DetailsSectionRow;
-        breakpointsRow.element.appendChild(this._breakpointsContentTreeOutline.element);
-
-        var breakpointsGroup = new WebInspector.DetailsSectionGroup([breakpointsRow]);
-        var breakpointsSection = new WebInspector.DetailsSection("scripts", WebInspector.UIString("Scripts"), [breakpointsGroup]);
-        this.contentView.element.appendChild(breakpointsSection.element);
-
         this._callStackContentTreeOutline = this.createContentTreeOutline(true, true);
         this._callStackContentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
 
         this._callStackRow = new WebInspector.DetailsSectionRow(WebInspector.UIString("No Call Frames"));
         this._callStackRow.showEmptyMessage();
 
-        var callStackGroup = new WebInspector.DetailsSectionGroup([this._callStackRow]);
+        let callStackGroup = new WebInspector.DetailsSectionGroup([this._callStackRow]);
         this._callStackSection = new WebInspector.DetailsSection("call-stack", WebInspector.UIString("Call Stack"), [callStackGroup]);
 
         this._pauseReasonTreeOutline = null;
@@ -173,13 +174,6 @@ WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspec
         WebInspector.IssueMessage.removeEventListener(null, null, this);
     }
 
-    get hasSelectedElement()
-    {
-        return !!this._breakpointsContentTreeOutline.selectedTreeElement
-            || !!this._callStackContentTreeOutline.selectedTreeElement
-            || (this._pauseReasonTreeOutline && !!this._pauseReasonTreeOutline.selectedTreeElement);
-    }
-
     showDefaultContentView()
     {
         var currentTreeElement = this._contentTreeOutline.children[0];
@@ -608,55 +602,33 @@ WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspec
 
     _treeSelectionDidChange(event)
     {
-        function deselectCallStackContentTreeElements()
-        {
-            var selectedTreeElement = this._callStackContentTreeOutline.selectedTreeElement;
-            if (selectedTreeElement)
-                selectedTreeElement.deselect();
-        }
-
-        function deselectBreakpointContentTreeElements()
-        {
-            var selectedTreeElement = this._breakpointsContentTreeOutline.selectedTreeElement;
-            if (selectedTreeElement)
-                selectedTreeElement.deselect();
-        }
+        let treeElement = event.data.selectedElement;
+        if (!treeElement)
+            return;
 
-        function deselectPauseReasonContentTreeElements()
-        {
-            if (!this._pauseReasonTreeOutline)
-                return;
+        // Deselect any other tree elements to prevent two selections in the sidebar.
+        for (let treeOutline of this.visibleContentTreeOutlines) {
+            if (treeOutline === treeElement.treeOutline)
+                continue;
 
-            var selectedTreeElement = this._pauseReasonTreeOutline.selectedTreeElement;
+            let selectedTreeElement = treeOutline.selectedTreeElement;
             if (selectedTreeElement)
                 selectedTreeElement.deselect();
         }
 
-        let treeElement = event.data.selectedElement;
-        if (!treeElement)
-            return;
-
         if (treeElement instanceof WebInspector.ResourceTreeElement || treeElement instanceof WebInspector.ScriptTreeElement) {
-            deselectCallStackContentTreeElements.call(this);
-            deselectPauseReasonContentTreeElements.call(this);
             WebInspector.showSourceCode(treeElement.representedObject);
             return;
         }
 
         if (treeElement instanceof WebInspector.CallFrameTreeElement) {
-            // Deselect any tree element in the breakpoint / pause reason content tree outlines to prevent two selections in the sidebar.
-            deselectBreakpointContentTreeElements.call(this);
-            deselectPauseReasonContentTreeElements.call(this);
-
-            var callFrame = treeElement.callFrame;
+            let callFrame = treeElement.callFrame;
             WebInspector.debuggerManager.activeCallFrame = callFrame;
             WebInspector.showSourceCodeLocation(callFrame.sourceCodeLocation);
             return;
         }
 
         if (treeElement instanceof WebInspector.IssueTreeElement) {
-            deselectCallStackContentTreeElements.call(this);
-            deselectPauseReasonContentTreeElements.call(this);
             WebInspector.showSourceCodeLocation(treeElement.issueMessage.sourceCodeLocation);
             return;
         }
@@ -664,15 +636,7 @@ WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspec
         if (!(treeElement instanceof WebInspector.BreakpointTreeElement) || treeElement.parent.constructor === WebInspector.FolderTreeElement)
             return;
 
-        // Deselect any other tree elements to prevent two selections in the sidebar.
-        deselectCallStackContentTreeElements.call(this);
-
-        if (treeElement.treeOutline === this._pauseReasonTreeOutline)
-            deselectBreakpointContentTreeElements.call(this);
-        else
-            deselectPauseReasonContentTreeElements.call(this);
-
-        var breakpoint = treeElement.breakpoint;
+        let breakpoint = treeElement.breakpoint;
         if (treeElement.treeOutline === this._pauseReasonTreeOutline) {
             WebInspector.showSourceCodeLocation(breakpoint.sourceCodeLocation);
             return;
@@ -741,17 +705,16 @@ WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspec
         case WebInspector.DebuggerManager.PauseReason.Breakpoint:
             console.assert(pauseData, "Expected breakpoint identifier, but found none.");
             if (pauseData && pauseData.breakpointId) {
-                var breakpoint = WebInspector.debuggerManager.breakpointForIdentifier(pauseData.breakpointId);
-                var breakpointTreeOutline = this.createContentTreeOutline(true, true);
-                breakpointTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
+                let breakpoint = WebInspector.debuggerManager.breakpointForIdentifier(pauseData.breakpointId);
+                this._pauseReasonTreeOutline = this.createContentTreeOutline(true, true);
+                this._pauseReasonTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
 
-                var breakpointTreeElement = new WebInspector.BreakpointTreeElement(breakpoint, WebInspector.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName, WebInspector.UIString("Triggered Breakpoint"));
-                var breakpointDetailsSection = new WebInspector.DetailsSectionRow;
-                breakpointTreeOutline.appendChild(breakpointTreeElement);
-                breakpointDetailsSection.element.appendChild(breakpointTreeOutline.element);
+                let breakpointTreeElement = new WebInspector.BreakpointTreeElement(breakpoint, WebInspector.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName, WebInspector.UIString("Triggered Breakpoint"));
+                let breakpointDetailsSection = new WebInspector.DetailsSectionRow;
+                this._pauseReasonTreeOutline.appendChild(breakpointTreeElement);
+                breakpointDetailsSection.element.appendChild(this._pauseReasonTreeOutline.element);
 
                 this._pauseReasonGroup.rows = [breakpointDetailsSection];
-                this._pauseReasonTreeOutline = breakpointTreeOutline;
                 return true;
             }
             break;
index bfc201c..4317784 100644 (file)
@@ -57,19 +57,25 @@ body.window-inactive .sidebar > .panel.navigation > .overflow-shadow {
     border-bottom-color: hsl(0, 0%, 85%);
 }
 
-.sidebar > .panel.navigation > .empty-content-placeholder {
-    position: absolute;
-    top: 0;
+.sidebar > .panel.navigation > .content .empty-content-placeholder {
     left: 0;
     right: 0;
-    bottom: 28px;
+    padding-top: 15px;
+    padding-bottom: 15px;
     display: flex;
     justify-content: center;
     align-items: center;
     overflow: hidden;
 }
 
-.sidebar > .panel.navigation > .empty-content-placeholder > .message {
+.sidebar > .panel.navigation > .content > .empty-content-placeholder {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    padding: 0;
+}
+
+.sidebar > .panel.navigation > .content .empty-content-placeholder > .message {
     display: inline-block;
     white-space: nowrap;
 
index 320b968..5f2a63c 100644 (file)
@@ -36,6 +36,7 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
         this.contentView.element.addEventListener("scroll", this._updateContentOverflowShadowVisibility.bind(this));
 
         this._contentTreeOutline = this.createContentTreeOutline(true);
+        this._selectedContentTreeOutline = null;
 
         this._filterBar = new WebInspector.FilterBar;
         this._filterBar.addEventListener(WebInspector.FilterBar.Event.FilterDidChange, this._filterDidChange, this);
@@ -58,12 +59,8 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
         this._filtersSetting = new WebInspector.Setting(identifier + "-navigation-sidebar-filters", {});
         this._filterBar.filters = this._filtersSetting.value;
 
-        this._emptyContentPlaceholderElement = document.createElement("div");
-        this._emptyContentPlaceholderElement.className = WebInspector.NavigationSidebarPanel.EmptyContentPlaceholderElementStyleClassName;
-
-        this._emptyContentPlaceholderMessageElement = document.createElement("div");
-        this._emptyContentPlaceholderMessageElement.className = WebInspector.NavigationSidebarPanel.EmptyContentPlaceholderMessageElementStyleClassName;
-        this._emptyContentPlaceholderElement.appendChild(this._emptyContentPlaceholderMessageElement);
+        this._emptyContentPlaceholderElements = new Map;
+        this._emptyFilterResults = new Map;
 
         this._generateStyleRulesIfNeeded();
 
@@ -97,11 +94,6 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
         this._contentBrowser = contentBrowser || null;
     }
 
-    get contentTreeOutlineElement()
-    {
-        return this._contentTreeOutline.element;
-    }
-
     get contentTreeOutline()
     {
         return this._contentTreeOutline;
@@ -114,6 +106,7 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
             return;
 
         if (this._contentTreeOutline) {
+            this.hideEmptyContentPlaceholder(this._contentTreeOutline);
             this._contentTreeOutline.hidden = true;
             this._visibleContentTreeOutlines.delete(this._contentTreeOutline);
         }
@@ -133,7 +126,7 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
 
     get hasSelectedElement()
     {
-        return !!this._contentTreeOutline.selectedTreeElement;
+        return this._visibleContentTreeOutlines.some((treeOutline) => !!treeOutline.selectedTreeElement);
     }
 
     get filterBar()
@@ -168,8 +161,11 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
             contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementAdded, this._treeElementAddedOrChanged, this);
             contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementDidChange, this._treeElementAddedOrChanged, this);
             contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementDisclosureDidChanged, this._treeElementDisclosureDidChange, this);
+            contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
         }
 
+        contentTreeOutline[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol] = suppressFiltering;
+
         if (dontHideByDefault)
             this._visibleContentTreeOutlines.add(contentTreeOutline);
 
@@ -188,7 +184,14 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
 
     treeElementForRepresentedObject(representedObject)
     {
-        return this._contentTreeOutline.getCachedTreeElement(representedObject);
+        let treeElement = null;
+        for (let treeOutline of this._visibleContentTreeOutlines) {
+            treeElement = treeOutline.getCachedTreeElement(representedObject);
+            if (treeElement)
+                break;
+        }
+
+        return treeElement;
     }
 
     showDefaultContentView()
@@ -263,37 +266,47 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
         this._finalAttemptToRestoreViewStateTimeout = setTimeout(finalAttemptToRestoreViewStateFromCookie.bind(this), relaxedMatchDelay);
     }
 
-    showEmptyContentPlaceholder(message)
+    showEmptyContentPlaceholder(message, treeOutline)
     {
         console.assert(message);
 
-        if (this._emptyContentPlaceholderElement.parentNode && this._emptyContentPlaceholderMessageElement.textContent === message)
+        treeOutline = treeOutline || this._contentTreeOutline;
+
+        let emptyContentPlaceholderElement = this._createEmptyContentPlaceholderIfNeeded(treeOutline);
+        if (emptyContentPlaceholderElement.parentNode && emptyContentPlaceholderElement.children[0].textContent === message)
             return;
 
-        this._emptyContentPlaceholderMessageElement.textContent = message;
-        this.element.appendChild(this._emptyContentPlaceholderElement);
+        emptyContentPlaceholderElement.children[0].textContent = message;
+
+        let emptyContentPlaceholderParentElement = treeOutline.element.parentNode;
+        emptyContentPlaceholderParentElement.appendChild(emptyContentPlaceholderElement);
 
         this._updateContentOverflowShadowVisibility();
     }
 
-    hideEmptyContentPlaceholder()
+    hideEmptyContentPlaceholder(treeOutline)
     {
-        if (!this._emptyContentPlaceholderElement.parentNode)
+        treeOutline = treeOutline || this._contentTreeOutline;
+
+        let emptyContentPlaceholderElement = this._emptyContentPlaceholderElements.get(treeOutline);
+        if (!emptyContentPlaceholderElement || !emptyContentPlaceholderElement.parentNode)
             return;
 
-        this._emptyContentPlaceholderElement.parentNode.removeChild(this._emptyContentPlaceholderElement);
+        emptyContentPlaceholderElement.remove();
 
         this._updateContentOverflowShadowVisibility();
     }
 
-    updateEmptyContentPlaceholder(message)
+    updateEmptyContentPlaceholder(message, treeOutline)
     {
-        if (!this._contentTreeOutline.children.length) {
+        treeOutline = treeOutline || this._contentTreeOutline;
+
+        if (!treeOutline.children.length) {
             // No tree elements, so no results.
-            this.showEmptyContentPlaceholder(message);
-        } else if (!this._emptyFilterResults) {
+            this.showEmptyContentPlaceholder(message, treeOutline);
+        } else if (!this._emptyFilterResults.get(treeOutline)) {
             // There are tree elements, and not all of them are hidden by the filter.
-            this.hideEmptyContentPlaceholder();
+            this.hideEmptyContentPlaceholder(treeOutline);
         }
     }
 
@@ -425,7 +438,12 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
 
         super.show();
 
-        this.contentTreeOutlineElement.focus();
+        let treeOutline = this._selectedContentTreeOutline;
+        if (!treeOutline && this._visibleContentTreeOutlines.length)
+            treeOutline = this._visibleContentTreeOutlines[0];
+
+        if (treeOutline)
+            treeOutline.element.focus();
     }
 
     shown()
@@ -502,26 +520,47 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
 
     _checkForEmptyFilterResults()
     {
-        // No tree elements, so don't touch the empty content placeholder.
-        if (!this._contentTreeOutline.children.length)
-            return;
+        function checkTreeOutlineForEmptyFilterResults(treeOutline)
+        {
+            // No tree elements, so don't touch the empty content placeholder.
+            if (!treeOutline.children.length)
+                return;
+
+            // Iterate over all the top level tree elements. If any filterable elements are visible, return early.
+            let filterableTreeElementFound = false;
+            let unfilteredTreeElementFound = false;
+            let currentTreeElement = treeOutline.children[0];
+            while (currentTreeElement) {
+                let suppressFilteringForTreeElement = currentTreeElement[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol];
+                if (!suppressFilteringForTreeElement) {
+                    filterableTreeElementFound = true;
+
+                    if (!currentTreeElement.hidden) {
+                        unfilteredTreeElementFound = true;
+                        break;
+                    }
+                }
+
+                currentTreeElement = currentTreeElement.nextSibling;
+            }
 
-        // Iterate over all the top level tree elements. If any are visible, return early.
-        var currentTreeElement = this._contentTreeOutline.children[0];
-        while (currentTreeElement) {
-            if (!currentTreeElement.hidden && !currentTreeElement[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol]) {
-                // Not hidden, so hide any empty content message.
-                this.hideEmptyContentPlaceholder();
-                this._emptyFilterResults = false;
+            if (unfilteredTreeElementFound || !filterableTreeElementFound) {
+                this.hideEmptyContentPlaceholder(treeOutline);
+                this._emptyFilterResults.set(treeOutline, false);
                 return;
             }
 
-            currentTreeElement = currentTreeElement.nextSibling;
+            // All top level tree elements are hidden, so filtering hid everything. Show a message.
+            this.showEmptyContentPlaceholder(WebInspector.UIString("No Filter Results"), treeOutline);
+            this._emptyFilterResults.set(treeOutline, true);
         }
 
-        // All top level tree elements are hidden, so filtering hid everything. Show a message.
-        this.showEmptyContentPlaceholder(WebInspector.UIString("No Filter Results"));
-        this._emptyFilterResults = true;
+        for (let treeOutline of this._visibleContentTreeOutlines) {
+            if (treeOutline[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol])
+                continue;
+
+            checkTreeOutlineForEmptyFilterResults.call(this, treeOutline);
+        }
     }
 
     _filterDidChange()
@@ -531,27 +570,43 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
 
     _updateFilter()
     {
-        var selectedTreeElement = this._contentTreeOutline.selectedTreeElement;
-        var selectionWasHidden = selectedTreeElement && selectedTreeElement.hidden;
+        let selectedTreeElement;
+        for (let treeOutline of this.visibleContentTreeOutlines) {
+            if (treeOutline.hidden || treeOutline[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol])
+                continue;
+
+            selectedTreeElement = treeOutline.selectedTreeElement;
+            if (selectedTreeElement)
+                break;
+        }
+
+        let selectionWasHidden = selectedTreeElement && selectedTreeElement.hidden;
 
-        var filters = this._filterBar.filters;
+        let filters = this._filterBar.filters;
         this._textFilterRegex = simpleGlobStringToRegExp(filters.text, "i");
         this._filtersSetting.value = filters;
         this._filterFunctions = filters.functions;
 
         // Don't populate if we don't have any active filters.
         // We only need to populate when a filter needs to reveal.
-        var dontPopulate = !this._filterBar.hasActiveFilters() && !this.shouldFilterPopulate();
-
-        // Update the whole tree.
-        var currentTreeElement = this._contentTreeOutline.children[0];
-        while (currentTreeElement && !currentTreeElement.root) {
-            const currentTreeElementWasHidden = currentTreeElement.hidden;
-            this.applyFiltersToTreeElement(currentTreeElement);
-            if (currentTreeElementWasHidden !== currentTreeElement.hidden)
-                this.representedObjectWasFiltered(currentTreeElement.representedObject, currentTreeElement.hidden);
+        let dontPopulate = !this._filterBar.hasActiveFilters() && !this.shouldFilterPopulate();
+
+        // Update all trees that allow filtering.
+        for (let treeOutline of this.visibleContentTreeOutlines) {
+            if (treeOutline.hidden || treeOutline[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol])
+                continue;
+
+            let currentTreeElement = treeOutline.children[0];
+            while (currentTreeElement && !currentTreeElement.root) {
+                if (!currentTreeElement[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol]) {
+                    const currentTreeElementWasHidden = currentTreeElement.hidden;
+                    this.applyFiltersToTreeElement(currentTreeElement);
+                    if (currentTreeElementWasHidden !== currentTreeElement.hidden)
+                        this.representedObjectWasFiltered(currentTreeElement.representedObject, currentTreeElement.hidden);
+                }
 
-            currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, dontPopulate);
+                currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, dontPopulate);
+            }
         }
 
         this._checkForEmptyFilterResults();
@@ -576,10 +631,12 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
         let treeElement = event.data.element;
         let currentTreeElement = treeElement;
         while (currentTreeElement && !currentTreeElement.root) {
-            const currentTreeElementWasHidden = currentTreeElement.hidden;
-            this.applyFiltersToTreeElement(currentTreeElement);
-            if (currentTreeElementWasHidden !== currentTreeElement.hidden)
-                this.representedObjectWasFiltered(currentTreeElement.representedObject, currentTreeElement.hidden);
+            if (!currentTreeElement[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol]) {
+                const currentTreeElementWasHidden = currentTreeElement.hidden;
+                this.applyFiltersToTreeElement(currentTreeElement);
+                if (currentTreeElementWasHidden !== currentTreeElement.hidden)
+                    this.representedObjectWasFiltered(currentTreeElement.representedObject, currentTreeElement.hidden);
+            }
 
             currentTreeElement = currentTreeElement.traverseNextTreeElement(false, treeElement, dontPopulate);
         }
@@ -598,6 +655,12 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
         this._updateContentOverflowShadowVisibility();
     }
 
+    _treeSelectionDidChange(event)
+    {
+        let selectedElement = event.data.selectedElement;
+        this._selectedContentTreeOutline = selectedElement ? selectedElement.treeOutline : null;
+    }
+
     _generateStyleRulesIfNeeded()
     {
         if (WebInspector.NavigationSidebarPanel._styleElement)
@@ -726,6 +789,23 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
             }
         }
     }
+
+    _createEmptyContentPlaceholderIfNeeded(treeOutline)
+    {
+        let emptyContentPlaceholderElement = this._emptyContentPlaceholderElements.get(treeOutline);
+        if (emptyContentPlaceholderElement)
+            return emptyContentPlaceholderElement;
+
+        emptyContentPlaceholderElement = document.createElement("div");
+        emptyContentPlaceholderElement.classList.add(WebInspector.NavigationSidebarPanel.EmptyContentPlaceholderElementStyleClassName);
+        this._emptyContentPlaceholderElements.set(treeOutline, emptyContentPlaceholderElement);
+
+        let emptyContentPlaceholderMessageElement = document.createElement("div");
+        emptyContentPlaceholderMessageElement.className = WebInspector.NavigationSidebarPanel.EmptyContentPlaceholderMessageElementStyleClassName;
+        emptyContentPlaceholderElement.appendChild(emptyContentPlaceholderMessageElement);
+
+        return emptyContentPlaceholderElement;
+    }
 };
 
 WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol = Symbol("supresss-filtering");
index 3eb98ab..8ac1231 100644 (file)
@@ -264,11 +264,6 @@ WebInspector.TimelineSidebarPanel = class TimelineSidebarPanel extends WebInspec
             this.showTimelineOverview();
     }
 
-    get hasSelectedElement()
-    {
-        return !!this._contentTreeOutline.selectedTreeElement || !!this._recordingsTreeOutline.selectedTreeElement;
-    }
-
     treeElementForRepresentedObject(representedObject)
     {
         if (representedObject instanceof WebInspector.TimelineRecording)