WebExtensions in Firefox 48

We last updated you on our progress with WebExtensions when Firefox 47 landed in Developer Edition (Aurora), and today we have an update for Firefox 48, which landed in Developer Edition this week.

With the release of Firefox 48, we feel WebExtensions are in a stable state. We recommend developers start to use the WebExtensions API for their add-on development. Over the last release more than 82 bugs were closed on WebExtensions alone.

If you have authored an add-on in the past and are curious how it’s affected by the upcoming changes, please use the lookup tool. There is also a wiki page filled with resources to support you through the changes.

APIs Implemented

Many APIs gained improved support in this release, including: alarms, bookmarks, downloads, notifications, webNavigation, webRequest, windows and tabs.

The options v2 API is now supported so that developers can implement an options UI for their users. We do not plan to support the options v1 API, which is deprecated in Chrome. You can see an example of how to use this API in the WebExtensions examples on Github.

image08

In Firefox 48 we pushed hard to make the WebRequest API a solid foundation for privacy and security add-ons such as Ghostery, RequestPolicy and NoScript. With the current implementation of the onErrorOccurred function, it is now possible for Ghostery to be written as a WebExtension.

The addition of reliable origin information was a major requirement for existing Firefox security add-ons performing cross-origin checks such as NoScript or uBlock Origin. This feature is unique to Firefox, and is one of our first expansions beyond parity with the Chrome APIs for WebExtensions.

Although requestBody support is not in Firefox 48 at the time of publication, we hope it will be uplifted. This change to Gecko is quite significant because it will allow NoScript’s XSS filter to perform much better as a WebExtension, with huge speed gains (20 times or more) in some cases over the existing XUL and XPCOM extension for many operations (e.g. form submissions that include file uploads).

We’ve also had the chance to dramatically increase our unit test coverage again across the WebExtensions API, and now our modules have over 92% test coverage.

Content Security Policy Support

By default WebExtensions now use a Content Security Policy, limiting the location of resources that can be loaded. The default policy for Firefox is the same as Chrome’s:

"script-src 'self'; object-src 'self';"

This has many implications, such as the following: eval will no longer work, inline JavaScript will not be executed and only local scripts and resources are loaded. To relax that and define your own, you’ll need to define a new CSP using the content_security_policy entry in the WebExtension’s manifest.

For example, to load scripts from example.com, the manifest would include a policy configuration that would look like this:

"content_security_policy": "script-src 'self' https://example.com; object-src 'self'"

Please note: this will be a backwards incompatible change for any Firefox WebExtensions that did not adhere to this CSP. Existing WebExtensions that do not adhere to the CSP will need to be updated.

Chrome compatibility

To improve the compatibility with Chrome, a change has landed in Firefox that allows an add-on to be run in Firefox without the add-on id specified. That means that Chrome add-ons can now be run in Firefox with no manifest changes using about:debugging and loading it as a temporary add-on.

Support for WebExtensions with no add-on id specified in the manifest is being added to addons.mozilla.org (AMO) and our other tools, and should be in place on AMO for when Firefox 48 lands in release.

Android Support

With the release of Firefox 48 we are announcing Android support for WebExtensions. WebExtensions add-ons can now be installed and run on Android, just like any other add-on. However, because Firefox for Android makes use of a native user interface, anything that involves user interface interaction is currently unsupported (similar to existing extensions on Android).

You can see what the full list of APIs supported on Android in the WebExtensions documentation on MDN, these include alarms, cookies, i18n and runtime.

Developer Support

In Firefox 45 the ability to load add-ons temporarily was added to about:debugging. In Firefox 48 several exciting enhancements are added to about:debugging.

If your add-on fails to load for some reason in about:debugging (most commonly due to JSON syntax errors), then you’ll get a helpful message appearing at the top of about:debugging. In the past, the error would be hidden away in the browser console.

image02

It still remains in the browser console, but is now visible that an error occurred right in the same page where loading was triggered.

image04

Debugging

You can now debug background scripts and content scripts in the debugging tools. In this example, to debug background scripts I loaded the add-on bookmark-it from the MDN examples. Next click “Enable add-on debugging”, then click “debug”:

image03

You will need to accept the incoming remote debugger session request. Then you’ll have a Web Console for the background page. This allows you to interact with the background page. In this case I’m calling the toggleBookmark API.

image06

