Bug 1246034: Part 2 - [webext] Add support for _execute_browser_action. r?kmag draft
authorMatthew Wein <mwein@mozilla.com>
Fri, 08 Jul 2016 15:02:49 -0700
changeset 400794 ec178c4371a9e70a958ee98de1115fd8be7a30d3
parent 400793 1d8463698f620725419b2a7f71680866e3b112de
child 528330 33b39a1f6478c0085be3564f9a3746b0bfabdc7f
push id26284
push usermwein@mozilla.com
push dateMon, 15 Aug 2016 20:48:20 +0000
reviewerskmag
bugs1246034
milestone51.0a1
Bug 1246034: Part 2 - [webext] Add support for _execute_browser_action. r?kmag MozReview-Commit-ID: EIbPidn07qZ
browser/components/extensions/.eslintrc
browser/components/extensions/ext-browserAction.js
browser/components/extensions/ext-commands.js
browser/components/extensions/test/browser/browser.ini
browser/components/extensions/test/browser/browser_ext_commands_execute_browser_action.js
--- a/browser/components/extensions/.eslintrc
+++ b/browser/components/extensions/.eslintrc
@@ -1,18 +1,21 @@
 {
   "extends": "../../../toolkit/components/extensions/.eslintrc",
 
   "globals": {
     "AllWindowEvents": true,
+    "browserActionFor": true,
     "currentWindow": true,
     "EventEmitter": true,
     "IconDetails": true,
     "makeWidgetId": true,
     "pageActionFor": true,
     "PanelPopup": true,
     "TabContext": true,
     "ViewPopup": true,
     "WindowEventManager": true,
     "WindowListManager": true,
     "WindowManager": true,
   },
 }
+
+
--- a/browser/components/extensions/ext-browserAction.js
+++ b/browser/components/extensions/ext-browserAction.js
@@ -18,18 +18,16 @@ var {
   IconDetails,
 } = ExtensionUtils;
 
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
 // WeakMap[Extension -> BrowserAction]
 var browserActionMap = new WeakMap();
 
