Web Inspector: Uncaught Exception: null is not an object (evaluating 'this.ownerDocum...
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Views / QuickConsole.js
index 1ac669f..5187b30 100644 (file)
@@ -32,19 +32,22 @@ 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 = this._createExecutionContextPathComponent(WI.mainTarget.executionContext);
+        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");
         this.element.addEventListener("mousedown", this._handleMouseDown.bind(this));
 
         this.prompt = new WI.ConsolePrompt(null, "text/javascript");
-        this.prompt.element.classList.add("text-prompt");
         this.addSubview(this.prompt);
 
         // FIXME: CodeMirror 4 has a default "Esc" key handler that always prevents default.
@@ -64,7 +67,10 @@ 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);
 
         WI.Frame.addEventListener(WI.Frame.Event.PageExecutionContextChanged, this._framePageExecutionContextsChanged, this);
         WI.Frame.addEventListener(WI.Frame.Event.ExecutionContextsCleared, this._frameExecutionContextsCleared, this);
@@ -76,7 +82,7 @@ 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.consoleDrawer.addEventListener(WI.ConsoleDrawer.Event.CollapsedStateChanged, this._updateStyles, this);
+        WI.domManager.addEventListener(WI.DOMManager.Event.InspectedNodeChanged, this._handleInspectedNodeChanged, this);
 
         WI.TabBrowser.addEventListener(WI.TabBrowser.Event.SelectedTabContentViewDidChange, this._updateStyles, this);
     }
@@ -88,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);
@@ -110,6 +106,21 @@ WI.QuickConsole = class QuickConsole extends WI.View
         super.closed();
     }
 
+    initializeMainExecutionContextPathComponent()
+    {
+        if (!WI.mainTarget || !WI.mainTarget.executionContext)
+            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
 
     layout()
@@ -121,6 +132,36 @@ 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.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)
@@ -140,10 +181,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()
@@ -151,23 +195,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);
 
-        let newExecutionContextPathComponent = this._insertExecutionContextPathComponentForFrame(frame, shouldAutomaticallySelect);
-
-        if (shouldAutomaticallySelect) {
+        if (this._restoreSelectedExecutionContextForFrame === frame) {
             this._restoreSelectedExecutionContextForFrame = null;
-            this.selectedExecutionContext = newExecutionContextPathComponent.representedObject;
+
+            this._selectExecutionContext(newExecutionContextPathComponent.representedObject);
         }
     }
 
@@ -178,10 +223,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);
             }
         }
 
@@ -195,7 +242,7 @@ WI.QuickConsole = class QuickConsole extends WI.View
 
     _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);
@@ -204,12 +251,6 @@ WI.QuickConsole = class QuickConsole extends WI.View
         return pathComponent;
     }
 
-    _createExecutionContextPathComponentFromFrame(frame)
-    {
-        let preferredName = frame.name ? frame.name + " \u2014 " + frame.mainResource.displayName : frame.mainResource.displayName;
-        return this._createExecutionContextPathComponent(frame.pageExecutionContext, preferredName);
-    }
-
     _compareExecutionContextPathComponents(a, b)
     {
         let aExecutionContext = a.representedObject;
@@ -244,7 +285,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);
 
@@ -261,11 +302,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);
@@ -279,34 +319,37 @@ 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)
     {
         let target = event.data.target;
+        if (target.type !== WI.Target.Type.Worker)
+            return;
+
         console.assert(target.type === WI.Target.Type.Worker);
         let preferredName = WI.UIString("Worker \u2014 %s").format(target.displayName);
         let executionContextPathComponent = this._createExecutionContextPathComponent(target.executionContext, preferredName);
@@ -318,17 +361,23 @@ WI.QuickConsole = class QuickConsole extends WI.View
     _targetRemoved(event)
     {
         let target = event.data.target;
+        if (target.type !== WI.Target.Type.Worker)
+            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)
@@ -356,4 +405,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);
+    }
 };