commit 22d9e9a32397f1df3dbe5dd3077908f6d72599e9 Author: Venus Date: Thu Nov 6 01:30:13 2025 -0600 initial commit from extension examples diff --git a/README.md b/README.md new file mode 100644 index 0000000..ca79920 --- /dev/null +++ b/README.md @@ -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. diff --git a/_locales/en/messages.json b/_locales/en/messages.json new file mode 100644 index 0000000..709898f --- /dev/null +++ b/_locales/en/messages.json @@ -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." + } + +} diff --git a/background.js b/background.js new file mode 100644 index 0000000..7eb5df3 --- /dev/null +++ b/background.js @@ -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; + } +}); diff --git a/icons/LICENSE b/icons/LICENSE new file mode 100644 index 0000000..5e98d3b --- /dev/null +++ b/icons/LICENSE @@ -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). diff --git a/icons/page-16.png b/icons/page-16.png new file mode 100644 index 0000000..a6fed5c Binary files /dev/null and b/icons/page-16.png differ diff --git a/icons/page-32.png b/icons/page-32.png new file mode 100644 index 0000000..dae663d Binary files /dev/null and b/icons/page-32.png differ diff --git a/icons/page-48.png b/icons/page-48.png new file mode 100644 index 0000000..ba042cd Binary files /dev/null and b/icons/page-48.png differ diff --git a/icons/paint-blue-16.png b/icons/paint-blue-16.png new file mode 100644 index 0000000..24f9c73 Binary files /dev/null and b/icons/paint-blue-16.png differ diff --git a/icons/paint-blue-32.png b/icons/paint-blue-32.png new file mode 100644 index 0000000..8b001b8 Binary files /dev/null and b/icons/paint-blue-32.png differ diff --git a/icons/paint-green-16.png b/icons/paint-green-16.png new file mode 100644 index 0000000..02f35a8 Binary files /dev/null and b/icons/paint-green-16.png differ diff --git a/icons/paint-green-32.png b/icons/paint-green-32.png new file mode 100644 index 0000000..eb940a6 Binary files /dev/null and b/icons/paint-green-32.png differ diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..59c12ea --- /dev/null +++ b/manifest.json @@ -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" + } + +} diff --git a/sidebar/sidebar.html b/sidebar/sidebar.html new file mode 100644 index 0000000..bbfc03b --- /dev/null +++ b/sidebar/sidebar.html @@ -0,0 +1,13 @@ + + + + + + + + + +

My panel

+ + +