Web Inspector: TreeOutline should just dispatch events via WebInspector.Object
authormattbaker@apple.com <mattbaker@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Dec 2015 01:37:38 +0000 (01:37 +0000)
committermattbaker@apple.com <mattbaker@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Dec 2015 01:37:38 +0000 (01:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=148067

Reviewed by Timothy Hatcher.

TreeOutline now dispatches most events via WebInspector.Object. The onselect and
ondeselect callbacks are replaced by a SelectionDidChange event, which includes
both the selected and deselected elements in its event data. The onexpand and oncollapse
callbacks are replaced by an ElementDisclosureDidChange event. This is consistent with the
behavior of onhidden, which had no corresponding onvisible callback.

Alas, TimelineView and TreeOutlineDataGridSynchronizer depended on the order in which
TreeOutline.onselect callbacks were chained together. The synchronizer added its
callback after the timeline view, which ensured that the tree and grid were in sync
before the view handled onselect and dispatched a SelectionPathComponentsDidChange.
The change notification causes the view's path components to be read, and timeline
views need the grid selection to be in a valid state to build path components.

This is addressed by having timeline views dispatch SelectionPathComponentsDidChange
events when the grid selection changes, instead of the tree selection. The change
required that the synchronizer no longer suppress notifications when selecting grid nodes.

* UserInterface/Views/DebuggerSidebarPanel.js:
(WebInspector.DebuggerSidebarPanel):
(WebInspector.DebuggerSidebarPanel.prototype._treeSelectionDidChange):
(WebInspector.DebuggerSidebarPanel.prototype._updatePauseReasonSection):

* UserInterface/Views/NavigationSidebarPanel.js:
(WebInspector.NavigationSidebarPanel.prototype.createContentTreeOutline):
(WebInspector.NavigationSidebarPanel.prototype._treeElementAddedOrChanged):

* UserInterface/Views/NetworkGridContentView.js:
(WebInspector.NetworkGridContentView):
(WebInspector.NetworkGridContentView.prototype._treeSelectionDidChange):

* UserInterface/Views/ResourceSidebarPanel.js:
(WebInspector.ResourceSidebarPanel):
(WebInspector.ResourceSidebarPanel.prototype._treeSelectionDidChange):
(WebInspector.ResourceSidebarPanel.prototype._treeElementSelected): Deleted.

* UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
(WebInspector.ScopeChainDetailsSidebarPanel.prototype._generateCallFramesSection):
(WebInspector.ScopeChainDetailsSidebarPanel.prototype._generateWatchExpressionsSection):
(WebInspector.ScopeChainDetailsSidebarPanel.prototype._treeElementAdded):
(WebInspector.ScopeChainDetailsSidebarPanel.prototype._treeElementDisclosureDidChange):
(WebInspector.ScopeChainDetailsSidebarPanel.prototype._objectTreeExpandHandler): Deleted.
(WebInspector.ScopeChainDetailsSidebarPanel.prototype._objectTreeCollapseHandler): Deleted.

* UserInterface/Views/SearchSidebarPanel.js:
(WebInspector.SearchSidebarPanel):
(WebInspector.SearchSidebarPanel.prototype._treeSelectionDidChange):
(WebInspector.SearchSidebarPanel.prototype._treeElementSelected): Deleted.

* UserInterface/Views/StorageSidebarPanel.js:
(WebInspector.StorageSidebarPanel):
(WebInspector.StorageSidebarPanel._treeSelectionDidChange):

* UserInterface/Views/TimelineDataGrid.js:
(WebInspector.TimelineDataGrid.prototype._createPopoverContent):
(WebInspector.TimelineDataGrid.prototype._popoverCallStackTreeSelectionDidChange):
(WebInspector.TimelineDataGrid):

* UserInterface/Views/TimelineSidebarPanel.js:
(WebInspector.TimelineSidebarPanel):
(WebInspector.TimelineSidebarPanel.prototype._recordingsTreeSelectionDidChange):
(WebInspector.TimelineSidebarPanel.prototype._timelinesTreeSelectionDidChange):
(WebInspector.TimelineSidebarPanel.prototype._timelinesTreeElementSelected): Deleted.

* UserInterface/Views/TimelineView.js:
(WebInspector.TimelineView):
(WebInspector.TimelineView.prototype._treeSelectionDidChange):
(WebInspector.TimelineView.prototype.treeElementSelected):
Don't dispatch SelectionPathComponentsDidChange. Timeline views already do this
in response to grid selection events.

* UserInterface/Views/TreeOutline.js:
(WebInspector.TreeOutline.prototype.appendChild):
(WebInspector.TreeOutline.prototype.insertChild):
(WebInspector.TreeOutline.prototype.removeChildAtIndex):
(WebInspector.TreeOutline.prototype.removeChildren):
(WebInspector.TreeOutline.prototype.removeChildrenRecursive):
(WebInspector.TreeOutline.prototype._treeElementDidChange):
(WebInspector.TreeElement.prototype.set hidden):
(WebInspector.TreeElement.prototype.collapse):
(WebInspector.TreeElement.prototype.expand):
(WebInspector.TreeElement.prototype.select):
(WebInspector.TreeElement.prototype.deselect):
(WebInspector.TreeElement.prototype.get childrenListElement): Deleted.
Removed dead code.

* UserInterface/Views/TreeOutlineDataGridSynchronizer.js:
(WebInspector.TreeOutlineDataGridSynchronizer):
(WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeSelectionDidChange):
(WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementAdded):
(WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementRemoved):
(WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementDisclosureDidChange):
(WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementVisibilityDidChange):
(WebInspector.TreeOutlineDataGridSynchronizer.treeOutline.onadd): Deleted.
(WebInspector.TreeOutlineDataGridSynchronizer.treeOutline.onremove): Deleted.
(WebInspector.TreeOutlineDataGridSynchronizer.treeOutline.onexpand): Deleted.
(WebInspector.TreeOutlineDataGridSynchronizer.treeOutline.oncollapse): Deleted.
(WebInspector.TreeOutlineDataGridSynchronizer.treeOutline.onhidden): Deleted.
(WebInspector.TreeOutlineDataGridSynchronizer.treeOutline.onselect): Deleted.
(WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementSelected): Deleted.
(WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementExpanded): Deleted.
(WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementCollapsed): Deleted.
(WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementHiddenChanged): Deleted.

* UserInterface/Views/VisualStyleCommaSeparatedKeywordEditor.js:
(WebInspector.VisualStyleCommaSeparatedKeywordEditor):
(WebInspector.VisualStyleCommaSeparatedKeywordEditor.prototype._treeSelectionDidChange):
(WebInspector.VisualStyleCommaSeparatedKeywordEditor.prototype._treeElementSelected): Deleted.

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

14 files changed:
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/NetworkGridContentView.js
Source/WebInspectorUI/UserInterface/Views/ResourceSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/StorageSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/TimelineDataGrid.js
Source/WebInspectorUI/UserInterface/Views/TimelineSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/TimelineView.js
Source/WebInspectorUI/UserInterface/Views/TreeOutline.js
Source/WebInspectorUI/UserInterface/Views/TreeOutlineDataGridSynchronizer.js
Source/WebInspectorUI/UserInterface/Views/VisualStyleCommaSeparatedKeywordEditor.js

index c640c84..18f5338 100644 (file)
@@ -1,3 +1,118 @@
+2015-12-01  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: TreeOutline should just dispatch events via WebInspector.Object
+        https://bugs.webkit.org/show_bug.cgi?id=148067
+
+        Reviewed by Timothy Hatcher.
+
+        TreeOutline now dispatches most events via WebInspector.Object. The onselect and
+        ondeselect callbacks are replaced by a SelectionDidChange event, which includes
+        both the selected and deselected elements in its event data. The onexpand and oncollapse
+        callbacks are replaced by an ElementDisclosureDidChange event. This is consistent with the
+        behavior of onhidden, which had no corresponding onvisible callback.
+
+        Alas, TimelineView and TreeOutlineDataGridSynchronizer depended on the order in which
+        TreeOutline.onselect callbacks were chained together. The synchronizer added its
+        callback after the timeline view, which ensured that the tree and grid were in sync
+        before the view handled onselect and dispatched a SelectionPathComponentsDidChange.
+        The change notification causes the view's path components to be read, and timeline
+        views need the grid selection to be in a valid state to build path components.
+
+        This is addressed by having timeline views dispatch SelectionPathComponentsDidChange
+        events when the grid selection changes, instead of the tree selection. The change
+        required that the synchronizer no longer suppress notifications when selecting grid nodes.
+
+        * UserInterface/Views/DebuggerSidebarPanel.js:
+        (WebInspector.DebuggerSidebarPanel):
+        (WebInspector.DebuggerSidebarPanel.prototype._treeSelectionDidChange):
+        (WebInspector.DebuggerSidebarPanel.prototype._updatePauseReasonSection):
+
+        * UserInterface/Views/NavigationSidebarPanel.js:
+        (WebInspector.NavigationSidebarPanel.prototype.createContentTreeOutline):
+        (WebInspector.NavigationSidebarPanel.prototype._treeElementAddedOrChanged):
+
+        * UserInterface/Views/NetworkGridContentView.js:
+        (WebInspector.NetworkGridContentView):
+        (WebInspector.NetworkGridContentView.prototype._treeSelectionDidChange):
+
+        * UserInterface/Views/ResourceSidebarPanel.js:
+        (WebInspector.ResourceSidebarPanel):
+        (WebInspector.ResourceSidebarPanel.prototype._treeSelectionDidChange):
+        (WebInspector.ResourceSidebarPanel.prototype._treeElementSelected): Deleted.
+
+        * UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
+        (WebInspector.ScopeChainDetailsSidebarPanel.prototype._generateCallFramesSection):
+        (WebInspector.ScopeChainDetailsSidebarPanel.prototype._generateWatchExpressionsSection):
+        (WebInspector.ScopeChainDetailsSidebarPanel.prototype._treeElementAdded):
+        (WebInspector.ScopeChainDetailsSidebarPanel.prototype._treeElementDisclosureDidChange):
+        (WebInspector.ScopeChainDetailsSidebarPanel.prototype._objectTreeExpandHandler): Deleted.
+        (WebInspector.ScopeChainDetailsSidebarPanel.prototype._objectTreeCollapseHandler): Deleted.
+
+        * UserInterface/Views/SearchSidebarPanel.js:
+        (WebInspector.SearchSidebarPanel):
+        (WebInspector.SearchSidebarPanel.prototype._treeSelectionDidChange):
+        (WebInspector.SearchSidebarPanel.prototype._treeElementSelected): Deleted.
+
+        * UserInterface/Views/StorageSidebarPanel.js:
+        (WebInspector.StorageSidebarPanel):
+        (WebInspector.StorageSidebarPanel._treeSelectionDidChange):
+
+        * UserInterface/Views/TimelineDataGrid.js:
+        (WebInspector.TimelineDataGrid.prototype._createPopoverContent):
+        (WebInspector.TimelineDataGrid.prototype._popoverCallStackTreeSelectionDidChange):
+        (WebInspector.TimelineDataGrid):
+
+        * UserInterface/Views/TimelineSidebarPanel.js:
+        (WebInspector.TimelineSidebarPanel):
+        (WebInspector.TimelineSidebarPanel.prototype._recordingsTreeSelectionDidChange):
+        (WebInspector.TimelineSidebarPanel.prototype._timelinesTreeSelectionDidChange):
+        (WebInspector.TimelineSidebarPanel.prototype._timelinesTreeElementSelected): Deleted.
+
+        * UserInterface/Views/TimelineView.js:
+        (WebInspector.TimelineView):
+        (WebInspector.TimelineView.prototype._treeSelectionDidChange):
+        (WebInspector.TimelineView.prototype.treeElementSelected):
+        Don't dispatch SelectionPathComponentsDidChange. Timeline views already do this
+        in response to grid selection events.
+
+        * UserInterface/Views/TreeOutline.js:
+        (WebInspector.TreeOutline.prototype.appendChild):
+        (WebInspector.TreeOutline.prototype.insertChild):
+        (WebInspector.TreeOutline.prototype.removeChildAtIndex):
+        (WebInspector.TreeOutline.prototype.removeChildren):
+        (WebInspector.TreeOutline.prototype.removeChildrenRecursive):
+        (WebInspector.TreeOutline.prototype._treeElementDidChange):
+        (WebInspector.TreeElement.prototype.set hidden):
+        (WebInspector.TreeElement.prototype.collapse):
+        (WebInspector.TreeElement.prototype.expand):
+        (WebInspector.TreeElement.prototype.select):
+        (WebInspector.TreeElement.prototype.deselect):
+        (WebInspector.TreeElement.prototype.get childrenListElement): Deleted.
+        Removed dead code.
+
+        * UserInterface/Views/TreeOutlineDataGridSynchronizer.js:
+        (WebInspector.TreeOutlineDataGridSynchronizer):
+        (WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeSelectionDidChange):
+        (WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementAdded):
+        (WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementRemoved):
+        (WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementDisclosureDidChange):
+        (WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementVisibilityDidChange):
+        (WebInspector.TreeOutlineDataGridSynchronizer.treeOutline.onadd): Deleted.
+        (WebInspector.TreeOutlineDataGridSynchronizer.treeOutline.onremove): Deleted.
+        (WebInspector.TreeOutlineDataGridSynchronizer.treeOutline.onexpand): Deleted.
+        (WebInspector.TreeOutlineDataGridSynchronizer.treeOutline.oncollapse): Deleted.
+        (WebInspector.TreeOutlineDataGridSynchronizer.treeOutline.onhidden): Deleted.
+        (WebInspector.TreeOutlineDataGridSynchronizer.treeOutline.onselect): Deleted.
+        (WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementSelected): Deleted.
+        (WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementExpanded): Deleted.
+        (WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementCollapsed): Deleted.
+        (WebInspector.TreeOutlineDataGridSynchronizer.prototype._treeElementHiddenChanged): Deleted.
+
+        * UserInterface/Views/VisualStyleCommaSeparatedKeywordEditor.js:
+        (WebInspector.VisualStyleCommaSeparatedKeywordEditor):
+        (WebInspector.VisualStyleCommaSeparatedKeywordEditor.prototype._treeSelectionDidChange):
+        (WebInspector.VisualStyleCommaSeparatedKeywordEditor.prototype._treeElementSelected): Deleted.
+
 2015-12-01  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Timestamp in Tooltip of Event Markers is incorrect
index 2b3f007..5c09cef 100644 (file)
@@ -113,7 +113,7 @@ 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;
-        this._breakpointsContentTreeOutline.onselect = this._treeElementSelected.bind(this);
+        this._breakpointsContentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
         this._breakpointsContentTreeOutline.ondelete = this._breakpointTreeOutlineDeleteTreeElement.bind(this);
         this._breakpointsContentTreeOutline.oncontextmenu = this._breakpointTreeOutlineContextMenuTreeElement.bind(this);
 
@@ -130,7 +130,7 @@ WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspec
         this.contentElement.appendChild(breakpointsSection.element);
 
         this._callStackContentTreeOutline = this.createContentTreeOutline(true, true);
-        this._callStackContentTreeOutline.onselect = this._treeElementSelected.bind(this);
+        this._callStackContentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
 
         this._callStackRow = new WebInspector.DetailsSectionRow(WebInspector.UIString("No Call Frames"));
         this._callStackRow.showEmptyMessage();
@@ -598,7 +598,7 @@ WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspec
         contextMenu.appendItem(WebInspector.UIString("Delete Breakpoints"), removeAllResourceBreakpoints);
     }
 
