mirror of
https://github.com/GoogleChrome/chrome-extensions-samples.git
synced 2026-03-26 13:19:49 +07:00
feat: add chrome.commands API sample (#1629)
Add a new MV3 sample demonstrating the chrome.commands API. The sample registers custom keyboard shortcuts in the manifest, handles command events in the service worker with notifications and badge text feedback, and uses chrome.commands.getAll() in the popup to display all registered shortcuts. Closes #1126
This commit is contained in:
13
api-samples/commands/README.md
Normal file
13
api-samples/commands/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# chrome.commands
|
||||
|
||||
This sample demonstrates the [`chrome.commands`](https://developer.chrome.com/docs/extensions/reference/api/commands) API by defining custom keyboard shortcuts and responding to command events.
|
||||
|
||||
## Overview
|
||||
|
||||
The extension registers two custom keyboard shortcuts in the manifest and listens for them using `chrome.commands.onCommand`. One command shows a notification, the other toggles a feature on and off with badge text feedback. The popup uses `chrome.commands.getAll()` to display all registered shortcuts and their current key bindings.
|
||||
|
||||
## Running this extension
|
||||
|
||||
1. Clone this repository.
|
||||
2. Load this directory in Chrome as an [unpacked extension](https://developer.chrome.com/docs/extensions/mv3/getstarted/development-basics/#load-unpacked).
|
||||
3. Use the keyboard shortcuts shown in the popup or customize them at `chrome://extensions/shortcuts`.
|
||||
41
api-samples/commands/background.js
Normal file
41
api-samples/commands/background.js
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
let featureEnabled = false;
|
||||
|
||||
chrome.commands.onCommand.addListener(async (command) => {
|
||||
if (command === 'run-action') {
|
||||
chrome.notifications.create({
|
||||
type: 'basic',
|
||||
iconUrl: 'images/icon-128.png',
|
||||
title: 'Commands API Demo',
|
||||
message: 'The "run-action" command was triggered.'
|
||||
});
|
||||
}
|
||||
|
||||
if (command === 'toggle-feature') {
|
||||
featureEnabled = !featureEnabled;
|
||||
const state = featureEnabled ? 'ON' : 'OFF';
|
||||
|
||||
chrome.action.setBadgeText({ text: featureEnabled ? 'ON' : '' });
|
||||
chrome.action.setBadgeBackgroundColor({ color: '#4688F1' });
|
||||
|
||||
chrome.notifications.create({
|
||||
type: 'basic',
|
||||
iconUrl: 'images/icon-128.png',
|
||||
title: 'Feature Toggled',
|
||||
message: `The feature is now ${state}.`
|
||||
});
|
||||
}
|
||||
});
|
||||
BIN
api-samples/commands/images/icon-128.png
Normal file
BIN
api-samples/commands/images/icon-128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 727 B |
BIN
api-samples/commands/images/icon-16.png
Normal file
BIN
api-samples/commands/images/icon-16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 101 B |
BIN
api-samples/commands/images/icon-48.png
Normal file
BIN
api-samples/commands/images/icon-48.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 142 B |
39
api-samples/commands/manifest.json
Normal file
39
api-samples/commands/manifest.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "Commands API Demo",
|
||||
"version": "1.0",
|
||||
"description": "Uses the chrome.commands API to define keyboard shortcuts and handle command events.",
|
||||
"manifest_version": 3,
|
||||
"background": {
|
||||
"service_worker": "background.js"
|
||||
},
|
||||
"permissions": ["notifications"],
|
||||
"icons": {
|
||||
"16": "images/icon-16.png",
|
||||
"48": "images/icon-48.png",
|
||||
"128": "images/icon-128.png"
|
||||
},
|
||||
"action": {
|
||||
"default_popup": "popup.html",
|
||||
"default_icon": {
|
||||
"16": "images/icon-16.png",
|
||||
"48": "images/icon-48.png",
|
||||
"128": "images/icon-128.png"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"run-action": {
|
||||
"suggested_key": {
|
||||
"default": "Ctrl+Shift+Y",
|
||||
"mac": "Command+Shift+Y"
|
||||
},
|
||||
"description": "Run the sample action"
|
||||
},
|
||||
"toggle-feature": {
|
||||
"suggested_key": {
|
||||
"default": "Ctrl+Shift+U",
|
||||
"mac": "Command+Shift+U"
|
||||
},
|
||||
"description": "Toggle a feature on or off"
|
||||
}
|
||||
}
|
||||
}
|
||||
52
api-samples/commands/popup.css
Normal file
52
api-samples/commands/popup.css
Normal file
@@ -0,0 +1,52 @@
|
||||
body {
|
||||
width: 300px;
|
||||
padding: 12px 16px;
|
||||
font-family: system-ui, sans-serif;
|
||||
font-size: 14px;
|
||||
color: #202124;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
|
||||
.command-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #e8eaed;
|
||||
}
|
||||
|
||||
.command-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.command-name {
|
||||
color: #3c4043;
|
||||
}
|
||||
|
||||
kbd {
|
||||
background: #f1f3f4;
|
||||
border: 1px solid #dadce0;
|
||||
border-radius: 4px;
|
||||
padding: 2px 8px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
color: #5f6368;
|
||||
}
|
||||
|
||||
#hint {
|
||||
margin: 12px 0 0;
|
||||
font-size: 12px;
|
||||
color: #80868b;
|
||||
}
|
||||
|
||||
#hint code {
|
||||
background: #f1f3f4;
|
||||
padding: 1px 4px;
|
||||
border-radius: 3px;
|
||||
font-size: 11px;
|
||||
}
|
||||
16
api-samples/commands/popup.html
Normal file
16
api-samples/commands/popup.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="stylesheet" href="popup.css" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Registered Commands</h1>
|
||||
<div id="commands"></div>
|
||||
<p id="hint">
|
||||
Customize shortcuts at
|
||||
<code>chrome://extensions/shortcuts</code>
|
||||
</p>
|
||||
<script src="popup.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
36
api-samples/commands/popup.js
Normal file
36
api-samples/commands/popup.js
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
async function listCommands() {
|
||||
const commands = await chrome.commands.getAll();
|
||||
const container = document.getElementById('commands');
|
||||
|
||||
for (const command of commands) {
|
||||
const row = document.createElement('div');
|
||||
row.className = 'command-row';
|
||||
|
||||
const name = document.createElement('span');
|
||||
name.className = 'command-name';
|
||||
name.textContent = command.description || command.name;
|
||||
|
||||
const shortcut = document.createElement('kbd');
|
||||
shortcut.textContent = command.shortcut || 'Not set';
|
||||
|
||||
row.appendChild(name);
|
||||
row.appendChild(shortcut);
|
||||
container.appendChild(row);
|
||||
}
|
||||
}
|
||||
|
||||
listCommands();
|
||||
Reference in New Issue
Block a user