Browser extension basics
Structure
1 | + extension_directory |
Manifest file
Structure
Create manifest.json
file.
1 | { |
Load
Firefox
- In the address bar:
about:debugging#/runtime/this-firefox
. - Click on
Load Temporary Add-on
. - Choose the
manifest.json
file from the directory.
- In the address bar:
Chrome
- In the address bar:
chrome://extensions
. - Enable
Developer Mode
and switch into it. - Click the
Load unpacked
button and select the extension directory.
- In the address bar:
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 | { |
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
Add an
dummy_image.jpg
file to the extension directoryModify
main.js
1
2
3
4
5
6
7
8
9
10console.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';
}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"
]
}Reload the extension and visit any URL you like.
Add icons to your extension
- Edit the
manifest.json
file1
2
3
4
5
6{
"icons": {
"48": "icon-48.png",
"96": "icon-96.png"
}
}
Add a toolbar button
- Add the icon files to the extension directory.
- 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
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)Edit
manifest.json
1
2
3
4
5
6
7
8{
"background":{
"scripts": ["background.js"]
},
"permissions": [
"tabs"
]
}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");
})
})