-    _treeElementSelected(treeElement, selectedByUser)
+    _treeSelectionDidChange(event)
     {
         function deselectCallStackContentTreeElements()
         {
@@ -624,6 +624,10 @@ WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspec
                 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);
@@ -731,7 +735,8 @@ WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspec
             if (pauseData && pauseData.breakpointId) {
                 var breakpoint = WebInspector.debuggerManager.breakpointForIdentifier(pauseData.breakpointId);
                 var breakpointTreeOutline = this.createContentTreeOutline(true, true);
-                breakpointTreeOutline.onselect = this._treeElementSelected.bind(this);
+                breakpointTreeOutline.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);
index 8ae83b9..9591a96 100644 (file)
@@ -166,10 +166,9 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
         contentTreeOutline.allowsRepeatSelection = true;
 
         if (!suppressFiltering) {
-            contentTreeOutline.onadd = this._treeElementAddedOrChanged.bind(this);
-            contentTreeOutline.onchange = this._treeElementAddedOrChanged.bind(this);
-            contentTreeOutline.onexpand = this._treeElementExpandedOrCollapsed.bind(this);
-            contentTreeOutline.oncollapse = this._treeElementExpandedOrCollapsed.bind(this);
+            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);
         }
 
         if (dontHideByDefault)
@@ -556,14 +555,15 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
         }
     }
 
