Web Inspector: DOM: selecting a node in a different frame should automatically switch...
authordrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Mar 2019 17:45:02 +0000 (17:45 +0000)
committerdrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Mar 2019 17:45:02 +0000 (17:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195805
<rdar://problem/48930866>

Reviewed by Timothy Hatcher.

Add an "Auto" execution context item that is selected by default and will update the
selected execution context whenever the inspected node changes. It will also display the
preferred name for whatever execution context is currently active.

* UserInterface/Views/QuickConsole.js:
(WI.QuickConsole):
(WI.QuickConsole.prototype.initializeMainExecutionContextPathComponent):
(WI.QuickConsole.prototype._preferredNameForFrame): Added.
(WI.QuickConsole.prototype._selectExecutionContext): Added.
(WI.QuickConsole.prototype._executionContextPathComponentsToDisplay):
(WI.QuickConsole.prototype._rebuildExecutionContextPathComponents):
(WI.QuickConsole.prototype._framePageExecutionContextsChanged):
(WI.QuickConsole.prototype._frameExecutionContextsCleared):
(WI.QuickConsole.prototype._activeExecutionContextChanged):
(WI.QuickConsole.prototype._createExecutionContextPathComponent):
(WI.QuickConsole.prototype._insertOtherExecutionContextPathComponent):
(WI.QuickConsole.prototype._removeOtherExecutionContextPathComponent):
(WI.QuickConsole.prototype._insertExecutionContextPathComponentForFrame):
(WI.QuickConsole.prototype._removeExecutionContextPathComponentForFrame):
(WI.QuickConsole.prototype._targetRemoved):
(WI.QuickConsole.prototype._pathComponentSelected):
(WI.QuickConsole.prototype._handleInspectedNodeChanged): Added.
(WI.QuickConsole.prototype.get selectedExecutionContext): Deleted.
(WI.QuickConsole.prototype.set selectedExecutionContext): Deleted.
(WI.QuickConsole.prototype._createExecutionContextPathComponentFromFrame): Deleted.
* UserInterface/Views/QuickConsole.css:
(.quick-console > .navigation-bar > .hierarchical-path:not(.automatic-execution-context)): Added.
(.quick-console > .navigation-bar > .hierarchical-path:not(.automatic-execution-context) .execution-context): Added.
(.quick-console > .navigation-bar > .hierarchical-path:not(.automatic-execution-context) .execution-context .selector-arrows): Added.
(.quick-console > .navigation-bar > .hierarchical-path.non-default-execution-context .execution-context): Deleted.
(.quick-console > .navigation-bar > .hierarchical-path.non-default-execution-context .execution-context .selector-arrows): Deleted.

* UserInterface/Controllers/DOMManager.js:
(WI.DOMManager.prototype.get inspectedNode): Added.
(WI.DOMManager.prototype.setInspectedNode):
Broadcast when the inspected node changes.

* UserInterface/Views/NavigationBar.js:
(WI.NavigationBar.prototype.layout):
When `sizesToFit` is enabled, don't force any items to be hidden.

* Localizations/en.lproj/localizedStrings.js:

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

Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js
Source/WebInspectorUI/UserInterface/Views/NavigationBar.js
Source/WebInspectorUI/UserInterface/Views/QuickConsole.css
Source/WebInspectorUI/UserInterface/Views/QuickConsole.js

index 16da470..ffc648c 100644 (file)
@@ -1,5 +1,56 @@
 2019-03-20  Devin Rousso  <drousso@apple.com>
 
+        Web Inspector: DOM: selecting a node in a different frame should automatically switch the console prompt's execution context
+        https://bugs.webkit.org/show_bug.cgi?id=195805
+        <rdar://problem/48930866>
+
+        Reviewed by Timothy Hatcher.
+
+        Add an "Auto" execution context item that is selected by default and will update the
+        selected execution context whenever the inspected node changes. It will also display the
+        preferred name for whatever execution context is currently active.
+
+        * UserInterface/Views/QuickConsole.js:
+        (WI.QuickConsole):
+        (WI.QuickConsole.prototype.initializeMainExecutionContextPathComponent):
+        (WI.QuickConsole.prototype._preferredNameForFrame): Added.
+        (WI.QuickConsole.prototype._selectExecutionContext): Added.
+        (WI.QuickConsole.prototype._executionContextPathComponentsToDisplay):
+        (WI.QuickConsole.prototype._rebuildExecutionContextPathComponents):
+        (WI.QuickConsole.prototype._framePageExecutionContextsChanged):
+        (WI.QuickConsole.prototype._frameExecutionContextsCleared):
+        (WI.QuickConsole.prototype._activeExecutionContextChanged):
+        (WI.QuickConsole.prototype._createExecutionContextPathComponent):
+        (WI.QuickConsole.prototype._insertOtherExecutionContextPathComponent):
+        (WI.QuickConsole.prototype._removeOtherExecutionContextPathComponent):
+        (WI.QuickConsole.prototype._insertExecutionContextPathComponentForFrame):
+        (WI.QuickConsole.prototype._removeExecutionContextPathComponentForFrame):
+        (WI.QuickConsole.prototype._targetRemoved):
+        (WI.QuickConsole.prototype._pathComponentSelected):
+        (WI.QuickConsole.prototype._handleInspectedNodeChanged): Added.
+        (WI.QuickConsole.prototype.get selectedExecutionContext): Deleted.
+        (WI.QuickConsole.prototype.set selectedExecutionContext): Deleted.
+        (WI.QuickConsole.prototype._createExecutionContextPathComponentFromFrame): Deleted.
+        * UserInterface/Views/QuickConsole.css:
+        (.quick-console > .navigation-bar > .hierarchical-path:not(.automatic-execution-context)): Added.
+        (.quick-console > .navigation-bar > .hierarchical-path:not(.automatic-execution-context) .execution-context): Added.
+        (.quick-console > .navigation-bar > .hierarchical-path:not(.automatic-execution-context) .execution-context .selector-arrows): Added.
+        (.quick-console > .navigation-bar > .hierarchical-path.non-default-execution-context .execution-context): Deleted.
+        (.quick-console > .navigation-bar > .hierarchical-path.non-default-execution-context .execution-context .selector-arrows): Deleted.
+
+        * UserInterface/Controllers/DOMManager.js:
+        (WI.DOMManager.prototype.get inspectedNode): Added.
+        (WI.DOMManager.prototype.setInspectedNode):
+        Broadcast when the inspected node changes.
+
+        * UserInterface/Views/NavigationBar.js:
+        (WI.NavigationBar.prototype.layout):
+        When `sizesToFit` is enabled, don't force any items to be hidden.
+
+        * Localizations/en.lproj/localizedStrings.js:
+
+2019-03-20  Devin Rousso  <drousso@apple.com>
+
         Web Inspector: refactor WI.TimelineDataGridNode and its subclasses to unify the API surface
         https://bugs.webkit.org/show_bug.cgi?id=195959
         <rdar://problem/49028896>
index f1c6d0b..900e80d 100644 (file)
@@ -142,6 +142,8 @@ localizedStrings["Audit Warning: %s"] = "Audit Warning: %s";
 localizedStrings["Audit version: %s"] = "Audit version: %s";
 localizedStrings["Audits"] = "Audits";
 localizedStrings["Author Stylesheet"] = "Author Stylesheet";
+localizedStrings["Auto"] = "Auto";
+localizedStrings["Auto - %s"] = "Auto - %s";
 localizedStrings["Auto Increment"] = "Auto Increment";
 localizedStrings["Automatically continue after evaluating"] = "Automatically continue after evaluating";
 localizedStrings["Available Style Sheets"] = "Available Style Sheets";
@@ -437,6 +439,7 @@ localizedStrings["Events"] = "Events";
 localizedStrings["Events:"] = "Events:";
 localizedStrings["Example: \u201C%s\u201D"] = "Example: \u201C%s\u201D";
 localizedStrings["Exception with thrown value: %s"] = "Exception with thrown value: %s";
+localizedStrings["Execution context for $0"] = "Execution context for $0";
 localizedStrings["Exited Full-Screen Mode"] = "Exited Full-Screen Mode";
 localizedStrings["Exited Low-Power Mode"] = "Exited Low-Power Mode";
 localizedStrings["Expand All"] = "Expand All";
index bf7d31a..dd52c4e 100644 (file)
@@ -75,6 +75,8 @@ WI.DOMManager = class DOMManager extends WI.Object
 
     // Public
 
+    get inspectedNode() { return this._inspectedNode; }
+
     get eventListenerBreakpoints()
     {
         return Array.from(this._breakpointsForEventListeners.values());
@@ -554,6 +556,8 @@ WI.DOMManager = class DOMManager extends WI.Object
                 return;
 
             this._inspectedNode = node;
+
+            this.dispatchEventToListeners(WI.DOMManager.Event.InspectedNodeChanged);
         };
 
         // COMPATIBILITY (iOS 11): DOM.setInspectedNode did not exist.
@@ -666,4 +670,5 @@ WI.DOMManager.Event = {
     ChildNodeCountUpdated: "dom-manager-child-node-count-updated",
     DOMNodeWasInspected: "dom-manager-dom-node-was-inspected",
     InspectModeStateChanged: "dom-manager-inspect-mode-state-changed",
+    InspectedNodeChanged: "dom-manager-inspected-node-changed",
 };
index 7c03293..144fe16 100644 (file)
@@ -233,6 +233,9 @@ WI.NavigationBar = class NavigationBar extends WI.View
             item.updateLayout(true);
         }
 
