Always Proper An Extension Migration Story

By | October 2, 2017

Ive been constructing extensions for Firefox since 2005. Ive built-in bookmark companies (which acquired me a job at Mozilla!), fastened the default theme, enhanced the developer instruments, tweaked Github, optimized efficiency, eased tagging, bookmarked all Etherpads, fastened Pocket and heaps of different terrible great things.

Ive written XUL extensions, Jetpacks, Jetpacks (second kind), SDK add-ons and labored on the core of most of these as effectively. And now Ive seen all of it: Firefox has the WebExtensions API, a model new extension format designed with a aim of browser extensibility with out sacrificing efficiency and security.

In Firefox fifty seven, the WebExtensions API would be the solely supported extension format. So its time to maneuver on. I can not frolic within the luxurious of the insecure efficiency footgun APIs that the legacy extension codecs allowed. Its time emigrate the extensions I actually simply cant reside without.

I began with All the time Proper, one of the vital vital extensions for my each day browser use. I recorded this migration, full with hiccups, missteps and compromises. Hopefully this can allow you to in your extension migration odyssey!

Im All the time Right

Always Right is a straightforward Firefox extension which opens all new tabs instantly to the correct of the present tab, no matter how the tab is opened.

This is nice for a few reasons:

Tab opening habits is predictable it behaves the identical one hundred pc of the time. The default habits in Firefox is set by quite a few elements, too advanced to listing right here. Suffice it to say that altering Firefoxs default tab-opening habits is like chasing hornets in a hurricane.

Related tabs are grouped. When I’ve a considered one thing Im busy doing, and need to begin a model new search or open a tab associated to it, I open a model new tab. This addon makes positive that tab is grouped with the present tabs. The default habits opens that tab on the finish of the tab strip, which finally ends up in two separate clusters of tabs associated to the identical task.

Conceptually, All the time Proper is a straightforward extension however in the end required an entire rewrite with the intention to migrate to the model new WebExtensions API format. Nearly all of the rewrite was painless and quick, however as is our bane as builders, the earlier few bits took probably the most time and had been terribly frustrating.

Migration Overview

The general idea hasnt modified: An extension constructed with the model new APIs remains to be a zipper file containing a manifest and all of your code and asset information, identical to each different extension format earlier than it.

The main items of migration are:

Renaming and migrating to the model new manifest format.Rewrite the code to make use of the model new WebExtensions APIs.Use the model new web-ext CLI instrument for packaging.Migrating the Manifest

The first step is emigrate your manifest file, starting by renaming package.json to manifest.json.

Heres a picture that exhibits the variations between the previous file and the model new file:

The most vital change is so as to add the property manifest_version and provides it a worth of 2. With the manifest_version, identify and model fields in place, you now have all of the required properties for a legitimate extension. All the things else is optional.

Nonetheless, since youre updating an extension that already exists, that you must do a few different things.

The id property is important to guarantee that (AMO) to match the model new add-on with the previous one. Take away the top-level id discipline, and duplicate its worth into the applications/gecko/id field.

If you used the most important property, youll now specify your entry level file by the particular performance, equivalent to background scripts, content_scripts, browser_actions (toolbar buttons), page_actions and options_ui. In my extension, I want to take heed to tab occasions, so I used the background property to load a script.

The permissions property is used, however in one other way. The worth is now an array as a substitute of an object, and any values you had are possible not supported anymore, and can have to be changed. You may learn in regards to the supported permissions keys and values on the manifest.json permissions web page on MDN.

There are extra non-obligatory fields not lined right here. Learn in regards to the different fields within the new manifest.json docs, and for reference listed right here are the previous package.json docs.

Migrating the Functionality

The circulate of All the time Proper is that it listens to an occasion that specifies that a model new tab has been opened, after which modifies the index of that tab such that it’s instantly to the correct of the presently lively tab.

I first moved my /lib/main.js file to /index.js and specified it as a background script within the manifest.json file as famous above.

I then migrated the code in /index.js from the previous SDK tabs API to the WebExtensions tabs API. The previous SDK code used the event and the model new code makes use of the WebExtensions tabs.onCreated event.