-    _treeElementAddedOrChanged(treeElement)
+    _treeElementAddedOrChanged(event)
     {
         // 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();
 
         // Apply the filters to the tree element and its descendants.
-        var currentTreeElement = treeElement;
+        let treeElement = event.data.element;
+        let currentTreeElement = treeElement;
         while (currentTreeElement && !currentTreeElement.root) {
             const currentTreeElementWasHidden = currentTreeElement.hidden;
             this.applyFiltersToTreeElement(currentTreeElement);
@@ -582,7 +582,7 @@ WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebIn
         this.treeElementAddedOrChanged(treeElement);
     }
 
-    _treeElementExpandedOrCollapsed(treeElement)
+    _treeElementDisclosureDidChange(event)
     {
         this._updateContentOverflowShadowVisibility();
     }
index a34ed35..08ffb8f 100644 (file)
@@ -35,7 +35,7 @@ WebInspector.NetworkGridContentView = class NetworkGridContentView extends WebIn
         this._networkSidebarPanel = extraArguments.networkSidebarPanel;
 
         this._contentTreeOutline = this._networkSidebarPanel.contentTreeOutline;
-        this._contentTreeOutline.onselect = this._treeElementSelected.bind(this);
+        this._contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
 
         var columns = {domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}};
 
@@ -202,13 +202,14 @@ WebInspector.NetworkGridContentView = class NetworkGridContentView extends WebIn
         dataGridNode.revealAndSelect();
     }
 
