Skip to content

Instantly share code, notes, and snippets.

@mrowa44
Last active January 17, 2017 16:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrowa44/2508a50a9461288b069eb44038d4b5a3 to your computer and use it in GitHub Desktop.
Save mrowa44/2508a50a9461288b069eb44038d4b5a3 to your computer and use it in GitHub Desktop.
Porting Chrome plugins to Firefox

Plugins are really just a tiny web apps that run in a popup.

To load your local extension in Chrome:

  • open up extensions page by putting chrome://extensions/ in the address bar
  • check developer mode at the top
  • click load unpacked extension and select the folder your extension is in

To load your local extension in Firefox:

  • download and install a Nightly build of Firefox
  • create a new profile for testing and development
  • visit about:config and set xpinstall.signatures.required to false
  • you also need to explicitly declare it as compatible with Firefox by adding an applications key to your manifest:
"applications": {
    "gecko": {
        "id": "YOUR_ADDON_ID"
    }
}

Set "YOUR_ADDON_ID" to a made-up string formatted like "ext@example.org".

After that you can test your extension locally.

Plugin file structure:

  • manifest.json

An extension requires a manifest file to define the structure, permissions, icons and other metadata (like name, version, description). It’s just a JSON file.

"permissions": [
	"tabs",
	"storage",
	"<all_urls>"
]

You also need to add background page, which is a js file that is loaded as long as the extension is installed. You can set “persistent”: false to only load the file when needed, freeing up memory when the page is idle (not available in Firefox).

"background": {    
	"scripts": ["js/background.js"],    
	"persistent": false  
}

Next, you define commands to listen to, like a key combination:

"commands": {         
	"link1": {
		"suggested_key": {
		"default": "Shift+Alt+1",
		"mac": "MacCtrl+1"
	},
	"description": "Link1 Hotkey"
	}  
}
  • popup.html

this is the html file used by the popup that appears after clicking plugin icon

  • js/popup.js

This is a script included in the popup.html file. You can use here browser API that you have defined permissions to in manifest file (if you’re writing for Chrome use chrome object, if for Firefox browser)

document.addEventListener('DOMContentLoaded', function() {
	chrome.storage.local.get('urls', (result) => {
		[1, 2, 3, 4].forEach((i) => {
		document.getElementById(`input${i}`).value = result.urls[i-1];
	});
});
  • background.js

This is where you actually listen to events and do whatever your plugin is supposed to do, you can use the same API as in popup.js

Differences between Chrome and Firefox:

  • Firefox has browser object, Chrome chrome
  • Many of the APIs are asynchronous. In Chrome, asynchronous APIs use callbacks to return values, and runtime.lastError to communicate errors:
function logCookie(c) {
	if (chrome.extension.lastError) {
		console.error(chrome.extension.lastError);
	} else {
	    console.log(c);
	}
}

chrome.cookies.set(
    { url: 'https://developer.mozilla.org/' },
    logCookie
);

In Firefox you can use promises:

function logCookie(c) {
  console.log(c);
}

function logError(e) {
  console.error(e);
}

var setCookie = browser.cookies.set(
  { url: 'https://developer.mozilla.org/' }
);
setCookie.then(logCookie, logError);
  • Firefox does not support using alert(), confirm(), or prompt() from background pages.
  • To allow easier porting, Firefox also supports chrome and callbacks. That means that in many cases Chrome plugins will just work in Firefox without any changes. However, you should use browser as it’s a part of the WebExtensions standard.
  • Specific differences in the APIs are listed here

Sources:

https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities https://medium.com/@aidobreen/building-a-simple-chrome-extension-1b8a0fca3ca6 https://hacks.mozilla.org/2015/10/porting-chrome-extensions-to-firefox-with-webextensions/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment