Browser extension basics

Structure

1
2
3
+ extension_directory
|_ manifest.json
|_ main.js

Manifest file

Structure

Create manifest.json file.

1
2
3
4
5
{
"manifest_version":2,
"version":"1.0",
"name":"Test",
}

Load

  • Firefox

    1. In the address bar: about:debugging#/runtime/this-firefox.
    2. Click on Load Temporary Add-on.
    3. Choose the manifest.json file from the directory.
  • Chrome

    1. In the address bar: chrome://extensions.
    2. Enable Developer Mode and switch into it.
    3. Click the Load unpacked button and select the extension directory.

Add functionality

  • Content scripts can manipulate the Document Object Model of the web page, injecting JS (and CSS).
    • “matches”: list of domains and subdomains where the content script should be added
    • “js”: array of the JS files to be loaded.
1
2
3
4
5
6
7
8
9
10
11
{
"manifest_version":2,
"version":"1.0",
"name":"Test",
"content_scripts":[
{
"matches":["<all_urls>"],
"js":["main.js"]
}
]
}

Main script

Structure

Create main.js :

1
alert("The test extension is up and running")

Load

  • Reload the extension as seen on manifest.
  • Don’t forget to reload the extension anytime you edit the code

Customize examples

Change all the images of a webpage we visit to an image we choose

  1. Add an dummy_image.jpg file to the extension directory

  2. Modify main.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    console.log("The extension is up and running");

    // select all elememnt with the `img` tag
    var images = document.getElementsByTagName('img')

    for (elt of images){
    // alter all those images
    elt.src = '${browser.runtime.getURL("dummy_image.jpg")}';
    elt.alt = 'an alt text';
    }
  3. Modify manifest.json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "manifest_version":2,
    "version":"1.0",
    "name":"Test",
    "content_scripts":[
    {
    "matches":["<all_urls>"],
    "js":["main.js"]
    }
    ],
    "web_accessible_resources": [
    "dummy_image.jpg"
    ]
    }
  4. Reload the extension and visit any URL you like.

Add icons to your extension

  1. Edit the manifest.json file
    1
    2
    3
    4
    5
    6
    {
    "icons": {
    "48": "icon-48.png",
    "96": "icon-96.png"
    }
    }

Add a toolbar button

  1. Add the icon files to the extension directory.
  2. Modify manifest.json
    1
    2
    3
    4
    5
    6
    7
    8
    {
    "browser_action":{
    "default_icon":{
    "19":"icon-19.png",
    "38":"icon-38.png"
    }
    }
    }

Listen events for the toolbar button

  1. Create background.js.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // open a new tab...
    function openTab(){

    var newTab = browser.tabs.create({
    url:'https://angelesbroullon-codenotepad.statichost.eu/',
    active:true
    })
    }

    // when clicking
    browser.browserAction.onClicked.addListener(openTab)
  2. Edit manifest.json

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "background":{
    "scripts": ["background.js"]
    },
    "permissions": [
    "tabs"
    ]
    }
  3. Reload the extension

Full example

Copy snippets from stack overflow

  • manifest.json (only work on stackoverflow domain)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    {
    "manifest_version":2,
    "version":"1.0",
    "name":"copy code",
    "content_scripts":[
    {
    "matches":["*://*.stackoverflow.com/*"],
    "js":["main.js"]
    }
    ]
    }
  • main.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    // snippets are tagged as `s-code-block`
    var arr =document.getElementsByClassName("s-code-block");

    for(let i = 0 ; i < arr.length ; i++){
    // create and append the button
    var btn = document.createElement("button");
    btn.classList.add("copy_code_button");
    btn.appendChild(document.createTextNode("Copy"));
    arr[i].appendChild(btn);
    //styling the button
    btn.style.position = "relative";

    if(arr[i].scrollWidth === arr[i].offsetWidth
    && arr[i].scrollHeight === arr[i].offsetHeight) {
    btn.style.left = '${arr[i].offsetWidth - 70}px';
    } else if(arr[i].scrollWidth != arr[i].offsetWidth
    && arr[i].scrollHeight === arr[i].offsetWidth) {
    btn.style.left = '${arr[i].offsetWidth - 200}px';
    } else {
    btn.style.left = '${arr[i].offsetWidth - 150}px';
    }

    if(arr[i].scrollHeight === arr[i].offsetHeight) {
    btn.style.bottom = '${arr[i].offsetHeight - 50}px';
    } else {
    btn.style.bottom = '${arr[i].scrollHeight - 50}px';
    //end of styling the button
    }
    console.log("Appended");
    }

    // do the copy action when clicked
    // select all buttons
    var button = document.querySelectorAll(".copy_code_button")
    button.forEach((elm)=>{
    // listen to 'click' action
    elm.addEventListener('click',(e)=>{
    navigator.clipboard.writeText(elm.parentNode.childNodes[0].innerText);
    alert("Copied to Clipboard");
    })
    })