orange is the new blue: how to port chrome extension to firefox extension

57
Orange is the new blue How to port Chrome Extension to Firefox Extension or develop cross-browser extension from scratch Boris Mossounov facebook.com/mossounov linkedin.com/in/borismossounov anotherguru.me

Upload: chaykaborya

Post on 18-Jan-2017

649 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Orange is the new blueHow to port Chrome Extension to Firefox Extensionor develop cross-browser extension from scratch

Boris Mossounovfacebook.com/mossounov

linkedin.com/in/borismossounovanotherguru.me

Page 2: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Major architectural differences:Chrome Extension v.s. Firefox Addon

Page 3: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Developer documentation

https://developer.chrome.com/extensionshttps://developer.mozilla.org/en-US/Add-ons

Page 4: Orange is the new blue: How to port Chrome Extension to Firefox Extension

While digging Mozilla docs you can come across:Legacy Extensions Overlay extensions

Restartless Extensions Bootstrapped ExtensionsAdd-on SDK Extensions

Jetpack SDK Add-on SDK

==

=

Page 5: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Firefox Addon history digest:

Legacy Extensions / Overlay Extensions (XUL, JSM, XPCOM)

2004.06 - Firefox 0.9

Page 6: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Legacy Extensions / Overlay Extensions (XUL, JSM, XPCOM)

2004.06 - Firefox 0.9

Firefox Addon history digest:

Page 7: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Legacy Extensions / Overlay Extensions (XUL, JSM, XPCOM)

2004.06 - Firefox 0.9

browser.xul:

overlay.xul:

Firefox Addon history digest:

Page 8: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Legacy Extensions / Overlay Extensions (XUL, JSM, XPCOM)

2004.06 - Firefox 0.9

Mozilla starts Jetpack SDK project2009.09

Firefox Addon history digest:

Page 9: Orange is the new blue: How to port Chrome Extension to Firefox Extension
Page 10: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Legacy Extensions / Overlay Extensions (XUL, JSM, XPCOM)

2004.06 - Firefox 0.9

Mozilla starts Jetpack SDK project2009.09

Restartless Extensions / Bootstrapped Extensions2011.03 - Firefox 4+

Jetpack SDK 0.1 releaseAddon SDK extensionscfx tool (python powered)

2011.06

jpm tool (node.js powered)2015.05 - Firefox 38

Firefox Addon history digest:

Page 11: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Google announces Chrome Extensions support2009.09

Google Chrome Store launches(with blackjack and extensions)

2010.12

Chrome Extension history digest:

Page 12: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Краткая история:2004.06 - Firefox 0.9

2009.09

2011.03 - Firefox 4+

2011.06

2015.05 - Firefox 38

2010.12

Google announces Chrome Extensions support

Legacy Extensions / Overlay Extensions (XUL, JSM, XPCOM)addons.mozilla.org

Mozilla starts Jetpack SDK project

Restartless Extensions / Bootstrapped Extensions

Jetpack SDK 0.1 releaseAddon SDK extensionscfx tool (python powered)

jpm tool (node.js powered)

Google Chrome Store launches (with blackjack and extensions)

Page 13: Orange is the new blue: How to port Chrome Extension to Firefox Extension

While digging Mozilla docs you should read about:Legacy Extensions Overlay extensions

Restartless Extensions Bootstrapped ExtensionsAdd-on SDK Extensions

Jetpack SDK Add-on SDK

==

=

Page 14: Orange is the new blue: How to port Chrome Extension to Firefox Extension

An average browser extensionconsists of the following blocks:

manifest

background script

content scripts, styles, assets

toolbar button popup

locales

embedded pages(options / help)

Page 15: Orange is the new blue: How to port Chrome Extension to Firefox Extension

The major difference between Chrome Extension and Firefox Addon

is the way the following 3 blocks interact:

background.js

contentscript.js popup.js

Page 16: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Google Chrome possesses two APIs for message passing:

• Simple one-time requests• Long-lived connections

https://developer.chrome.com/extensions/messaging

Page 17: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Simple one-time requests

Page 18: Orange is the new blue: How to port Chrome Extension to Firefox Extension

chrome.runtime.sendMessage({greeting: «hello»}, function(response) {

console.log(response.farewell);});

background.js

contentscript.js popup.js

Page 19: Orange is the new blue: How to port Chrome Extension to Firefox Extension

chrome.tabs.sendMessage(tabs[0].id, {greeting: «hello»}, function(response) {console.log(response.farewell);});

background.js

contentscript.js

Page 20: Orange is the new blue: How to port Chrome Extension to Firefox Extension

chrome.runtime.onMessage.addListener( function(request, sender, callback) { console.log(sender.tab ? "from a content script:" +

sender.tab.url : "from the extension"); if (request.greeting ==

"hello") callback({farewell:

"goodbye"}); });

background.js

contentscript.js popup.js

?

Page 21: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Long-lived connections

