Title: [211061] trunk/Source/WebInspectorUI
Revision
211061
Author
[email protected]
Date
2017-01-23 14:24:01 -0800 (Mon, 23 Jan 2017)

Log Message

Web Inspector: tree elements with depth > 1 should have context menu "expand all"/"collapse all" commands
https://bugs.webkit.org/show_bug.cgi?id=135590

Patch by Devin Rousso <[email protected]> on 2017-01-23
Reviewed by Timothy Hatcher.

Rework the context menu event handlers for all TreeOutline and TreeElement instances such
that the TreeOutline handles the event listener and creates the context menu object and the
TreeElement populates the list with items.  This is necessary due to the way in which
children are laid out, as there is padding on either side of the element that would not
trigger a context menu event.

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Views/BreakpointTreeElement.js:
(WebInspector.BreakpointTreeElement.prototype.ondetach):
(WebInspector.BreakpointTreeElement.prototype.populateContextMenu):
(WebInspector.BreakpointTreeElement.prototype.oncontextmenu): Deleted.
* UserInterface/Views/ContextMenuUtilities.js:
(WebInspector.appendContextMenuItemsForSourceCode):
* UserInterface/Views/DOMTreeElement.js:
(WebInspector.DOMTreeElement.prototype._populateNodeContextMenu):
* UserInterface/Views/DOMTreeOutline.js:
(WebInspector.DOMTreeOutline):
(WebInspector.DOMTreeOutline.prototype.populateContextMenu):
(WebInspector.DOMTreeOutline.prototype._onmousedown):
(WebInspector.DOMTreeOutline.prototype._onmousemove):
(WebInspector.DOMTreeOutline.prototype._ondragstart):
(WebInspector.DOMTreeOutline.prototype._ondragover):
(WebInspector.DOMTreeOutline.prototype._ondrop):
(WebInspector.DOMTreeOutline.prototype._treeElementFromEvent): Deleted.
(WebInspector.DOMTreeOutline.prototype._contextMenuEventFired): Deleted.
* UserInterface/Views/DebuggerSidebarPanel.js:
(WebInspector.DebuggerSidebarPanel):
(WebInspector.DebuggerSidebarPanel.prototype._breakpointTreeOutlineContextMenuTreeElement):
* UserInterface/Views/FrameTreeElement.js:
(WebInspector.FrameTreeElement.prototype.onattach):
* UserInterface/Views/GeneralTreeElement.js:
(WebInspector.GeneralTreeElement.prototype.onattach):
(WebInspector.GeneralTreeElement.prototype.ondetach): Deleted.
* UserInterface/Views/ObjectTreeBaseTreeElement.js:
(WebInspector.ObjectTreeBaseTreeElement.prototype.populateContextMenu):
(WebInspector.ObjectTreeBaseTreeElement.prototype._logSymbolProperty):
(WebInspector.ObjectTreeBaseTreeElement.prototype._logValue):
(WebInspector.ObjectTreeBaseTreeElement.prototype.oncontextmenu): Deleted.
(WebInspector.ObjectTreeBaseTreeElement.prototype._contextMenuHandler): Deleted.
* UserInterface/Views/ResourceTreeElement.js:
(WebInspector.ResourceTreeElement.prototype.populateContextMenu):
(WebInspector.ResourceTreeElement.prototype.onattach): Deleted.
(WebInspector.ResourceTreeElement.prototype._handleContextMenuEvent): Deleted.
* UserInterface/Views/ThreadTreeElement.js:
(WebInspector.ThreadTreeElement.prototype.populateContextMenu):
(WebInspector.ThreadTreeElement.prototype.oncontextmenu): Deleted.
* UserInterface/Views/TreeElement.js:
(WebInspector.TreeElement.prototype.populateContextMenu):
(WebInspector.TreeElement):
* UserInterface/Views/TreeOutline.js:
(WebInspector.TreeOutline):
(WebInspector.TreeOutline.prototype.treeElementFromEvent):
(WebInspector.TreeOutline.prototype.populateContextMenu):
(WebInspector.TreeOutline._generateStyleRulesIfNeeded):
* UserInterface/Views/VisualStyleSelectorTreeItem.js:
(WebInspector.VisualStyleSelectorTreeItem.prototype.onattach):
(WebInspector.VisualStyleSelectorTreeItem.prototype.populateContextMenu):
(WebInspector.VisualStyleSelectorTreeItem.prototype._highlightNodesWithSelector):
(WebInspector.VisualStyleSelectorTreeItem.prototype._hideDOMNodeHighlight):
(WebInspector.VisualStyleSelectorTreeItem.prototype._handleContextMenuEvent): Deleted.
* UserInterface/Views/WorkerTreeElement.js:
(WebInspector.WorkerTreeElement.prototype.populateContextMenu):
(WebInspector.WorkerTreeElement.prototype.onattach):
(WebInspector.WorkerTreeElement.prototype._handleContextMenuEvent): Deleted.

