Bug 1787203 - Add active tab information to commands.onCommand event. r=mkmelin

Depends on D155564

Differential Revision: https://phabricator.services.mozilla.com/D155583

--HG--
extra : moz-landing-system : lando
This commit is contained in:
John Bieling 2022-08-26 23:25:07 +00:00
Родитель fce12b64a9
Коммит d9254539c7
4 изменённых файлов: 242 добавлений и 12 удалений

Просмотреть файл

@ -42,7 +42,7 @@ messenger.jar:
content/messenger/schemas/browserAction.json (schemas/browserAction.json)
content/messenger/schemas/chrome_settings_overrides.json (schemas/chrome_settings_overrides.json)
content/messenger/schemas/cloudFile.json (schemas/cloudFile.json)
content/messenger/schemas/commands.json (../../../../browser/components/extensions/schemas/commands.json)
content/messenger/schemas/commands.json (schemas/commands.json)
content/messenger/schemas/compose.json (schemas/compose.json)
content/messenger/schemas/composeAction.json (schemas/composeAction.json)
content/messenger/schemas/extensionScripts.json (schemas/extensionScripts.json)

Просмотреть файл

@ -43,7 +43,10 @@ this.commands = class extends ExtensionAPI {
inputHandling: true,
register: fire => {
let listener = (eventName, commandName) => {
fire.async(commandName);
let tab = context.extension.tabManager.convert(
tabTracker.activeTab
);
fire.async(commandName, tab);
};
this.on("command", listener);
return () => {

Просмотреть файл

@ -0,0 +1,188 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
[
{
"namespace": "manifest",
"types": [
{
"id": "KeyName",
"type": "string",
"format": "manifestShortcutKey"
},
{
"$extend": "WebExtensionManifest",
"properties": {
"commands": {
"type": "object",
"optional": true,
"additionalProperties": {
"type": "object",
"additionalProperties": { "$ref": "UnrecognizedProperty" },
"properties": {
"suggested_key": {
"type": "object",
"optional": true,
"properties": {
"default": {
"$ref": "KeyName",
"optional": true
},
"mac": {
"$ref": "KeyName",
"optional": true
},
"linux": {
"$ref": "KeyName",
"optional": true
},
"windows": {
"$ref": "KeyName",
"optional": true
},
"chromeos": {
"type": "string",
"optional": true
},
"android": {
"type": "string",
"optional": true
},
"ios": {
"type": "string",
"optional": true
},
"additionalProperties": {
"type": "string",
"deprecated": "Unknown platform name",
"optional": true
}
}
},
"description": {
"type": "string",
"preprocess": "localize",
"optional": true
}
}
}
}
}
}
]
},
{
"namespace": "commands",
"description": "Use the commands API to add keyboard shortcuts that trigger actions in your extension, for example, an action to open the browser action or send a command to the xtension.",
"permissions": ["manifest:commands"],
"types": [
{
"id": "Command",
"type": "object",
"properties": {
"name": {
"type": "string",
"optional": true,
"description": "The name of the Extension Command"
},
"description": {
"type": "string",
"optional": true,
"description": "The Extension Command description"
},
"shortcut": {
"type": "string",
"optional": true,
"description": "The shortcut active for this command, or blank if not active."
}
}
}
],
"events": [
{
"name": "onCommand",
"description": "Fired when a registered command is activated using a keyboard shortcut.",
"type": "function",
"parameters": [
{
"name": "command",
"type": "string"
},
{
"name": "tab",
"$ref": "tabs.Tab",
"description": "The details of the active tab while the command occurred."
}
]
}
],
"functions": [
{
"name": "update",
"type": "function",
"async": true,
"description": "Update the details of an already defined command.",
"parameters": [
{
"type": "object",
"name": "detail",
"description": "The new description for the command.",
"properties": {
"name": {
"type": "string",
"description": "The name of the command."
},
"description": {
"type": "string",
"optional": true,
"description": "The new description for the command."
},
"shortcut": {
"type": "string",
"format": "manifestShortcutKeyOrEmpty",
"optional": true
}
}
}
]
},
{
"name": "reset",
"type": "function",
"async": true,
"description": "Reset a command's details to what is specified in the manifest.",
"parameters": [
{
"type": "string",
"name": "name",
"description": "The name of the command."
}
]
},
{
"name": "getAll",
"type": "function",
"async": "callback",
"description": "Returns all the registered extension commands for this extension and their shortcut (if active).",
"parameters": [
{
"type": "function",
"name": "callback",
"optional": true,
"parameters": [
{
"name": "commands",
"type": "array",
"items": {
"$ref": "Command"
}
}
],
"description": "Called to return the registered commands."
}
]
}
]
}
]

Просмотреть файл

@ -9,6 +9,8 @@ add_task(async function test_user_defined_commands() {
name: "toggle-ctrl-a",
shortcut: "Ctrl+A",
key: "A",
// Does not work in compose window on Linux.
skip: ["messageCompose"],
modifiers: {
accelKey: true,
},
@ -26,6 +28,8 @@ add_task(async function test_user_defined_commands() {
name: "toggle-alt-a",
shortcut: "Alt+A",
key: "A",
// Does not work in compose window on Mac.
skip: ["messageCompose"],
modifiers: {
altKey: true,
},
@ -91,6 +95,8 @@ add_task(async function test_user_defined_commands() {
name: "toggle-alt-shift-a",
shortcut: "Alt+Shift+A",
key: "A",
// Does not work in compose window on Mac.
skip: ["messageCompose"],
modifiers: {
altKey: true,
shiftKey: true,
@ -211,8 +217,8 @@ add_task(async function test_user_defined_commands() {
}
function background() {
browser.commands.onCommand.addListener(commandName => {
browser.test.sendMessage("oncommand", commandName);
browser.commands.onCommand.addListener((commandName, activeTab) => {
browser.test.sendMessage("oncommand", { commandName, activeTab });
});
browser.test.sendMessage("ready");
}
@ -238,18 +244,26 @@ add_task(async function test_user_defined_commands() {
ExtensionTestUtils.failOnSchemaWarnings(true);
await extension.awaitMessage("ready");
async function runTest(window) {
async function runTest(window, expectedTabType) {
for (let testCommand of testCommands) {
if (testCommand.skip && testCommand.skip.includes(expectedTabType)) {
continue;
}
if (testCommand.shortcutMac && !testCommand.shortcut && !isMac) {
continue;
}
EventUtils.synthesizeKey(testCommand.key, testCommand.modifiers, window);
let message = await extension.awaitMessage("oncommand");
is(
message,
message.commandName,
testCommand.name,
`Expected onCommand listener to fire with the correct name: ${testCommand.name}`
);
is(
message.activeTab.type,
expectedTabType,
`Expected onCommand listener to fire with the correct tab type: ${expectedTabType}`
);
}
}
@ -262,14 +276,21 @@ add_task(async function test_user_defined_commands() {
? totalTestCommands
: totalTestCommands - totalMacOnlyCommands;
let account = createAccount();
addIdentity(account);
let win3 = await openComposeWindow(account);
// Some key combinations do not work if the TO field has focus.
win3.document.querySelector("editor").focus();
// Confirm the keysets have been added to both windows.
let keysetID = `ext-keyset-id-${makeWidgetId(extension.id)}`;
let keyset = win1.document.getElementById(keysetID);
ok(keyset != null, "Expected keyset to exist");
is(
keyset.children.length,
expectedCommandsRegistered,
"Expected keyset to have the correct number of children"
"Expected keyset of window #1 to have the correct number of children"
);
keyset = win2.document.getElementById(keysetID);
@ -277,27 +298,45 @@ add_task(async function test_user_defined_commands() {
is(
keyset.children.length,
expectedCommandsRegistered,
"Expected keyset to have the correct number of children"
"Expected keyset of window #2 to have the correct number of children"
);
keyset = win3.document.getElementById(keysetID);
ok(keyset != null, "Expected keyset to exist");
is(
keyset.children.length,
expectedCommandsRegistered,
"Expected keyset of window #3 to have the correct number of children"
);
// Confirm that the commands are registered to both windows.
await focusWindow(win1);
await runTest(win1);
await runTest(win1, "mail");
await focusWindow(win2);
await runTest(win2);
await runTest(win2, "mail");
await focusWindow(win3);
await runTest(win3, "messageCompose");
// Mitigation for "waiting for vsync to be disabled" error.
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(r => win3.setTimeout(r, 250));
await extension.unload();
// Confirm that the keysets have been removed from both windows after the extension is unloaded.
keyset = win1.document.getElementById(keysetID);
is(keyset, null, "Expected keyset to be removed from the window");
is(keyset, null, "Expected keyset to be removed from the window #1");
keyset = win2.document.getElementById(keysetID);
is(keyset, null, "Expected keyset to be removed from the window");
is(keyset, null, "Expected keyset to be removed from the window #2");
keyset = win3.document.getElementById(keysetID);
is(keyset, null, "Expected keyset to be removed from the window #3");
await BrowserTestUtils.closeWindow(win1);
await BrowserTestUtils.closeWindow(win2);
await BrowserTestUtils.closeWindow(win3);
SimpleTest.endMonitorConsole();
await waitForConsole;