Basics https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension - For extension named borderify , directory order should be like this: ``` borderify/ -- icons/ ---- border-48.png --borderify.js --manifest.json ``` - contents of manifest.json ` "matches": ["*://*.mozilla.org/*"],` this means that extension will work for the domain **mozilla.org** ```json { "manifest_version": 2, "name": "Borderify", "version": "1.0", "description": "Adds a red border to all webpages matching mozilla.org.", "icons": { "48": "icons/border-48.png" }, "content_scripts": [ { "matches": ["*://*.mozilla.org/*"], "js": ["borderify.js"] } ] } ``` - Contents of borderify.js `document.body.style.border = "5px solid red";` - Go to `about:debugging` in firefox url tab and click on load temporary extension and go to borderify folder and click on manifest.json as it links to every thing. now this extension is added until browser restart   - ### More (popups and content script)* https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_second_WebExtension ![5b63409ee09e83ddf25c12f9aa239c0c.png](../../../../_resources/5b63409ee09e83ddf25c12f9aa239c0c.png)   Structure ```text beastify/ beasts/ frog.jpg snake.jpg turtle.jpg content_scripts/ beastify.js icons/ beasts-32.png beasts-48.png popup/ choose_beast.css choose_beast.html choose_beast.js manifest.json ``` browser methods This browser object is a main difference between web apps and firefox add on as it let popup access paths and ability to communicate with content scripts. https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API Some are `browser.` - `runttime.` : This module provides information about your extension and the environment it's running in. - `getURL` : get url for the path. this path is used to access resources of the extension whole folder eg: `browser.runtime.getURL("beasts/frog.jpg")` - `onMessage`: Use this event to listen for messages from another part of your extension. eg ```js browser.runtime.onMessage.addListener((message)=>{ if(message.command==="beastify") { insertBeast(message.beastURL); } else if( message.command === "reset" ){ removeExistingBeasts(); } }) ``` - `tabs.` - `insertCSS` : to inject css to active tab. this is an asynchronous function that returns promise eg : ```js const hidePage=`body > :not(.beastify-image){ display : none; }`; await browser.tabs.insertCSS({code: hidePage}) ``` - `sendMessage` : to send single message from extension background script(or popup_script or page_script) to content scripts. its an asynchronous function eg : ```js browser.tabs.sendMessage(tabs[0].id, { command : "beastify", beastURL : url }) ``` - `removeCSS` : to remove css from the page which was injected by insertCSS method. it wont remove original CSS of page eg : `await browser.tabs.removeCSS({code: hidePage})` - `query` : Gets all tabs that have the specified properties, or all tabs if no properties are specified. an asynchronous function that returns `Promise` eg : `const tabs=await browser.tabs.query({active: true, currentWindow : true})` - `executeScript` : injects javascript code to page. It is available for manifest v2 only eg : `browser.tabs.executeScript({file: "/content_scripts/beastify.js"})` or `browser.tabs.executeScript({code: "console.log('hello')"`