* UserInterface/Views/DataGrid.js:
(WebInspector.DataGrid.prototype._contextMenuInDataTable):
Add "Expand All"/"Collapse All" context menu items.

Modified Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (211060 => 211061)


--- trunk/Source/WebInspectorUI/ChangeLog	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/ChangeLog	2017-01-23 22:24:01 UTC (rev 211061)
@@ -1,5 +1,81 @@
 2017-01-23  Devin Rousso  <[email protected]>
 
+        Web Inspector: tree elements with depth > 1 should have context menu "expand all"/"collapse all" commands
+        https://bugs.webkit.org/show_bug.cgi?id=135590
+
+        Reviewed by Timothy Hatcher.
+
+        Rework the context menu event handlers for all TreeOutline and TreeElement instances such
+        that the TreeOutline handles the event listener and creates the context menu object and the
+        TreeElement populates the list with items.  This is necessary due to the way in which
+        children are laid out, as there is padding on either side of the element that would not
+        trigger a context menu event.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Views/BreakpointTreeElement.js:
+        (WebInspector.BreakpointTreeElement.prototype.ondetach):
+        (WebInspector.BreakpointTreeElement.prototype.populateContextMenu):
+        (WebInspector.BreakpointTreeElement.prototype.oncontextmenu): Deleted.
+        * UserInterface/Views/ContextMenuUtilities.js:
+        (WebInspector.appendContextMenuItemsForSourceCode):
+        * UserInterface/Views/DOMTreeElement.js:
+        (WebInspector.DOMTreeElement.prototype._populateNodeContextMenu):
+        * UserInterface/Views/DOMTreeOutline.js:
+        (WebInspector.DOMTreeOutline):
+        (WebInspector.DOMTreeOutline.prototype.populateContextMenu):
+        (WebInspector.DOMTreeOutline.prototype._onmousedown):
+        (WebInspector.DOMTreeOutline.prototype._onmousemove):
+        (WebInspector.DOMTreeOutline.prototype._ondragstart):
+        (WebInspector.DOMTreeOutline.prototype._ondragover):
+        (WebInspector.DOMTreeOutline.prototype._ondrop):
+        (WebInspector.DOMTreeOutline.prototype._treeElementFromEvent): Deleted.
+        (WebInspector.DOMTreeOutline.prototype._contextMenuEventFired): Deleted.
+        * UserInterface/Views/DebuggerSidebarPanel.js:
+        (WebInspector.DebuggerSidebarPanel):
+        (WebInspector.DebuggerSidebarPanel.prototype._breakpointTreeOutlineContextMenuTreeElement):
+        * UserInterface/Views/FrameTreeElement.js:
+        (WebInspector.FrameTreeElement.prototype.onattach):
+        * UserInterface/Views/GeneralTreeElement.js:
+        (WebInspector.GeneralTreeElement.prototype.onattach):
+        (WebInspector.GeneralTreeElement.prototype.ondetach): Deleted.
+        * UserInterface/Views/ObjectTreeBaseTreeElement.js:
+        (WebInspector.ObjectTreeBaseTreeElement.prototype.populateContextMenu):
+        (WebInspector.ObjectTreeBaseTreeElement.prototype._logSymbolProperty):
+        (WebInspector.ObjectTreeBaseTreeElement.prototype._logValue):
+        (WebInspector.ObjectTreeBaseTreeElement.prototype.oncontextmenu): Deleted.
+        (WebInspector.ObjectTreeBaseTreeElement.prototype._contextMenuHandler): Deleted.
+        * UserInterface/Views/ResourceTreeElement.js:
+        (WebInspector.ResourceTreeElement.prototype.populateContextMenu):
+        (WebInspector.ResourceTreeElement.prototype.onattach): Deleted.
+        (WebInspector.ResourceTreeElement.prototype._handleContextMenuEvent): Deleted.
+        * UserInterface/Views/ThreadTreeElement.js:
+        (WebInspector.ThreadTreeElement.prototype.populateContextMenu):
+        (WebInspector.ThreadTreeElement.prototype.oncontextmenu): Deleted.
+        * UserInterface/Views/TreeElement.js:
+        (WebInspector.TreeElement.prototype.populateContextMenu):
+        (WebInspector.TreeElement):
+        * UserInterface/Views/TreeOutline.js:
+        (WebInspector.TreeOutline):
+        (WebInspector.TreeOutline.prototype.treeElementFromEvent):
+        (WebInspector.TreeOutline.prototype.populateContextMenu):
+        (WebInspector.TreeOutline._generateStyleRulesIfNeeded):
+        * UserInterface/Views/VisualStyleSelectorTreeItem.js:
+        (WebInspector.VisualStyleSelectorTreeItem.prototype.onattach):
+        (WebInspector.VisualStyleSelectorTreeItem.prototype.populateContextMenu):
+        (WebInspector.VisualStyleSelectorTreeItem.prototype._highlightNodesWithSelector):
+        (WebInspector.VisualStyleSelectorTreeItem.prototype._hideDOMNodeHighlight):
+        (WebInspector.VisualStyleSelectorTreeItem.prototype._handleContextMenuEvent): Deleted.
+        * UserInterface/Views/WorkerTreeElement.js:
+        (WebInspector.WorkerTreeElement.prototype.populateContextMenu):
+        (WebInspector.WorkerTreeElement.prototype.onattach):
+        (WebInspector.WorkerTreeElement.prototype._handleContextMenuEvent): Deleted.
+
+        * UserInterface/Views/DataGrid.js:
+        (WebInspector.DataGrid.prototype._contextMenuInDataTable):
+        Add "Expand All"/"Collapse All" context menu items.
+
+2017-01-23  Devin Rousso  <[email protected]>
+
         Web Inspector: color picker should feature an editable CSS value
         https://bugs.webkit.org/show_bug.cgi?id=124356
 

Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -178,6 +178,7 @@
 localizedStrings["Closure Variables"] = "Closure Variables";
 localizedStrings["Closure Variables (%s)"] = "Closure Variables (%s)";
 localizedStrings["Code"] = "Code";