+        if (this.sizesToFit)
+            return;
+
         let visibleNavigationItems = this._visibleNavigationItems;
 
         function calculateVisibleItemWidth() {
index 99fb49c..f4bf940 100644 (file)
     display: none;
 }
 
-.quick-console > .navigation-bar > .hierarchical-path.non-default-execution-context .execution-context {
+.quick-console > .navigation-bar > .hierarchical-path:not(.automatic-execution-context) {
+    -webkit-padding-start: 5px;
+}
+
+.quick-console > .navigation-bar > .hierarchical-path:not(.automatic-execution-context) .execution-context {
     background: var(--selected-background-color);
     border-radius: 3px;
     color: var(--selected-foreground-color);
 }
 
-.quick-console > .navigation-bar > .hierarchical-path.non-default-execution-context .execution-context .selector-arrows {
+.quick-console > .navigation-bar > .hierarchical-path:not(.automatic-execution-context) .execution-context .selector-arrows {
     color: var(--selected-foreground-color);
     opacity: 1;
 }
index 1d23bc4..f3a55e7 100644 (file)
@@ -32,13 +32,16 @@ WI.QuickConsole = class QuickConsole extends WI.View
         this._toggleOrFocusKeyboardShortcut = new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.Escape, this._toggleOrFocus.bind(this));
         this._toggleOrFocusKeyboardShortcut.implicitlyPreventsDefault = false;
 
-        this._mainExecutionContextPathComponent = null;
-        this.initializeMainExecutionContextPathComponent();
+        this._automaticExecutionContextPathComponent = this._createExecutionContextPathComponent(null, WI.UIString("Auto"));
+        this._automaticExecutionContextPathComponent.tooltip = WI.UIString("Execution context for $0");
 
+        this._mainExecutionContextPathComponent = null;
         this._otherExecutionContextPathComponents = [];
+
         this._frameToPathComponent = new Map;
         this._targetToPathComponent = new Map;
 
+        this._shouldAutomaticallySelectExecutionContext = true;
         this._restoreSelectedExecutionContextForFrame = false;
 
         this.element.classList.add("quick-console");
@@ -64,7 +67,7 @@ WI.QuickConsole = class QuickConsole extends WI.View
         this._executionContextSelectorDivider = new WI.DividerNavigationItem;
         this._navigationBar.addNavigationItem(this._executionContextSelectorDivider);
 
-        this._rebuildExecutionContextPathComponents();
+        this.initializeMainExecutionContextPathComponent();
 
         WI.consoleDrawer.toggleButtonShortcutTooltip(this._toggleOrFocusKeyboardShortcut);
         WI.consoleDrawer.addEventListener(WI.ConsoleDrawer.Event.CollapsedStateChanged, this._updateStyles, this);
@@ -79,6 +82,8 @@ WI.QuickConsole = class QuickConsole extends WI.View
         WI.targetManager.addEventListener(WI.TargetManager.Event.TargetAdded, this._targetAdded, this);
         WI.targetManager.addEventListener(WI.TargetManager.Event.TargetRemoved, this._targetRemoved, this);
 
+        WI.domManager.addEventListener(WI.DOMManager.Event.InspectedNodeChanged, this._handleInspectedNodeChanged, this);
+
         WI.TabBrowser.addEventListener(WI.TabBrowser.Event.SelectedTabContentViewDidChange, this._updateStyles, this);
     }
 