For instance, this:

window.tabs.on(‘open’, function(newTab) { // do stuff});

Turned into this:

browser.tabs.onCreated.addListener(function(newTab) { // do stuff});

A extra fascinating conversion was the proper method to get entry to the presently lively tab.

In the SDK, you may possibly merely entry window.tabs.activeTab, however within the new world of extensions youll want to do this:

browser.tabs.query({currentWindow: true, lively: true}).then(function(tabs) { // do stuff with the lively tab var activeTab = tabs[0];});

Those had been the principle adjustments. Utility logic and code circulate stayed just about the identical as earlier than. Nonetheless, since its a model new API with different behaviors, a few issues got here up. I needed to make the next adjustments:

The WebExtensions API code initializes earlier than the lively tab is retrievable, so I wanted so as to add checks for the lively tab and no-op if it wasnt out there yet.

The SDK tabs API didnt fireplace when the consumer reopened a previously-closed tab, however the WebExtensions API does. So I had so as to add checks to be positive that I didnt relocate these tabs.

Another habits change is that putting a tab adjoining to a pinned tab thats not the final pinned tab places it on the finish of the tab strip, as a substitute of simply putting it on the finish of the pinned tabs, just like the SDK API did. So now I get all tabs and iterate over them till I discover the final pinned tab, and place the tab there manually.

I additionally needed to ship with some habits thats lower than ideally suited and never fixable yet:

The WebExtensions API executes tabs.onCreated listeners after the tab is added to the tab strip. Because of this with All the time Proper, when you’ve got got loads of tabs (say, hundreds), you may really see the tab added to the far finish of the tabstrip after which whiz again over to the correct of the lively tab. Its dizzying.

Compounding the issue above, the tab strip scrolls to the model new tab, so the presently lively tab is scrolled out of view.

Testing and Debugging

The new, improved developer workflow for testing in an current profile is totally different from the Firefox SDK.

To set up your add-on for testing, open a model new tab navigate to about:debugging (see screenshot below). Click on the Load Momentary Add-on button and choose any file out of your extensions supply listing. Your extension can be installed!

about:debugging screenshot

But what in case you see an error there? What if the performance isn’t working as anticipated? You may debug your extension utilizing the Browser Toolbox. Learn right here the proper method to configure and open the toolbox.

Later within the growth course of I discovered the web-ext CLI which is nice. Use web-ext run such as you would cfx/jpm. It opens in a brief lived profile.


Once my adjustments had been completed and examined, I relied on my new-found pal web-ext and bundled a zipper file with web-ext build. The zip file is discovered within the web-ext-artifacts subdirectory, named with the model new model quantity. I uploaded the file the identical as all the time on, and the extension handed validation. I waited lower than a day and my extension was reviewed and live!

VICTORY! Effectively, not whole victory: Instantly the bugs got here in. In a spectacular show of beneficiant hearts, my customers reported the bugs by giving the add-on 5 star critiques and commenting in regards to the new model being damaged. ?

Ive fastened a lot of the reported points, so my customers and I can now experience fortunately off into the sundown together.

Looking for assist? Theres detailed documentation on migrating your add-ons on MDN, take a glance at the legacy extension porting page.

You can see the supply code to this add-on within the Always Proper repo on Github. In case you see any extra bugs, let me know!

And if youd wish to strive the extension out, you may set up Always Proper from


All code is a piece in progress, and taking part within the growth course of by reporting bugs is the simplest technique to get issues fastened. In case you encounter bugs within the WebExtensions APIs, file them within the WebExtensions elements in Bugzilla.

The bugs I filed whereas migrating this extension:

Dietrich is a technical evangelist at Mozilla. He is labored on Firefox, Firefox OS and quite a few different Mozilla initiatives for over a decade. He is presently touring round Asia talking and writing about Mozilla, Firefox and the Web.

More articles by Dietrich Ayala

Please check this great service at: or visit FREE SERVICES menu
[Total: 0    Average: 0/5]