+localizedStrings["Collapse All"] = "Collapse All";
 localizedStrings["Collapse columns"] = "Collapse columns";
 localizedStrings["Color"] = "Color";
 localizedStrings["Comment"] = "Comment";
@@ -334,6 +335,7 @@
 localizedStrings["Event Listeners"] = "Event Listeners";
 localizedStrings["Events"] = "Events";
 localizedStrings["Exception with thrown value: %s"] = "Exception with thrown value: %s";
+localizedStrings["Expand All"] = "Expand All";
 localizedStrings["Expand columns"] = "Expand columns";
 localizedStrings["Expanded"] = "Expanded";
 localizedStrings["Expires"] = "Expires";

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -101,12 +101,6 @@
         return true;
     }
 
-    oncontextmenu(event)
-    {
-        let contextMenu = WebInspector.ContextMenu.createFromEvent(event);
-        WebInspector.breakpointPopoverController.appendContextMenuItems(contextMenu, this._breakpoint, this._statusImageElement);
-    }
-
     onattach()
     {
         super.onattach();
@@ -120,8 +114,6 @@
 
     ondetach()
     {
-        super.ondetach();
-
         this._listenerSet.uninstall();
 
         if (this._probeSet)
@@ -128,6 +120,13 @@
             this._removeProbeSet(this._probeSet);
     }
 
+    populateContextMenu(contextMenu, event)
+    {
+        WebInspector.breakpointPopoverController.appendContextMenuItems(contextMenu, this._breakpoint, this._statusImageElement);
+
+        super.populateContextMenu(contextMenu, event);
+    }
+
     removeStatusImage()
     {
         this._statusImageElement.remove();

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -33,6 +33,8 @@
     if (!(sourceCode instanceof WebInspector.SourceCode))
         return;
 
+    contextMenu.appendSeparator();
+
     if (sourceCode.url) {
         contextMenu.appendItem(WebInspector.UIString("Open in New Tab"), () => {
             const frame = null;

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -55,8 +55,6 @@
         this._editing = false;
         this._visible = false;
 
-        this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this));
-
         this._hideElementKeyboardShortcut = new WebInspector.KeyboardShortcut(null, "H", this._hideElement.bind(this), this.element);
         this._hideElementKeyboardShortcut.implicitlyPreventsDefault = false;
 
@@ -245,25 +243,21 @@
         let commentNode = event.target.enclosingNodeOrSelfWithClass("html-comment");
         let pseudoElement = event.target.enclosingNodeOrSelfWithClass("html-pseudo-element");
 
-        let populated = false;
         if (tag && treeElement._populateTagContextMenu) {
-            if (populated)
-                contextMenu.appendSeparator();
+            contextMenu.appendSeparator();
+
             treeElement._populateTagContextMenu(contextMenu, event);
-            populated = true;
         } else if (textNode && treeElement._populateTextContextMenu) {
-            if (populated)
-                contextMenu.appendSeparator();
+            contextMenu.appendSeparator();
+
             treeElement._populateTextContextMenu(contextMenu, textNode);
-            populated = true;
         } else if ((commentNode || pseudoElement) && treeElement._populateNodeContextMenu) {
-            if (populated)
-                contextMenu.appendSeparator();
+            contextMenu.appendSeparator();
+
             treeElement._populateNodeContextMenu(contextMenu);
-            populated = true;
         }
 
-        return populated;
+        super.populateContextMenu(contextMenu, event, treeElement);
     }
 
     adjustCollapsedRange()
@@ -291,35 +285,9 @@
         treeElement.revealAndSelect(omitFocus);
     }
 
-    _treeElementFromEvent(event)
-    {
-        var scrollContainer = this.element.parentElement;
-
-        // We choose this X coordinate based on the knowledge that our list
-        // items extend at least to the right edge of the outer <ol> container.
-        // In the no-word-wrap mode the outer <ol> may be wider than the tree container
-        // (and partially hidden), in which case we are left to use only its right boundary.
-        var x = scrollContainer.totalOffsetLeft + scrollContainer.offsetWidth - 36;
-
-        var y = event.pageY;
-
-        // Our list items have 1-pixel cracks between them vertically. We avoid
-        // the cracks by checking slightly above and slightly below the mouse
-        // and seeing if we hit the same element each time.
-        var elementUnderMouse = this.treeElementFromPoint(x, y);
-        var elementAboveMouse = this.treeElementFromPoint(x, y - 2);
-        var element;
-        if (elementUnderMouse === elementAboveMouse)
-            element = elementUnderMouse;
-        else
-            element = this.treeElementFromPoint(x, y + 2);
-
-        return element;
-    }
-
     _onmousedown(event)
     {
-        var element = this._treeElementFromEvent(event);
+        let element = this.treeElementFromEvent(event);
         if (!element || element.isEventWithinDisclosureTriangle(event)) {
             event.preventDefault();
             return;
@@ -330,7 +298,7 @@
 
     _onmousemove(event)
     {
-        var element = this._treeElementFromEvent(event);
+        let element = this.treeElementFromEvent(event);
         if (element && this._previousHoveredElement === element)
             return;
 
@@ -367,7 +335,7 @@
 
     _ondragstart(event)
     {
-        var treeElement = this._treeElementFromEvent(event);
+        let treeElement = this.treeElementFromEvent(event);
         if (!treeElement)
             return false;
 
@@ -397,7 +365,7 @@
         if (!this._nodeBeingDragged)
             return false;
 
-        let treeElement = this._treeElementFromEvent(event);
+        let treeElement = this.treeElementFromEvent(event);
         if (!this._isValidDragSourceOrTarget(treeElement))
             return false;
 
@@ -454,7 +422,7 @@
                 this.selectDOMNode(newNode, true);
         }
 
-        let treeElement = this._treeElementFromEvent(event);
+        let treeElement = this.treeElementFromEvent(event);
         if (this._nodeBeingDragged && treeElement) {
             let parentNode = null;
             let anchorNode = null;
@@ -496,16 +464,6 @@
         }
     }
 
-    _contextMenuEventFired(event)
-    {
-        let treeElement = this._treeElementFromEvent(event);
-        if (!treeElement)
-            return;
-
-        let contextMenu = WebInspector.ContextMenu.createFromEvent(event);
-        this.populateContextMenu(contextMenu, event, treeElement);
-    }
-
     _updateModifiedNodes()
     {
         if (this._elementsTreeUpdater)

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -1646,23 +1646,32 @@
         if (this.dataGrid._refreshCallback && (!gridNode || gridNode !== this.placeholderNode))
             contextMenu.appendItem(WebInspector.UIString("Refresh"), this._refreshCallback.bind(this));
 
-        if (gridNode && gridNode.selectable && gridNode.copyable && !gridNode.isEventWithinDisclosureTriangle(event)) {
-            contextMenu.appendItem(WebInspector.UIString("Copy Row"), this._copyRow.bind(this, event.target));
-            contextMenu.appendItem(WebInspector.UIString("Copy Table"), this._copyTable.bind(this));
+        if (gridNode) {
+            if (gridNode.selectable && gridNode.copyable && !gridNode.isEventWithinDisclosureTriangle(event)) {
+                contextMenu.appendItem(WebInspector.UIString("Copy Row"), this._copyRow.bind(this, event.target));
+                contextMenu.appendItem(WebInspector.UIString("Copy Table"), this._copyTable.bind(this));
 
-            if (this.dataGrid._editCallback) {
-                if (gridNode === this.placeholderNode)
-                    contextMenu.appendItem(WebInspector.UIString("Add New"), this._startEditing.bind(this, event.target));
-                else {
-                    let element = event.target.enclosingNodeOrSelfWithNodeName("td");
-                    let columnIdentifier = element.__columnIdentifier;
-                    let columnTitle = this.dataGrid.columns.get(columnIdentifier)["title"];
-                    contextMenu.appendItem(WebInspector.UIString("Edit ā€œ%sā€").format(columnTitle), this._startEditing.bind(this, event.target));
+                if (this.dataGrid._editCallback) {
+                    if (gridNode === this.placeholderNode)
+                        contextMenu.appendItem(WebInspector.UIString("Add New"), this._startEditing.bind(this, event.target));
+                    else {
+                        let element = event.target.enclosingNodeOrSelfWithNodeName("td");
+                        let columnIdentifier = element.__columnIdentifier;
+                        let columnTitle = this.dataGrid.columns.get(columnIdentifier)["title"];
+                        contextMenu.appendItem(WebInspector.UIString("Edit ā€œ%sā€").format(columnTitle), this._startEditing.bind(this, event.target));
+                    }
                 }
+
+                if (this.dataGrid._deleteCallback && gridNode !== this.placeholderNode)
+                    contextMenu.appendItem(WebInspector.UIString("Delete"), this._deleteCallback.bind(this, gridNode));
             }
 
-            if (this.dataGrid._deleteCallback && gridNode !== this.placeholderNode)
-                contextMenu.appendItem(WebInspector.UIString("Delete"), this._deleteCallback.bind(this, gridNode));
+            if (gridNode.children.some((child) => child.hasChildren) || (gridNode.hasChildren && !gridNode.children.length)) {
+                contextMenu.appendSeparator();
+
+                contextMenu.appendItem(WebInspector.UIString("Expand All"), gridNode.expandRecursively.bind(gridNode));
+                contextMenu.appendItem(WebInspector.UIString("Collapse All"), gridNode.collapseRecursively.bind(gridNode));
+            }
         }
     }
 

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -153,8 +153,12 @@
 
         this._breakpointsContentTreeOutline.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
         this._breakpointsContentTreeOutline._ondelete_ = this._breakpointTreeOutlineDeleteTreeElement.bind(this);
-        this._breakpointsContentTreeOutline._oncontextmenu_ = this._breakpointTreeOutlineContextMenuTreeElement.bind(this);
+        this._breakpointsContentTreeOutline.populateContextMenu = function(contextMenu, event, treeElement) {
+            this._breakpointTreeOutlineContextMenuTreeElement(contextMenu, event, treeElement);
 
+            WebInspector.TreeOutline.prototype.populateContextMenu(contextMenu, event, treeElement);
+        }.bind(this);
+
         this._breakpointsContentTreeOutline.appendChild(this._allExceptionsBreakpointTreeElement);
         this._breakpointsContentTreeOutline.appendChild(this._allUncaughtExceptionsBreakpointTreeElement);
 
@@ -747,9 +751,10 @@
         return true;
     }
 
-    _breakpointTreeOutlineContextMenuTreeElement(event, treeElement)
+    _breakpointTreeOutlineContextMenuTreeElement(contextMenu, event, treeElement)
     {
-        console.assert(treeElement instanceof WebInspector.ResourceTreeElement || treeElement instanceof WebInspector.ScriptTreeElement);
+        // This check is necessary since the context menu is created by the TreeOutline, meaning
+        // that any child could be the target of the context menu event.
         if (!(treeElement instanceof WebInspector.ResourceTreeElement) && !(treeElement instanceof WebInspector.ScriptTreeElement))
             return;
 
@@ -764,7 +769,6 @@
             this._toggleAllBreakpoints(breakpoints, shouldDisable);
         };
 
-        let contextMenu = WebInspector.ContextMenu.createFromEvent(event);
         if (shouldDisable)
             contextMenu.appendItem(WebInspector.UIString("Disable Breakpoints"), toggleAllResourceBreakpoints);
         else

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/FrameTreeElement.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/FrameTreeElement.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/FrameTreeElement.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -108,8 +108,6 @@
     {
         // Immediate superclasses are skipped, since Frames handle their own SourceMapResources.
         WebInspector.GeneralTreeElement.prototype.onattach.call(this);
-
-        this.element.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this));
     }
 
     // Overrides from FolderizedTreeElement (Protected).

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/GeneralTreeElement.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/GeneralTreeElement.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/GeneralTreeElement.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -208,26 +208,8 @@
         if (this._statusElement)
             this._listItemNode.appendChild(this._statusElement);
         this._listItemNode.appendChild(this._titlesElement);
-
-        if (this.oncontextmenu && typeof this._oncontextmenu_ === "function") {
-            this._boundContextMenuEventHandler = this.oncontextmenu.bind(this);
-            this._listItemNode.addEventListener("contextmenu", this._boundContextMenuEventHandler);
-        }
-
-        if (!this._boundContextMenuEventHandler && this.treeOutline.oncontextmenu && typeof this.treeOutline._oncontextmenu_ === "function") {
-            this._boundContextMenuEventHandler = (event) => { this.treeOutline.oncontextmenu(event, this); };
-            this._listItemNode.addEventListener("contextmenu", this._boundContextMenuEventHandler);
-        }
     }
 
-    ondetach()
-    {
-        if (this._boundContextMenuEventHandler) {
-            this._listItemNode.removeEventListener("contextmenu", this._boundContextMenuEventHandler);
-            this._boundContextMenuEventHandler = null;
-        }
-    }
-
     onreveal()
     {
         if (this._listItemNode)

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -55,11 +55,6 @@
 
     // Protected
 
-    oncontextmenu(event)
-    {
-        this._contextMenuHandler(event);
-    }
-
     resolvedValue()
     {
         console.assert(this._property);
@@ -151,43 +146,13 @@
         return setterElement;
     }
 
-    // Private
-
-    _logSymbolProperty()
+    populateContextMenu(contextMenu, event)
     {
-        var symbol = this._property.symbol;
-        if (!symbol)
-            return;
-
-        var text = WebInspector.UIString("Selected Symbol");
-        WebInspector.consoleLogViewController.appendImmediateExecutionWithResult(text, symbol, true);
-    }
-
-    _logValue(value)
-    {
-        var resolvedValue = value || this.resolvedValue();
-        if (!resolvedValue)
-            return;
-
-        var propertyPath = this.resolvedValuePropertyPath();
-        var isImpossible = propertyPath.isFullPathImpossible();
-        var text = isImpossible ? WebInspector.UIString("Selected Value") : propertyPath.displayPath(this.propertyPathType());
-
-        if (!isImpossible)
-            WebInspector.quickConsole.prompt.pushHistoryItem(text);
-
-        WebInspector.consoleLogViewController.appendImmediateExecutionWithResult(text, resolvedValue, isImpossible);
-    }
-
-    _contextMenuHandler(event)
-    {
         if (event.__addedObjectPreviewContextMenuItems)
             return;
         if (event.__addedObjectTreeContextMenuItems)
             return;
 
-        let contextMenu = WebInspector.ContextMenu.createFromEvent(event);
-
         event.__addedObjectTreeContextMenuItems = true;
 
         if (typeof this.treeOutline.objectTreeElementAddContextMenuItems === "function") {
@@ -215,8 +180,38 @@
         contextMenu.appendSeparator();
 
         this._appendMenusItemsForObject(contextMenu, resolvedValue);
+
+        super.populateContextMenu(contextMenu, event);
     }
 
+    // Private
+
+    _logSymbolProperty()
+    {
+        var symbol = this._property.symbol;
+        if (!symbol)
+            return;
+
+        var text = WebInspector.UIString("Selected Symbol");
+        WebInspector.consoleLogViewController.appendImmediateExecutionWithResult(text, symbol, true);
+    }
+
+    _logValue(value)
+    {
+        var resolvedValue = value || this.resolvedValue();
+        if (!resolvedValue)
+            return;
+
+        var propertyPath = this.resolvedValuePropertyPath();
+        var isImpossible = propertyPath.isFullPathImpossible();
+        var text = isImpossible ? WebInspector.UIString("Selected Value") : propertyPath.displayPath(this.propertyPathType());
+
+        if (!isImpossible)
+            WebInspector.quickConsole.prompt.pushHistoryItem(text);
+
+        WebInspector.consoleLogViewController.appendImmediateExecutionWithResult(text, resolvedValue, isImpossible);
+    }
+
     _appendMenusItemsForObject(contextMenu, resolvedValue)
     {
         if (resolvedValue.type === "function") {

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -89,13 +89,6 @@
         return {text: [urlComponents.lastPathComponent, urlComponents.path, this._resource.url]};
     }
 
-    onattach()
-    {
-        super.onattach();
-
-        this.element.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this));
-    }
-
     ondblclick()
     {
         InspectorFrontendHost.openInNewTab(this._resource.url);
@@ -163,11 +156,11 @@
             this.callFirstAncestorFunction("descendantResourceTreeElementMainTitleDidChange", [this, oldMainTitle]);
     }
 
-    _handleContextMenuEvent(event)
+    populateContextMenu(contextMenu, event)
     {
-        let contextMenu = WebInspector.ContextMenu.createFromEvent(event);
+        WebInspector.appendContextMenuItemsForSourceCode(contextMenu, this._resource);
 
-        WebInspector.appendContextMenuItemsForSourceCode(contextMenu, this._resource);
+        super.populateContextMenu(contextMenu, event);
     }
 
     // Private

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ThreadTreeElement.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ThreadTreeElement.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ThreadTreeElement.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -108,14 +108,15 @@
         this.expand();
     }
 
-    oncontextmenu(event)
+    populateContextMenu(contextMenu, event)
     {
         let targetData = WebInspector.debuggerManager.dataForTarget(this._target);
 
-        let contextMenu = WebInspector.ContextMenu.createFromEvent(event);
         contextMenu.appendItem(WebInspector.UIString("Resume Thread"), () => {
             WebInspector.debuggerManager.continueUntilNextRunLoop(this._target);
         }, !targetData.paused);
+
+        super.populateContextMenu(contextMenu, event);
     }
 
     // Private

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -609,4 +609,14 @@
         var left = this._listItemNode.totalOffsetLeft + computedLeftPadding;
         return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren;
     }
+
+    populateContextMenu(contextMenu, event)
+    {
+        if (this.children.some((child) => child.hasChildren) || (this.hasChildren && !this.children.length)) {
+            contextMenu.appendSeparator();
+
+            contextMenu.appendItem(WebInspector.UIString("Expand All"), this.expandRecursively.bind(this));
+            contextMenu.appendItem(WebInspector.UIString("Collapse All"), this.collapseRecursively.bind(this));
+        }
+    }
 };

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -34,6 +34,7 @@
 
         this.element = element || document.createElement("ol");
         this.element.classList.add(WebInspector.TreeOutline.ElementStyleClassName);