-    _treeElementSelected(treeElement, selectedByUser)
+    _treeSelectionDidChange(event)
     {
         this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
 
         if (!this._networkSidebarPanel.canShowDifferentContentView())
             return;
 
+        let treeElement = event.data.selectedElement;
         if (treeElement instanceof WebInspector.ResourceTreeElement) {
             WebInspector.showRepresentedObject(treeElement.representedObject);
             return;
index 56e7312..0735157 100644 (file)
@@ -62,7 +62,7 @@ WebInspector.ResourceSidebarPanel = class ResourceSidebarPanel extends WebInspec
 
         WebInspector.notifications.addEventListener(WebInspector.Notification.ExtraDomainsActivated, this._extraDomainsActivated, this);
 
-        this.contentTreeOutline.onselect = this._treeElementSelected.bind(this);
+        this.contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
         this.contentTreeOutline.includeSourceMapResourceChildren = true;
 
         if (WebInspector.debuggableType === WebInspector.DebuggableType.JavaScript)
@@ -333,9 +333,10 @@ WebInspector.ResourceSidebarPanel = class ResourceSidebarPanel extends WebInspec
         }
     }
 
-    _treeElementSelected(treeElement, selectedByUser)
+    _treeSelectionDidChange(event)
     {
-        if (treeElement instanceof WebInspector.FolderTreeElement)
+        let treeElement = event.data.selectedElement;
+        if (!treeElement || treeElement instanceof WebInspector.FolderTreeElement)
             return;
 
         if (treeElement instanceof WebInspector.ResourceTreeElement
index c6ed902..7483b32 100644 (file)
@@ -221,9 +221,8 @@ WebInspector.ScopeChainDetailsSidebarPanel = class ScopeChainDetailsSidebarPanel
                 objectTree.appendExtraPropertyDescriptor(extraPropertyDescriptor);
 
             let treeOutline = objectTree.treeOutline;
-            treeOutline.onadd = this._objectTreeAddHandler.bind(this, detailsSectionIdentifier);
-            treeOutline.onexpand = this._objectTreeExpandHandler.bind(this, detailsSectionIdentifier);
-            treeOutline.oncollapse = this._objectTreeCollapseHandler.bind(this, detailsSectionIdentifier);
+            treeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementAdded, this._treeElementAdded.bind(this, detailsSectionIdentifier), this);
+            treeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementDisclosureDidChanged, this._treeElementDisclosureDidChange.bind(this, detailsSectionIdentifier), this);
 
             let detailsSection = new WebInspector.DetailsSection(detailsSectionIdentifier, title, null, null, collapsedByDefault);
             detailsSection.groups[0].rows = [new WebInspector.DetailsSectionPropertiesRow(objectTree)];
@@ -254,9 +253,8 @@ WebInspector.ScopeChainDetailsSidebarPanel = class ScopeChainDetailsSidebarPanel
 
         let treeOutline = objectTree.treeOutline;
         const watchExpressionSectionIdentifier = "watch-expressions";
-        treeOutline.onadd = this._objectTreeAddHandler.bind(this, watchExpressionSectionIdentifier);
-        treeOutline.onexpand = this._objectTreeExpandHandler.bind(this, watchExpressionSectionIdentifier);
-        treeOutline.oncollapse = this._objectTreeCollapseHandler.bind(this, watchExpressionSectionIdentifier);
+        treeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementAdded, this._treeElementAdded.bind(this, watchExpressionSectionIdentifier), this);
+        treeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementDisclosureDidChanged, this._treeElementDisclosureDidChange.bind(this, watchExpressionSectionIdentifier), this);
         treeOutline.objectTreeElementAddContextMenuItems = this._objectTreeElementAddContextMenuItems.bind(this);
 
         let promises = [];
@@ -422,8 +420,9 @@ WebInspector.ScopeChainDetailsSidebarPanel = class ScopeChainDetailsSidebarPanel
         return identifier + "-" + propertyPath.fullPath;
     }
 
-    _objectTreeAddHandler(identifier, treeElement)
+    _treeElementAdded(identifier, event)
     {
+        let treeElement = event.data.element;
         let propertyPathIdentifier = this._propertyPathIdentifierForTreeElement(identifier, treeElement);
         if (!propertyPathIdentifier)
             return;
@@ -432,22 +431,17 @@ WebInspector.ScopeChainDetailsSidebarPanel = class ScopeChainDetailsSidebarPanel
             treeElement.expand();
     }
 
-    _objectTreeExpandHandler(identifier, treeElement)
+    _treeElementDisclosureDidChange(identifier, event)
     {
+        let treeElement = event.data.element;
         let propertyPathIdentifier = this._propertyPathIdentifierForTreeElement(identifier, treeElement);
         if (!propertyPathIdentifier)
             return;
 
-        WebInspector.ScopeChainDetailsSidebarPanel._autoExpandProperties.add(propertyPathIdentifier);
-    }
-
-    _objectTreeCollapseHandler(identifier, treeElement)
-    {
-        let propertyPathIdentifier = this._propertyPathIdentifierForTreeElement(identifier, treeElement);
-        if (!propertyPathIdentifier)
-            return;
-
-        WebInspector.ScopeChainDetailsSidebarPanel._autoExpandProperties.delete(propertyPathIdentifier);
+        if (treeElement.expanded)
+            WebInspector.ScopeChainDetailsSidebarPanel._autoExpandProperties.add(propertyPathIdentifier);
+        else
+            WebInspector.ScopeChainDetailsSidebarPanel._autoExpandProperties.delete(propertyPathIdentifier);
     }
 
     _updateWatchExpressionsNavigationBar()
index 40faebc..81c8588 100644 (file)
@@ -52,7 +52,7 @@ WebInspector.SearchSidebarPanel = class SearchSidebarPanel extends WebInspector.
 
         WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
 
-        this.contentTreeOutline.onselect = this._treeElementSelected.bind(this);
+        this.contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
     }
 
     // Public
@@ -346,9 +346,10 @@ WebInspector.SearchSidebarPanel = class SearchSidebarPanel extends WebInspector.
             this.focusSearchField();
     }
 
