<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[212171] trunk/Source/WebInspectorUI</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/212171">212171</a></dd>
<dt>Author</dt> <dd>mattbaker@apple.com</dd>
<dt>Date</dt> <dd>2017-02-10 18:25:04 -0800 (Fri, 10 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: Debugger sidebar panel should not have multiple tree selections
https://bugs.webkit.org/show_bug.cgi?id=166000
&lt;rdar://problem/29721988&gt;

Reviewed by Timothy Hatcher.

The method for synchronizing tree element selection across a sidebar's
tree outlines fails for selections made during startup, because it depends
on events which are being suppressed.

This adds a new class, TreeOutlineGroup, which restricts tree element selection
inside a group of tree outlines by receiving messages directly from TreeElement.

* UserInterface/Main.html:
Add file for TreeOutlineGroup class.

* UserInterface/Views/ContentBrowserTabContentView.js:
(WebInspector.ContentBrowserTabContentView.prototype._revealAndSelectRepresentedObject):
(WebInspector.ContentBrowserTabContentView):
* UserInterface/Views/DebuggerSidebarPanel.js:
(WebInspector.DebuggerSidebarPanel):
(WebInspector.DebuggerSidebarPanel.prototype._updatePauseReasonSection):
Update `createContentTreeOutline` calls for new signature.

* UserInterface/Views/NavigationSidebarPanel.js:
(WebInspector.NavigationSidebarPanel):
Replace _visibleContentTreeOutlines with a TreeOutlineGroup, which
contains the single-selection behavior previously handled by the sidebar.

(WebInspector.NavigationSidebarPanel.prototype.get contentTreeOutlines):
(WebInspector.NavigationSidebarPanel.prototype.get hasSelectedElement):
Implement using the sidebar's tree outline group.
(WebInspector.NavigationSidebarPanel.prototype.createContentTreeOutline):
Remove first parameter, which is always true.
(WebInspector.NavigationSidebarPanel.prototype.treeElementForRepresentedObject):
(WebInspector.NavigationSidebarPanel.prototype.saveStateToCookie):
(WebInspector.NavigationSidebarPanel.prototype.pruneStaleResourceTreeElements):
(WebInspector.NavigationSidebarPanel.prototype._checkForEmptyFilterResults):
(WebInspector.NavigationSidebarPanel.prototype._updateFilter):
(WebInspector.NavigationSidebarPanel.prototype._checkOutlinesForPendingViewStateCookie):
(WebInspector.NavigationSidebarPanel.prototype.set contentTreeOutline): Deleted.
Remove unused setter.
(WebInspector.NavigationSidebarPanel.prototype.get visibleContentTreeOutlines): Deleted.
Renamed to contentTreeOutlines.
(WebInspector.NavigationSidebarPanel.prototype._contentTreeOutlineDidFocus): Deleted.
No longer needed.
(WebInspector.NavigationSidebarPanel.prototype._contentTreeOutlineTreeSelectionDidChange): Deleted.
Selection across trees handled by the tree outline group.

* UserInterface/Views/TreeElement.js:
(WebInspector.TreeElement.prototype.select):
Inform the element's tree outline group (if any), of the selection changed.

* UserInterface/Views/TreeOutlineGroup.js: Added.
(WebInspector.TreeOutlineGroup):
(WebInspector.TreeOutlineGroup.groupForTreeOutline):
(WebInspector.TreeOutlineGroup.prototype.get selectedTreeElement):
(WebInspector.TreeOutlineGroup.prototype.itemAdded):
Associate tree outline with the group and wrap tree elements. If the
incoming tree outline has a selection, deselect the group's currently
selected tree element.

(WebInspector.TreeOutlineGroup.prototype.itemRemoved):
Disassociate the tree outline from the group.
(WebInspector.TreeOutlineGroup.prototype.didSelectTreeElement):
Called by TreeElement when it becomes selected.
(WebInspector.TreeOutlineGroup.prototype._removeConflictingTreeSelections):
Deselect any selected items in all tree outlines belonging to the group,
except for the specified item.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainhtml">trunk/Source/WebInspectorUI/UserInterface/Main.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsContentBrowserTabContentViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/ContentBrowserTabContentView.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsDebuggerSidebarPaneljs">trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsNavigationSidebarPaneljs">trunk/Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsTreeElementjs">trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsTreeOutlineGroupjs">trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutlineGroup.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (212170 => 212171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2017-02-11 02:20:21 UTC (rev 212170)
+++ trunk/Source/WebInspectorUI/ChangeLog        2017-02-11 02:25:04 UTC (rev 212171)
</span><span class="lines">@@ -1,5 +1,77 @@
</span><span class="cx"> 2017-02-10  Matt Baker  &lt;mattbaker@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Web Inspector: Debugger sidebar panel should not have multiple tree selections
+        https://bugs.webkit.org/show_bug.cgi?id=166000
+        &lt;rdar://problem/29721988&gt;
+
+        Reviewed by Timothy Hatcher.
+
+        The method for synchronizing tree element selection across a sidebar's
+        tree outlines fails for selections made during startup, because it depends
+        on events which are being suppressed.
+
+        This adds a new class, TreeOutlineGroup, which restricts tree element selection
+        inside a group of tree outlines by receiving messages directly from TreeElement.
+
+        * UserInterface/Main.html:
+        Add file for TreeOutlineGroup class.
+
+        * UserInterface/Views/ContentBrowserTabContentView.js:
+        (WebInspector.ContentBrowserTabContentView.prototype._revealAndSelectRepresentedObject):
+        (WebInspector.ContentBrowserTabContentView):
+        * UserInterface/Views/DebuggerSidebarPanel.js:
+        (WebInspector.DebuggerSidebarPanel):
+        (WebInspector.DebuggerSidebarPanel.prototype._updatePauseReasonSection):
+        Update `createContentTreeOutline` calls for new signature.
+
+        * UserInterface/Views/NavigationSidebarPanel.js:
+        (WebInspector.NavigationSidebarPanel):
+        Replace _visibleContentTreeOutlines with a TreeOutlineGroup, which
+        contains the single-selection behavior previously handled by the sidebar.
+
+        (WebInspector.NavigationSidebarPanel.prototype.get contentTreeOutlines):
+        (WebInspector.NavigationSidebarPanel.prototype.get hasSelectedElement):
+        Implement using the sidebar's tree outline group.
+        (WebInspector.NavigationSidebarPanel.prototype.createContentTreeOutline):
+        Remove first parameter, which is always true.
+        (WebInspector.NavigationSidebarPanel.prototype.treeElementForRepresentedObject):
+        (WebInspector.NavigationSidebarPanel.prototype.saveStateToCookie):
+        (WebInspector.NavigationSidebarPanel.prototype.pruneStaleResourceTreeElements):
+        (WebInspector.NavigationSidebarPanel.prototype._checkForEmptyFilterResults):
+        (WebInspector.NavigationSidebarPanel.prototype._updateFilter):
+        (WebInspector.NavigationSidebarPanel.prototype._checkOutlinesForPendingViewStateCookie):
+        (WebInspector.NavigationSidebarPanel.prototype.set contentTreeOutline): Deleted.
+        Remove unused setter.
+        (WebInspector.NavigationSidebarPanel.prototype.get visibleContentTreeOutlines): Deleted.
+        Renamed to contentTreeOutlines.
+        (WebInspector.NavigationSidebarPanel.prototype._contentTreeOutlineDidFocus): Deleted.
+        No longer needed.
+        (WebInspector.NavigationSidebarPanel.prototype._contentTreeOutlineTreeSelectionDidChange): Deleted.
+        Selection across trees handled by the tree outline group.
+
+        * UserInterface/Views/TreeElement.js:
+        (WebInspector.TreeElement.prototype.select):
+        Inform the element's tree outline group (if any), of the selection changed.
+
+        * UserInterface/Views/TreeOutlineGroup.js: Added.
+        (WebInspector.TreeOutlineGroup):
+        (WebInspector.TreeOutlineGroup.groupForTreeOutline):
+        (WebInspector.TreeOutlineGroup.prototype.get selectedTreeElement):
+        (WebInspector.TreeOutlineGroup.prototype.itemAdded):
+        Associate tree outline with the group and wrap tree elements. If the
+        incoming tree outline has a selection, deselect the group's currently
+        selected tree element.
+
+        (WebInspector.TreeOutlineGroup.prototype.itemRemoved):
+        Disassociate the tree outline from the group.
+        (WebInspector.TreeOutlineGroup.prototype.didSelectTreeElement):
+        Called by TreeElement when it becomes selected.
+        (WebInspector.TreeOutlineGroup.prototype._removeConflictingTreeSelections):
+        Deselect any selected items in all tree outlines belonging to the group,
+        except for the specified item.
+
+2017-02-10  Matt Baker  &lt;mattbaker@apple.com&gt;
+
</ins><span class="cx">         Web Inspector: ContentViewContainer can have redundant back-forward entries after ContentView close
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=168105
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (212170 => 212171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html        2017-02-11 02:20:21 UTC (rev 212170)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html        2017-02-11 02:25:04 UTC (rev 212171)
</span><span class="lines">@@ -427,6 +427,7 @@
</span><span class="cx">     &lt;script src=&quot;Views/TimelineView.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/TreeElement.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/TreeOutline.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Views/TreeOutlineGroup.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> 
</span><span class="cx">     &lt;script src=&quot;Views/ButtonNavigationItem.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/DatabaseUserQueryViewBase.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsContentBrowserTabContentViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ContentBrowserTabContentView.js (212170 => 212171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ContentBrowserTabContentView.js        2017-02-11 02:20:21 UTC (rev 212170)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ContentBrowserTabContentView.js        2017-02-11 02:25:04 UTC (rev 212171)
</span><span class="lines">@@ -254,7 +254,7 @@
</span><span class="cx">             // If a tree outline is processing a selection currently then we can assume the selection does not
</span><span class="cx">             // need to be changed. This is needed to allow breakpoint and call frame tree elements to be selected
</span><span class="cx">             // without jumping back to selecting the resource tree element.
</span><del>-            for (let contentTreeOutline of this.navigationSidebarPanel.visibleContentTreeOutlines) {
</del><ins>+            for (let contentTreeOutline of this.navigationSidebarPanel.contentTreeOutlines) {
</ins><span class="cx">                 if (contentTreeOutline.processingSelectionChange)
</span><span class="cx">                     return;
</span><span class="cx">             }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsDebuggerSidebarPaneljs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js (212170 => 212171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js        2017-02-11 02:20:21 UTC (rev 212170)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js        2017-02-11 02:25:04 UTC (rev 212171)
</span><span class="lines">@@ -166,7 +166,7 @@
</span><span class="cx">         if (DebuggerAgent.setPauseOnAssertions)
</span><span class="cx">             this._breakpointsContentTreeOutline.appendChild(this._assertionsBreakpointTreeElement);
</span><span class="cx"> 
</span><del>-        this._scriptsContentTreeOutline = this.createContentTreeOutline(true);
</del><ins>+        this._scriptsContentTreeOutline = this.createContentTreeOutline();
</ins><span class="cx">         this._scriptsContentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
</span><span class="cx"> 
</span><span class="cx">         let scriptsRow = new WebInspector.DetailsSectionRow;
</span><span class="lines">@@ -176,9 +176,8 @@
</span><span class="cx">         this._scriptsSection = new WebInspector.DetailsSection(&quot;scripts&quot;, WebInspector.UIString(&quot;Sources&quot;), [scriptsGroup]);
</span><span class="cx">         this.contentView.element.appendChild(this._scriptsSection.element);
</span><span class="cx"> 
</span><del>-        const dontHideByDefault = true;
</del><span class="cx">         const suppressFiltering = true;
</span><del>-        this._callStackTreeOutline = this.createContentTreeOutline(dontHideByDefault, suppressFiltering);
</del><ins>+        this._callStackTreeOutline = this.createContentTreeOutline(suppressFiltering);
</ins><span class="cx">         this._callStackTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
</span><span class="cx"> 
</span><span class="cx">         this._mainTargetTreeElement = new WebInspector.ThreadTreeElement(WebInspector.mainTarget);
</span><span class="lines">@@ -883,10 +882,11 @@
</span><span class="cx">         case WebInspector.DebuggerManager.PauseReason.Breakpoint:
</span><span class="cx">             console.assert(pauseData, &quot;Expected breakpoint identifier, but found none.&quot;);
</span><span class="cx">             if (pauseData &amp;&amp; pauseData.breakpointId) {
</span><del>-                let breakpoint = WebInspector.debuggerManager.breakpointForIdentifier(pauseData.breakpointId);
-                this._pauseReasonTreeOutline = this.createContentTreeOutline(true, true);
</del><ins>+                const suppressFiltering = true;
+                this._pauseReasonTreeOutline = this.createContentTreeOutline(suppressFiltering);
</ins><span class="cx">                 this._pauseReasonTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
</span><span class="cx"> 
</span><ins>+                let breakpoint = WebInspector.debuggerManager.breakpointForIdentifier(pauseData.breakpointId);
</ins><span class="cx">                 let breakpointTreeElement = new WebInspector.BreakpointTreeElement(breakpoint, WebInspector.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName, WebInspector.UIString(&quot;Triggered Breakpoint&quot;));
</span><span class="cx">                 let breakpointDetailsSection = new WebInspector.DetailsSectionRow;
</span><span class="cx">                 this._pauseReasonTreeOutline.appendChild(breakpointTreeElement);
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsNavigationSidebarPaneljs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.js (212170 => 212171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.js        2017-02-11 02:20:21 UTC (rev 212170)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.js        2017-02-11 02:25:04 UTC (rev 212171)
</span><span class="lines">@@ -31,11 +31,10 @@
</span><span class="cx"> 
</span><span class="cx">         this.element.classList.add(&quot;navigation&quot;);
</span><span class="cx"> 
</span><del>-        this._visibleContentTreeOutlines = new Set;
-
</del><span class="cx">         this.contentView.element.addEventListener(&quot;scroll&quot;, this.soon._updateContentOverflowShadowVisibility);
</span><span class="cx"> 
</span><del>-        this._contentTreeOutline = this.createContentTreeOutline(true);
</del><ins>+        this._contentTreeOutlineGroup = new WebInspector.TreeOutlineGroup;
+        this._contentTreeOutline = this.createContentTreeOutline();
</ins><span class="cx"> 
</span><span class="cx">         this._filterBar = new WebInspector.FilterBar;
</span><span class="cx">         this._filterBar.addEventListener(WebInspector.FilterBar.Event.FilterDidChange, this._filterDidChange, this);
</span><span class="lines">@@ -96,34 +95,14 @@
</span><span class="cx">         return this._contentTreeOutline;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    set contentTreeOutline(newTreeOutline)
</del><ins>+    get contentTreeOutlines()
</ins><span class="cx">     {
</span><del>-        console.assert(newTreeOutline);
-        if (!newTreeOutline)
-            return;
-
-        if (this._contentTreeOutline) {
-            this.hideEmptyContentPlaceholder(this._contentTreeOutline);
-            this._contentTreeOutline.hidden = true;
-            this._visibleContentTreeOutlines.delete(this._contentTreeOutline);
-        }
-
-        this._contentTreeOutline = newTreeOutline;
-        this._contentTreeOutline.hidden = false;
-
-        this._visibleContentTreeOutlines.add(newTreeOutline);
-
-        this._updateFilter();
</del><ins>+        return this._contentTreeOutlineGroup.items;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    get visibleContentTreeOutlines()
-    {
-        return this._visibleContentTreeOutlines;
-    }
-
</del><span class="cx">     get hasSelectedElement()
</span><span class="cx">     {
</span><del>-        return this._visibleContentTreeOutlines.some((treeOutline) =&gt; !!treeOutline.selectedTreeElement);
</del><ins>+        return !!this._contentTreeOutlineGroup.selectedTreeElement
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     get filterBar()
</span><span class="lines">@@ -145,17 +124,13 @@
</span><span class="cx">         this._finalAttemptToRestoreViewStateTimeout = undefined;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    createContentTreeOutline(dontHideByDefault, suppressFiltering)
</del><ins>+    createContentTreeOutline(suppressFiltering)
</ins><span class="cx">     {
</span><span class="cx">         let contentTreeOutline = new WebInspector.TreeOutline;
</span><span class="cx">         contentTreeOutline.allowsRepeatSelection = true;
</span><del>-        contentTreeOutline.hidden = !dontHideByDefault;
</del><span class="cx">         contentTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementStyleClassName);
</span><del>-        contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._contentTreeOutlineTreeSelectionDidChange, this);
-        contentTreeOutline.element.addEventListener(&quot;focus&quot;, this._contentTreeOutlineDidFocus, this);
</del><span class="cx"> 
</span><del>-        // FIXME Remove ContentTreeOutlineSymbol once &lt;https://webkit.org/b/157825&gt; is finished.
-        contentTreeOutline.element[WebInspector.NavigationSidebarPanel.ContentTreeOutlineSymbol] = contentTreeOutline;
</del><ins>+        this._contentTreeOutlineGroup.add(contentTreeOutline);
</ins><span class="cx"> 
</span><span class="cx">         this.contentView.element.appendChild(contentTreeOutline.element);
</span><span class="cx"> 
</span><span class="lines">@@ -167,9 +142,6 @@
</span><span class="cx"> 
</span><span class="cx">         contentTreeOutline[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol] = suppressFiltering;
</span><span class="cx"> 
</span><del>-        if (dontHideByDefault)
-            this._visibleContentTreeOutlines.add(contentTreeOutline);
-
</del><span class="cx">         return contentTreeOutline;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -186,7 +158,7 @@
</span><span class="cx">     treeElementForRepresentedObject(representedObject)
</span><span class="cx">     {
</span><span class="cx">         let treeElement = null;
</span><del>-        for (let treeOutline of this._visibleContentTreeOutlines) {
</del><ins>+        for (let treeOutline of this.contentTreeOutlines) {
</ins><span class="cx">             treeElement = treeOutline.getCachedTreeElement(representedObject);
</span><span class="cx">             if (treeElement)
</span><span class="cx">                 break;
</span><span class="lines">@@ -234,7 +206,7 @@
</span><span class="cx"> 
</span><span class="cx">         // This does not save folder selections, which lack a represented object and content view.
</span><span class="cx">         var selectedTreeElement = null;
</span><del>-        this._visibleContentTreeOutlines.forEach(function(outline) {
</del><ins>+        this.contentTreeOutlines.forEach(function(outline) {
</ins><span class="cx">             if (outline.selectedTreeElement)
</span><span class="cx">                 selectedTreeElement = outline.selectedTreeElement;
</span><span class="cx">         });
</span><span class="lines">@@ -465,7 +437,7 @@
</span><span class="cx">             this._checkForStaleResourcesTimeoutIdentifier = undefined;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        for (var contentTreeOutline of this._visibleContentTreeOutlines) {
</del><ins>+        for (let contentTreeOutline of this.contentTreeOutlines) {
</ins><span class="cx">             // Check all the ResourceTreeElements at the top level to make sure their Resource still has a parentFrame in the frame hierarchy.
</span><span class="cx">             // If the parentFrame is no longer in the frame hierarchy we know it was removed due to a navigation or some other page change and
</span><span class="cx">             // we should remove the issues for that resource.
</span><span class="lines">@@ -553,7 +525,7 @@
</span><span class="cx">             this._emptyFilterResults.set(treeOutline, true);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        for (let treeOutline of this._visibleContentTreeOutlines) {
</del><ins>+        for (let treeOutline of this.contentTreeOutlines) {
</ins><span class="cx">             if (treeOutline[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol])
</span><span class="cx">                 continue;
</span><span class="cx"> 
</span><span class="lines">@@ -569,7 +541,7 @@
</span><span class="cx">     _updateFilter()
</span><span class="cx">     {
</span><span class="cx">         let selectedTreeElement;
</span><del>-        for (let treeOutline of this.visibleContentTreeOutlines) {
</del><ins>+        for (let treeOutline of this.contentTreeOutlines) {
</ins><span class="cx">             if (treeOutline.hidden || treeOutline[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol])
</span><span class="cx">                 continue;
</span><span class="cx"> 
</span><span class="lines">@@ -588,7 +560,7 @@
</span><span class="cx">         let dontPopulate = !this._filterBar.hasActiveFilters() &amp;&amp; !this.shouldFilterPopulate();
</span><span class="cx"> 
</span><span class="cx">         // Update all trees that allow filtering.
</span><del>-        for (let treeOutline of this.visibleContentTreeOutlines) {
</del><ins>+        for (let treeOutline of this.contentTreeOutlines) {
</ins><span class="cx">             if (treeOutline.hidden || treeOutline[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol])
</span><span class="cx">                 continue;
</span><span class="cx"> 
</span><span class="lines">@@ -645,49 +617,6 @@
</span><span class="cx">         this.soon._updateContentOverflowShadowVisibility();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    _contentTreeOutlineDidFocus(event)
-    {
-        let treeOutline = event.target[WebInspector.NavigationSidebarPanel.ContentTreeOutlineSymbol];
-        if (!treeOutline)
-            return;
-
-        let previousSelectedTreeElement = treeOutline[WebInspector.NavigationSidebarPanel.PreviousSelectedTreeElementSymbol];
-        if (!previousSelectedTreeElement || previousSelectedTreeElement.hidden) {
-            const skipUnrevealed = true;
-            let firstVisibleTreeElement = treeOutline.children[0];
-            while (firstVisibleTreeElement &amp;&amp; firstVisibleTreeElement.hidden)
-                firstVisibleTreeElement = firstVisibleTreeElement.traverseNextTreeElement(skipUnrevealed, this);
-
-            previousSelectedTreeElement = firstVisibleTreeElement;
-        }
-
-        if (!previousSelectedTreeElement)
-            return;
-
-        previousSelectedTreeElement.select();
-    }
-
-    _contentTreeOutlineTreeSelectionDidChange(event)
-    {
-        let selectedElement = event.data.selectedElement;
-        if (!selectedElement)
-            return;
-
-        let selectedTreeOutline = selectedElement.treeOutline;
-        selectedTreeOutline[WebInspector.NavigationSidebarPanel.PreviousSelectedTreeElementSymbol] = selectedElement;
-
-        // Prevent multiple selections in the sidebar.
-        for (let treeOutline of this._visibleContentTreeOutlines) {
-            if (selectedTreeOutline === treeOutline)
-                continue;
-
-            if (treeOutline.selectedTreeElement) {
-                treeOutline.selectedTreeElement.deselect();
-                break;
-            }
-        }
-    }
-
</del><span class="cx">     _checkForStaleResourcesIfNeeded()
</span><span class="cx">     {
</span><span class="cx">         if (!this._checkForStaleResourcesTimeoutIdentifier || !this._shouldAutoPruneStaleTopLevelResourceTreeElements)
</span><span class="lines">@@ -726,7 +655,7 @@
</span><span class="cx">         this._checkForStaleResourcesIfNeeded();
</span><span class="cx"> 
</span><span class="cx">         var visibleTreeElements = [];
</span><del>-        this._visibleContentTreeOutlines.forEach(function(outline) {
</del><ins>+        this.contentTreeOutlines.forEach(function(outline) {
</ins><span class="cx">             var currentTreeElement = outline.hasChildren ? outline.children[0] : null;
</span><span class="cx">             while (currentTreeElement) {
</span><span class="cx">                 visibleTreeElements.push(currentTreeElement);
</span><span class="lines">@@ -815,8 +744,6 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-WebInspector.NavigationSidebarPanel.ContentTreeOutlineSymbol = Symbol(&quot;content-tree-outline&quot;);
-WebInspector.NavigationSidebarPanel.PreviousSelectedTreeElementSymbol = Symbol(&quot;previous-selected-tree-element&quot;);
</del><span class="cx"> WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol = Symbol(&quot;suppress-filtering&quot;);
</span><span class="cx"> WebInspector.NavigationSidebarPanel.WasExpandedDuringFilteringSymbol = Symbol(&quot;was-expanded-during-filtering&quot;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTreeElementjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js (212170 => 212171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js        2017-02-11 02:20:21 UTC (rev 212170)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js        2017-02-11 02:25:04 UTC (rev 212171)
</span><span class="lines">@@ -511,6 +511,12 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         treeOutline.processingSelectionChange = false;
</span><ins>+
+        let treeOutlineGroup = WebInspector.TreeOutlineGroup.groupForTreeOutline(treeOutline);
+        if (!treeOutlineGroup)
+            return;
+
+        treeOutlineGroup.didSelectTreeElement(this);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     revealAndSelect(omitFocus, selectedByUser, suppressOnSelect, suppressOnDeselect)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTreeOutlineGroupjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutlineGroup.js (0 => 212171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutlineGroup.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutlineGroup.js        2017-02-11 02:25:04 UTC (rev 212171)
</span><span class="lines">@@ -0,0 +1,96 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.TreeOutlineGroup = class TreeOutlineGroup extends WebInspector.Collection
+{
+    constructor()
+    {
+        super((object) =&gt; object instanceof WebInspector.TreeOutline);
+    }
+
+    // Static
+
+    static groupForTreeOutline(treeOutline)
+    {
+        return treeOutline[WebInspector.TreeOutlineGroup.GroupForTreeOutlineSymbol] || null;
+    }
+
+    // Public
+
+    get selectedTreeElement()
+    {
+        for (let treeOutline of this.items) {
+            if (treeOutline.selectedTreeElement)
+                return treeOutline.selectedTreeElement;
+        }
+
+        return null;
+    }
+
+    // Protected
+
+    itemAdded(treeOutline)
+    {
+        console.assert(!treeOutline[WebInspector.TreeOutlineGroup.GroupForTreeOutlineSymbol]);
+        treeOutline[WebInspector.TreeOutlineGroup.GroupForTreeOutlineSymbol] = this;
+
+        if (treeOutline.selectedTreeElement)
+            this._removeConflictingTreeSelections(treeOutline.selectedTreeElement);
+    }
+
+    itemRemoved(treeOutline)
+    {
+        console.assert(treeOutline[WebInspector.TreeOutlineGroup.GroupForTreeOutlineSymbol] === this);
+        treeOutline[WebInspector.TreeOutlineGroup.GroupForTreeOutlineSymbol] = null;
+    }
+
+    didSelectTreeElement(treeElement)
+    {
+        // Called by TreeOutline.
+
+        if (!treeElement)
+            return;
+
+        this._removeConflictingTreeSelections(treeElement);
+    }
+
+    // Private
+
+    _removeConflictingTreeSelections(treeElement)
+    {
+        let selectedTreeOutline = treeElement.treeOutline;
+        console.assert(selectedTreeOutline, &quot;Should have a parent tree outline.&quot;);
+
+        for (let treeOutline of this.items) {
+            if (selectedTreeOutline === treeOutline)
+                continue;
+
+            if (treeOutline.selectedTreeElement)
+                treeOutline.selectedTreeElement.deselect();
+        }
+    }
+};
+
+WebInspector.TreeOutlineGroup.GroupForTreeOutlineSymbol = Symbol(&quot;group-for-tree-outline&quot;);
</ins></span></pre>
</div>
</div>

</body>
</html>