Bug 1568825 - 2 - Moving the nodePicker singleton to the toolbox r=gl
authorPatrick Brosset <pbrosset@mozilla.com>
Fri, 16 Aug 2019 04:48:27 +0000
changeset 488432 36627f38d627e5fb3498aa7bfba482e60f927a4a
parent 488431 515ff404fcfe6f0c728799d1b64c6889748393ca
child 488433 e1193c2352a11eff6302aa2689894dac6b772cc5
push id36443
push userccoroiu@mozilla.com
push dateFri, 16 Aug 2019 09:48:15 +0000
treeherdermozilla-central@5d4cbfe103bb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgl
bugs1568825
milestone70.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 1568825 - 2 - Moving the nodePicker singleton to the toolbox r=gl Differential Revision: https://phabricator.services.mozilla.com/D41597
devtools/client/definitions.js
devtools/client/framework/test/browser_keybindings_01.js
devtools/client/framework/toolbox.js
devtools/client/inspector/animation/animation.js
devtools/client/inspector/boxmodel/box-model.js
devtools/client/inspector/boxmodel/test/head.js
devtools/client/inspector/markup/markup.js
devtools/client/inspector/node-picker.js
devtools/client/inspector/rules/test/browser_rules_colorpicker-hides-element-picker.js
devtools/client/inspector/test/browser_inspector_highlighter-03.js
devtools/client/inspector/test/browser_inspector_highlighter-07.js
devtools/client/inspector/test/browser_inspector_highlighter-cancel.js
devtools/client/inspector/test/browser_inspector_highlighter-iframes_01.js
devtools/client/inspector/test/browser_inspector_highlighter-keybinding_01.js
devtools/client/inspector/test/browser_inspector_highlighter-keybinding_02.js
devtools/client/inspector/test/browser_inspector_highlighter-keybinding_03.js
devtools/client/inspector/test/browser_inspector_highlighter-keybinding_04.js
devtools/client/inspector/test/browser_inspector_highlighter-xbl.js
devtools/client/inspector/test/browser_inspector_iframe-navigation.js
devtools/client/inspector/test/browser_inspector_picker-stop-on-tool-change.js
devtools/client/inspector/test/browser_inspector_switch-to-inspector-on-pick.js
devtools/client/inspector/test/head.js
devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js
devtools/client/webconsole/test/browser/head.js
devtools/client/webreplay/mochitest/browser_rr_inspector-02.js
devtools/shared/fronts/inspector.js
--- a/devtools/client/definitions.js
+++ b/devtools/client/definitions.js
@@ -158,19 +158,18 @@ Tools.inspector = {
     return l10n("inspector.tooltip2", ctrlShiftC);
   },
   inMenu: true,
 
   preventClosingOnKey: true,
   // preventRaisingOnKey is used to keep the focus on the content window for shortcuts
   // that trigger the element picker.
   preventRaisingOnKey: true,