-    _treeElementSelected(treeElement, selectedByUser)
+    _treeSelectionDidChange(event)
     {
-        if (treeElement instanceof WebInspector.FolderTreeElement)
+        let treeElement = event.data.selectedElement;
+        if (!treeElement || treeElement instanceof WebInspector.FolderTreeElement)
             return;
 
         if (treeElement instanceof WebInspector.ResourceTreeElement || treeElement instanceof WebInspector.ScriptTreeElement) {
index 603698d..f79ba42 100644 (file)
@@ -86,7 +86,7 @@ WebInspector.StorageSidebarPanel = class StorageSidebarPanel extends WebInspecto
         WebInspector.applicationCacheManager.addEventListener(WebInspector.ApplicationCacheManager.Event.FrameManifestAdded, this._frameManifestAdded, this);
         WebInspector.applicationCacheManager.addEventListener(WebInspector.ApplicationCacheManager.Event.FrameManifestRemoved, this._frameManifestRemoved, this);
 
-        this.contentTreeOutline.onselect = this._treeElementSelected.bind(this);
+        this.contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
 
         for (var domStorageObject of WebInspector.storageManager.domStorageObjects)
             this._addDOMStorageObject(domStorageObject);
@@ -161,8 +161,12 @@ WebInspector.StorageSidebarPanel = class StorageSidebarPanel extends WebInspecto
 
     // Private
 
-    _treeElementSelected(treeElement, selectedByUser)
+    _treeSelectionDidChange(event)
     {
+        let treeElement = event.data.selectedElement;
+        if (!treeElement)
+            return;
+
         if (treeElement instanceof WebInspector.FolderTreeElement || treeElement instanceof WebInspector.DatabaseHostTreeElement ||
             treeElement instanceof WebInspector.IndexedDatabaseHostTreeElement || treeElement instanceof WebInspector.IndexedDatabaseTreeElement
             || treeElement instanceof WebInspector.ApplicationCacheManifestTreeElement)
index 08d84e9..fd49e1b 100644 (file)
@@ -453,7 +453,7 @@ WebInspector.TimelineDataGrid = class TimelineDataGrid extends WebInspector.Data
             var contentElement = document.createElement("ol");
             contentElement.classList.add("timeline-data-grid-tree-outline");
             this._popoverCallStackTreeOutline = new WebInspector.TreeOutline(contentElement);
-            this._popoverCallStackTreeOutline.onselect = this._popoverCallStackTreeElementSelected.bind(this);
+            this._popoverCallStackTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._popoverCallStackTreeSelectionDidChange, this);
         } else
             this._popoverCallStackTreeOutline.removeChildren();
 
@@ -469,8 +469,12 @@ WebInspector.TimelineDataGrid = class TimelineDataGrid extends WebInspector.Data
         return content;
     }
 
-    _popoverCallStackTreeElementSelected(treeElement, selectedByUser)
+    _popoverCallStackTreeSelectionDidChange(event)
     {
+        let treeElement = event.data.selectedElement;
+        if (!treeElement)
+            return;
+
         this._popover.dismiss();
 
         console.assert(treeElement instanceof WebInspector.CallFrameTreeElement, "TreeElements in TimelineDataGrid popover should always be CallFrameTreeElements");
index 50c8649..e344a1e 100644 (file)
@@ -62,13 +62,13 @@ WebInspector.TimelineSidebarPanel = class TimelineSidebarPanel extends WebInspec
         this._recordingsTreeOutline = this.createContentTreeOutline(true, true);
         this._recordingsTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.HideDisclosureButtonsStyleClassName);
         this._recordingsTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName);
-        this._recordingsTreeOutline.onselect = this._recordingsTreeElementSelected.bind(this);
+        this._recordingsTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._recordingsTreeSelectionDidChange, this);
         this._timelinesContentContainerElement.appendChild(this._recordingsTreeOutline.element);
 
         // Maintain a tree outline with tree elements for each timeline of the selected recording.
         this._timelinesTreeOutline = this.createContentTreeOutline(true, true);
         this._timelinesTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.HideDisclosureButtonsStyleClassName);
-        this._timelinesTreeOutline.onselect = this._timelinesTreeElementSelected.bind(this);
+        this._timelinesTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._timelinesTreeSelectionDidChange, this);
         this._timelinesContentContainerElement.appendChild(this._timelinesTreeOutline.element);
 
         this._timelineTreeElementMap = new Map;
@@ -614,8 +614,12 @@ WebInspector.TimelineSidebarPanel = class TimelineSidebarPanel extends WebInspec
             this.showTimelineOverview();
     }
 
-    _recordingsTreeElementSelected(treeElement, selectedByUser)
+    _recordingsTreeSelectionDidChange(event)
     {
+        let treeElement = event.data.selectedElement;
+        if (!treeElement)
+            return;
+
         console.assert(treeElement.representedObject instanceof WebInspector.TimelineRecording);
 
         this._recordingSelected(treeElement.representedObject);
@@ -627,17 +631,22 @@ WebInspector.TimelineSidebarPanel = class TimelineSidebarPanel extends WebInspec
             this._refreshFrameSelectionChart();
     }
 
-    _timelinesTreeElementSelected(treeElement, selectedByUser)
+    _timelinesTreeSelectionDidChange(event)
     {
+        let treeElement = event.data.selectedElement;
+        if (!treeElement)
+            return;
+
         console.assert(this._timelineTreeElementMap.get(treeElement.representedObject) === treeElement, treeElement);
 
         // If not selected by user, then this selection merely synced the tree element with the content view's contents.
+        let selectedByUser = event.data.selectedByUser;
         if (!selectedByUser) {
             console.assert(this._displayedContentView.currentTimelineView.representedObject === treeElement.representedObject);
             return;
         }
 
-        var timeline = treeElement.representedObject;
+        let timeline = treeElement.representedObject;
         console.assert(timeline instanceof WebInspector.Timeline, timeline);
         console.assert(this._displayedRecording.timelines.get(timeline.type) === timeline, timeline);
 
index f556622..205bd47 100644 (file)
@@ -39,8 +39,7 @@ WebInspector.TimelineView = class TimelineView extends WebInspector.ContentView
         this._timelineSidebarPanel = extraArguments.timelineSidebarPanel;
 
         this._contentTreeOutline = this._timelineSidebarPanel.createContentTreeOutline();
-        this._contentTreeOutline.onselect = this.treeElementSelected.bind(this);
-        this._contentTreeOutline.ondeselect = this.treeElementDeselected.bind(this);
+        this._contentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
         this._contentTreeOutline.__canShowContentViewForTreeElement = this.canShowContentViewForTreeElement.bind(this);
 
         this.element.classList.add("timeline-view");
@@ -229,8 +228,6 @@ WebInspector.TimelineView = class TimelineView extends WebInspector.ContentView
     {
         // Implemented by sub-classes if needed.
 
-        this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
-
         if (!this._timelineSidebarPanel.canShowDifferentContentView())
             return;
 
@@ -239,4 +236,15 @@ WebInspector.TimelineView = class TimelineView extends WebInspector.ContentView
 
         this.showContentViewForTreeElement(treeElement);
     }
+
+    // Private
+
+    _treeSelectionDidChange(event)
+    {
+        if (event.data.deselectedElement)
+            this.treeElementDeselected(event.data.deselectedElement);
+
+        if (event.data.selectedElement)
+            this.treeElementSelected(event.data.selectedElement, event.data.selectedByUser);
+    }
 };
