Bug 1364251 - Adding Tab key modifier support for onCommand in web extensions r?kmag
MozReview-Commit-ID: 2CJMB8kuZRI
--- a/browser/components/extensions/ext-commands.js
+++ b/browser/components/extensions/ext-commands.js
@@ -16,16 +16,19 @@ this.commands = class extends ExtensionA
this.windowOpenListener = null;
// Map[{String} commandName -> {Object} commandProperties]
this.commands = this.loadCommandsFromManifest(this.extension.manifest);
// WeakMap[Window -> <xul:keyset>]
this.keysetsMap = new WeakMap();
+ // WeakMap[Window -> bool]
+ this.handleCtrlTabMap = new WeakMap();
+
this.register();
EventEmitter.decorate(this);
}
onShutdown(reason) {
this.unregister();
}
@@ -51,16 +54,20 @@ this.commands = class extends ExtensionA
* Unregisters the commands from all open windows and stops commands
* from being registered to windows which are later created.
*/
unregister() {
for (let window of windowTracker.browserWindows()) {
if (this.keysetsMap.has(window)) {
this.keysetsMap.get(window).remove();
}
+ // Restore initial handleCtrlTab setup
+ if (this.handleCtrlTabMap.has(window)) {
+ window.gBrowser.mTabBox.handleCtrlTab = this.handleCtrlTabMap.get(window);
+ }
}
windowTracker.removeOpenListener(this.windowOpenListener);
}
/**
* Creates a Map from commands for each command in the manifest.commands object.
*
@@ -87,24 +94,32 @@ this.commands = class extends ExtensionA
/**
* Registers the commands to a document.
* @param {ChromeWindow} window The XUL window to insert the Keyset.
*/
registerKeysToDocument(window) {
let doc = window.document;
let keyset = doc.createElementNS(XUL_NS, "keyset");
keyset.id = `ext-keyset-id-${this.id}`;
+ let handleCtrlTab = null;
this.commands.forEach((command, name) => {
if (command.shortcut) {
let keyElement = this.buildKey(doc, name, command.shortcut);
+ if (!handleCtrlTab && command.shortcut.match(/^\s*Ctrl\s*\+\s*(Shift\s*\+\s*)?Tab\s*$/)) {
+ handleCtrlTab = window.gBrowser.mTabBox.handleCtrlTab;
+ window.gBrowser.mTabBox.handleCtrlTab = false;
+ }
keyset.appendChild(keyElement);
}
});
doc.documentElement.appendChild(keyset);
this.keysetsMap.set(window, keyset);
+ if (handleCtrlTab !== null) {
+ this.handleCtrlTabMap.set(window, handleCtrlTab);
+ }
}
/**
* Builds a XUL Key element and attaches an onCommand listener which
* emits a command event with the provided name when fired.
*
* @param {Document} doc The XUL document.
* @param {string} name The name of the command.
--- a/browser/components/extensions/schemas/commands.json
+++ b/browser/components/extensions/schemas/commands.json
@@ -6,17 +6,17 @@
{
"namespace": "manifest",
"types": [
{
"id": "KeyName",
"choices": [
{
"type": "string",
- "pattern": "^\\s*(Alt|Ctrl|Command|MacCtrl)\\s*\\+\\s*(Shift\\s*\\+\\s*)?([A-Z0-9]|Comma|Period|Home|End|PageUp|PageDown|Space|Insert|Delete|Up|Down|Left|Right)\\s*$"
+ "pattern": "^\\s*(Alt|Ctrl|Command|MacCtrl)\\s*\\+\\s*(Shift\\s*\\+\\s*)?([A-Z0-9]|Comma|Period|Home|End|PageUp|PageDown|Tab|Space|Insert|Delete|Up|Down|Left|Right)\\s*$"
},
{
"type": "string",
"pattern": "^\\s*((Alt|Ctrl|Command|MacCtrl)\\s*\\+\\s*)?(Shift\\s*\\+\\s*)?(F[1-9]|F1[0-2])\\s*$"
},
{
"type": "string",
"pattern": "^(MediaNextTrack|MediaPlayPause|MediaPrevTrack|MediaStop)$"
--- a/browser/components/extensions/test/browser/browser_ext_commands_onCommand.js
+++ b/browser/components/extensions/test/browser/browser_ext_commands_onCommand.js
@@ -18,16 +18,33 @@ add_task(function* test_user_defined_com
{
name: "toggle-ctrl-up",
shortcut: "Ctrl+Up",
key: "VK_UP",
modifiers: {
accelKey: true,
},
},
+ {
+ name: "toggle-ctrl-tab",
+ shortcut: "Ctrl+Tab",
+ key: "VK_TAB",
+ modifiers: {
+ accelKey: true,
+ },
+ },
+ {
+ name: "toggle-ctrl-shift-tab",
+ shortcut: "Ctrl+Shift+Tab",
+ key: "VK_TAB",
+ modifiers: {
+ accelKey: true,
+ shiftKey: true,
+ },
+ },
// Alt Shortcuts
{
name: "toggle-alt-a",
shortcut: "Alt+A",
key: "A",
modifiers: {
altKey: true,
},
@@ -35,16 +52,25 @@ add_task(function* test_user_defined_com
{
name: "toggle-alt-down",
shortcut: "Alt+Down",
key: "VK_DOWN",
modifiers: {
altKey: true,
},
},
+ {
+ name: "toggle-alt-shift-tab",
+ shortcut: "Alt+Shift+Tab",
+ key: "VK_TAB",
+ modifiers: {
+ altKey: true,
+ shiftKey: true,
+ },
+ },
// Mac Shortcuts
{
name: "toggle-command-shift-page-up",
shortcutMac: "Command+Shift+PageUp",
key: "VK_PAGE_UP",
modifiers: {
accelKey: true,
shiftKey: true,
--- a/browser/components/extensions/test/xpcshell/test_ext_manifest_commands.js
+++ b/browser/components/extensions/test/xpcshell/test_ext_manifest_commands.js
@@ -10,16 +10,16 @@ add_task(function* test_manifest_command
"suggested_key": {"default": "Shifty+Y"},
"description": "Send a 'toggle-feature' event to the extension",
},
},
});
let expectedError = (
String.raw`commands.toggle-feature.suggested_key.default: Value must either: ` +
- String.raw`match the pattern /^\s*(Alt|Ctrl|Command|MacCtrl)\s*\+\s*(Shift\s*\+\s*)?([A-Z0-9]|Comma|Period|Home|End|PageUp|PageDown|Space|Insert|Delete|Up|Down|Left|Right)\s*$/, ` +
+ String.raw`match the pattern /^\s*(Alt|Ctrl|Command|MacCtrl)\s*\+\s*(Shift\s*\+\s*)?([A-Z0-9]|Comma|Period|Home|End|PageUp|PageDown|Tab|Space|Insert|Delete|Up|Down|Left|Right)\s*$/, ` +
String.raw`match the pattern /^\s*((Alt|Ctrl|Command|MacCtrl)\s*\+\s*)?(Shift\s*\+\s*)?(F[1-9]|F1[0-2])\s*$/, or ` +
String.raw`match the pattern /^(MediaNextTrack|MediaPlayPause|MediaPrevTrack|MediaStop)$/`
);
ok(normalized.error.includes(expectedError),
`The manifest error ${JSON.stringify(normalized.error)} must contain ${JSON.stringify(expectedError)}`);
});