-  onkey: async function(panel, toolbox) {
-    const inspectorFront = await toolbox.target.getFront("inspector");
-    inspectorFront.nodePicker.togglePicker();
+  onkey: function(panel, toolbox) {
+    toolbox.nodePicker.togglePicker();
   },
 
   isTargetSupported: function(target) {
     return target.hasActor("inspector");
   },
 
   build: function(iframeWindow, toolbox) {
     return new InspectorPanel(iframeWindow, toolbox);
--- a/devtools/client/framework/test/browser_keybindings_01.js
+++ b/devtools/client/framework/test/browser_keybindings_01.js
@@ -99,23 +99,22 @@ add_task(async function() {
     await inspectorShouldBeOpenAndHighlighting(inspectorKeys[1]);
   }
 
   gBrowser.removeCurrentTab();
 
   async function inspectorShouldBeOpenAndHighlighting(inspector) {
     is(toolbox.currentToolId, "inspector", "Correct tool has been loaded");
 
-    const nodePicker = (await toolbox.target.getFront("inspector")).nodePicker;
-    await nodePicker.once("picker-started");
+    await toolbox.nodePicker.once("picker-started");
 
     ok(true, "picker-started event received, highlighter started");
     inspector.synthesizeKey();
 
-    await nodePicker.once("picker-stopped");
+    await toolbox.nodePicker.once("picker-stopped");
     ok(true, "picker-stopped event received, highlighter stopped");
   }
 
   function webconsoleShouldBeSelected() {
     is(toolbox.currentToolId, "webconsole", "webconsole should be selected.");
   }
 
   function netmonitorShouldBeSelected() {
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -33,16 +33,21 @@ var {
 const { KeyCodes } = require("devtools/client/shared/keycodes");
 var Startup = Cc["@mozilla.org/devtools/startup-clh;1"].getService(
   Ci.nsISupports
 ).wrappedJSObject;
 
 const { BrowserLoader } = ChromeUtils.import(
   "resource://devtools/client/shared/browser-loader.js"
 );
+loader.lazyRequireGetter(
+  this,
+  "NodePicker",
+  "devtools/client/inspector/node-picker"
+);
 
 const { LocalizationHelper } = require("devtools/shared/l10n");
 const L10N = new LocalizationHelper(
   "devtools/client/locales/toolbox.properties"
 );
 
 loader.lazyRequireGetter(
   this,
@@ -1762,52 +1767,52 @@ Toolbox.prototype = {
       this.hostType === Toolbox.HostType.RIGHT;
     const currentPanel = this.getCurrentPanel();
     if (currentPanel.togglePicker) {
       currentPanel.togglePicker(focus);
     } else {
       if (!this.inspectorFront) {
         await this.initInspector();
       }
-      this.inspectorFront.nodePicker.togglePicker(focus);
+      this.nodePicker.togglePicker(focus);
     }
   },
 
   /**
    * If the picker is activated, then allow the Escape key to deactivate the
    * functionality instead of the default behavior of toggling the console.
    */
   _onPickerKeypress: function(event) {
     if (event.keyCode === KeyCodes.DOM_VK_ESCAPE) {
       const currentPanel = this.getCurrentPanel();
       if (currentPanel.cancelPicker) {
         currentPanel.cancelPicker();
       } else {
-        this.inspectorFront.nodePicker.cancel();
+        this.nodePicker.cancel();
       }
       // Stop the console from toggling.
       event.stopImmediatePropagation();
     }
   },
 
   _onPickerStarting: async function() {
     this.tellRDMAboutPickerState(true);
     this.pickerButton.isChecked = true;
     await this.selectTool("inspector", "inspect_dom");
-    this.on("select", this.inspectorFront.nodePicker.stop);
+    this.on("select", this.nodePicker.stop);
   },
 
   _onPickerStarted: async function() {
     this.doc.addEventListener("keypress", this._onPickerKeypress, true);
     this.telemetry.scalarAdd("devtools.inspector.element_picker_used", 1);
   },
 
   _onPickerStopped: function() {
     this.tellRDMAboutPickerState(false);
-    this.off("select", this.inspectorFront.nodePicker.stop);
+    this.off("select", this.nodePicker.stop);
     this.doc.removeEventListener("keypress", this._onPickerKeypress, true);
     this.pickerButton.isChecked = false;
   },
 
   /**
    * When the picker is canceled, make sure the toolbox
    * gets the focus.
    */
@@ -3318,41 +3323,28 @@ Toolbox.prototype = {
       this._initInspector = async function() {
         // Temporary fix for bug #1493131 - inspector has a different life cycle
         // than most other fronts because it is closely related to the toolbox.
         // TODO: replace with getFront once inspector is separated from the toolbox
         // TODO: remove these bindings
         this._inspector = await this.target.getFront("inspector");
         this._walker = this.inspectorFront.walker;
         this._highlighter = this.inspectorFront.highlighter;
-
-        this.inspectorFront.nodePicker.on(
-          "picker-starting",
-          this._onPickerStarting
-        );
-        this.inspectorFront.nodePicker.on(
-          "picker-started",
-          this._onPickerStarted
-        );
-        this.inspectorFront.nodePicker.on(
-          "picker-stopped",
-          this._onPickerStopped
+        this.nodePicker = new NodePicker(
+          this._highlighter,
+          this._walker,
+          this.selection
         );
-        this.inspectorFront.nodePicker.on(
-          "picker-node-canceled",
-          this._onPickerCanceled
-        );
-        this.inspectorFront.nodePicker.on(
-          "picker-node-picked",
-          this._onPickerPicked
-        );
-        this.inspectorFront.nodePicker.on(
-          "picker-node-previewed",
-          this._onPickerPreviewed
-        );
+
+        this.nodePicker.on("picker-starting", this._onPickerStarting);
+        this.nodePicker.on("picker-started", this._onPickerStarted);
+        this.nodePicker.on("picker-stopped", this._onPickerStopped);
+        this.nodePicker.on("picker-node-canceled", this._onPickerCanceled);
+        this.nodePicker.on("picker-node-picked", this._onPickerPicked);
+        this.nodePicker.on("picker-node-previewed", this._onPickerPreviewed);
         registerWalkerListeners(this);
       }.bind(this)();
     }
     return this._initInspector;
   },
 
   /**
    * An helper function that returns an object contain a highlighter and unhighlighter
--- a/devtools/client/inspector/animation/animation.js
+++ b/devtools/client/inspector/animation/animation.js
@@ -145,21 +145,21 @@ class AnimationInspector {
         simulateAnimation,
         simulateAnimationForKeyframesProgressBar,
         toggleElementPicker,
       })
     );
     this.provider = provider;
 
     this.inspector.sidebar.on("select", this.onSidebarSelectionChanged);
-    this.inspector.inspectorFront.nodePicker.on(
+    this.inspector.toolbox.nodePicker.on(
       "picker-started",
       this.onElementPickerStarted
     );
-    this.inspector.inspectorFront.nodePicker.on(
+    this.inspector.toolbox.nodePicker.on(
       "picker-stopped",
       this.onElementPickerStopped
     );
     this.inspector.toolbox.on("select", this.onSidebarSelectionChanged);
   }
 
   _getAnimationsFront() {
     if (this.animationsFrontPromise) {
@@ -178,21 +178,21 @@ class AnimationInspector {
     this.setAnimationStateChangedListenerEnabled(false);
     this.inspector.off("new-root", this.onNavigate);
     this.inspector.selection.off("new-node-front", this.update);
     this.inspector.sidebar.off("select", this.onSidebarSelectionChanged);
     this.inspector.toolbox.off(
       "inspector-sidebar-resized",
       this.onSidebarResized
     );
-    this.inspector.inspectorFront.nodePicker.off(
+    this.inspector.toolbox.nodePicker.off(
       "picker-started",
       this.onElementPickerStarted
     );
-    this.inspector.inspectorFront.nodePicker.off(
+    this.inspector.toolbox.nodePicker.off(
       "picker-stopped",
       this.onElementPickerStopped
     );
     this.inspector.toolbox.off("select", this.onSidebarSelectionChanged);
 
     this.animationsFrontPromise.then(front => {
       front.off("mutations", this.onAnimationsMutation);
     });
@@ -706,17 +706,17 @@ class AnimationInspector {
       this.win,
       this.onCurrentTimeTimerUpdated
     );
     currentTimeTimer.start();
     this.currentTimeTimer = currentTimeTimer;
   }
 
   toggleElementPicker() {
-    this.inspector.inspectorFront.nodePicker.togglePicker();
+    this.inspector.toolbox.nodePicker.togglePicker();
   }
 
   async update() {
     const done = this.inspector.updating("animationinspector");
 
     const selection = this.inspector.selection;
     const animationsFront = await this.animationsFrontPromise;
     const animations =
--- a/devtools/client/inspector/boxmodel/box-model.js
+++ b/devtools/client/inspector/boxmodel/box-model.js
@@ -248,17 +248,20 @@ BoxModel.prototype = {
    * geometry editor enabled state.
    */
   onHideGeometryEditor() {
     const { markup, selection, inspector } = this.inspector;
 
     this.highlighters.hideGeometryEditor();
     this.store.dispatch(updateGeometryEditorEnabled(false));
 
-    inspector.nodePicker.off("picker-started", this.onHideGeometryEditor);
+    inspector.toolbox.nodePicker.off(
+      "picker-started",
+      this.onHideGeometryEditor
+    );
     selection.off("new-node-front", this.onHideGeometryEditor);
     markup.off("leave", this.onMarkupViewLeave);
     markup.off("node-hover", this.onMarkupViewNodeHover);
   },
 
   /**
    * Handler function that re-shows the geometry editor for an element that already
    * had the geometry editor enabled. This handler function is called on a "leave" event
@@ -437,23 +440,29 @@ BoxModel.prototype = {
     const state = this.store.getState();
     const enabled = !state.boxModel.geometryEditorEnabled;
 
     this.highlighters.toggleGeometryHighlighter(nodeFront);
     this.store.dispatch(updateGeometryEditorEnabled(enabled));
 
     if (enabled) {
       // Hide completely the geometry editor if the picker is clicked or a new node front
-      inspector.nodePicker.on("picker-started", this.onHideGeometryEditor);
+      inspector.toolbox.nodePicker.on(
+        "picker-started",
+        this.onHideGeometryEditor
+      );
       selection.on("new-node-front", this.onHideGeometryEditor);
       // Temporary hide the geometry editor
       markup.on("leave", this.onMarkupViewLeave);
       markup.on("node-hover", this.onMarkupViewNodeHover);
     } else {
-      inspector.nodePicker.off("picker-started", this.onHideGeometryEditor);
+      inspector.toolbox.nodePicker.off(
+        "picker-started",
+        this.onHideGeometryEditor
+      );
       selection.off("new-node-front", this.onHideGeometryEditor);
       markup.off("leave", this.onMarkupViewLeave);
       markup.off("node-hover", this.onMarkupViewNodeHover);
     }
   },
 };
 
 module.exports = BoxModel;
--- a/devtools/client/inspector/boxmodel/test/head.js
+++ b/devtools/client/inspector/boxmodel/test/head.js
@@ -26,19 +26,17 @@ registerCleanupFunction(() => {
  * @param  {InspectorPanel} inspector
  *         The instance of InspectorPanel currently loaded in the toolbox.
  * @return {Promise} a promise that resolves when the inspector is updated with the new
  *         node.
  */
 async function selectAndHighlightNode(selectorOrNodeFront, inspector) {
   info("Highlighting and selecting the node " + selectorOrNodeFront);
   const nodeFront = await getNodeFront(selectorOrNodeFront, inspector);
-  const onHovered = inspector.inspectorFront.nodePicker.once(
-    "picker-node-hovered"
-  );
+  const onHovered = inspector.toolbox.nodePicker.once("picker-node-hovered");
   inspector.selection.setNodeFront(nodeFront, { reason: "test-highlight" });
   await onHovered;
 }
 
 /**
  * Is the given node visible in the page (rendered in the frame tree).
  * @param {DOMNode}
  * @return {Boolean}
--- a/devtools/client/inspector/markup/markup.js
+++ b/devtools/client/inspector/markup/markup.js
@@ -313,21 +313,21 @@ function MarkupView(inspector, frame, co
   this._elt.addEventListener("mouseout", this._onMouseOut);
   this._frame.addEventListener("focus", this._onFocus);
   this.inspector.selection.on("new-node-front", this._onNewSelection);
   this.walker.on("display-change", this._onWalkerNodeStatesChanged);
   this.walker.on("scrollable-change", this._onWalkerNodeStatesChanged);
   this.walker.on("mutations", this._mutationObserver);
   this.win.addEventListener("copy", this._onCopy);
   this.win.addEventListener("mouseup", this._onMouseUp);
-  this.inspector.inspectorFront.nodePicker.on(
+  this.inspector.toolbox.nodePicker.on(
     "picker-node-canceled",
     this._onToolboxPickerCanceled
   );
-  this.inspector.inspectorFront.nodePicker.on(
+  this.inspector.toolbox.nodePicker.on(
     "picker-node-hovered",
     this._onToolboxPickerHover
   );
 
   if (flags.testing) {
     // In tests, we start listening immediately to avoid having to simulate a mousemove.
     this._initTooltips();
   } else {
@@ -2264,17 +2264,17 @@ MarkupView.prototype = {
 
     this._elt.removeEventListener("blur", this._onBlur, true);
     this._elt.removeEventListener("click", this._onMouseClick);
     this._elt.removeEventListener("contextmenu", this._onContextMenu);
     this._elt.removeEventListener("mousemove", this._onMouseMove);
     this._elt.removeEventListener("mouseout", this._onMouseOut);
     this._frame.removeEventListener("focus", this._onFocus);
     this.inspector.selection.off("new-node-front", this._onNewSelection);
-    this.inspector.inspectorFront.nodePicker.off(
+    this.inspector.toolbox.nodePicker.off(
       "picker-node-hovered",
       this._onToolboxPickerHover
     );
     this.walker.off("display-change", this._onWalkerNodeStatesChanged);
     this.walker.off("scrollable-change", this._onWalkerNodeStatesChanged);
     this.walker.off("mutations", this._mutationObserver);
     this.win.removeEventListener("copy", this._onCopy);
     this.win.removeEventListener("mouseup", this._onMouseUp);
--- a/devtools/client/inspector/node-picker.js
+++ b/devtools/client/inspector/node-picker.js
@@ -133,9 +133,9 @@ class NodePicker extends EventEmitter {
    * When the picker is canceled, stop the picker, and make sure the toolbox
    * gets the focus.
    */
   _onCanceled() {
     return this.cancel();
   }
 }
 
-exports.NodePicker = NodePicker;
+module.exports = NodePicker;
--- a/devtools/client/inspector/rules/test/browser_rules_colorpicker-hides-element-picker.js
+++ b/devtools/client/inspector/rules/test/browser_rules_colorpicker-hides-element-picker.js
@@ -6,20 +6,18 @@
 // Tests that on selecting colorpicker eyedropper stops picker
 // if the picker is already selected.
 
 const TEST_URI = `<style>body{background:red}</style>`;
 
 add_task(async function() {
   await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
 
-  const { inspector, toolbox, view } = await openRuleView();
-  const pickerStopped = inspector.inspectorFront.nodePicker.once(
-    "picker-stopped"
-  );
+  const { toolbox, view } = await openRuleView();
+  const pickerStopped = toolbox.nodePicker.once("picker-stopped");
 
   await startPicker(toolbox);
 
   info("Get the background property from the rule-view");
   const property = getRuleViewProperty(view, "body", "background");
   const swatch = property.valueSpan.querySelector(".ruleview-colorswatch");
   ok(swatch, "Color swatch is displayed for the background property");
 
--- a/devtools/client/inspector/test/browser_inspector_highlighter-03.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-03.js
@@ -61,21 +61,21 @@ add_task(async function() {
 
   ok(
     await testActor.assertHighlightedNode(iframeBodySelector),
     "highlighter shows the right node"
   );
   await testActor.isNodeCorrectlyHighlighted(iframeBodySelector, is);
 
   info("Waiting for the element picker to deactivate.");
-  await inspector.inspectorFront.nodePicker.stop();
+  await toolbox.nodePicker.stop();
 
   function moveMouseOver(selector, x, y) {
     info("Waiting for element " + selector + " to be highlighted");
     testActor.synthesizeMouse({
       selector,
       x,
       y,
       options: { type: "mousemove" },
     });
-    return inspector.inspectorFront.nodePicker.once("picker-node-hovered");
+    return toolbox.nodePicker.once("picker-node-hovered");
   }
 });
--- a/devtools/client/inspector/test/browser_inspector_highlighter-07.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-07.js
@@ -90,11 +90,11 @@ add_task(async function() {
   function moveMouseOver(selector, x, y) {
     info("Waiting for element " + selector + " to be highlighted");
     testActor.synthesizeMouse({
       selector,
       x,
       y,
       options: { type: "mousemove" },
     });
-    return inspector.inspectorFront.nodePicker.once("picker-node-hovered");
+    return toolbox.nodePicker.once("picker-node-hovered");
   }
 });
--- a/devtools/client/inspector/test/browser_inspector_highlighter-cancel.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-cancel.js
@@ -34,17 +34,17 @@ add_task(async function() {
   ok(
     isSelectedMarkupNodeInView(),
     "The currently selected node is focused back on the screen."
   );
 
   function cancelPickerByShortcut() {
     info("Key pressed. Waiting for picker to be canceled.");
     testActor.synthesizeKey({ key: "VK_ESCAPE", options: {} });
-    return inspector.inspectorFront.nodePicker.once("picker-node-canceled");
+    return toolbox.nodePicker.once("picker-node-canceled");
   }
 
   function moveMouseOver(selector) {
     info(`Waiting for element ${selector} to be hovered in the markup view`);
     testActor.synthesizeMouse({
       options: { type: "mousemove" },
       center: true,
       selector: selector,
--- a/devtools/client/inspector/test/browser_inspector_highlighter-iframes_01.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-iframes_01.js
@@ -21,17 +21,17 @@ const OUTER_FRAME_SRC =
 const TEST_URI =
   "data:text/html;charset=utf-8," +
   "iframe tests for inspector" +
   '<iframe src="' +
   OUTER_FRAME_SRC +
   '" />';
 
 add_task(async function() {
-  const { inspector, testActor } = await openInspectorForURL(TEST_URI);
+  const { toolbox, inspector, testActor } = await openInspectorForURL(TEST_URI);
   const outerFrameDiv = ["iframe", "div"];
   const innerFrameDiv = ["iframe", "iframe", "div"];
 
   info("Waiting for element picker to activate.");
   await startPicker(inspector.toolbox);
 
   info("Moving mouse over outerFrameDiv");
   await moveMouseOver(outerFrameDiv);
@@ -65,23 +65,21 @@ add_task(async function() {
 
   is(
     inspector.breadcrumbs.nodeHierarchy.length,
     9,
     "Breadcrumbs have 9 items."
   );
 
   info("Waiting for element picker to deactivate.");
-  await inspector.inspectorFront.nodePicker.stop();
+  await toolbox.nodePicker.stop();
 
   function moveMouseOver(selector) {
     info("Waiting for element " + selector + " to be highlighted");
     testActor
       .synthesizeMouse({
         selector: selector,
         options: { type: "mousemove" },
         center: true,
       })
-      .then(() =>
-        inspector.inspectorFront.nodePicker.once("picker-node-hovered")
-      );
+      .then(() => toolbox.nodePicker.once("picker-node-hovered"));
   }
 });
--- a/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_01.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_01.js
@@ -4,18 +4,17 @@
 
 "use strict";
 
 // Test that the keybindings for Picker work alright
 
 const TEST_URL = URL_ROOT + "doc_inspector_highlighter_dom.html";
 
 add_task(async function() {
-  const { inspector, toolbox, testActor } = await openInspectorForURL(TEST_URL);
-  const { inspectorFront } = inspector;
+  const { toolbox, testActor } = await openInspectorForURL(TEST_URL);
 
   await startPicker(toolbox);
 
   info("Selecting the simple-div1 DIV");
   await moveMouseOver("#simple-div1");
 
   ok(
     await testActor.assertHighlightedNode("#simple-div1"),
@@ -50,26 +49,26 @@ add_task(async function() {
   ok(
     await testActor.assertHighlightedNode("#simple-div1"),
     "The highlighter shows #simple-div1. OK."
   );
 
   info("First child selection test Passed.");
 
   info("Stopping the picker");
-  await inspectorFront.nodePicker.stop();
+  await toolbox.nodePicker.stop();
 
   function doKeyHover(args) {
     info("Key pressed. Waiting for element to be highlighted/hovered");
     testActor.synthesizeKey(args);
-    return inspectorFront.nodePicker.once("picker-node-hovered");
+    return toolbox.nodePicker.once("picker-node-hovered");
   }
 
   function moveMouseOver(selector) {
     info("Waiting for element " + selector + " to be highlighted");
     testActor.synthesizeMouse({
       options: { type: "mousemove" },
       center: true,
       selector: selector,
     });
-    return inspectorFront.nodePicker.once("picker-node-hovered");
+    return toolbox.nodePicker.once("picker-node-hovered");
   }
 });
--- a/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_02.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_02.js
@@ -4,18 +4,17 @@
 
 "use strict";
 
 // Test that the keybindings for Picker work alright
 
 const TEST_URL = URL_ROOT + "doc_inspector_highlighter_dom.html";
 
 add_task(async function() {
-  const { inspector, toolbox, testActor } = await openInspectorForURL(TEST_URL);
-  const { inspectorFront } = inspector;
+  const { toolbox, testActor } = await openInspectorForURL(TEST_URL);
 
   await startPicker(toolbox);
 
   // Previously chosen child memory
   info("Testing whether previously chosen child is remembered");
 
   info("Selecting the ahoy paragraph DIV");
   await moveMouseOver("#ahoy");
@@ -44,32 +43,28 @@ add_task(async function() {
   ok(
     await testActor.assertHighlightedNode("#simple-div2"),
     "The highlighter shows #simple-div2. OK."
   );
 
   info("Previously chosen child is remembered. Passed.");
 
   info("Stopping the picker");
-  await inspectorFront.nodePicker.stop();
+  await toolbox.nodePicker.stop();
 
   function doKeyHover(args) {
     info("Key pressed. Waiting for element to be highlighted/hovered");
-    const onPickerNodeHovered = inspectorFront.nodePicker.once(
-      "picker-node-hovered"
-    );
+    const onPickerNodeHovered = toolbox.nodePicker.once("picker-node-hovered");
     testActor.synthesizeKey(args);
     return onPickerNodeHovered;
   }
 
   function moveMouseOver(selector) {
     info("Waiting for element " + selector + " to be highlighted");
-    const onPickerNodeHovered = inspectorFront.nodePicker.once(
-      "picker-node-hovered"
-    );
+    const onPickerNodeHovered = toolbox.nodePicker.once("picker-node-hovered");
     testActor.synthesizeMouse({
       options: { type: "mousemove" },
       center: true,
       selector: selector,
     });
     return onPickerNodeHovered;
   }
 });
--- a/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_03.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_03.js
@@ -52,31 +52,29 @@ add_task(async function() {
   );
 
   function doKeyPick(args) {
     info("Key pressed. Waiting for element to be picked");
     testActor.synthesizeKey(args);
     return promise.all([
       inspector.selection.once("new-node-front"),
       inspector.once("inspector-updated"),
-      inspector.inspectorFront.nodePicker.once("picker-stopped"),
+      toolbox.nodePicker.once("picker-stopped"),
     ]);
   }
 
   function doKeyStop(args) {
     info("Key pressed. Waiting for picker to be canceled");
     testActor.synthesizeKey(args);
-    return inspector.inspectorFront.nodePicker.once("picker-stopped");
+    return toolbox.nodePicker.once("picker-stopped");
   }
 
   function moveMouseOver(selector) {
     info("Waiting for element " + selector + " to be highlighted");
-    const onPickerNodeHovered = inspector.inspectorFront.nodePicker.once(
-      "picker-node-hovered"
-    );
+    const onPickerNodeHovered = toolbox.nodePicker.once("picker-node-hovered");
     testActor.synthesizeMouse({
       options: { type: "mousemove" },
       center: true,
       selector: selector,
     });
     return onPickerNodeHovered;
   }
 });
--- a/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_04.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-keybinding_04.js
@@ -6,33 +6,30 @@
 
 // Tests that pressing ESC twice while in picker mode first stops the picker and
 // then opens the split-console (see bug 988278).
 
 const TEST_URL = "data:text/html;charset=utf8,<div></div>";
 
 add_task(async function() {
   const { inspector, toolbox, testActor } = await openInspectorForURL(TEST_URL);
-  const { inspectorFront } = inspector;
 
   await startPicker(toolbox);
 
   info("Start using the picker by hovering over nodes");
-  const onHover = inspectorFront.nodePicker.once("picker-node-hovered");
+  const onHover = toolbox.nodePicker.once("picker-node-hovered");
   testActor.synthesizeMouse({
     options: { type: "mousemove" },
     center: true,
     selector: "div",
   });
   await onHover;
 
   info("Press escape and wait for the picker to stop");
-  const onPickerStopped = inspectorFront.nodePicker.once(
-    "picker-node-canceled"
-  );
+  const onPickerStopped = toolbox.nodePicker.once("picker-node-canceled");
   testActor.synthesizeKey({
     key: "VK_ESCAPE",
     options: {},
   });
   await onPickerStopped;
 
   info("Press escape again and wait for the split console to open");
   const onSplitConsole = toolbox.once("split-console");
--- a/devtools/client/inspector/test/browser_inspector_highlighter-xbl.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-xbl.js
@@ -32,11 +32,11 @@ add_task(async function() {
 
   function moveMouseOver(selector) {
     info("Waiting for element " + selector + " to be highlighted");
     testActor.synthesizeMouse({
       options: { type: "mousemove" },
       center: true,
       selector: selector,
     });
-    return inspector.inspectorFront.nodePicker.once("picker-node-hovered");
+    return toolbox.nodePicker.once("picker-node-hovered");
   }
 });
--- a/devtools/client/inspector/test/browser_inspector_iframe-navigation.js
+++ b/devtools/client/inspector/test/browser_inspector_iframe-navigation.js
@@ -7,26 +7,23 @@
 // navigations.
 
 const TEST_URI =
   "data:text/html;charset=utf-8," +
   "<p>bug 699308 - test iframe navigation</p>" +
   "<iframe src='data:text/html;charset=utf-8,hello world'></iframe>";
 
 add_task(async function() {
-  const { inspector, toolbox, testActor } = await openInspectorForURL(TEST_URI);
-  const { inspectorFront } = inspector;
+  const { toolbox, testActor } = await openInspectorForURL(TEST_URI);
 
   info("Starting element picker.");
   await startPicker(toolbox);
 
   info("Waiting for body to be hovered.");
-  const onHovered = inspector.inspectorFront.nodePicker.once(
-    "picker-node-hovered"
-  );
+  const onHovered = toolbox.nodePicker.once("picker-node-hovered");
   testActor.synthesizeMouse({
     selector: "body",
     options: { type: "mousemove" },
     x: 1,
     y: 1,
   });
   await onHovered;
 
@@ -38,10 +35,10 @@ add_task(async function() {
 
   await testActor.reloadFrame("iframe");
   info("Frame reloaded twice.");
 
   isVisible = await testActor.isHighlighting();
   ok(isVisible, "Inspector is highlighting after iframe nav.");
 
   info("Stopping element picker.");
-  await inspectorFront.nodePicker.stop();
+  await toolbox.nodePicker.stop();
 });
--- a/devtools/client/inspector/test/browser_inspector_picker-stop-on-tool-change.js
+++ b/devtools/client/inspector/test/browser_inspector_picker-stop-on-tool-change.js
@@ -7,19 +7,18 @@
 // Test that the highlighter's picker is stopped when a different tool is
 // selected
 
 const TEST_URI =
   "data:text/html;charset=UTF-8," +
   "testing the highlighter goes away on tool selection";
 
 add_task(async function() {
-  const { inspector, toolbox } = await openInspectorForURL(TEST_URI);
-  const { inspectorFront } = inspector;
-  const pickerStopped = inspectorFront.nodePicker.once("picker-stopped");
+  const { toolbox } = await openInspectorForURL(TEST_URI);
+  const pickerStopped = toolbox.nodePicker.once("picker-stopped");
 
   info("Starting the inspector picker");
   await startPicker(toolbox);
 
   info("Selecting another tool than the inspector in the toolbox");
   await toolbox.selectNextTool();
 
   info("Waiting for the picker-stopped event to be fired");
--- a/devtools/client/inspector/test/browser_inspector_switch-to-inspector-on-pick.js
+++ b/devtools/client/inspector/test/browser_inspector_switch-to-inspector-on-pick.js
@@ -58,22 +58,21 @@ add_task(async function() {
   Services.telemetry.clearEvents();
 
   // Ensure no events have been logged
   const snapshot = Services.telemetry.snapshotEvents(ALL_CHANNELS, true);
   ok(!snapshot.parent, "No events have been logged for the main process");
 
   const tab = await addTab(TEST_URI);
   const toolbox = await openToolbox(tab);
-  const inspectorFront = await toolbox.target.getFront("inspector");
 
   await startPickerAndAssertSwitchToInspector(toolbox);
 
   info("Stoppping element picker.");
-  await inspectorFront.nodePicker.stop();
+  await toolbox.nodePicker.stop();
 
   checkResults();
 });
 
 async function openToolbox(tab) {
   info("Opening webconsole.");
   const target = await TargetFactory.forTab(tab);
   return gDevTools.showToolbox(target, "webconsole");
--- a/devtools/client/inspector/test/head.js
+++ b/devtools/client/inspector/test/head.js
@@ -69,21 +69,19 @@ var navigateTo = async function(inspecto
 };
 
 /**
  * Start the element picker and focus the content window.
  * @param {Toolbox} toolbox
  * @param {Boolean} skipFocus - Allow tests to bypass the focus event.
  */
 var startPicker = async function(toolbox, skipFocus) {
-  const inspectorFront = await toolbox.target.getFront("inspector");
-
   info("Start the element picker");
   toolbox.win.focus();
-  await inspectorFront.nodePicker.start();
+  await toolbox.nodePicker.start();
   if (!skipFocus) {
     // By default make sure the content window is focused since the picker may not focus
     // the content window by default.
     await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
       content.focus();
     });
   }
 };
@@ -126,19 +124,17 @@ function pickElement(inspector, testActo
  *        X-offset from the top-left corner of the element matching the provided selector
  * @param {Number} y
  *        Y-offset from the top-left corner of the element matching the provided selector
  * @return {Promise} promise that resolves when the "picker-node-hovered" event is
  *         emitted.
  */
 function hoverElement(inspector, testActor, selector, x, y) {
   info("Waiting for element " + selector + " to be hovered");
-  const onHovered = inspector.inspectorFront.nodePicker.once(
-    "picker-node-hovered"
-  );
+  const onHovered = inspector.toolbox.nodePicker.once("picker-node-hovered");
   testActor.synthesizeMouse({ selector, x, y, options: { type: "mousemove" } });
   return onHovered;
 }
 
 /**
  * Highlight a node and set the inspector's current selection to the node or
  * the first match of the given css selector.
  * @param {String|NodeFront} selector
--- a/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js
+++ b/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js
@@ -234,17 +234,17 @@ class SwatchColorPickerTooltip extends S
   _openEyeDropper() {
     const { inspectorFront, toolbox, telemetry } = this.inspector;
 
     telemetry
       .getHistogramById(TELEMETRY_PICKER_EYEDROPPER_OPEN_COUNT)
       .add(true);
 
     // cancelling picker(if it is already selected) on opening eye-dropper
-    inspectorFront.nodePicker.cancel();
+    toolbox.nodePicker.cancel();
 
     // pickColorFromPage will focus the content document. If the devtools are in a
     // separate window, the colorpicker tooltip will be closed before pickColorFromPage
     // resolves. Flip the flag early to avoid issues with onTooltipHidden().
     this.eyedropperOpen = true;
 
     inspectorFront.pickColorFromPage({ copyOnSelect: false }).then(() => {
       // close the colorpicker tooltip so that only the eyedropper is open.
--- a/devtools/client/webconsole/test/browser/head.js
+++ b/devtools/client/webconsole/test/browser/head.js
@@ -1131,26 +1131,25 @@ function isReverseSearchInputFocused(hud
  *
  * @param {Object} toolbox
  * @param {Object} testActor: A test actor registered on the target. Needed to click on
  *                            the content element.
  * @param {String} selector: The selector for the node we want to select.
  */
 async function selectNodeWithPicker(toolbox, testActor, selector) {
   const inspector = toolbox.getPanel("inspector");
-  const inspectorFront = inspector.inspectorFront;
 
-  const onPickerStarted = inspectorFront.nodePicker.once("picker-started");
-  inspectorFront.nodePicker.start();
+  const onPickerStarted = toolbox.nodePicker.once("picker-started");
+  toolbox.nodePicker.start();
   await onPickerStarted;
 
   info(
     `Picker mode started, now clicking on "${selector}" to select that node`
   );
-  const onPickerStopped = inspectorFront.nodePicker.once("picker-stopped");
+  const onPickerStopped = toolbox.nodePicker.once("picker-stopped");
   const onInspectorUpdated = inspector.once("inspector-updated");
 
   testActor.synthesizeMouse({
     selector,
     center: true,
     options: {},
   });
 
--- a/devtools/client/webreplay/mochitest/browser_rr_inspector-02.js
+++ b/devtools/client/webreplay/mochitest/browser_rr_inspector-02.js
@@ -19,21 +19,21 @@ add_task(async function() {
 
   await threadFront.interrupt();
   await threadFront.resume();
 
   await threadFront.interrupt();
   const bp = await setBreakpoint(threadFront, "doc_inspector_basic.html", 9);
   await rewindToLine(threadFront, 9);
 
-  const { inspector, testActor } = await openInspector();
+  const { testActor } = await openInspector();
 
   info("Waiting for element picker to become active.");
   toolbox.win.focus();
-  await inspector.inspectorFront.nodePicker.start();
+  await toolbox.nodePicker.start();
 
   info("Moving mouse over div.");
   await moveMouseOver("#maindiv", 1, 1);
 
   // Checks in isNodeCorrectlyHighlighted are off for an unknown reason, even
   // though the highlighting appears correctly in the UI.
   info("Performing checks");
   await testActor.isNodeCorrectlyHighlighted("#maindiv", is);
@@ -44,11 +44,11 @@ add_task(async function() {
   function moveMouseOver(selector, x, y) {
     info("Waiting for element " + selector + " to be highlighted");
     testActor.synthesizeMouse({
       selector,
       x,
       y,
       options: { type: "mousemove" },
     });
-    return inspector.inspectorFront.nodePicker.once("picker-node-hovered");
+    return toolbox.nodePicker.once("picker-node-hovered");
   }
 });
--- a/devtools/shared/fronts/inspector.js
+++ b/devtools/shared/fronts/inspector.js
@@ -2,17 +2,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const Services = require("Services");
 const defer = require("devtools/shared/defer");
 const Telemetry = require("devtools/client/shared/telemetry");
-const { NodePicker } = require("devtools/client/inspector/node-picker");
 const {
   FrontClassWithSpec,
   types,
   registerFront,
 } = require("devtools/shared/protocol.js");
 const {
   inspectorSpec,
   walkerSpec,
@@ -485,17 +484,16 @@ class InspectorFront extends FrontClassW
 
     // Attribute name from which to retrieve the actorID out of the target actor's form
     this.formAttributeName = "inspectorActor";
   }
 
   // async initialization
   async initialize() {
     await Promise.all([this._getWalker(), this._getHighlighter()]);
-    this.nodePicker = new NodePicker(this.highlighter, this.walker);
   }
 
   async _getWalker() {
     const showAllAnonymousContent = Services.prefs.getBoolPref(
       SHOW_ALL_ANONYMOUS_CONTENT_PREF
     );
     const showUserAgentShadowRoots = Services.prefs.getBoolPref(
       SHOW_UA_SHADOW_ROOTS_PREF