diff --git a/beastify/README.md b/beastify/README.md index e848b64d..7b1012e8 100644 --- a/beastify/README.md +++ b/beastify/README.md @@ -1,40 +1,41 @@ # beastify +This extension used a tootlbar button to enable the section of beast that replaces the content of the active web page. + ## What it does ## The extension includes: -* a browser action with a popup including HTML, CSS, and JS -* a content script -* three images, each of a different beast, packaged as web accessible resources +* An action with a popup that includes HTML, CSS, and JavaScript. +* A content script. +* Three images, each of a beast, packaged as web accessible resources. -When the user clicks the browser action button, the popup is shown, enabling -the user to choose one of three beasts. +When the user clicks the action (toolbar button), the popup displays, enabling the user to choose one of three beasts. -When it is shown, the popup injects a content script into the current page. +When it's displayed, the popup injects a content script into the active page. -When the user chooses a beast, the extension sends the content script a message containing -the name of the chosen beast. +When the user chooses a beast, the extension sends the content script a message containing the name of the chosen beast. -When the content script receives this message, it replaces the current page -content with an image of the chosen beast. +When the content script receives this message, it replaces the active page content with an image of the chosen beast. -When the user clicks the reset button, the page reloads, and reverts to its original form. +When the user clicks the reset button, the page reloads and reverts to its original form. Note that: -* if the user reloads the tab, or switches tabs, while the popup is open, then the popup won't be able to beastify the page any more (because the content script was injected into the original tab). +* If the user reloads the tab, or switches tabs, while the popup is open, then the popup can't beastify the page (because the content script was injected into the original tab). -* by default [`tabs.executeScript()`](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/executeScript) injects the script only when the web page and its resources have finished loading. This means that clicks in the popup will have no effect until the page has finished loading. +* By default, [`scripting.executeScript()`](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/scripting/executeScript) injects the script only when the web page and its resources have finished loading. This means that clicks in the popup have no effect until the page has finished loading. -* it's not possible to inject content scripts into certain pages, including privileged browser pages like "about:debugging" and the [addons.mozilla.org](https://addons.mozilla.org/) website. If the user clicks the beastify icon when such a page is loaded into the active tab, the popup displays an error message. +* It isn't possible to inject content scripts into certain pages, including privileged browser pages such as "about:debugging" and the [addons.mozilla.org](https://addons.mozilla.org/) website. If the user clicks the beastify icon on one of these pages, the popup displays an error message. ## What it shows ## -* write a browser action with a popup -* how to have different browser_action images based upon the theme -* give the popup style and behavior using CSS and JS -* inject a content script programmatically using `tabs.executeScript()` -* send a message from the main extension to a content script -* use web accessible resources to enable web pages to load packaged content -* reload web pages +In this eample, you see how to: + +* Write an action (toolbar button) with a popup. +* Display action (toolbar button) icons based on the browser theme. +* Give a popup style and behavior using CSS and JavaScript. +* Inject a content script programmatically using `scripting.executeScript()`. +* Send a message from the main extension to a content script. +* Use web accessible resources to enable web pages to load packaged content. +* Reload web pages. diff --git a/beastify/content_scripts/beastify.js b/beastify/content_scripts/beastify.js index 0c851b4e..7f7b67ab 100644 --- a/beastify/content_scripts/beastify.js +++ b/beastify/content_scripts/beastify.js @@ -1,8 +1,8 @@ (function() { /** - * Check and set a global guard variable. - * If this content script is injected into the same page again, - * it will do nothing next time. + * Check and set a global guard variable to + * ensure that if this content script is injected into a page again, + * it returns (and does nothing). */ if (window.hasRun) { return; @@ -10,9 +10,9 @@ window.hasRun = true; /** - * Given a URL to a beast image, remove all existing beasts, then - * create and style an IMG node pointing to - * that image, then insert the node into the document. + * Given a URL for a beast image, remove all beasts, + * then create and style an IMG node pointing to the image and + * insert the node into the document. */ function insertBeast(beastURL) { removeExistingBeasts(); @@ -24,7 +24,7 @@ } /** - * Remove every beast from the page. + * Remove all beasts from the page. */ function removeExistingBeasts() { let existingBeasts = document.querySelectorAll(".beastify-image"); @@ -35,7 +35,7 @@ /** * Listen for messages from the background script. - * Call "beastify()" or "reset()". + * Depending on the message, call "beastify()" or "reset()". */ browser.runtime.onMessage.addListener((message) => { if (message.command === "beastify") { diff --git a/beastify/manifest.json b/beastify/manifest.json index 08b2fb4b..0aedd13d 100644 --- a/beastify/manifest.json +++ b/beastify/manifest.json @@ -1,7 +1,7 @@ { "description": "Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples#beastify", - "manifest_version": 2, + "manifest_version": 3, "name": "Beastify", "version": "1.0", "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify", @@ -10,10 +10,20 @@ }, "permissions": [ - "activeTab" + "activeTab", + "scripting" ], - "browser_action": { + "browser_specific_settings": { + "gecko": { + "id": "beastify@mozilla.org", + "data_collection_permissions": { + "required": ["none"] + } + } + }, + + "action": { "default_icon": "icons/beasts-32.png", "theme_icons": [{ "light": "icons/beasts-32-light.png", @@ -25,7 +35,10 @@ }, "web_accessible_resources": [ - "beasts/*.jpg" + { + "resources": [ "beasts/*.jpg" ], + "matches": [ "*://*/*" ] + } ] } diff --git a/beastify/popup/choose_beast.js b/beastify/popup/choose_beast.js index ad1d4cfe..26320e7f 100644 --- a/beastify/popup/choose_beast.js +++ b/beastify/popup/choose_beast.js @@ -1,6 +1,6 @@ /** * CSS to hide everything on the page, - * except for elements that have the "beastify-image" class. + * except for elements that have the ".beastify-image" class. */ const hidePage = `body > :not(.beastify-image) { display: none; @@ -12,9 +12,8 @@ const hidePage = `body > :not(.beastify-image) { */ function listenForClicks() { document.addEventListener("click", (e) => { - /** - * Given the name of a beast, get the URL to the corresponding image. + * Given the name of a beast, get the URL for the corresponding image. */ function beastNameToURL(beastName) { switch (beastName) { @@ -29,33 +28,45 @@ function listenForClicks() { /** * Insert the page-hiding CSS into the active tab, - * then get the beast URL and + * get the beast URL, and * send a "beastify" message to the content script in the active tab. */ function beastify(tabs) { - browser.tabs.insertCSS({code: hidePage}).then(() => { - const url = beastNameToURL(e.target.textContent); - browser.tabs.sendMessage(tabs[0].id, { - command: "beastify", - beastURL: url + const tabId = tabs[0].id; + browser.scripting + .insertCSS({ + target: { tabId }, + css: hidePage, + }) + .then(() => { + const url = beastNameToURL(e.target.textContent); + browser.tabs.sendMessage(tabId, { + command: "beastify", + beastURL: url, + }); }); - }); } /** - * Remove the page-hiding CSS from the active tab, + * Remove the page-hiding CSS from the active tab and * send a "reset" message to the content script in the active tab. */ function reset(tabs) { - browser.tabs.removeCSS({code: hidePage}).then(() => { - browser.tabs.sendMessage(tabs[0].id, { - command: "reset", + const tabId = tabs[0].id; + browser.scripting + .removeCSS({ + target: { tabId }, + css: hidePage, + }) + .then(() => { + browser.tabs.sendMessage(tabId, { + command: "reset", + }); }); - }); } /** - * Just log the error to the console. + * Log the error to the console. */ function reportError(error) { console.error(`Could not beastify: ${error}`); @@ -68,13 +79,15 @@ function listenForClicks() { if (e.target.tagName !== "BUTTON" || !e.target.closest("#popup-content")) { // Ignore when click is not on a button within