DEVELOPERS RELEASES WEBEXTENSIONS
Extensions in Firefox 67
Mike Conca March 26, 2019 7 responses
There are a couple of major changes coming to Firefox. One is in the current Beta 67 release,
while the other in the Nightly 68 release, but is covered here as an early preview for
extension developers.
Respecting User Privacy
The biggest change in release 67 is Firefox now offers controls to determine which
extensions run in private browsing windows. Prior to this release, all extensions ran in all
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
windows, normal and private, which wasn’t in line with Mozilla’s commitment to user privacy.
Starting with release 67, though, both developers and users have ways to specify which
extensions are allowed to run in private windows.
Going Incognito
For extension developers, Firefox now fully supports the value not_allowed for the manifest
`incognito` key. As with Chrome, specifying not_allowed in the manifest will prevent the
extension from running or receiving events from private windows.
The Mozilla Add-on Policies require that extensions not store browsing data or leak identity
information to private windows. Depending on what features your extension provides, using
not_allowed might be an easy way to guarantee that your extension adheres to the policy.
Note that Chrome’s split value for incognito is not supported in Firefox at this time.
Raising User Awareness
There are significant changes in Firefox’s behavior and user interface so that users can
better see and control which extensions run in private windows. Starting with release 67,
any extension that is installed will be, by default, disallowed from running in private windows.
The post-install door hanger, shown after an extension has been installed, now includes a
checkbox asking the user if the extension should be allowed to run in private windows.
To avoid potentially breaking existing user workflows, extensions that are already installed
when a user upgrades from a previous version of Firefox to version 67 will automatically be
granted permission to run in private windows. Only newly installed extensions will be
excluded from private windows by default and subject to the installation flow described
above.
There are significant changes to the Add-ons Manager page (about:addons), too. First, a
banner at the top of the page describes the new behavior in Firefox.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
This banner will remain in Firefox for at least two releases to make sure all users have a
chance to understand and get used to the new policy.
In addition, for each extension that is allowed to run in private windows, the Add-ons
Manager will add a badge to the extension’s card indicating that it has this permission, as
shown below.
The lack of a badge indicates that the extension is not allowed to run in private windows and
will, therefore, only run in normal windows. To change the behavior and either grant or
revoke permission to run in private windows, the user can click on an extension’s card to
bring up its details.
On the detail page, the user can choose to either allow or disallow the extension to run in
private windows.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Finally, to make sure that users of private windows are fully aware of the new extension
behavior, Firefox will display a message the first time a user opens a new private window.
Proper Private Behavior
As a developer, you should take steps to ensure that, when the user has not granted your
extension permission to run in private windows, it continues to work normally. If your
extension depends on access to private windows, it is important to communicate this to your
users, including the reasons why access is needed. You can use the
extension.isAllowedIncognitoAccess API to determine whether users have granted your
extension permission to run in private windows.
Note that some WebExtension API may still affect private windows, even if the user has not
granted the calling extension access to private windows. The browserSettings API is the
best example of this, where an extension may make changes to the general behavior of
Firefox, including how private windows behave, without needing permission to access
private windows.
Finally, there is a known issue where some extensions that use the proxy.settings API require
private browsing permission to use that API even in normal windows (all other proxy API
work as expected). Mozilla is working to address this and will be reaching out to impacted
developers.
User Scripts Are Coming
This is a bit of a teaser for Firefox 68, but after many months of design, implementation and
testing, a WebExtensions user scripts API is just about ready. User scripts have been around
for a very long time and are often closely associated with Firefox. With the help of a user
script extension such as Greasemonkey or Tampermonkey, users can find and install scripts
that modify how sites look and/or work, all without having to write an extension themselves.
Support for user scripts is available by default in the Nightly version of Firefox 68, but can be
enabled in both the current Firefox release (66) and Beta release (67) versions by setting the
following preference in about:config:
extensions.webextensions.userScripts.enabled = true
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
This is a fairly complex feature and we would love for developers to give it a try as early as
possible, which is why it’s being mentioned now. Documentation on MDN is still being
developed, but below is a brief description of how this feature works.
Registering A User Script
The userScripts API provides a browser.userScripts.register API very similar to the
browser.contentScripts.register API. It returns a promise which is resolved to an API object
that provides an unregister method to unregister the script from all child processes.
const registeredUserScript = await browser.userScripts.register(
userScriptOptions // object
);
...
await registeredUserScript.unregister();
userScriptOptions is an object that represents the user scripts to register. It has the same
syntax as the contentScript options supported by browser.contentScripts.register that
describe which web pages the scripts should be applied to, but with two differences:
It does not support a css property (use browser.contentScripts.register to
dynamically register/unregister stylesheets).
It supports an optional property, scriptMetadata, a plain JSON object which contains
metadata properties associated with the registered user script.
Providing User Script Functionality
To support injected user scripts, an extension must provide a special kind of content script
called an APIScript. Like a regular content script, it:
runs in the content processes
has access to the window and document globals related to the webpage attached to
it
can use the same subset of WebExtension APIs usually available in a content script
The APIScript is declared in the manifest using the user_scripts.api_script property:
manifest.json
{
...
"user_scripts": {
"api_script": "apiscript.js",
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
}
}
The APIScript is executed automatically on any page matched by the userScript.register
API called from the same extension. It is executed before the user script is executed.
The userScript API also provides a new event, browser.userScripts.onBeforeScript, which
the APIScript can listen for. It is called right before a matched user script is executed,
allowing the APIScript to export custom API methods to the user script.
browser.userScripts.onBeforeScript.addListener(listener)
browser.userScripts.onBeforeScript.removeListener(listener)
browser.userScripts.onBeforeScript.hasListener(listener)
In the above API, listener is a function called right before a user script is executed. The
function will be passed a single argument, a script object that represents the user script
that matched a web page. The script object provides the following properties and methods:
metadata – The scriptMetadata property that was set when the user script was
registered via the userScripts.register API.
global – Provides access to the isolated sandbox for this particular user script.
defineGlobals – An API method that exports an object containing globally available
properties and methods to the user script sandbox. This method must be called
synchronously to guarantee that the user script has not already executed.
export – An API method that converts a given value to a value that the user script code
is allowed to access (this method can be used in API methods exported to the userScript
to result or resolve non primitive values, the exported objects can also provide methods
that the userScripts code is allowed to access and call).
The example below shows how a listener might work:
browser.userScripts.onBeforeScript.addListener(function (script) {
script // This is an API object that represents the userScript
// that is going to be executed.
script.metadata // Access the userScript metadata (returns the
// value of the scriptMetadata property from
// the call to userScripts.register
// Export some global properties into the userScript sandbox
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
// (this method has to be called synchronously from the
// listener, otherwise the userScript may have been already
// be executed).
script.defineGlobals({
aGlobalPropertyAccessibleFromUserScriptCode: “prop value”,
myCustomAPIMethod(param1, param2) {
// Custom methods exported from the API script can use
// the WebExtensions APIs available to the extension
// content scripts
browser.runtime.sendMessage(...);
...
return 123; // primitive values can be returned directly
...
// Non primitive values have to be exported explicitly
// using the export method provided by the script API
// object
return script.export({{
objKey1: {
nestedProp: "nestedvalue",
},
// Explicitly exported objects can also provide methods.
objMethod() { ... }
},
async myAsyncMethod(param1, param2, param2) {
// exported methods can also be declared as async
},
});
});
Miscellaneous Items
It was a busy release and besides the two major features detailed above, a number of
smaller features (and fixes) also made it into Firefox 67.
Support for setting storage.managed values via an enterprise policy.
Extension context menus now respect any enterprise policy that has restricted the
removal of extensions.
It is now possible to theme the foreground and background colors of the selected text in
the URL bar.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Corrected the implementation of runtime.setUninstallURL to honor `null` as an accepted
value.
Preserved the state of tabs, including lazy loading, when moving between windows.
Updated the browser_style CSS to properly style invalid input elements.
Prevented the built-in CTRL+Page Up/Down keyboard shortcut from being assigned to
an extension.
Made the UI for extensions with a lot of keyboard shortcuts much easier to understand
and navigate.
Any optional permissions granted to extensions are now properly removed when the
extension is uninstalled.
Match patterns now properly support IPv6 literals.
Thank You
Within the WebExtensions API, a total of 74 bugs were closed in Firefox 67. Volunteer
contributors continue to be an integral part of the effort and a huge thank you goes out
those that contributed to this release, including: Oriol Brufau, Shailja Agarwala, Edward Wu,
violet.bugreport and rugk. The combined efforts of Mozilla and its amazing community
members are what make Firefox the best browser in the world.
Tags: developers, firefox 67, releases, webextensions
Browse fast. Browse free.
Download Firefox
Gallupo wrote on March 27, 2019 at 12:50 am:
Many good news to look forward to, but I hope that userscripts are
something the user has to enable themself (just as today where extension
require a informed decision). Or else i forsee a storm incoming with millions
of uninformed users having something enabled by default…
Jessica wrote on March 27, 2019 at 10:26 am:
Y’all absolutely ruined the add-ons UI with Firefox 64. It’s not even properly
responsive like the old one and the new one hides a lot of information that I
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
actually use and makes many functions more annoying to use like the
changelog.
Oh and we’re still waiting for something a little closer to the add-ons we had
before. This is happening so slowly. I might as well use Chrome because
Firefox doesn’t have a one up anymore. In fact, Chrome does. I can set
permissions for indidivual sites on Chrome. One benefit Firefox does have
however, is non-ephemeral Flash permissions but Flash use will be getting
*even harder* with 69, and I haven’t even touched on the terrible
performance of Flash compared to Chrome.
J Redhead wrote on April 15, 2019 at 11:31 pm:
Just FYI it is actually possible adjust permissions for individual sites in
firefox, the UI is just hidden/clunkier:
Click the lock for site information, then show connection details (arrow
next to connection), and and “More Information” — This will open the
page info popup for the page, which includes permissions.
They really ought to expose all the information better (or at least have a
keyboard shortcut to open page info!)
erosman wrote on March 28, 2019 at 10:55 am:
FireMonkey has been using the new user script API since Firefox 65.
https://addons.mozilla.org/firefox/addon/firemonkey/
Kilazur wrote on April 2, 2019 at 9:43 am:
I just lost all my installed addons after this update. It seems Firefox simply
reinstalled itself, and even re-imported bookmarks (from the last installation,
I assume, since I don’t seem to have lost anything in that department).
Any reason why?
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Caitlin Neiman wrote on April 3, 2019 at 4:52 pm:
Hi Kilazur, this might have been related to a new dedicated profile being
installed when you upgraded to Firefox 67 (https://support.mozilla.org/en-
US/kb/dedicated-profiles-firefox-installation#w_what-changes-are-we-
making-to-profiles-in-firefox-67). You might want to try switching back to a
previous profile and see if your extensions are still installed (instructions
here: https://support.mozilla.org/en-US/kb/profile-manager-create-and-
remove-firefox-profiles).
If it wasn’t due to the profile installation, you may need to ask our support
team at https://support.mozilla.org to help investigate further.
basil wrote on April 24, 2019 at 9:59 pm:
“we disabled legacy addons because they were a security risk, but here,
have userscripts that could also be trouble!”
yes. i see the logic here.
(also as a note, since i’m getting the “we don’t support this version of firefox”
notifs on some of the sites i use, now i have to go to a sketchy github page
to download a tweak for quantum to re-enable the legacy addons i need to
work/use the internet. So that whole “doing it for your safety” thing worked
out real well)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF