Title: [212171] trunk/Source/WebInspectorUI
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");
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to