initial commit from extension examples

This commit is contained in:
Venus
2025-11-06 01:30:13 -06:00
commit 22d9e9a323
13 changed files with 300 additions and 0 deletions

36
README.md Normal file
View File

@@ -0,0 +1,36 @@
# menu-demo
A demo of the [menus API](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/menus/).
**This add-on injects JavaScript into web pages. The `addons.mozilla.org` domain disallows this operation, so this add-on will not work properly when it's run on pages in the `addons.mozilla.org` domain.**
**This add-on uses the `menus` namespace to access the functions it needs to create menu items. Note that Chrome, Edge, and Opera all use the `contextMenus` namespace for this, so this extension will not work in these browsers. For compatibility with these browsers, Firefox also offers the `contextMenus` namespace, so to make this extension work with other browsers, use `contextMenus`.**
## What it does
This add-on adds several items to the browser's context menu:
* one shown when there is a selection in the page, that logs the selected text
to the browser console when clicked.
* one shown in all contexts, that is removed when clicked.
* two "radio" items that are shown in all contexts.
These items are grouped using a separator item on each side.
One radio item adds a blue border to the page, the other adds a green border.
Note that these buttons only work on normal web pages, not special pages
like about:debugging.
* one "checkbox" item, shown in all contexts, whose title is updated when the
item is clicked.
* one item that uses the "commands" property to open the add-on's sidebar.
It also adds one item to the browser's "Tools" menu.
## What it shows
* How to create various types of menu item:
* normal
* radio
* separator
* checkbox
* How to use contexts to control when an item appears.
* How to update an item's properties.
* How to remove an item.

52
_locales/en/messages.json Normal file
View File

@@ -0,0 +1,52 @@
{
"extensionName": {
"message": "Menu demo",
"description": "Name of the extension."
},
"extensionDescription": {
"message": "Demonstrates the menus API.",
"description": "Description of the add-on."
},
"menuItemSelectionLogger": {
"message": "Log '%s' to the browser console",
"description": "Title of context menu item that logs the selected text when clicked."
},
"menuItemRemoveMe": {
"message": "Remove me!",
"description": "Title of context menu item that removes itself when clicked."
},
"menuItemGreenify": {
"message": "Greenify",
"description": "Title of context menu item that adds a green border when clicked."
},
"menuItemBluify": {
"message": "Bluify",
"description": "Title of context menu item that adds a green border when clicked."
},
"menuItemCheckMe": {
"message": "Check me",
"description": "Title of context menu item when the item is checked."
},
"menuItemUncheckMe": {
"message": "Uncheck me",
"description": "Title of context menu item when the item is unchecked."
},
"menuItemOpenSidebar": {
"message": "Open sidebar",
"description": "Title of context menu item that opens a sidebar."
},
"menuItemToolsMenu": {
"message": "Click me!",
"description": "Title of tools menu item."
}
}

160
background.js Normal file
View File