@@ -89,16 +94,6 @@ WI.QuickConsole = class QuickConsole extends WI.View
         return this._navigationBar;
     }
 
-    get selectedExecutionContext()
-    {
-        return WI.runtimeManager.activeExecutionContext;
-    }
-
-    set selectedExecutionContext(executionContext)
-    {
-        WI.runtimeManager.activeExecutionContext = executionContext;
-    }
-
     closed()
     {
         WI.Frame.removeEventListener(null, null, this);
@@ -117,6 +112,13 @@ WI.QuickConsole = class QuickConsole extends WI.View
             return;
 
         this._mainExecutionContextPathComponent = this._createExecutionContextPathComponent(WI.mainTarget.executionContext);
+        this._mainExecutionContextPathComponent.previousSibling = this._automaticExecutionContextPathComponent;
+
+        this._automaticExecutionContextPathComponent.nextSibling = this._mainExecutionContextPathComponent;
+
+        this._shouldAutomaticallySelectExecutionContext = true;
+        this._selectExecutionContext(WI.mainTarget.executionContext);
+        this._rebuildExecutionContextPathComponents();
     }
 
     // Protected
@@ -130,6 +132,37 @@ WI.QuickConsole = class QuickConsole extends WI.View
 
     // Private
 
+    _preferredNameForFrame(frame)
+    {
+        if (frame.name)
+            return WI.UIString("%s (%s)").format(frame.name, frame.mainResource.displayName);
+        return frame.mainResource.displayName;
+    }
+
+    _selectExecutionContext(executionContext)
+    {
+        let preferredName = null;
+
+        let inspectedNode = WI.domManager.inspectedNode;
+        if (inspectedNode) {
+            let frame = inspectedNode.ownerDocument.frame;
+            if (frame) {
+                if (this._shouldAutomaticallySelectExecutionContext)
+                    executionContext = frame.pageExecutionContext;
+
+                preferredName = this._preferredNameForFrame(frame);
+            }
+        }
+
+        console.assert(executionContext);
+        if (!executionContext)
+            executionContext = WI.mainTarget.executionContext;
+
+        WI.runtimeManager.activeExecutionContext = executionContext;
+
+        this._automaticExecutionContextPathComponent.displayName = WI.UIString("Auto - %s").format(preferredName || executionContext.name);
+    }
+
     _handleMouseDown(event)
     {
         if (event.target !== this.element)
@@ -149,10 +182,13 @@ WI.QuickConsole = class QuickConsole extends WI.View
         if (!this._otherExecutionContextPathComponents.length)
             return [];
 
-        if (this.selectedExecutionContext === WI.mainTarget.executionContext)
+        if (this._shouldAutomaticallySelectExecutionContext)
+            return [this._automaticExecutionContextPathComponent];
+
+        if (WI.runtimeManager.activeExecutionContext === WI.mainTarget.executionContext)
             return [this._mainExecutionContextPathComponent];
 
-        return this._otherExecutionContextPathComponents.filter((component) => component.representedObject === this.selectedExecutionContext);
+        return this._otherExecutionContextPathComponents.filter((component) => component.representedObject === WI.runtimeManager.activeExecutionContext);
     }
 
     _rebuildExecutionContextPathComponents()
