Bug 1245287 - Add toolbox API for isToolRegistered and events for tool-registered and tool-unregistered;r=jryans draft
authorBrian Grinstead <bgrinstead@mozilla.com>
Tue, 02 Feb 2016 14:33:14 -0800
changeset 328333 a7c8837a2cf3509d498b2c5a17bbad9427c7d7de
parent 328302 1b290ea60421e25cb0942e85c4975975815d2a27
child 513801 d425199d0f9f42de1361b56d88c5a42ae49e8b5c
push id10344
push userbgrinstead@mozilla.com
push dateTue, 02 Feb 2016 22:33:23 +0000
reviewersjryans
bugs1245287
milestone47.0a1
Bug 1245287 - Add toolbox API for isToolRegistered and events for tool-registered and tool-unregistered;r=jryans
devtools/client/framework/test/browser_devtools_api.js
devtools/client/framework/toolbox.js
--- a/devtools/client/framework/test/browser_devtools_api.js
+++ b/devtools/client/framework/test/browser_devtools_api.js
@@ -34,21 +34,21 @@ function runTests1(aTab) {
     label: "someLabel",
     build: function(iframeWindow, toolbox) {
       let panel = new DevToolPanel(iframeWindow, toolbox);
       return panel.open();
     },
   };
 
   ok(gDevTools, "gDevTools exists");