+        this.element.addEventListener("contextmenu", this._handleContextmenu.bind(this));
 
         this.children = [];
         this.selectedTreeElement = null;
@@ -599,6 +600,38 @@
         return false;
     }
 
+    // Protected
+
+    treeElementFromEvent(event)
+    {
+        let scrollContainer = this.element.parentElement;
+
+        // We choose this X coordinate based on the knowledge that our list
+        // items extend at least to the right edge of the outer <ol> container.
+        // In the no-word-wrap mode the outer <ol> may be wider than the tree container
+        // (and partially hidden), in which case we are left to use only its right boundary.
+        let x = scrollContainer.totalOffsetLeft + scrollContainer.offsetWidth - 36;
+        let y = event.pageY;
+
+        // Our list items have 1-pixel cracks between them vertically. We avoid
+        // the cracks by checking slightly above and slightly below the mouse
+        // and seeing if we hit the same element each time.
+        let elementUnderMouse = this.treeElementFromPoint(x, y);
+        let elementAboveMouse = this.treeElementFromPoint(x, y - 2);
+        let element = null;
+        if (elementUnderMouse === elementAboveMouse)
+            element = elementUnderMouse;
+        else
+            element = this.treeElementFromPoint(x, y + 2);
+
+        return element;
+    }
+
+    populateContextMenu(contextMenu, event, treeElement)
+    {
+        treeElement.populateContextMenu(contextMenu, event);
+    }
+
     // Private
 
     static _generateStyleRulesIfNeeded()