@@ -160,23 +196,24 @@ WI.QuickConsole = class QuickConsole extends WI.View
         let components = this._executionContextPathComponentsToDisplay();
         let isEmpty = !components.length;
 
+        this._executionContextSelectorItem.element.classList.toggle("automatic-execution-context", this._shouldAutomaticallySelectExecutionContext);
         this._executionContextSelectorItem.components = components;
 
         this._executionContextSelectorItem.hidden = isEmpty;
         this._executionContextSelectorDivider.hidden = isEmpty;
+
     }
 
     _framePageExecutionContextsChanged(event)
     {
         let frame = event.target;
 
-        let shouldAutomaticallySelect = this._restoreSelectedExecutionContextForFrame === frame;
-
-        let newExecutionContextPathComponent = this._insertExecutionContextPathComponentForFrame(frame, shouldAutomaticallySelect);
+        let newExecutionContextPathComponent = this._insertExecutionContextPathComponentForFrame(frame);
 
-        if (shouldAutomaticallySelect) {
+        if (this._restoreSelectedExecutionContextForFrame === frame) {
             this._restoreSelectedExecutionContextForFrame = null;
-            this.selectedExecutionContext = newExecutionContextPathComponent.representedObject;
+
+            this._selectExecutionContext(newExecutionContextPathComponent.representedObject);
         }
     }
 
@@ -187,10 +224,12 @@ WI.QuickConsole = class QuickConsole extends WI.View
         // If this frame is navigating and it is selected in the UI we want to reselect its new item after navigation.
         if (event.data.committingProvisionalLoad && !this._restoreSelectedExecutionContextForFrame) {
             let executionContextPathComponent = this._frameToPathComponent.get(frame);
-            if (executionContextPathComponent && executionContextPathComponent.representedObject === this.selectedExecutionContext) {
+            if (executionContextPathComponent && executionContextPathComponent.representedObject === WI.runtimeManager.activeExecutionContext) {
                 this._restoreSelectedExecutionContextForFrame = frame;
                 // As a fail safe, if the frame never gets an execution context, clear the restore value.
-                setTimeout(() => { this._restoreSelectedExecutionContextForFrame = false; }, 10);
+                setTimeout(() => {
+                    this._restoreSelectedExecutionContextForFrame = false;
+                }, 10);
             }
         }
 
@@ -200,13 +239,11 @@ WI.QuickConsole = class QuickConsole extends WI.View
     _activeExecutionContextChanged(event)
     {
         this._rebuildExecutionContextPathComponents();
-
-        this._executionContextSelectorItem.element.classList.toggle("non-default-execution-context", this.selectedExecutionContext !== WI.mainTarget.executionContext);
     }
 
     _createExecutionContextPathComponent(executionContext, preferredName)
     {
-        console.assert(executionContext instanceof WI.ExecutionContext);
+        console.assert(!executionContext || executionContext instanceof WI.ExecutionContext);
 
         let pathComponent = new WI.HierarchicalPathComponent(preferredName || executionContext.name, "execution-context", executionContext, true, true);
         pathComponent.addEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this._pathComponentSelected, this);
@@ -215,12 +252,6 @@ WI.QuickConsole = class QuickConsole extends WI.View
         return pathComponent;
     }
 
-    _createExecutionContextPathComponentFromFrame(frame)
-    {
-        let preferredName = frame.name ? WI.UIString("%s (%s)").format(frame.name, frame.mainResource.displayName) : frame.mainResource.displayName;
-        return this._createExecutionContextPathComponent(frame.pageExecutionContext, preferredName);
-    }
-
     _compareExecutionContextPathComponents(a, b)
     {
         let aExecutionContext = a.representedObject;
@@ -255,7 +286,7 @@ WI.QuickConsole = class QuickConsole extends WI.View
         return a.displayName.extendedLocaleCompare(b.displayName);
     }
 
-    _insertOtherExecutionContextPathComponent(executionContextPathComponent, skipRebuild)
+    _insertOtherExecutionContextPathComponent(executionContextPathComponent)
     {
         let index = insertionIndexForObjectInListSortedByFunction(executionContextPathComponent, this._otherExecutionContextPathComponents, this._compareExecutionContextPathComponents);
 
@@ -272,11 +303,10 @@ WI.QuickConsole = class QuickConsole extends WI.View
 
         this._otherExecutionContextPathComponents.splice(index, 0, executionContextPathComponent);
 
-        if (!skipRebuild)
-            this._rebuildExecutionContextPathComponents();
+        this._rebuildExecutionContextPathComponents();
     }
 
-    _removeOtherExecutionContextPathComponent(executionContextPathComponent, skipRebuild)
+    _removeOtherExecutionContextPathComponent(executionContextPathComponent)
     {
         executionContextPathComponent.removeEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this._pathComponentSelected, this);
         executionContextPathComponent.removeEventListener(WI.HierarchicalPathComponent.Event.Clicked, this._pathComponentClicked, this);
@@ -290,29 +320,29 @@ WI.QuickConsole = class QuickConsole extends WI.View
 
         this._otherExecutionContextPathComponents.remove(executionContextPathComponent, true);
 
-        if (!skipRebuild)
-            this._rebuildExecutionContextPathComponents();
+        this._rebuildExecutionContextPathComponents();
     }
 
