Bug 1568825 - 3 - Remove the nodePicker's dependency on highlighter and walker r=gl
authorPatrick Brosset <pbrosset@mozilla.com>
Fri, 16 Aug 2019 04:48:27 +0000
changeset 488433 e1193c2352a11eff6302aa2689894dac6b772cc5
parent 488432 36627f38d627e5fb3498aa7bfba482e60f927a4a
child 488434 a7ac9f64f6ea3fd6faf7263c18f20c7dae9d20ec
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 - 3 - Remove the nodePicker's dependency on highlighter and walker r=gl Differential Revision: https://phabricator.services.mozilla.com/D41598
devtools/client/framework/toolbox.js
devtools/client/inspector/node-picker.js
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -3323,21 +3323,17 @@ 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.nodePicker = new NodePicker(
-          this._highlighter,
-          this._walker,
-          this.selection
-        );
+        this.nodePicker = new NodePicker(this.target, this.selection);
 
         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);
--- a/devtools/client/inspector/node-picker.js
+++ b/devtools/client/inspector/node-picker.js
@@ -12,123 +12,165 @@ loader.lazyRequireGetter(this, "EventEmi
  */
 
 /**
  * Get the NodePicker instance for an inspector front.
  * The NodePicker wraps the highlighter so that it can interact with the
  * walkerFront and selection api. The nodeFront is stateless, with the
  * HighlighterFront managing it's own state.
  *
- * @param {highlighter} highlighterFront
- * @param {walker} walkerFront
- * @return {Object} the NodePicker public API
+ * @param {Target} target
+ *        The target the toolbox will debug
+ * @param {Selection} selection
+ *        The global Selection object
  */
 class NodePicker extends EventEmitter {
-  constructor(highlighter, walker) {
+  constructor(target, selection) {
     super();
-    this.highlighter = highlighter;
-    this.walker = walker;
+
+    this.target = target;
+    this.selection = selection;
+
+    // Whether or not the node picker is active.
+    this.isPicking = false;
+
+    // The list of inspector fronts corresponding to the frames where picking happens.
+    this._currentInspectorFronts = [];
 
     this.cancel = this.cancel.bind(this);
     this.start = this.start.bind(this);
     this.stop = this.stop.bind(this);
     this.togglePicker = this.togglePicker.bind(this);
 
     this._onHovered = this._onHovered.bind(this);
     this._onPicked = this._onPicked.bind(this);
     this._onPreviewed = this._onPreviewed.bind(this);
     this._onCanceled = this._onCanceled.bind(this);
   }
 
   /**
+   * Get all of the InspectorFront instances corresponding to the frames where the node
+   * picking should occur.
+   *
+   * @return {Array<InspectorFront>}
+   *         The list of InspectorFront instances
+   */
+  async getAllInspectorFronts() {
+    // TODO: For Fission, we should list all remote frames here.
+    // TODO: For the Browser Toolbox, we should list all remote browsers here.
+    // TODO: For now we just return a single item in the array.
+    const inspectorFront = await this.target.getFront("inspector");
+    return [inspectorFront];
+  }
+
+  /**
    * Start/stop the element picker on the debuggee target.
-   * @param {Boolean} doFocus - Optionally focus the content area once the picker is
-   *                            activated.
+   *
+   * @param {Boolean} doFocus
+   *        Optionally focus the content area once the picker is activated.
    * @return Promise that resolves when done
    */
   togglePicker(doFocus) {
-    if (this.highlighter.isPicking) {
+    if (this.isPicking) {
       return this.stop();
     }
     return this.start(doFocus);
   }
 
   /**
    * Start the element picker on the debuggee target.
    * This will request the inspector actor to start listening for mouse events
    * on the target page to highlight the hovered/picked element.
    * Depending on the server-side capabilities, this may fire events when nodes
    * are hovered.
-   * @param {Boolean} doFocus - Optionally focus the content area once the picker is
-   *                            activated.
-   * @return Promise that resolves when the picker has started or immediately
-   * if it is already started
+   *
+   * @param {Boolean} doFocus
+   *        Optionally focus the content area once the picker is activated.
    */
   async start(doFocus) {
-    if (this.highlighter.isPicking) {
-      return null;
+    if (this.isPicking) {
+      return;
     }
+    this.isPicking = true;
+
     this.emit("picker-starting");
-    this.walker.on("picker-node-hovered", this._onHovered);
-    this.walker.on("picker-node-picked", this._onPicked);
-    this.walker.on("picker-node-previewed", this._onPreviewed);
-    this.walker.on("picker-node-canceled", this._onCanceled);
+
+    this._currentInspectorFronts = await this.getAllInspectorFronts();
 
-    const picked = await this.highlighter.pick(doFocus);
+    for (const { walker, highlighter } of this._currentInspectorFronts) {
+      walker.on("picker-node-hovered", this._onHovered);
+      walker.on("picker-node-picked", this._onPicked);
+      walker.on("picker-node-previewed", this._onPreviewed);
+      walker.on("picker-node-canceled", this._onCanceled);
+
+      await highlighter.pick(doFocus);
+    }
+
     this.emit("picker-started");
-    return picked;
   }
 
   /**
    * Stop the element picker. Note that the picker is automatically stopped when
-   * an element is picked
-   * @return Promise that resolves when the picker has stopped or immediately
-   * if it is already stopped
+   * an element is picked.
    */
   async stop() {
-    if (!this.highlighter.isPicking) {
+    if (!this.isPicking) {
       return;
     }
-    await this.highlighter.cancelPick();
-    this.walker.off("picker-node-hovered", this._onHovered);
-    this.walker.off("picker-node-picked", this._onPicked);
-    this.walker.off("picker-node-previewed", this._onPreviewed);
-    this.walker.off("picker-node-canceled", this._onCanceled);
+    this.isPicking = false;
+
+    for (const { walker, highlighter } of this._currentInspectorFronts) {
+      await highlighter.cancelPick();
+
+      walker.off("picker-node-hovered", this._onHovered);
+      walker.off("picker-node-picked", this._onPicked);
+      walker.off("picker-node-previewed", this._onPreviewed);
+      walker.off("picker-node-canceled", this._onCanceled);
+    }
+
+    this._currentInspectorFronts = [];
+
     this.emit("picker-stopped");
   }
 
   /**
    * Stop the picker, but also emit an event that the picker was canceled.
    */
   async cancel() {
     await this.stop();
     this.emit("picker-node-canceled");
   }
 
   /**
    * When a node is hovered by the mouse when the highlighter is in picker mode
-   * @param {Object} data Information about the node being hovered
+   *
+   * @param {Object} data
+   *        Information about the node being hovered
    */
   _onHovered(data) {
     this.emit("picker-node-hovered", data.node);
   }
 
   /**
    * When a node has been picked while the highlighter is in picker mode
-   * @param {Object} data Information about the picked node
+   *
+   * @param {Object} data
+   *        Information about the picked node
    */
   _onPicked(data) {
     this.emit("picker-node-picked", data.node);
     return this.stop();
   }
 
   /**
    * When a node has been shift-clicked (previewed) while the highlighter is in
    * picker mode
-   * @param {Object} data Information about the picked node
+   *
+   * @param {Object} data
+   *        Information about the picked node
    */
   _onPreviewed(data) {
     this.emit("picker-node-previewed", data.node);
   }
 
   /**
    * When the picker is canceled, stop the picker, and make sure the toolbox
    * gets the focus.