Bug 1605175 - Selecting an element in remote iframe should switch context and update selector. r=nchevobbe
authorJason Laster <jlaster@mozilla.com>
Tue, 24 Mar 2020 15:28:52 +0000
changeset 520224 f0e8903666316ca39735aa89e731238ca7872399
parent 520223 aea3c8ce3ff8182d15ac0948d0029ad98f6a63f8
child 520225 94a18b916feccccfa76832c86e3958b269737395
push id37245
push useropoprus@mozilla.com
push dateTue, 24 Mar 2020 21:46:41 +0000
treeherdermozilla-central@dbabf2e388fa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnchevobbe
bugs1605175
milestone76.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1605175 - Selecting an element in remote iframe should switch context and update selector. r=nchevobbe Differential Revision: https://phabricator.services.mozilla.com/D67083
devtools/client/framework/toolbox.js
devtools/client/inspector/markup/markup-context-menu.js
devtools/client/webconsole/actions/input.js
devtools/client/webconsole/commands.js
devtools/client/webconsole/webconsole-ui.js
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -3493,21 +3493,28 @@ Toolbox.prototype = {
 
         const unHighlight = currentHighlighterFront.unhighlight(forceHide);
         currentHighlighterFront = null;
         return unHighlight;
       },
     };
   },
 
-  _onNewSelectedNodeFront: function() {
+  _onNewSelectedNodeFront: async function() {
     // Emit a "selection-changed" event when the toolbox.selection has been set
     // to a new node (or cleared). Currently used in the WebExtensions APIs (to
     // provide the `devtools.panels.elements.onSelectionChanged` event).
     this.emit("selection-changed");
+
+    const threadFront = await this.selection?.nodeFront?.targetFront.getFront(
+      "thread"
+    );
+    if (threadFront) {
+      this.selectThread(threadFront.actorID);
+    }
   },
 
   _onInspectObject: function(packet) {
     this.inspectObjectActor(packet.objectActor, packet.inspectFromAnnotation);
   },
 
   _onToolSelected: function() {
     this._refreshHostTitle();
--- a/devtools/client/inspector/markup/markup-context-menu.js
+++ b/devtools/client/inspector/markup/markup-context-menu.js
@@ -363,20 +363,18 @@ class MarkupContextMenu {
     const evalString = `{ let i = 0;
       while (window.hasOwnProperty("temp" + i) && i < 1000) {
         i++;
       }
       window["temp" + i] = $0;
       "temp" + i;
     }`;
 
-    const options = {
-      selectedNodeActor: this.selection.nodeFront.actorID,
-    };
-    const res = await hud.evaluateJSAsync(evalString, options);
+    const selectedNodeActor = this.selection.nodeFront.actorID;
+    const res = await hud.evaluateJSAsync(evalString, { selectedNodeActor });
     hud.setInputValue(res.result);
     this.inspector.emit("console-var-ready");
   }
 
   _buildA11YMenuItem(menu) {
     if (
       !(this.selection.isElementNode() || this.selection.isTextNode()) ||
       !Services.prefs.getBoolPref("devtools.accessibility.enabled")
--- a/devtools/client/webconsole/actions/input.js
+++ b/devtools/client/webconsole/actions/input.js
@@ -90,17 +90,17 @@ function evaluateExpression(expression) 
     // Even if the evaluation fails,
     // we still need to pass the error response to onExpressionEvaluated.
     const onSettled = res => res;
 
     const response = await client
       .evaluateJSAsync(expression, {
         selectedThreadFront,
         frameActor,
-        selectedNodeFront: webConsoleUI.getSelectedNodeFront(),
+        selectedNodeActor: webConsoleUI.getSelectedNodeActor(),
         mapped,
       })
       .then(onSettled, onSettled);
 
     return dispatch(onExpressionEvaluated(response));
   };
 }
 
@@ -254,17 +254,17 @@ function terminalInputChanged(expression
     ({ expression, mapped } = await getMappedExpression(hud, expression));
 
     const frameActor = await webConsoleUI.getFrameActor();
     const selectedThreadFront = toolbox && toolbox.getSelectedThreadFront();
 
     const response = await client.evaluateJSAsync(expression, {
       frameActor,
       selectedThreadFront,
-      selectedNodeFront: webConsoleUI.getSelectedNodeFront(),
+      selectedNodeActor: webConsoleUI.getSelectedNodeActor(),
       mapped,
       eager: true,
     });
 
     return dispatch({
       type: SET_TERMINAL_EAGER_RESULT,
       result: getEagerEvaluationResult(response),
     });
--- a/devtools/client/webconsole/commands.js
+++ b/devtools/client/webconsole/commands.js
@@ -12,50 +12,47 @@ class ConsoleCommands {
   }
 
   getFrontByID(id) {
     return this.devToolsClient.getFrontByID(id);
   }
 
   async evaluateJSAsync(expression, options = {}) {
     const {
-      selectedNodeFront,
       selectedThreadFront,
       frameActor,
       selectedObjectActor,
+      selectedNodeActor,
     } = options;
     let front = await this.hud.currentTarget.getFront("console");
+    const selectedActor = selectedObjectActor || selectedNodeActor;
 
     // Defer to the selected paused thread front
+    // NOTE: when the context selector is enabled, this will no longer be needed
     if (frameActor) {
       const frameFront = this.getFrontByID(frameActor);
       if (frameFront) {
         front = await frameFront.targetFront.getFront("console");
       }
     }
 
     // NOTE: once we handle the other tasks in console evaluation,
     // all of the implicit actions like pausing, selecting a frame in the inspector,
     // etc will update the selected thread and we will no longer need to support these other
     // cases.
+
+    // Get the selected thread's, webconsole front so that we can
+    // evaluate expressions against it.
     if (selectedThreadFront) {
       front = await selectedThreadFront.targetFront.getFront("console");
-
-      // If there's a selectedObjectActor option, this means the user intend to do a
-      // given action on a specific object, so it should take precedence over selected
-      // node front.
-    } else if (selectedObjectActor) {
-      const objectFront = this.getFrontByID(selectedObjectActor);
-      if (objectFront) {
-        front = await objectFront.targetFront.getFront("console");
+    } else if (selectedActor) {
+      const selectedFront = this.getFrontByID(selectedActor);
+      if (selectedFront) {
+        front = await selectedFront.targetFront.getFront("console");
       }
-    } else if (selectedNodeFront) {
-      // Defer to the selected node's thread console front
-      front = await selectedNodeFront.targetFront.getFront("console");
-      options.selectedNodeActor = selectedNodeFront.actorID;
     }
 
     return front.evaluateJSAsync(expression, options);
   }
 
   timeWarp(executionPoint) {
     return this.threadFront.timeWarp(executionPoint);
   }
--- a/devtools/client/webconsole/webconsole-ui.js
+++ b/devtools/client/webconsole/webconsole-ui.js
@@ -610,23 +610,18 @@ class WebConsoleUI {
     if (!threadFront) {
       return this.webConsoleFront;
     }
 
     return threadFront.getWebconsoleFront();
   }
 
   getSelectedNodeActor() {
-    const front = this.getSelectedNodeFront();
-    return front ? front.actorID : null;
-  }
-
-  getSelectedNodeFront() {
     const inspectorSelection = this.hud.getInspectorSelection();
-    return inspectorSelection ? inspectorSelection.nodeFront : null;
+    return inspectorSelection?.nodeFront?.actorID;
   }
 
   onMessageHover(type, message) {
     this.emit("message-hover", type, message);
   }
 }
 
 /* This is the same as DevelopmentHelpers.quickRestart, but it runs in all