This will call the toggleBookmark function and bookmark the page (note the bookmark icon is now blue. If you want to debug the toggleBookmark function,  just add the debugger statement at the appropriate line. When you trigger toggleBookmark, you’ll be dropped into the debugger:image09

You can now debug content scripts. In this example I’ve loaded the beastify add-on from the MDN examples using about:debugging. This add-on runs a content script to alter the current page by adding a red border.

All you have to do to debug it is to insert the debugger statement into your content script, open up the Developer Tools debugger and trigger the debug statement:

image05

You are then dropped into the debugger ready to start debugging the content script.

Reloading

As you may know, restarting Firefox and adding in a new add-on is can be slow, so about:debugging now allows you to reload an add-on. This will remove the add-on and then re-enable the add-on, so that you don’t have to keep restarting Firefox. This is especially useful for changes to the manifest, which will not be automatically refreshed. It also resets UI buttons.

In the following example the add-on just calls setBadgeText to add “Test” onto the browser action button (in the top right) when you press the button added by the add-on.

image03

Hitting reload for that add-on clears the state for that button and reloads the add-on from the manifest, meaning that after a reload, the “Test” text has been removed.

image07

This makes developing and debugging WebExtensions really easy. Coming soon, web-ext, the command line tool for developing add-ons, will gain the ability to trigger this each time a file in the add-on changes.

There are also lots of other ways to get involved with WebExtensions, so please check them out!

Update: clarified that no add-on id refers to the manifest as a WebExtension.

16 comments on “WebExtensions in Firefox 48”

  1. Mindaugas J. wrote on

    Exciting!

    > This will remove the add-on and then re-enable the add-on, so that you don’t have to keep restarting Firefox.
    What happens to add-on storage, e. g. localStorage, indexedDB, storage.local?

    1. Andy McKay wrote on

      Currently nothing. However if https://bugzilla.mozilla.org/show_bug.cgi?id=1213990 lands, it will be cleared.

      1. Anton wrote on

        Hmm, this will make it very tedious to develop / test / debug addons which require any configuration — edit code, refresh, re-enter all config again, try, fail (with my luck), start over.

        I certainly understand why clearing data is relevant for uninstall, but for reload this seems overkill.

  2. Łukasz Polowczyk wrote on

    Do you bring CSS API interface for Firefox?
    And if you bring an API interface to modify elements of Firefox?

  3. Chris Parker wrote on

    How is Native Messaging coming along? connectNative()?

    1. Andy McKay wrote on

      Follow the bug here: https://bugzilla.mozilla.org/show_bug.cgi?id=1190682

  4. Per Bothner wrote on

    I’m finding it difficult to find information about how one could write a stand-alone application with WebExtensions. I.e. is there are replacement for:

    firefox –app /path/to/app/application.ini

    I’ve written a terminal emulator in JavaScript (http://domterm.org), and I want to start up new terminal emulator window without the user necessarily know that Firefox is involved. For example, I don’t want a location bar. Currently, that is fairly easy to do with XUL and the –app option. However, everything I’ve seen about WebExtensions focuses on plugins or extensions running in a regular browser session, with regular browser Chrome.

  5. Joe wrote on

    I was wondering if it is possible to use WebExtension APIs in SDK based add-ons. This way we can gradually migrate to WebExtensions without the need to break the add-ons. For instance for now I would like to use “chrome.browserAction” in my SDK based add-on.

    P.S: I know webRequest can be used in SDK based add-ons.
    https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/WebRequest.jsm

    Anyhow it seems having a reference about how to use WebExtension APIs in both SDK based and XUL based extension would help developers a smoother migration.

    P.S: Currently most SDK based modules are available to XUL based extensions through “require” calls;
    var {require} = Cu.import(“resource://gre/modules/commonjs/toolkit/require.js”, {});

    1. Andy McKay wrote on

      In progress, check out the bugs under: https://bugzilla.mozilla.org/show_bug.cgi?id=1252272

  6. Per Bothner wrote on

    Is there some write-up somewhere on how to write stand-alone applications, rather than just browser add-ons? Currently you can write an application with XUL, completely replacing the browser chrome (including location bar), and start it up with:

    firefox -app /path/to/application.ini

    Is there some example of how to the equivalent with WebExtensions?

    1. Andy McKay wrote on

      Not that I know of. If you make any explorations into that area, I’d be curious to know how it goes.

  7. someone wrote on

    Can I use the WebExtension APIs to create a “web firewall”, requiring the user to click before any network connection is made or any piece of content is interpreted/run?

    1. Andy McKay wrote on

      Probably, check out the webNavigation and webRequest APIs https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/WebNavigation, https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/WebRequest.

  8. Alan Miles wrote on

    Concentrating more toward Chromium is very limiting original purpose /power of FF whileiIt is going to be more resource hungry than Chrome?

  9. Glen Little wrote on

    My Web Extension was rejected, with this message: “We do not allow the Google Analytics script to be included in the extension, you need to use a content iframe to include GA.”

    Is there any documentation explaining this? I do not use iframes anywhere, and don’t see how that would help. How do I use Google Analytics in the extension?

  10. Sero wrote on

    Is it possible in Webextensions to block requests based on their content? It looks like webRequest.onBeforeRequest with the requestBody parameter would be the right way, but requestBody is not available. And to call a manuell XHR request to the URL will perform an asynchronous request, which could not be “returned” to the webRequest block parameter. So, is there actually a way to perform such an extension? Or is it just with requestBody possible? If yes, when will it be available?