index 79c7b1e..b158e15 100644 (file)
@@ -89,8 +89,8 @@ WebInspector.TreeOutline = class TreeOutline extends WebInspector.Object
         if (this._childrenListNode)
             child._attach();
 
-        if (this.treeOutline.onadd)
-            this.treeOutline.onadd(child);
+        if (this.treeOutline)
+            this.treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementAdded, {element: child});
 
         if (isFirstChild && this.expanded)
             this.expand();
@@ -139,8 +139,8 @@ WebInspector.TreeOutline = class TreeOutline extends WebInspector.Object
         if (this._childrenListNode)
             child._attach();
 
-        if (this.treeOutline.onadd)
-            this.treeOutline.onadd(child);
+        if (this.treeOutline)
+            this.treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementAdded, {element: child});
 
         if (isFirstChild && this.expanded)
             this.expand();
@@ -152,10 +152,10 @@ WebInspector.TreeOutline = class TreeOutline extends WebInspector.Object
         if (childIndex < 0 || childIndex >= this.children.length)
             return;
 
-        var child = this.children[childIndex];
+        let child = this.children[childIndex];
         this.children.splice(childIndex, 1);
 
-        var parent = child.parent;
+        let parent = child.parent;
         if (child.deselect(suppressOnDeselect)) {
             if (child.previousSibling && !suppressSelectSibling)
                 child.previousSibling.select(true, false);
@@ -170,9 +170,10 @@ WebInspector.TreeOutline = class TreeOutline extends WebInspector.Object
         if (child.nextSibling)
             child.nextSibling.previousSibling = child.previousSibling;
 
-        if (child.treeOutline) {
-            child.treeOutline._forgetTreeElement(child);
-            child.treeOutline._forgetChildrenRecursive(child);
+        let treeOutline = child.treeOutline;
+        if (treeOutline) {
+            treeOutline._forgetTreeElement(child);
+            treeOutline._forgetChildrenRecursive(child);
         }
 
         child._detach();
@@ -181,8 +182,8 @@ WebInspector.TreeOutline = class TreeOutline extends WebInspector.Object
         child.nextSibling = null;
         child.previousSibling = null;
 
-        if (this.treeOutline && this.treeOutline.onremove)
-            this.treeOutline.onremove(child);
+        if (treeOutline)
+            treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementRemoved, {element: child});
     }
 
     removeChild(child, suppressOnDeselect, suppressSelectSibling)
@@ -207,15 +208,13 @@ WebInspector.TreeOutline = class TreeOutline extends WebInspector.Object
 
     removeChildren(suppressOnDeselect)
     {
-        var treeOutline = this.treeOutline;
-
-        for (var i = 0; i < this.children.length; ++i) {
-            var child = this.children[i];
+        for (let child of this.children) {
             child.deselect(suppressOnDeselect);
 
-            if (child.treeOutline) {
-                child.treeOutline._forgetTreeElement(child);
-                child.treeOutline._forgetChildrenRecursive(child);
+            let treeOutline = child.treeOutline;
+            if (treeOutline) {
+                treeOutline._forgetTreeElement(child);
+                treeOutline._forgetChildrenRecursive(child);
             }
 
             child._detach();
@@ -224,8 +223,8 @@ WebInspector.TreeOutline = class TreeOutline extends WebInspector.Object
             child.nextSibling = null;
             child.previousSibling = null;
 
-            if (treeOutline && treeOutline.onremove)
-                treeOutline.onremove(child);
+            if (treeOutline)
+                treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementRemoved, {element: child});
         }
 
         this.children = [];
@@ -233,23 +232,21 @@ WebInspector.TreeOutline = class TreeOutline extends WebInspector.Object
 
     removeChildrenRecursive(suppressOnDeselect)
     {
-        var childrenToRemove = this.children;
-
-        var treeOutline = this.treeOutline;
-
-        var child = this.children[0];
+        let childrenToRemove = this.children;
+        let child = this.children[0];
         while (child) {
             if (child.children.length)
                 childrenToRemove = childrenToRemove.concat(child.children);
             child = child.traverseNextTreeElement(false, this, true);
         }
 
-        for (var i = 0; i < childrenToRemove.length; ++i) {
+        for (let child of childrenToRemove) {
             child = childrenToRemove[i];
             child.deselect(suppressOnDeselect);
 
-            if (child.treeOutline)
-                child.treeOutline._forgetTreeElement(child);
+            let treeOutline = child.treeOutline;
+            if (treeOutline)
+                treeOutline._forgetTreeElement(child);
 
             child._detach();
             child.children = [];
@@ -258,8 +255,8 @@ WebInspector.TreeOutline = class TreeOutline extends WebInspector.Object
             child.nextSibling = null;
             child.previousSibling = null;
 
-            if (treeOutline && treeOutline.onremove)
-                treeOutline.onremove(child);
+            if (treeOutline)
+                treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementRemoved, {element: child});
         }
 
         this.children = [];
@@ -371,8 +368,7 @@ WebInspector.TreeOutline = class TreeOutline extends WebInspector.Object
         if (treeElement.treeOutline !== this)
             return;
 
-        if (this.onchange)
-            this.onchange(treeElement);
+        this.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementDidChange, {element: treeElement});
     }
 
     treeElementFromNode(node)
@@ -519,6 +515,15 @@ WebInspector.TreeOutline = class TreeOutline extends WebInspector.Object
     }
 };
 