-    _insertExecutionContextPathComponentForFrame(frame, skipRebuild)
+    _insertExecutionContextPathComponentForFrame(frame)
     {
         if (frame.isMainFrame())
             return this._mainExecutionContextPathComponent;
 
-        let executionContextPathComponent = this._createExecutionContextPathComponentFromFrame(frame);
-        this._insertOtherExecutionContextPathComponent(executionContextPathComponent, skipRebuild);
+        let executionContextPathComponent = this._createExecutionContextPathComponent(frame.pageExecutionContext, this._preferredNameForFrame(frame));
+        this._insertOtherExecutionContextPathComponent(executionContextPathComponent);
         this._frameToPathComponent.set(frame, executionContextPathComponent);
-
         return executionContextPathComponent;
     }
 
-    _removeExecutionContextPathComponentForFrame(frame, skipRebuild)
+    _removeExecutionContextPathComponentForFrame(frame)
     {
-        if (frame.isMainFrame())
+        if (frame.isMainFrame()) {
+            this._shouldAutomaticallySelectExecutionContext = true;
             return;
+        }
 
         let executionContextPathComponent = this._frameToPathComponent.take(frame);
-        this._removeOtherExecutionContextPathComponent(executionContextPathComponent, skipRebuild);
+        this._removeOtherExecutionContextPathComponent(executionContextPathComponent);
     }
 
     _targetAdded(event)