-  is(gDevTools.getToolDefinitionMap().has(toolId1), false,
+  ok(!gDevTools.getToolDefinitionMap().has(toolId1),
     "The tool is not registered");
 
   gDevTools.registerTool(toolDefinition);
-  is(gDevTools.getToolDefinitionMap().has(toolId1), true,
+  ok(gDevTools.getToolDefinitionMap().has(toolId1),
     "The tool is registered");
 
   let target = TargetFactory.forTab(gBrowser.selectedTab);
 
   let events = {};
 
   // Check events on the gDevTools and toolbox objects.
   gDevTools.once(toolId1 + "-init", (event, toolbox, iframe) => {
@@ -93,21 +93,21 @@ function runTests2() {
     visibilityswitch: "devtools.test-tool.enabled",
     url: "about:blank",
     label: "someLabel",
     build: function(iframeWindow, toolbox) {
       return new DevToolPanel(iframeWindow, toolbox);
     },
   };
 
-  is(gDevTools.getToolDefinitionMap().has(toolId2), false,
+  ok(!gDevTools.getToolDefinitionMap().has(toolId2),
     "The tool is not registered");
 
   gDevTools.registerTool(toolDefinition);
-  is(gDevTools.getToolDefinitionMap().has(toolId2), true,
+  ok(gDevTools.getToolDefinitionMap().has(toolId2),
     "The tool is registered");
 
   let target = TargetFactory.forTab(gBrowser.selectedTab);
 
   let events = {};
 
   // Check events on the gDevTools and toolbox objects.
   gDevTools.once(toolId2 + "-init", (event, toolbox, iframe) => {
@@ -144,45 +144,63 @@ function runTests2() {
     ok(events["init"], "init event fired");
     ok(events["build"], "build event fired");
     ok(events["ready"], "ready event fired");
 
     continueTests(toolbox);
   });
 }
 
-function continueTests(toolbox, panel) {
+var continueTests = Task.async(function*(toolbox, panel) {
   ok(toolbox.getCurrentPanel(), "panel value is correct");
   is(toolbox.currentToolId, toolId2, "toolbox _currentToolId is correct");
 
   ok(!toolbox.doc.getElementById("toolbox-tab-" + toolId2).hasAttribute("icon-invertable"),
     "The tool tab does not have the invertable attribute");
 
   ok(toolbox.doc.getElementById("toolbox-tab-inspector").hasAttribute("icon-invertable"),
     "The builtin tool tabs do have the invertable attribute");
 
   let toolDefinitions = gDevTools.getToolDefinitionMap();
-  is(toolDefinitions.has(toolId2), true, "The tool is in gDevTools");
+  ok(toolDefinitions.has(toolId2), "The tool is in gDevTools");
 
   let toolDefinition = toolDefinitions.get(toolId2);
   is(toolDefinition.id, toolId2, "toolDefinition id is correct");
 
-  gDevTools.unregisterTool(toolId2);
-  is(gDevTools.getToolDefinitionMap().has(toolId2), false,
+  info("Testing toolbox tool-unregistered event");
+  let toolSelected = toolbox.once("select");
+  let unregisteredTool = yield new Promise(resolve => {
+    toolbox.once("tool-unregistered", (e,id) => resolve(id));
+    gDevTools.unregisterTool(toolId2);
+  });
+  yield toolSelected;
+
+  is(unregisteredTool, toolId2, "Event returns correct id");
+  ok(!toolbox.isToolRegistered(toolId2),
+    "Toolbox: The tool is not registered");
+  ok(!gDevTools.getToolDefinitionMap().has(toolId2),
     "The tool is no longer registered");
 
-  // Wait for unregisterTool to select the next tool before
-  // attempting to destroy.
-  toolbox.on("select", function selectListener (_, id) {
-    if (id !== "test-tool") {
-      toolbox.off("select", selectListener);
-      destroyToolbox(toolbox);
-    }
+  info("Testing toolbox tool-registered event");
+  let registeredTool = yield new Promise(resolve => {
+    toolbox.once("tool-registered", (e,id) => resolve(id));
+    gDevTools.registerTool(toolDefinition);
   });
-}
+
+  is(registeredTool, toolId2, "Event returns correct id");
+  ok(toolbox.isToolRegistered(toolId2),
+    "Toolbox: The tool is registered");
+  ok(gDevTools.getToolDefinitionMap().has(toolId2),
+    "The tool is registered");
+
+  info("Unregistering tool")
+  gDevTools.unregisterTool(toolId2);
+
+  destroyToolbox(toolbox);
+});
 
 function destroyToolbox(toolbox) {
   toolbox.destroy().then(function() {
     let target = TargetFactory.forTab(gBrowser.selectedTab);
     ok(gDevTools._toolboxes.get(target) == null, "gDevTools doesn't know about target");
     ok(toolbox._target == null, "toolbox doesn't know about target.");
     finishUp();
   });
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -1768,25 +1768,38 @@ Toolbox.prototype = {
       // away.
       this.frame.contentWindow.focus();
 
       this.emit("host-changed");
     });
   },
 
   /**
+   * Return if the tool is available as a tab (i.e. if it's checked
+   * in the options panel). This is different from Toolbox.getPanel -
+   * a tool could be registered but not yet opened in which case
+   * isToolRegistered would return true but getPanel would return false.
+   */
+  isToolRegistered: function(toolId) {
+    return gDevTools.getToolDefinitionMap().has(toolId);
+  },
+
+  /**
    * Handler for the tool-registered event.
    * @param  {string} event
    *         Name of the event ("tool-registered")
    * @param  {string} toolId
    *         Id of the tool that was registered
    */
   _toolRegistered: function(event, toolId) {
     let tool = gDevTools.getToolDefinition(toolId);
     this._buildTabForTool(tool);
+    // Emit the event so tools can listen to it from the toolbox level
+    // instead of gDevTools
+    this.emit("tool-registered", toolId);
   },
 
   /**
    * Handler for the tool-unregistered event.
    * @param  {string} event
    *         Name of the event ("tool-unregistered")
    * @param  {string|object} toolId
    *         Definition or id of the tool that was unregistered. Passing the
@@ -1828,16 +1841,19 @@ Toolbox.prototype = {
 
     if (this.hostType == Toolbox.HostType.WINDOW) {
       let doc = this.doc.defaultView.parent.document;
       let key = doc.getElementById("key_" + toolId);
       if (key) {
         key.parentNode.removeChild(key);
       }
     }
+    // Emit the event so tools can listen to it from the toolbox level
+    // instead of gDevTools
+    this.emit("tool-unregistered", toolId);
   },
 
   /**
    * Initialize the inspector/walker/selection/highlighter fronts.
    * Returns a promise that resolves when the fronts are initialized
    */
   initInspector: function() {
     if (!this._initInspector) {