-global.browserActionOf = browserActionOf;
-
 // Responsible for the browser_action section of the manifest as well
 // as the associated popup.
 function BrowserAction(options, extension) {
   this.extension = extension;
 
   let widgetId = makeWidgetId(extension.id);
   this.id = `${widgetId}-browser-action`;
   this.viewId = `PanelUI-webext-${widgetId}-browser-action-view`;
--- a/browser/components/extensions/ext-commands.js
+++ b/browser/components/extensions/ext-commands.js
@@ -123,16 +123,19 @@ CommandList.prototype = {
 
     /* eslint-disable mozilla/balanced-listeners */
     // We remove all references to the key elements when the extension is shutdown,
     // therefore the listeners for these elements will be garbage collected.
     keyElement.addEventListener("command", (event) => {
       if (name == "_execute_page_action") {
         let win = event.target.ownerDocument.defaultView;
         pageActionFor(this.extension).triggerAction(win);
+      } else if (name == "_execute_browser_action") {
+        let win = event.target.ownerDocument.defaultView;
+        browserActionFor(this.extension).triggerAction(win);
       } else {
         TabManager.for(this.extension)
                   .addActiveTabPermission(TabManager.activeTab);
         this.emit("command", name);
       }
     });
     /* eslint-enable mozilla/balanced-listeners */
 
--- a/browser/components/extensions/test/browser/browser.ini
+++ b/browser/components/extensions/test/browser/browser.ini
@@ -19,16 +19,17 @@ support-files =
 
 [browser_ext_browserAction_context.js]
 [browser_ext_browserAction_disabled.js]
 [browser_ext_browserAction_pageAction_icon.js]
 [browser_ext_browserAction_pageAction_icon_permissions.js]
 [browser_ext_browserAction_popup.js]
 [browser_ext_browserAction_popup_resize.js]
 [browser_ext_browserAction_simple.js]
+[browser_ext_commands_execute_browser_action.js]
 [browser_ext_commands_execute_page_action.js]
 [browser_ext_commands_getAll.js]
 [browser_ext_commands_onCommand.js]
 [browser_ext_contentscript_connect.js]
 [browser_ext_contextMenus.js]
 [browser_ext_contextMenus_checkboxes.js]
 [browser_ext_contextMenus_icons.js]
 [browser_ext_contextMenus_radioGroups.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_commands_execute_browser_action.js
@@ -0,0 +1,113 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+function* testExecuteBrowserActionWithOptions(options = {}) {
+  let extensionOptions = {};
+
+  extensionOptions.manifest = {
+    "commands": {
+      "_execute_browser_action": {
+        "suggested_key": {
+          "default": "Alt+Shift+J",
+        },
+      },
+    },
+    "browser_action": {
+      "browser_style": true,
+    },
+  };
+
+  if (options.withPopup) {
+    extensionOptions.manifest.browser_action.default_popup = "popup.html";
+
+    extensionOptions.files = {
+      "popup.html": `
+        <!DOCTYPE html>
+        <html>
+          <head>
+            <meta charset="utf-8">
+            <script src="popup.js"></script>
+          </head>
+        </html>
+      `,
+
+      "popup.js": function() {
+        browser.runtime.sendMessage("from-browser-action-popup");
+      },
+    };
+  }
+
+  extensionOptions.background = () => {
+    browser.test.onMessage.addListener((message, withPopup) => {
+      browser.commands.onCommand.addListener((commandName) => {
+        if (commandName == "_execute_browser_action") {
+          browser.test.fail("The onCommand listener should never fire for _execute_browser_action.");
+        }
+      });
+
+      browser.browserAction.onClicked.addListener(() => {
+        if (withPopup) {
+          browser.test.fail("The onClick listener should never fire if the browserAction has a popup.");
+          browser.test.notifyFail("execute-browser-action-on-clicked-fired");
+        } else {
+          browser.test.notifyPass("execute-browser-action-on-clicked-fired");
+        }
+      });
+
+      browser.runtime.onMessage.addListener(msg => {
+        if (msg == "from-browser-action-popup") {
+          browser.test.notifyPass("execute-browser-action-popup-opened");
+        }
+      });
+
+      browser.test.sendMessage("send-keys");
+    });
+  }
+
+  let extension = ExtensionTestUtils.loadExtension(extensionOptions);
+
+  extension.onMessage("send-keys", () => {
+    EventUtils.synthesizeKey("j", {altKey: true, shiftKey: true});
+  });
+
+  yield extension.startup();
+
+  if (options.inArea) {
+    let widget = getBrowserActionWidget(extension);
+    CustomizableUI.addWidgetToArea(widget.id, options.inArea);
+  }
+
+  extension.sendMessage("withPopup", options.withPopup);
+
+  if (options.withPopup) {
+    yield extension.awaitFinish("execute-browser-action-popup-opened");
+    yield closeBrowserAction(extension);
+  } else {
+    yield extension.awaitFinish("execute-browser-action-on-clicked-fired");
+  }
+  yield extension.unload();
+}
+
+add_task(function* test_execute_browser_action_with_popup() {
+  yield testExecuteBrowserActionWithOptions({
+    withPopup: true,
+  });
+});
+
+add_task(function* test_execute_browser_action_without_popup() {
+  yield testExecuteBrowserActionWithOptions();
+});
+
+add_task(function* test_execute_browser_action_in_hamburger_menu_with_popup() {
+  yield testExecuteBrowserActionWithOptions({
+    withPopup: true,
+    inArea: CustomizableUI.AREA_PANEL,
+  });
+});
+
+add_task(function* test_execute_browser_action_in_hamburger_menu_without_popup() {
+  yield testExecuteBrowserActionWithOptions({
+    inArea: CustomizableUI.AREA_PANEL,
+  });
+});
\ No newline at end of file