+WebInspector.TreeOutline.Event = {
+    ElementAdded: Symbol("element-added"),
+    ElementDidChange: Symbol("element-did-change"),
+    ElementRemoved: Symbol("element-removed"),
+    ElementDisclosureDidChanged: Symbol("element-disclosure-did-change"),
+    ElementVisibilityDidChange: Symbol("element-visbility-did-change"),
+    SelectionDidChange: Symbol("selection-did-change")
+};
+
 WebInspector.TreeOutline._knownTreeElementNextIdentifier = 1;
 
 WebInspector.TreeElement = class TreeElement extends WebInspector.Object
@@ -581,11 +586,6 @@ WebInspector.TreeElement = class TreeElement extends WebInspector.Object
         return this._listItemNode;
     }
 
-    get childrenListElement()
-    {
-        return this._childrenListNode;
-    }
-
     get title()
     {
         return this._title;
@@ -671,8 +671,8 @@ WebInspector.TreeElement = class TreeElement extends WebInspector.Object
                 this._childrenListNode.classList.remove("hidden");
         }
 
-        if (this.treeOutline && this.treeOutline.onhidden)
-            this.treeOutline.onhidden(this, x);
+        if (this.treeOutline)
+            this.treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementVisibilityDidChange, {element: this});
     }
 
     get shouldRefreshChildren()
@@ -842,8 +842,8 @@ WebInspector.TreeElement = class TreeElement extends WebInspector.Object
         if (this.oncollapse)
             this.oncollapse(this);
 
-        if (this.treeOutline && this.treeOutline.oncollapse)
-            this.treeOutline.oncollapse(this);
+        if (this.treeOutline)
+            this.treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementDisclosureDidChanged, {element: this});
     }
 
     collapseRecursively()
@@ -861,9 +861,9 @@ WebInspector.TreeElement = class TreeElement extends WebInspector.Object
         if (this.expanded && !this._shouldRefreshChildren && this._childrenListNode)
             return;
 
-        // Set this before onpopulate. Since onpopulate can add elements and call onadd, this makes
-        // sure the expanded flag is true before calling those functions. This prevents the possibility
-        // of an infinite loop if onpopulate or onadd were to call expand.
+        // Set this before onpopulate. Since onpopulate can add elements and dispatch an ElementAdded event,
+        // this makes sure the expanded flag is true before calling those functions. This prevents the
+        // possibility of an infinite loop if onpopulate or an event handler were to call expand.
 
         this.expanded = true;
         if (this.treeOutline)
@@ -904,8 +904,8 @@ WebInspector.TreeElement = class TreeElement extends WebInspector.Object
         if (this.onexpand)
             this.onexpand(this);
 
-        if (this.treeOutline && this.treeOutline.onexpand)
-            this.treeOutline.onexpand(this);
+        if (this.treeOutline)
+            this.treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementDisclosureDidChanged, {element: this});
     }
 
     expandRecursively(maxDepth)
@@ -990,12 +990,19 @@ WebInspector.TreeElement = class TreeElement extends WebInspector.Object
             this.treeOutline._childrenListNode.focus();
 
         // Focusing on another node may detach "this" from tree.
-        var treeOutline = this.treeOutline;
+        let treeOutline = this.treeOutline;
         if (!treeOutline)
             return;
 
         treeOutline.processingSelectionChange = true;
 
+        // Prevent dispatching a SelectionDidChange event for the deselected element if
+        // it will be dispatched for the selected element. The event data includes both
+        // the selected and deselected elements, so one event is.
+        if (!suppressOnSelect)
+            suppressOnDeselect = true;
+
+        let deselectedElement = treeOutline.selectedTreeElement;
         if (!this.selected) {
             if (treeOutline.selectedTreeElement)
                 treeOutline.selectedTreeElement.deselect(suppressOnDeselect);
@@ -1007,11 +1014,12 @@ WebInspector.TreeElement = class TreeElement extends WebInspector.Object
                 this._listItemNode.classList.add("selected");
         }
 
-        if (this.onselect && !suppressOnSelect)
-            this.onselect(this, selectedByUser);
+        if (!suppressOnSelect) {
+            if (this.onselect)
+                this.onselect(this, selectedByUser);
 
-        if (treeOutline.onselect && !suppressOnSelect)
-            treeOutline.onselect(this, selectedByUser);
+            treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.SelectionDidChange, {selectedElement: this, deselectedElement, selectedByUser});
+        }
 
         treeOutline.processingSelectionChange = false;
     }
@@ -1033,11 +1041,12 @@ WebInspector.TreeElement = class TreeElement extends WebInspector.Object
         if (this._listItemNode)
             this._listItemNode.classList.remove("selected");
 
-        if (this.ondeselect && !suppressOnDeselect)
-            this.ondeselect(this);
+        if (!suppressOnDeselect) {
+            if (this.ondeselect)
+                this.ondeselect(this);
 
-        if (this.treeOutline.ondeselect && !suppressOnDeselect)
-            this.treeOutline.ondeselect(this);
+            this.treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.SelectionDidChange, {deselectedElement: this});
+        }
 
         return true;
     }
index 1dd62b3..c8ccab6 100644 (file)
@@ -49,49 +49,11 @@ WebInspector.TreeOutlineDataGridSynchronizer = class TreeOutlineDataGridSynchron
         this._treeOutline.element.addEventListener("focus", this._treeOutlineGainedFocus.bind(this));
         this._treeOutline.element.addEventListener("blur", this._treeOutlineLostFocus.bind(this));
 