@@ -625,6 +658,16 @@
 
         document.head.appendChild(WebInspector.TreeOutline._styleElement);
     }
+
+    _handleContextmenu(event)
+    {
+        let treeElement = this.treeElementFromEvent(event);
+        if (!treeElement)
+            return;
+
+        let contextMenu = WebInspector.ContextMenu.createFromEvent(event);
+        this.populateContextMenu(contextMenu, event, treeElement);
+    }
 };
 
 WebInspector.TreeOutline._styleElement = null;

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleSelectorTreeItem.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleSelectorTreeItem.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleSelectorTreeItem.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -93,7 +93,6 @@
 
         this._listItemNode.addEventListener("mouseover", this._highlightNodesWithSelector.bind(this));
         this._listItemNode.addEventListener("mouseout", this._hideDOMNodeHighlight.bind(this));
-        this._listItemNode.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this));
 
         this._checkboxElement = document.createElement("input");
         this._checkboxElement.type = "checkbox";
@@ -122,27 +121,8 @@
         this._listItemNode.classList.remove("editable");
     }
 
-    // Private
-
-    _highlightNodesWithSelector()
+    populateContextMenu(contextMenu, event)
     {
-        if (!this.representedObject.ownerRule) {
-            WebInspector.domTreeManager.highlightDOMNode(this.representedObject.node.id);
-            return;
-        }
-
-        WebInspector.domTreeManager.highlightSelector(this.selectorText, this.representedObject.node.ownerDocument.frameIdentifier);
-    }
-
-    _hideDOMNodeHighlight()
-    {
-        WebInspector.domTreeManager.hideDOMNodeHighlight();
-    }
-
-    _handleContextMenuEvent(event)
-    {
-        let contextMenu = WebInspector.ContextMenu.createFromEvent(event);
-
         contextMenu.appendItem(WebInspector.UIString("Copy Rule"), () => {
             InspectorFrontendHost.copyText(this.representedObject.generateCSSRuleString());
         });
@@ -213,8 +193,27 @@
                 this.representedObject.nodeStyles.addRule(pseudoSelectors.join(", "), styleText);
             });
         }