@@ -0,0 +1,160 @@
/*
Called when the item has been created, or when creation failed due to an error.
We'll just log success/failure here.
*/
function onCreated() {
if (browser.runtime.lastError) {
console.log(`Error: ${browser.runtime.lastError}`);
} else {
console.log("Item created successfully");
}
}
/*
Called when the item has been removed.
We'll just log success here.
*/
function onRemoved() {
console.log("Item removed successfully");
}
/*
Called when there was an error.
We'll just log the error here.
*/
function onError(error) {
console.log(`Error: ${error}`);
}
/*
Create all the context menu items.
*/
browser.menus.create({
id: "log-selection",
title: browser.i18n.getMessage("menuItemSelectionLogger"),
contexts: ["selection"]
}, onCreated);
browser.menus.create({
id: "remove-me",
title: browser.i18n.getMessage("menuItemRemoveMe"),
contexts: ["all"]
}, onCreated);
browser.menus.create({
id: "separator-1",
type: "separator",
contexts: ["all"]
}, onCreated);
browser.menus.create({
id: "greenify",
type: "radio",
title: browser.i18n.getMessage("menuItemGreenify"),
contexts: ["all"],
checked: true,
icons: {
"16": "icons/paint-green-16.png",
"32": "icons/paint-green-32.png"
}
}, onCreated);
browser.menus.create({
id: "bluify",
type: "radio",
title: browser.i18n.getMessage("menuItemBluify"),
contexts: ["all"],
checked: false,
icons: {
"16": "icons/paint-blue-16.png",
"32": "icons/paint-blue-32.png"
}
}, onCreated);
browser.menus.create({
id: "separator-2",
type: "separator",
contexts: ["all"]
}, onCreated);
browser.menus.create({
id: "check-uncheck",
type: "checkbox",
title: browser.i18n.getMessage("menuItemUncheckMe"),
contexts: ["all"],
checked: true,
}, onCreated);
browser.menus.create({
id: "open-sidebar",
title: browser.i18n.getMessage("menuItemOpenSidebar"),
contexts: ["all"],
command: "_execute_sidebar_action"
}, onCreated);
browser.menus.create({
id: "tools-menu",
title: browser.i18n.getMessage("menuItemToolsMenu"),
contexts: ["tools_menu"],
}, onCreated);
/*
Set a colored border on the document in the given tab.
Note that this only work on normal web pages, not special pages
like about:debugging.
*/
let blue = 'document.body.style.border = "5px solid blue"';
let green = 'document.body.style.border = "5px solid green"';
function borderify(tabId, color) {
browser.tabs.executeScript(tabId, {
code: color
});
}
/*
Update the menu item's title according to current "checked" value.
*/
function updateCheckUncheck(checkedState) {
if (checkedState) {
browser.menus.update("check-uncheck", {
title: browser.i18n.getMessage("menuItemUncheckMe"),
});
} else {
browser.menus.update("check-uncheck", {
title: browser.i18n.getMessage("menuItemCheckMe"),
});
}
}
/*
The click event listener, where we perform the appropriate action given the
ID of the menu item that was clicked.
*/
browser.menus.onClicked.addListener((info, tab) => {
switch (info.menuItemId) {
case "log-selection":
console.log(info.selectionText);
break;
case "remove-me":
let removing = browser.menus.remove(info.menuItemId);
removing.then(onRemoved, onError);
break;
case "bluify":
borderify(tab.id, blue);
break;
case "greenify":
borderify(tab.id, green);
break;
case "check-uncheck":
updateCheckUncheck(info.checked);
break;
case "open-sidebar":
console.log("Opening my sidebar");
break;
case "tools-menu":
console.log("Clicked the tools menu item");
break;
}
});

4
icons/LICENSE Normal file
View File

@@ -0,0 +1,4 @@
The "page-32.png" and "page-48.png" icons are taken from the miu iconset created by Linh Pham Thi Dieu, and are used under the terms of its license: http://linhpham.me/miu/.
The "paint-blue-16", "paint-blue-32", "paint-green-16", and "paint-green-32" icons are adapted from an icon in the ["Outline icons" set](https://www.iconfinder.com/icons/1021026/paint_icon).

BIN
icons/page-16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

BIN
icons/page-32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

BIN
icons/page-48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
icons/paint-blue-16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

BIN
icons/paint-blue-32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 B

BIN
icons/paint-green-16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

BIN
icons/paint-green-32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 B

35
manifest.json Normal file
View File

@@ -0,0 +1,35 @@
{
"manifest_version": 2,
"name": "__MSG_extensionName__",
"description": "__MSG_extensionDescription__",
"version": "1.0",
"default_locale": "en",
"browser_specific_settings": {
"gecko": {
"strict_min_version": "56.0a1"
}
},
"background": {
"scripts": ["background.js"]
},
"permissions": [
"menus",
"activeTab"
],
"icons": {
"16": "icons/page-16.png",
"32": "icons/page-32.png",
"48": "icons/page-48.png"
},
"sidebar_action": {
"default_icon": "icons/page-32.png",
"default_title" : "My sidebar",
"default_panel": "sidebar/sidebar.html"
}
}

13
sidebar/sidebar.html Normal file
View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="panel.css"/>
</head>
<body>
<h1>My panel</h1>
</body>
</html>