Bug 1246028 - Implement chrome.commands.getAll. r=kmag
☠☠ backed out by fdf9c9e0ea67 ☠ ☠
authorMatthew Wein <mwein@mozilla.com>
Tue, 23 Feb 2016 16:13:16 -0800
changeset 285520 6d8c09f110ee89530087abcd55d9f44691248f59
parent 285519 d86655d3c54c7b1ac9ac824b9e2c1948620b6446
child 285521 046e5f381e66ba1a1d3272ccb5ceaa20e3d26df6
push id72403
push usercbook@mozilla.com
push dateThu, 25 Feb 2016 10:59:17 +0000
treeherdermozilla-inbound@3b913f81cb98 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1246028
milestone47.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 1246028 - Implement chrome.commands.getAll. r=kmag
browser/components/extensions/ext-commands.js
browser/components/extensions/jar.mn
browser/components/extensions/test/browser/browser.ini
browser/components/extensions/test/browser/browser_ext_commands.js
browser/components/nsBrowserGlue.js
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/ext-commands.js
@@ -0,0 +1,53 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+Cu.import("resource://gre/modules/ExtensionUtils.jsm");
+
+var {
+   PlatformInfo,
+} = ExtensionUtils;
+
+// WeakMap[Extension -> Map[name => Command]]
+var commandsMap = new WeakMap();
+
+function Command(description, shortcut) {
+  this.description = description;
+  this.shortcut = shortcut;
+}
+
+/* eslint-disable mozilla/balanced-listeners */
+extensions.on("manifest_commands", (type, directive, extension, manifest) => {
+  let commands = new Map();
+  for (let name of Object.keys(manifest.commands)) {
+    let os = PlatformInfo.os == "win" ? "windows" : PlatformInfo.os;
+    let manifestCommand = manifest.commands[name];
+    let description = manifestCommand.description;
+    let shortcut = manifestCommand.suggested_key[os] || manifestCommand.suggested_key.default;
+    let command = new Command(description, shortcut);
+    commands.set(name, command);
+  }
+  commandsMap.set(extension, commands);
+});
+
+extensions.on("shutdown", (type, extension) => {
+  commandsMap.delete(extension);
+});
+/* eslint-enable mozilla/balanced-listeners */
+
+extensions.registerSchemaAPI("commands", null, (extension, context) => {
+  return {
+    commands: {
+      getAll() {
+        let commands = Array.from(commandsMap.get(extension), ([name, command]) => {
+          return ({
+            name,
+            description: command.description,
+            shortcut: command.shortcut,
+          });
+        });
+        return Promise.resolve(commands);
+      },
+    },
+  };
+});
--- a/browser/components/extensions/jar.mn
+++ b/browser/components/extensions/jar.mn
@@ -1,14 +1,15 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # 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/.
 
 browser.jar:
     content/browser/extension.svg
     content/browser/ext-utils.js
+    content/browser/ext-commands.js
     content/browser/ext-contextMenus.js
     content/browser/ext-browserAction.js
     content/browser/ext-pageAction.js
     content/browser/ext-desktop-runtime.js
     content/browser/ext-tabs.js
     content/browser/ext-windows.js
     content/browser/ext-bookmarks.js
--- a/browser/components/extensions/test/browser/browser.ini
+++ b/browser/components/extensions/test/browser/browser.ini
@@ -4,16 +4,17 @@ support-files =
   context.html
   ctxmenu-image.png
   context_tabs_onUpdated_page.html
   context_tabs_onUpdated_iframe.html
   file_popup_api_injection_a.html
   file_popup_api_injection_b.html
 
 [browser_ext_simple.js]