+
+        super.populateContextMenu(contextMenu, event);
     }
 
+    // Private
+
+    _highlightNodesWithSelector()
+    {
+        if (!this.representedObject.ownerRule) {
+            WebInspector.domTreeManager.highlightDOMNode(this.representedObject.node.id);
+            return;
+        }
+
+        WebInspector.domTreeManager.highlightSelector(this.selectorText, this.representedObject.node.ownerDocument.frameIdentifier);
+    }
+
+    _hideDOMNodeHighlight()
+    {
+        WebInspector.domTreeManager.hideDOMNodeHighlight();
+    }
+
     _handleCheckboxChanged(event)
     {
         this._updateCheckboxTitle();

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/WorkerTreeElement.js (211060 => 211061)


--- trunk/Source/WebInspectorUI/UserInterface/Views/WorkerTreeElement.js	2017-01-23 21:41:23 UTC (rev 211060)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/WorkerTreeElement.js	2017-01-23 22:24:01 UTC (rev 211061)
@@ -100,6 +100,14 @@
         }
     }
 
+    populateContextMenu(contextMenu, event)
+    {
+        // FIXME: <https://webkit.org/b/164427> Web Inspector: WorkerTarget's mainResource should be a Resource not a Script
+        WebInspector.appendContextMenuItemsForSourceCode(contextMenu, this.script.resource ? this.script.resource : this.script);
+
+        super.populateContextMenu(contextMenu, event);
+    }
+
     // Overrides from SourceCodeTreeElement.
 
     updateSourceMapResources()
@@ -122,8 +130,6 @@
         // Handle our own SourceMapResources. Skip immediate superclasses.
 
         WebInspector.GeneralTreeElement.prototype.onattach.call(this);
-
-        this.element.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this));
     }
 
     // Overrides from FolderizedTreeElement
@@ -144,14 +150,6 @@
 
     // Private
 
-    _handleContextMenuEvent(event)
-    {
-        let contextMenu = WebInspector.ContextMenu.createFromEvent(event);
-
-        // FIXME: <https://webkit.org/b/164427> Web Inspector: WorkerTarget's mainResource should be a Resource not a Script
-        WebInspector.appendContextMenuItemsForSourceCode(contextMenu, this.script.resource ? this.script.resource : this.script);
-    }
-
     _scriptAdded(event)
     {
         let script = event.data.script;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to