Firefox has used the WebExtensions API as its extension API considering 2017. We encourage you to read this Mozilla firefox extension development guide to help you build a Mozilla Firefox extension.
Also, you can discover reference documentation for the WebExtensions API on MDN.
Please do no longer reference this text for extension improvement, as it’s far out-of-date. If you’re the developer of a legacy add-on, please talk to this web page for resources that will help you migrate to the contemporary API.
We will create a Mozilla Firefox extension to locate all links within the modern internet web page, highlight the ones which have a target characteristic and alert you what number of links it found.
The good component is that once you have achieved this, you have got both an expertise of Firefox extension development as well as a blueprint for any extension you would want to develop within the future.
What is a Mozilla Firefox Browser Extension?
A browser extension is a collection of scripts accomplished whilst Firefox browses to unique pages. Those scripts can modify the HTML, CSS, and JavaScript of a web page, and have access to particular JavaScript APIs (bookmarks, identity, etc.)
There are two sorts of scripts: content material and background. Content scripts are finished on the web page whereas historical past scripts perform long-term operations and keep long-term state. Background scripts also have access to all of the WebExtension API.
A firefox extension web developer needs two main scripts, i.e., AJAX requests to handle background work and a Content Script to register a click event. Let’s start with the Content Script -
Content Script
The content material script (devtopocket.Js) registers the click and sends the request to our older script.
document.getElementById(“reaction-butt-readinglist”).addEventListener(“click”, function() { if(window.confirm(“Do you want to save this article in Pocket?”)) { sendBackgroundToPocket(); }});
The sendBackgroundToPocket approach needs to speak with the historical past script and ask it to send the Ajax request.
browser.runtime offers us a communication channel among all the extension scripts. It sends a message on that channel and waits for a response on the other side.
If you get the answer, it means the Ajax request is complete while displayed to the user.
function sendBackgroundToPocket(){ browser.runtime.sendMessage({“url”: window.location.href}).then(function(){ document.getElementById(“article-reaction-actions”).insertAdjacentHTML(“afterend”, “This article has been saved to Pocket!”) setTimeout(function(){ document.getElementById(“devtopocket_notification”).remove() }, 2000) }); }
Background Script
A history script is used to write time-consuming operations that do not rely on a particular net web page being opened. These scripts are loaded with the extension and are executed until the extension is disabled or uninstalled.
Our historical past script (historical past.Js) has two roles:
Sending the Ajax request
Reacting to URL adjustments thru History API
In the extension configuration (manifest.Json below), we’re going to say “load devtopocket.Js on pages matching an URL pattern” and it really works while we browse immediately to an article page.
The “issue” with the dev.To internet site is that it uses HTML5 History API to browse pages (as does every unmarried web page internet app). Mozilla Firefox browser extension doesn’t do URL changes and hence doesn’t execute on the basis of the content script.
That’s why we’re going to need a historical script to concentrate for url adjustments via History API, and manually execute the frontend script when needed. We concentrate to url adjustments via the use of the webNavigation API:
background.jsbrowser.webNavigation.onHistoryStateUpdated.addListener(function(details) { browser.tabs.executeScript(null,{file:”devtopocket.js”});}, { url: [{originAndPathMatches: "^.+://dev.to/.+/.+$"}]});
AndPathMatche restricts the listener to a specific target URL pattern (similar to the one we’re additionally going to define in our manifest.Json). The browser.Tabs.ExecuteScript method masses a content material script within the cutting-edge tab.
The heritage scripts expects a message from our content material script (while the “Reading listing” button is clicked):
background.jsfunction handleMessage(message, sender, sendResponse) { if(message.url) { sendToPocket(message.url, sendResponse) return true; }}browser.runtime.onMessage.addListener(handleMessage)
The sendToPocket approach is called upon message receiving. To save our url in Pocket, we’re going to call the existing shop page furnished by way of Pocket (https://getpocket.Com/shop). A traditional Ajax request will do the trick:
function sendToPocket(url, sendResponse) { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { sendResponse(); } }; xhr.open(“GET”, “https://getpocket.com/save?url=”+url, true); xhr.send();}
You might see coming to the Cross-Origin Request problem, we’ll address it later with the extension permissions.
The Manifest
Manifest.Json is our extension configuration document. It’s like a package.Json in a javascript net app or an AndroidManifest.Xml in an Android app.
You define the version and call of your task, permissions that you want, and JavaScript source documents that compose your extension.
First, we write the app definition:
{ “manifest_version”: 2, “name”: “DevToPocket”, “version”: “1.0.0″,
“description”: “Send your DEV.to reading list to Pocket”,
“icons”: { “48″: “icons/devtopocket-48.png” }, …}
Supply at least a 48×48 icon, if you supply more sizes Firefox will try to use the best icon size depending on your screen resolution.
{ … “permissions”: [ "storage", "cookies", "webNavigation", "tabs", "*://dev.to/*/*", "*://getpocket.com/*" ]}
You can discover the permissions listing in the Mozilla documentation. URLs in the permissions give our extension prolonged privileges. In our case, it gives us access to getpocket.Com from dev. So without cross-starting place restrictions, we will inject a script in dev.
To through tabs.ExecuteScript and we have to get admission to getpocket.Com cookies so the Ajax request is authenticated. The full host permissions listing is to be had here. The full manifest.Json file:
{ “manifest_version”: 2, “name”: “DevToPocket”, “version”: “1.0.0″,
“description”: “Send your DEV.to reading list to Pocket”,
“icons”: { “48″: “icons/devtopocket-48.png” },
“content_scripts”: [ { "matches": ["*://dev.to/*/*"], “js”: ["devtopocket.js"] } ], “background”: { “scripts”: ["background.js"] },
“permissions”: [ "storage", "cookies", "webNavigation", "tabs", "*://dev.to/*/*", "*://getpocket.com/*" ]}
Run Mozilla Extension
To run your extension, use the web-ext command. This is a command-line device that assists firefox extension development, run, and the test WebExtensions.
Npm install –global internet-ext
Then to your terminal, run the following command in your venture folder: net-ext run.
It’s going to release a browser along with your extension quickly loaded. The extension is automatically reloaded while you make some changes. If you wish to create a firefox extension, then we recommend you contact the best browser extension development company in USA!