+[browser_ext_commands.js]
 [browser_ext_currentWindow.js]
 [browser_ext_browserAction_simple.js]
 [browser_ext_browserAction_pageAction_icon.js]
 [browser_ext_browserAction_context.js]
 [browser_ext_browserAction_disabled.js]
 [browser_ext_pageAction_context.js]
 [browser_ext_pageAction_popup.js]
 [browser_ext_browserAction_popup.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_commands.js
@@ -0,0 +1,77 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+var {AppConstants} = Cu.import("resource://gre/modules/AppConstants.jsm");
+
+add_task(function* () {
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "name": "Commands Extension",
+      "commands": {
+        "with-desciption": {
+          "suggested_key": {
+            "default": "Ctrl+Shift+Y",
+          },
+          "description": "should have a description",
+        },
+        "without-description": {
+          "suggested_key": {
+            "default": "Ctrl+Shift+D",
+          },
+        },
+        "with-platform-info": {
+          "suggested_key": {
+            "mac": "Ctrl+Shift+M",
+            "linux": "Ctrl+Shift+L",
+            "windows": "Ctrl+Shift+W",
+            "android": "Ctrl+Shift+A",
+          },
+        },
+      },
+    },
+
+    background: function() {
+      browser.test.onMessage.addListener((message, additionalScope) => {
+        browser.commands.getAll((commands) => {
+          browser.test.log(JSON.stringify(commands));
+          browser.test.assertEq(commands.length, 3, "getAll should return an array of commands");
+
+          let command = commands.find(c => c.name == "with-desciption");
+          browser.test.assertEq("should have a description", command.description,
+            "The description should match what is provided in the manifest");
+          browser.test.assertEq("Ctrl+Shift+Y", command.shortcut,
+            "The shortcut should match the default shortcut provided in the manifest");
+
+          command = commands.find(c => c.name == "without-description");
+          browser.test.assertEq(null, command.description,
+            "The description should be empty when it is not provided");
+          browser.test.assertEq("Ctrl+Shift+D", command.shortcut,
+            "The shortcut should match the default shortcut provided in the manifest");
+
+          let platformKeys = {
+            macosx: "M",
+            linux: "L",
+            win: "W",
+            android: "A",
+          };
+
+          command = commands.find(c => c.name == "with-platform-info");
+          let platformKey = platformKeys[additionalScope.platform];
+          let shortcut = `Ctrl+Shift+${platformKey}`;
+          browser.test.assertEq(shortcut, command.shortcut,
+            `The shortcut should match the one provided in the manifest for OS='${additionalScope.platform}'`);
+
+          browser.test.notifyPass("commands");
+        });
+      });
+      browser.test.sendMessage("ready");
+    },
+  });
+
+  yield extension.startup();
+  yield extension.awaitMessage("ready");
+  extension.sendMessage("additional-scope", {platform: AppConstants.platform});
+  yield extension.awaitFinish("commands");
+  yield extension.unload();
+});
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -541,16 +541,17 @@ BrowserGlue.prototype = {
 
     if (AppConstants.NIGHTLY_BUILD) {
       os.addObserver(this, AddonWatcher.TOPIC_SLOW_ADDON_DETECTED, false);
     }
 
     ExtensionManagement.registerScript("chrome://browser/content/ext-utils.js");
     ExtensionManagement.registerScript("chrome://browser/content/ext-browserAction.js");
     ExtensionManagement.registerScript("chrome://browser/content/ext-pageAction.js");
+    ExtensionManagement.registerScript("chrome://browser/content/ext-commands.js");
     ExtensionManagement.registerScript("chrome://browser/content/ext-contextMenus.js");
     ExtensionManagement.registerScript("chrome://browser/content/ext-desktop-runtime.js");
     ExtensionManagement.registerScript("chrome://browser/content/ext-tabs.js");
     ExtensionManagement.registerScript("chrome://browser/content/ext-windows.js");
     ExtensionManagement.registerScript("chrome://browser/content/ext-bookmarks.js");
 
     ExtensionManagement.registerSchema("chrome://browser/content/schemas/bookmarks.json");
     ExtensionManagement.registerSchema("chrome://browser/content/schemas/browser_action.json");