Build Your Own Extension

Jyotsna Gupta

Mozilla Representative

Add-ons Content Reviewer

Former Featured Add-ons Advisory Board Member
Judge at Firefox Quantum Extension Challenge'18

@jyotsna17gupta| jyotsna17gupta.github.io |

 jyotsna17gupta@gmail.com

  • Browser Add-ons
  • WebExtensions
  • Anatomy of WebExtensions
  • Extension API's
  • Contribution opportunities

Agenda

Browser Add-ons extend and modify the functionality of the browser.

Browser Add-ons?

Firefox is the most customizable browser!

1 Million+ add-ons downloaded everyday

150million+ Add-ons used everyday

45+ percentage of users use at least one Add-on

WebExtensions

A cross-browser system for developing browser add-ons

  • Uses standard HTML, CSS and JS
  • e10s compatible (multiprocess)
  • With Zero or Minimal changes, run it on Chrome, Edge and Opera
  • Documentations from multiple resources.

Why WebExtensions?

Few WebExtension API's

Anatomy/Architecture of WebExtensions

manifest.json

{
	"manifest_version": 2,
	"name": "PrivateX",
	"version": "2.0",
	"description": "This add-on lets the user open websites with critical user information [Like banking, travel sites, etc] in a private window, without the hassle of copying the URL. In-case an URL doesn't work, mail us at jyotsna17gupta [AT] gmail [DOT] com.",
	 "homepage_url": "https://github.com/jyotsna17gupta/PrivateX",
	// Addon Manager Icons
	"icons": {
		"16": "icons/unsafe-16.png",
		"32": "icons/unsafe-32.png",
		"48": "icons/unsafe-48.png",
		"64": "icons/unsafe-64.png",
		"128": "icons/unsafe-128.png"
	},
	
	"permissions": [
		"activeTab",
		"tabs"
		],
	
	"page_action": {
		"browser_style": true,
		"default_icon": {
		"16": "icons/unsafe-16.png",
		"32": "icons/unsafe-32.png",
		"48": "icons/unsafe-48.png"
	},
	
	"default_title": "Click here for Private browsing!"
	},
	  
	"background": {
		"scripts": ["background.js"]
	}
}

Background scripts

  • Loaded as soon as the extension is loaded

  • Stay loaded until the extension is disabled or uninstalled

  • You can use any of the WebExtension APIs in the script

"background": {
  "scripts": ["background-script.js"]
}

Content Scripts

  • Similar to loading normal scripts in the page

  • Can access DOM structure and use a small subset of the WebExtension APIs

  • Make cross-domain XHR requests

  • Exchange messages with their background scripts and can in this way indirectly access all the WebExtension APIs

"content_scripts": [
  {
    "matches": ["*://*.mozilla.org/*"],
    "js": ["jquery.js", "content-script.js"]
  }
]

Browser action

  • Used to add button to browser toolbar
  • Use this when your add-on's features are applicable to all websites else use Page action instead.
"browser_action": {
  "default_icon": {
    "19": "button/geo-19.png",
    "38": "button/geo-38.png"
  },
  "default_title": "Whereami?",
  "default_popup": "popup/choose_beast.html"
}
browser.browserAction.onClicked.addListener(handleClick);

Page action

  • Used to add button to address toolbar
  • Use this when your add-on's features are specific to a particular website.
"page_action": {
  "default_icon": {
    "19": "button/geo-19.png",
    "38": "button/geo-38.png"
  },
  "default_title": "Whereami?",
  "default_popup": "popup/choose_beast.html"
}
browser.pageAction.onClicked.addListener(handleClick);

WebExtension API's

Notifications API

 browser.notifications.create(cakeNotification, {
    "type": "basic",
    "iconUrl": browser.extension.getURL("icons/cake-96.png"),
    "title": "Time for cake!",
    "message": "Something something cake"
  });

Tabs API

function onCreated(tab) {
  console.log(`Created new tab: ${tab.id}`)
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener(function() {
  var creating = browser.tabs.create({
    url:"https://example.org"
  });
  creating.then(onCreated, onError);
});

Alarms API

const delayInMinutes = 5;

browser.alarms.create({
  delayInMinutes
});
function onCreated(windowInfo) {
  console.log(`Created window: ${windowInfo.id}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener((tab) => {
  var creating = browser.windows.create({
    url: ["https://developer.mozilla.org",
          "https://addons.mozilla.org"]
  });
  creating.then(onCreated, onError);
});

Windows API

webRequest API

Sequence of events

var target = "https://developer.mozilla.org/*";

/*
e.g.
"https://developer.mozilla.org/en-US/"
200

or:

"https://developer.mozilla.org/en-US/xfgkdkjdfhs"
404
*/
function logResponse(responseDetails) {
  console.log(responseDetails.url);
  console.log(responseDetails.statusCode);
}

browser.webRequest.onCompleted.addListener(
  logResponse,
  {urls: [target]}
);

Example:

web-ext CLI

A command line tool to help build, run, and test WebExtensions.

npm install --global web-ext

Few Commands

  • run
    • Run the extension
  • lint
    • Validate the extension source
  • sign
    • Sign the extension so it can be installed in Firefox
  • build
    • Create an extension package from source
  • docs
    • Open the web-ext documentation in a browser
use --help on the command line, such as web-ext build --help

Debugging your add-on

Publishing your Add-on

https://addons.mozilla.org/en-US/developers/

 

http://bit.ly/publish-firefox-addon

Contribution Opportunities

You can be a content reviewer!

or an Addon Reviewer!

Code Contribution!

AMO(add-ons frontend and server)

Themes in Firefox!

Don't know what to make?

Need a few ideas??

Here you go!!!

 http://bit.ly/addons-ideas

Links:

Need help?

IRC Channels: #webextensions, #extdev, #addons

Mailing List: https://mail.mozilla.org/listinfo/dev-addons

Telegram: @addonschat

Questions?

Jyotsna Gupta | @jyotsna17gupta | jyotsna17gupta@gmail.com

Slides: https://slides.com/jenal/fx-addons/

Cross Browser Add-ons

By Jyotsna Gupta

Cross Browser Add-ons

Build Your Own Extension

  • 1,387