Page 22: Orange is the new blue: How to port Chrome Extension to Firefox Extension

port.postMessage({joke: "Knock knock»});

port.onMessage.addListener(function(msg) { if (msg.question == "Who's there?"){ port.postMessage({answer: "#4front"}); }});

background.js

contentscript.js popup.js

Page 23: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Window chrome.extension.getBackgroundPage()

background.js

contentscript.js popup.js

contentscript.js & popup.js can:

Is cross-browser support on the table?

If it is, then don’t.If not, go on.

Page 24: Orange is the new blue: How to port Chrome Extension to Firefox Extension

background.js

contentscript.js popup.js

• two message passing APIs• contentscript.js & popup.js can get

background window object and store some objects and methods there.

• all blocks can interact using untitled messages and setting response callbacks.

• background.js knows nothing about other scripts till they connect to it

Page 25: Orange is the new blue: How to port Chrome Extension to Firefox Extension

What about Firefox?

https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts/using_port

Page 26: Orange is the new blue: How to port Chrome Extension to Firefox Extension

port.emit("myMessage", msg);

port.on("myMessage",function(msg) { if (msg.question == "Who's there?") port.emit("myMessage.reply", {

answer: "#4front"});});

background.js

contentscript.js popup.js

Page 27: Orange is the new blue: How to port Chrome Extension to Firefox Extension
Page 28: Orange is the new blue: How to port Chrome Extension to Firefox Extension

background.js

contentscript.js popup.js

• all blocks are run in isolated runtimes and can interact using named messages without response callbacks

• background.js creates contentscript.js & popup.js and can control them

Page 29: Orange is the new blue: How to port Chrome Extension to Firefox Extension

callbacks = {«1234»:

function(payload){},«1235»:

function(payload){}

}

message = {action:

«myMessage.reply»,uid: 1234,paylaod: {}}

message = {}

message = {action:

«myMessage»,paylaod: {}}

message = {action:

«myMessage»,uid: 1234,paylaod: {}}

Page 30: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Let’s compare Mozilla Extension & Chrome Extensionby blocks:

manifest

background script

content scripts, styles, assets

toolbar button popup

locales

embedded pages(options / help)

Page 31: Orange is the new blue: How to port Chrome Extension to Firefox Extension

manifest

manifest.jsondescribes:• title, description,

version, license,• location of all

scripts, styles, html,• permissions

package.jsondescribes:• title, description,

version, license,• location of background

script

and background scriptloads all the content & popup scripts, styles, html

Page 32: Orange is the new blue: How to port Chrome Extension to Firefox Extension

manifest

How to develop cross-browser way:

Setup grunt task, that will synchronize manifest.json & package.json (version, title, description…)

Page 33: Orange is the new blue: How to port Chrome Extension to Firefox Extension

• Invisible html page with it’s window js-object,

• this window js-object shares the same runtime context with content scripts and popup script

• Separate javascript without window object.

• this javascript is run in an isolated runtime

• Background script initializes content scripts and popup and can control them.

• EcmaScript 6

background script

Page 34: Orange is the new blue: How to port Chrome Extension to Firefox Extension

How to develop cross-browser way:

1. Avoid chrome.extension.getBackgroundPage() at all costs

2. For Firefox - create separate background script since firefox addon sdk is implemented on ES6.

3. Develop a cross-browser middle layer to call browser specific API that above all implements message passing with named messages and response callbacks

4. Store background script and content script / popup script logic in separate files. Even if some mechanisms require both background and content scripts. Use message passing, Luke.

background script

Page 35: Orange is the new blue: How to port Chrome Extension to Firefox Extension

• content scripts are run in a web-page isolated world

• can access background window

• cross-domain request are manifest permission dependent

• content scripts are run in a web-page isolated world

• are run in context isolated from background script

• cross-domain requests are forbidden

content scripts, styles, assets

Page 36: Orange is the new blue: How to port Chrome Extension to Firefox Extension

How to develop cross-browser way:

1. Avoid chrome.extension.getBackgroundPage() at all costs2. Develop a cross-browser middle layer to call browser

specific API that above all implements message passing with named messages and response callbacks

3. Store background script and content script / popup script logic in separate files. Even if some mechanisms require both background and content scripts. Use message passing, Luke.

4. For ajax requests in Firefox use Request API in background and message passing.

content scripts, styles, assets

Page 37: Orange is the new blue: How to port Chrome Extension to Firefox Extension

• only one toolbar button• can access background

window • popup load on toolbar

button click and unload on hide

• javascript is loaded using <script>

• popup size is calculated automatically

• several toolbar buttons allowed

• popup javascript context is isolated from background js

• popup is loaded when extension is initialized and unloaded with extension itself

• scripts should be loaded like content scripts

• popup size is set manually

toolbar button popup

Page 38: Orange is the new blue: How to port Chrome Extension to Firefox Extension

How to develop cross-browser way:

1. Avoid chrome.extension.getBackgroundPage() at all costs2. Consider that only one toolbar button allowed3. Develop popup script assuming it is loaded once and should

react to all events that occur in content scripts and background script.

4. Keep in mind that Chrome and Firefox load popup differently though.

5. In Firefox load popup scripts using content script mechanism and block those loaded using <script>. (https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Display_a_Popup)

toolbar button popup

Page 39: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Format: .json

locale API available in:• background script• content script• popup script

Format: .properties

locale API available in:• background script only

that can pass dictionary to rest of scripts

• in popup.html you can use nls ids that will be replaced by localized strings

locales

Page 40: Orange is the new blue: How to port Chrome Extension to Firefox Extension

How to develop cross-browser way:

1. Chose one of the formats as the base one (json).2. Use firefox properties to store language identifier only.3. In Firefox content scripts and popup scripts should request whole localized dictionary that background should read from json. Or you can provide dictionary on initialization of content and popup scripts as config.

locales

Page 41: Orange is the new blue: How to port Chrome Extension to Firefox Extension

How to assemble cross-browser extension:

npm install -g yonpm install -g generator-chrome-extensionnpm install -g generator-firefox-extensionnpm install -g jpm

Page 42: Orange is the new blue: How to port Chrome Extension to Firefox Extension

How to assemble?yo chrome-extension yo firefox-extension

Main difference:background scripts - /liball the rest - /data

Page 43: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Lets make it look more consistent

yo chrome-extension yo firefox-extension

Page 44: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Let’s move both to the single project

yo chrome-extension yo firefox-extension

.gitignore

.gitignore

1. In the single project:app-chromeapp-firefox

2. grunt copy:app-chrome/scripts/bg-* ->

app-firefox/libвсе остальное ->

app-firefox/data

3. add to .gitignoreapp-firefox/libapp-firefox/data

Page 45: Orange is the new blue: How to port Chrome Extension to Firefox Extension

yo chrome-extension yo firefox-extension

or…

adjust folder structure to the Firefox standards and update manifest.json

Let’s move both to the single project

Page 46: Orange is the new blue: How to port Chrome Extension to Firefox Extension

en-US.properties contains only one string:

lng= en

it is used to detect language and load appropriate .jsondictionary in bg-main-firefox

locales

Page 47: Orange is the new blue: How to port Chrome Extension to Firefox Extension

and one last thing…

generator-firefox-extension uses cfx utility for building and runs it using shell

cfx is deprecated by Mozillayou should use jpm instead

but that’s easy

Page 48: Orange is the new blue: How to port Chrome Extension to Firefox Extension

cfx syntax

Page 49: Orange is the new blue: How to port Chrome Extension to Firefox Extension

jpm syntax

don’t forget:cd app-firefox

Page 50: Orange is the new blue: How to port Chrome Extension to Firefox Extension

How to develop cross-browser way:• To generate prject use yeoman generators: generator-chrome-extension & generator-firefox-

extension. Replace cfx with jpm.• Merge code base to the single project and setup grunt build.• Setup grunt task that will synchronize manifest.json & package.json (version, title,

description…).• Develop a cross-browser middle layer to call browser specific API that above all implements

message passing with named messages and response callbacks• Avoid chrome.extension.getBackgroundPage() at all costs• Create two separate background scripts for Chrome & Firefox.• Store background script and content script / popup script logic in separate files. Even if some

mechanisms require both background and content scripts. Use message passing, Luke.• For ajax requests in Firefox use Request API in background and message passing, in Chrome -

jQuery.ajax will do.• Consider that only one toolbar button allowed.• Develop popup script assuming it is loaded once and should react to all events that occur in

content scripts and background script. Keep in mind that Chrome and Firefox load popup differently though.

• In Firefox load popup scripts using content script mechanism and block those loaded using <script>. (https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Display_a_Popup).

• Chose one of the formats as the base one (json). Use firefox properties to store language identifier only. In Firefox content scripts and popup scripts should request whole localized dictionary that background should read from json. Or you can provide dictionary on initialization of content and popup scripts as config.

manifestbackground scriptcontent scripts, styles, assets

toolbar button popupall together

Page 51: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Is it worth it?

Page 52: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Browsers market share in Russian Federation

Page 53: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Overall browsers market share

Page 54: Orange is the new blue: How to port Chrome Extension to Firefox Extension

To create IE extension with the same functionality like Chrome or Firefox extension you need to

implement it on C#, so no cross-browser support here.

Google Chrome = Webkit = Opera = Yandex Browser, etc

Apple Safari is almost Webkit.

Keep in mind:

Page 55: Orange is the new blue: How to port Chrome Extension to Firefox Extension

What about Safari?

Page 56: Orange is the new blue: How to port Chrome Extension to Firefox Extension

So implementing browser extension the way it was described here covers support of all the

major browsers except IE.

Page 57: Orange is the new blue: How to port Chrome Extension to Firefox Extension

Questions?