Bug 1341304 - Emit "selection-changed" event on the DevTools toolbox object. r=jdescottes,ochameau
authorLuca Greco <lgreco@mozilla.com>
Thu, 06 Jul 2017 19:47:21 +0200
changeset 418131 bf290e0676b5a16a6851369327fbc4cb1ad686d3
parent 418130 299ca152f01a7725e8eda4c818a6370543f9d729
child 418132 2fb0f93b7b5bc9880f57534673f0e27c6b5a789e
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes, ochameau
bugs1341304
milestone56.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 1341304 - Emit "selection-changed" event on the DevTools toolbox object. r=jdescottes,ochameau MozReview-Commit-ID: G2jRxqDH9wx
devtools/client/framework/test/browser.ini
devtools/client/framework/test/browser_toolbox_selectionchanged_event.js
devtools/client/framework/toolbox.js
--- a/devtools/client/framework/test/browser.ini
+++ b/devtools/client/framework/test/browser.ini
@@ -86,16 +86,17 @@ skip-if = true # Bug 1177463 - Temporari
 # skip-if = os == "win"
 [browser_toolbox_races.js]
 [browser_toolbox_ready.js]
 [browser_toolbox_remoteness_change.js]
 run-if = e10s
 [browser_toolbox_select_event.js]
 skip-if = e10s # Bug 1069044 - destroyInspector may hang during shutdown
 [browser_toolbox_selected_tool_unavailable.js]
+[browser_toolbox_selectionchanged_event.js]
 [browser_toolbox_sidebar.js]
 [browser_toolbox_sidebar_events.js]
 [browser_toolbox_sidebar_existing_tabs.js]
 [browser_toolbox_sidebar_overflow_menu.js]
 [browser_toolbox_split_console.js]
 [browser_toolbox_target.js]
 [browser_toolbox_tabsswitch_shortcuts.js]
 [browser_toolbox_textbox_context_menu.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/framework/test/browser_toolbox_selectionchanged_event.js
@@ -0,0 +1,41 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const PAGE_URL = "data:text/html;charset=utf-8,<body><div></div></body>";
+
+add_task(function* () {
+  let tab = yield addTab(PAGE_URL);
+  let toolbox = yield openToolboxForTab(tab, "inspector", "bottom");
+  let inspector = toolbox.getCurrentPanel();
+
+  let root = yield inspector.walker.getRootNode();
+  let body = yield inspector.walker.querySelector(root, "body");
+  let node = yield inspector.walker.querySelector(root, "div");
+
+  is(inspector.selection.nodeFront, body, "Body is selected by default");
+
+  // Listen to selection changed
+  let onSelectionChanged = toolbox.once("selection-changed");
+
+  info("Select the div and wait for the selection-changed event to be fired.");
+  inspector.selection.setNodeFront(node, "browser-context-menu");
+
+  yield onSelectionChanged;
+
+  is(inspector.selection.nodeFront, node, "Div is now selected");
+
+  // Listen to cleared selection changed
+  let onClearSelectionChanged = toolbox.once("selection-changed");
+
+  info("Clear the selection and wait for the selection-changed event to be fired.");
+  inspector.selection.setNodeFront(undefined, "browser-context-menu");
+
+  yield onClearSelectionChanged;
+
+  is(inspector.selection.nodeFront, undefined, "The selection is undefined as expected");
+});
+
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -132,16 +132,17 @@ function Toolbox(target, selectedTool, h
   this._toggleMinimizeMode = this._toggleMinimizeMode.bind(this);
   this._onToolbarFocus = this._onToolbarFocus.bind(this);
   this._onToolbarArrowKeypress = this._onToolbarArrowKeypress.bind(this);
   this._onPickerClick = this._onPickerClick.bind(this);
   this._onPickerKeypress = this._onPickerKeypress.bind(this);
   this._onPickerStarted = this._onPickerStarted.bind(this);
   this._onPickerStopped = this._onPickerStopped.bind(this);
   this._onInspectObject = this._onInspectObject.bind(this);
+  this._onNewSelectedNodeFront = this._onNewSelectedNodeFront.bind(this);
   this.selectTool = this.selectTool.bind(this);
 
   this._target.on("close", this.destroy);
 
   if (!selectedTool) {
     selectedTool = Services.prefs.getCharPref(this._prefs.LAST_TOOL);
   }
   this._defaultToolId = selectedTool;
@@ -2214,29 +2215,37 @@ Toolbox.prototype = {
   initInspector: function () {
     if (!this._initInspector) {
       this._initInspector = Task.spawn(function* () {
         this._inspector = InspectorFront(this._target.client, this._target.form);
         let pref = "devtools.inspector.showAllAnonymousContent";
         let showAllAnonymousContent = Services.prefs.getBoolPref(pref);
         this._walker = yield this._inspector.getWalker({ showAllAnonymousContent });
         this._selection = new Selection(this._walker);
+        this._selection.on("new-node-front", this._onNewSelectedNodeFront);
 
         if (this.highlighterUtils.isRemoteHighlightable()) {
           this.walker.on("highlighter-ready", this._highlighterReady);
           this.walker.on("highlighter-hide", this._highlighterHidden);
 
           let autohide = !flags.testing;
           this._highlighter = yield this._inspector.getHighlighter(autohide);
         }
       }.bind(this));
     }
     return this._initInspector;
   },
 
+  _onNewSelectedNodeFront: function (evt) {
+    // 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");
+  },
+
   _onInspectObject: function (evt, packet) {
     this.inspectObjectActor(packet.objectActor, packet.inspectFromAnnotation);
   },
 
   inspectObjectActor: async function (objectActor, inspectFromAnnotation) {
     if (objectActor.preview &&
         objectActor.preview.nodeType === domNodeConstants.ELEMENT_NODE) {
       // Open the inspector and select the DOM Element.
@@ -2298,16 +2307,17 @@ Toolbox.prototype = {
         // proceed with the rest of destruction if it fails.
         // FF42+ now does the cleanup from the actor.
         if (!this.highlighter.traits.autoHideOnDestroy) {
           this.highlighterUtils.unhighlight();
         }
         yield this._highlighter.destroy();
       }
       if (this._selection) {
+        this._selection.off("new-node-front", this._onNewSelectedNodeFront);
         this._selection.destroy();
       }
 
       if (this.walker) {
         this.walker.off("highlighter-ready", this._highlighterReady);
         this.walker.off("highlighter-hide", this._highlighterHidden);
       }