@@ -336,16 +366,19 @@ WI.QuickConsole = class QuickConsole extends WI.View
             return;
 
         let executionContextPathComponent = this._targetToPathComponent.take(target);
-        this._removeOtherExecutionContextPathComponent(executionContextPathComponent);
 
-        if (this.selectedExecutionContext === executionContextPathComponent.representedObject)
-            this.selectedExecutionContext = WI.mainTarget.executionContext;
+        if (WI.runtimeManager.activeExecutionContext === executionContextPathComponent.representedObject) {
+            this._shouldAutomaticallySelectExecutionContext = true;
+            this._selectExecutionContext();
+        }
+
+        this._removeOtherExecutionContextPathComponent(executionContextPathComponent);
     }
 
     _pathComponentSelected(event)
     {
-        let executionContext = event.data.pathComponent.representedObject;
-        this.selectedExecutionContext = executionContext;
+        this._shouldAutomaticallySelectExecutionContext = event.data.pathComponent === this._automaticExecutionContextPathComponent;
+        this._selectExecutionContext(event.data.pathComponent.representedObject);
     }
 
     _pathComponentClicked(event)
@@ -373,4 +406,9 @@ WI.QuickConsole = class QuickConsole extends WI.View
     {
         this.element.classList.toggle("showing-log", WI.isShowingConsoleTab() || WI.isShowingSplitConsole());
     }
+
+    _handleInspectedNodeChanged(event)
+    {
+        this._selectExecutionContext(WI.runtimeManager.activeExecutionContext);
+    }
 };