- Revision
- 212171
- Author
- mattba...@apple.com
- Date
- 2017-02-10 18:25:04 -0800 (Fri, 10 Feb 2017)
Log Message
Web Inspector: Debugger sidebar panel should not have multiple tree selections
https://bugs.webkit.org/show_bug.cgi?id=166000
<rdar://problem/29721988>
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.
Modified Paths
Added Paths
Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (212170 => 212171)
--- 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)
@@ -1,5 +1,77 @@
2017-02-10 Matt Baker <mattba...@apple.com>
+ Web Inspector: Debugger sidebar panel should not have multiple tree selections
+ https://bugs.webkit.org/show_bug.cgi?id=166000
+ <rdar://problem/29721988>
+
+ 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 <mattba...@apple.com>
+
Web Inspector: ContentViewContainer can have redundant back-forward entries after ContentView close
https://bugs.webkit.org/show_bug.cgi?id=168105
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (212170 => 212171)
--- 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)
@@ -427,6 +427,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ContentBrowserTabContentView.js (212170 => 212171)
--- 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)
@@ -254,7 +254,7 @@
// If a tree outline is processing a selection currently then we can assume the selection does not
// need to be changed. This is needed to allow breakpoint and call frame tree elements to be selected
// without jumping back to selecting the resource tree element.
- for (let contentTreeOutline of this.navigationSidebarPanel.visibleContentTreeOutlines) {
+ for (let contentTreeOutline of this.navigationSidebarPanel.contentTreeOutlines) {
if (contentTreeOutline.processingSelectionChange)
return;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js (212170 => 212171)
--- 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)
@@ -166,7 +166,7 @@
if (DebuggerAgent.setPauseOnAssertions)
this._breakpointsContentTreeOutline.appendChild(this._assertionsBreakpointTreeElement);
- this._scriptsContentTreeOutline = this.createContentTreeOutline(true);
+ this._scriptsContentTreeOutline = this.createContentTreeOutline();
this._scriptsContentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
let scriptsRow = new WebInspector.DetailsSectionRow;
@@ -176,9 +176,8 @@
this._scriptsSection = new WebInspector.DetailsSection("scripts", WebInspector.UIString("Sources"), [scriptsGroup]);
this.contentView.element.appendChild(this._scriptsSection.element);
- const dontHideByDefault = true;
const suppressFiltering = true;
- this._callStackTreeOutline = this.createContentTreeOutline(dontHideByDefault, suppressFiltering);
+ this._callStackTreeOutline = this.createContentTreeOutline(suppressFiltering);
this._callStackTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
this._mainTargetTreeElement = new WebInspector.ThreadTreeElement(WebInspector.mainTarget);
@@ -883,10 +882,11 @@
case WebInspector.DebuggerManager.PauseReason.Breakpoint:
console.assert(pauseData, "Expected breakpoint identifier, but found none.");
if (pauseData && pauseData.breakpointId) {
- let breakpoint = WebInspector.debuggerManager.breakpointForIdentifier(pauseData.breakpointId);
- this._pauseReasonTreeOutline = this.createContentTreeOutline(true, true);
+ const suppressFiltering = true;
+ this._pauseReasonTreeOutline = this.createContentTreeOutline(suppressFiltering);
this._pauseReasonTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
+ let breakpoint = WebInspector.debuggerManager.breakpointForIdentifier(pauseData.breakpointId);
let breakpointTreeElement = new WebInspector.BreakpointTreeElement(breakpoint, WebInspector.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName, WebInspector.UIString("Triggered Breakpoint"));
let breakpointDetailsSection = new WebInspector.DetailsSectionRow;
this._pauseReasonTreeOutline.appendChild(breakpointTreeElement);
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.js (212170 => 212171)
--- 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)
@@ -31,11 +31,10 @@
this.element.classList.add("navigation");
- this._visibleContentTreeOutlines = new Set;
-
this.contentView.element.addEventListener("scroll", this.soon._updateContentOverflowShadowVisibility);
- this._contentTreeOutline = this.createContentTreeOutline(true);
+ this._contentTreeOutlineGroup = new WebInspector.TreeOutlineGroup;
+ this._contentTreeOutline = this.createContentTreeOutline();
this._filterBar = new WebInspector.FilterBar;
this._filterBar.addEventListener(WebInspector.FilterBar.Event.FilterDidChange, this._filterDidChange, this);
@@ -96,34 +95,14 @@
return this._contentTreeOutline;
}
- set contentTreeOutline(newTreeOutline)
+ get contentTreeOutlines()
{
- 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();
+ return this._contentTreeOutlineGroup.items;
}
- get visibleContentTreeOutlines()
- {
- return this._visibleContentTreeOutlines;
- }
-
get hasSelectedElement()
{
- return this._visibleContentTreeOutlines.some((treeOutline) => !!treeOutline.selectedTreeElement);
+ return !!this._contentTreeOutlineGroup.selectedTreeElement
}
get filterBar()
@@ -145,17 +124,13 @@
this._finalAttemptToRestoreViewStateTimeout = undefined;
}
- createContentTreeOutline(dontHideByDefault, suppressFiltering)
+ createContentTreeOutline(suppressFiltering)
{
let contentTreeOutline = new WebInspector.TreeOutline;
contentTreeOutline.allowsRepeatSelection = true;
- contentTreeOutline.hidden = !dontHideByDefault;
contentTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementStyleClassName);
- contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._contentTreeOutlineTreeSelectionDidChange, this);
- contentTreeOutline.element.addEventListener("focus", this._contentTreeOutlineDidFocus, this);
- // FIXME Remove ContentTreeOutlineSymbol once <https://webkit.org/b/157825> is finished.
- contentTreeOutline.element[WebInspector.NavigationSidebarPanel.ContentTreeOutlineSymbol] = contentTreeOutline;
+ this._contentTreeOutlineGroup.add(contentTreeOutline);
this.contentView.element.appendChild(contentTreeOutline.element);
@@ -167,9 +142,6 @@
contentTreeOutline[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol] = suppressFiltering;
- if (dontHideByDefault)
- this._visibleContentTreeOutlines.add(contentTreeOutline);
-
return contentTreeOutline;
}
@@ -186,7 +158,7 @@
treeElementForRepresentedObject(representedObject)
{
let treeElement = null;
- for (let treeOutline of this._visibleContentTreeOutlines) {
+ for (let treeOutline of this.contentTreeOutlines) {
treeElement = treeOutline.getCachedTreeElement(representedObject);
if (treeElement)
break;
@@ -234,7 +206,7 @@
// This does not save folder selections, which lack a represented object and content view.
var selectedTreeElement = null;
- this._visibleContentTreeOutlines.forEach(function(outline) {
+ this.contentTreeOutlines.forEach(function(outline) {
if (outline.selectedTreeElement)
selectedTreeElement = outline.selectedTreeElement;
});
@@ -465,7 +437,7 @@
this._checkForStaleResourcesTimeoutIdentifier = undefined;
}
- for (var contentTreeOutline of this._visibleContentTreeOutlines) {
+ for (let contentTreeOutline of this.contentTreeOutlines) {
// Check all the ResourceTreeElements at the top level to make sure their Resource still has a parentFrame in the frame hierarchy.
// 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
// we should remove the issues for that resource.
@@ -553,7 +525,7 @@
this._emptyFilterResults.set(treeOutline, true);
}
- for (let treeOutline of this._visibleContentTreeOutlines) {
+ for (let treeOutline of this.contentTreeOutlines) {
if (treeOutline[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol])
continue;
@@ -569,7 +541,7 @@
_updateFilter()
{
let selectedTreeElement;
- for (let treeOutline of this.visibleContentTreeOutlines) {
+ for (let treeOutline of this.contentTreeOutlines) {
if (treeOutline.hidden || treeOutline[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol])
continue;
@@ -588,7 +560,7 @@
let dontPopulate = !this._filterBar.hasActiveFilters() && !this.shouldFilterPopulate();
// Update all trees that allow filtering.
- for (let treeOutline of this.visibleContentTreeOutlines) {
+ for (let treeOutline of this.contentTreeOutlines) {
if (treeOutline.hidden || treeOutline[WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol])
continue;
@@ -645,49 +617,6 @@
this.soon._updateContentOverflowShadowVisibility();
}
- _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 && 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;
- }
- }
- }
-
_checkForStaleResourcesIfNeeded()
{
if (!this._checkForStaleResourcesTimeoutIdentifier || !this._shouldAutoPruneStaleTopLevelResourceTreeElements)
@@ -726,7 +655,7 @@
this._checkForStaleResourcesIfNeeded();
var visibleTreeElements = [];
- this._visibleContentTreeOutlines.forEach(function(outline) {
+ this.contentTreeOutlines.forEach(function(outline) {
var currentTreeElement = outline.hasChildren ? outline.children[0] : null;
while (currentTreeElement) {
visibleTreeElements.push(currentTreeElement);
@@ -815,8 +744,6 @@
}
};
-WebInspector.NavigationSidebarPanel.ContentTreeOutlineSymbol = Symbol("content-tree-outline");
-WebInspector.NavigationSidebarPanel.PreviousSelectedTreeElementSymbol = Symbol("previous-selected-tree-element");
WebInspector.NavigationSidebarPanel.SuppressFilteringSymbol = Symbol("suppress-filtering");
WebInspector.NavigationSidebarPanel.WasExpandedDuringFilteringSymbol = Symbol("was-expanded-during-filtering");
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js (212170 => 212171)
--- 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)
@@ -511,6 +511,12 @@
}
treeOutline.processingSelectionChange = false;
+
+ let treeOutlineGroup = WebInspector.TreeOutlineGroup.groupForTreeOutline(treeOutline);
+ if (!treeOutlineGroup)
+ return;
+
+ treeOutlineGroup.didSelectTreeElement(this);
}
revealAndSelect(omitFocus, selectedByUser, suppressOnSelect, suppressOnDeselect)
Added: trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutlineGroup.js (0 => 212171)
--- 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)
@@ -0,0 +1,96 @@
+/*
+ * 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) => 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, "Should have a parent tree outline.");
+
+ for (let treeOutline of this.items) {
+ if (selectedTreeOutline === treeOutline)
+ continue;
+
+ if (treeOutline.selectedTreeElement)
+ treeOutline.selectedTreeElement.deselect();
+ }
+ }
+};
+
+WebInspector.TreeOutlineGroup.GroupForTreeOutlineSymbol = Symbol("group-for-tree-outline");