-        // FIXME: This is a hack. TreeOutline should just dispatch events via WebInspector.Object.
-        var existingOnAdd = treeOutline.onadd;
-        var existingOnRemove = treeOutline.onremove;
-        var existingOnExpand = treeOutline.onexpand;
-        var existingOnCollapse = treeOutline.oncollapse;
-        var existingOnHidden = treeOutline.onhidden;
-        var existingOnSelect = treeOutline.onselect;
-
-        treeOutline.onadd = function(element) {
-            this._treeElementAdded(element);
-            if (existingOnAdd)
-                existingOnAdd.call(treeOutline, element);
-        }.bind(this);
-
-        treeOutline.onremove = function(element) {
-            this._treeElementRemoved(element);
-            if (existingOnRemove)
-                existingOnRemove.call(treeOutline, element);
-        }.bind(this);
-
-        treeOutline.onexpand = function(element) {
-            this._treeElementExpanded(element);
-            if (existingOnExpand)
-                existingOnExpand.call(treeOutline, element);
-        }.bind(this);
-
-        treeOutline.oncollapse = function(element) {
-            this._treeElementCollapsed(element);
-            if (existingOnCollapse)
-                existingOnCollapse.call(treeOutline, element);
-        }.bind(this);
-
-        treeOutline.onhidden = function(element, hidden) {
-            this._treeElementHiddenChanged(element, hidden);
-            if (existingOnHidden)
-                existingOnHidden.call(treeOutline, element, hidden);
-        }.bind(this);
-
-        treeOutline.onselect = function(element, selectedByUser) {
-            this._treeElementSelected(element, selectedByUser);
-            if (existingOnSelect)
-                existingOnSelect.call(treeOutline, element, selectedByUser);
-        }.bind(this);
+        treeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementAdded, this._treeElementAdded, this);
+        treeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementRemoved, this._treeElementRemoved, this);
+        treeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementDisclosureDidChanged, this._treeElementDisclosureDidChange, this);
+        treeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementVisibilityDidChange, this._treeElementVisibilityDidChange, this);
+        treeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
     }
 
     // Public
@@ -243,27 +205,36 @@ WebInspector.TreeOutlineDataGridSynchronizer = class TreeOutlineDataGridSynchron
         this._dataGrid.element.classList.remove("force-focus");
     }
 
-    _treeElementSelected(treeElement, selectedByUser)
+    _treeSelectionDidChange(event)
     {
         if (!this._enabled)
             return;
 
-        var dataGridNode = treeElement.__dataGridNode;
+        let treeElement = event.data.selectedElement || event.data.deselectedElement;
+        console.assert(treeElement);
+        if (!treeElement)
+            return;
+
+        let dataGridNode = treeElement.__dataGridNode;
         console.assert(dataGridNode);
 
-        dataGridNode.select(true);
+        if (event.data.selectedElement)
+            dataGridNode.select();
+        else
+            dataGridNode.deselect();
     }
 
-    _treeElementAdded(treeElement)
+    _treeElementAdded(event)
     {
         if (!this._enabled)
             return;
 
-        var dataGridNode = this.dataGridNodeForTreeElement(treeElement);
+        let treeElement = event.data.element;
+        let dataGridNode = this.dataGridNodeForTreeElement(treeElement);
         console.assert(dataGridNode);
 
         var parentDataGridNode = treeElement.parent.__dataGridNode;
-        console.assert(dataGridNode);
+        console.assert(parentDataGridNode);
 
         var childIndex = treeElement.parent.children.indexOf(treeElement);
         console.assert(childIndex !== -1);
@@ -271,50 +242,43 @@ WebInspector.TreeOutlineDataGridSynchronizer = class TreeOutlineDataGridSynchron
         parentDataGridNode.insertChild(dataGridNode, childIndex);
     }
 
-    _treeElementRemoved(treeElement)
+    _treeElementRemoved(event)
     {
         if (!this._enabled)
             return;
 
-        var dataGridNode = treeElement.__dataGridNode;
+        let treeElement = event.data.element;
+        let dataGridNode = treeElement.__dataGridNode;
         console.assert(dataGridNode);
 
         if (dataGridNode.parent)
             dataGridNode.parent.removeChild(dataGridNode);
     }
 
-    _treeElementExpanded(treeElement)
+    _treeElementDisclosureDidChange(event)
     {
         if (!this._enabled)
             return;
 
-        var dataGridNode = treeElement.__dataGridNode;
+        let treeElement = event.data.element;
+        let dataGridNode = treeElement.__dataGridNode;
         console.assert(dataGridNode);
 
-        if (!dataGridNode.expanded)
+        if (treeElement.expanded)
             dataGridNode.expand();
-    }
-
-    _treeElementCollapsed(treeElement)
-    {
-        if (!this._enabled)
-            return;
-
-        var dataGridNode = treeElement.__dataGridNode;
-        console.assert(dataGridNode);
-
-        if (dataGridNode.expanded)
+        else
             dataGridNode.collapse();
     }
 
-    _treeElementHiddenChanged(treeElement, hidden)
+    _treeElementVisibilityDidChange(event)
     {
         if (!this._enabled)
             return;
 
-        var dataGridNode = treeElement.__dataGridNode;
+        let treeElement = event.data.element;
+        let dataGridNode = treeElement.__dataGridNode;
         console.assert(dataGridNode);
 
-        dataGridNode.element.classList.toggle("hidden", hidden);
+        dataGridNode.element.classList.toggle("hidden", treeElement.hidden);
     }
 };
index 0684964..cdaec52 100644 (file)
@@ -38,7 +38,7 @@ WebInspector.VisualStyleCommaSeparatedKeywordEditor = class VisualStyleCommaSepa
         this.contentElement.appendChild(listElement);
 
         this._commaSeparatedKeywords = new WebInspector.TreeOutline(listElement);
-        this._commaSeparatedKeywords.onselect = this._treeElementSelected.bind(this);
+        this._commaSeparatedKeywords.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
 
         let controlContainer = document.createElement("div");
         controlContainer.classList.add("visual-style-comma-separated-keyword-controls");
@@ -185,10 +185,14 @@ WebInspector.VisualStyleCommaSeparatedKeywordEditor = class VisualStyleCommaSepa
             this._removeSelectedCommaSeparatedKeyword();
     }
 
-    _treeElementSelected(item, selectedByUser)
+    _treeSelectionDidChange(event)
     {
+        let treeElement = event.data.selectedElement;
+        if (!treeElement)
+            return;
+
         this._removeEmptyCommaSeparatedKeywords();
-        this.dispatchEventToListeners(WebInspector.VisualStyleCommaSeparatedKeywordEditor.Event.TreeItemSelected, {text: item.mainTitle});
+        this.dispatchEventToListeners(WebInspector.VisualStyleCommaSeparatedKeywordEditor.Event.TreeItemSelected, {text: treeElement.mainTitle});
     }
 
     _treeElementIsEmpty(item)