Add-ons Blog

Announcing Add-on SDK 1.16!

I’m pleased to announce the immediate availability of Add-on SDK 1.16! You can download the SDK directly in either zip or tarball format. This is a minor release meant to provide compatibility with Firefox 29 and a smooth development experience when using the new Australis UI apis I featured in my previous post. In addition, this new release fixes the following issues:

  • Bug 944951 – “bootstrap.js must remove the added resource: URIs on unload”
  • Bug 958609 – “Add-on SDK 1.15 incompatible with Python 2.7.6″
  • Bug 963401 – “Console is flooded with javascript strict warnings” sorry for any confusion, this change did not make it to release.

The AMO validator tool is scheduled to be updated to support extensions created with SDK 1.16 next Tuesday April 1st (no, really). As always, we’d love to hear from you about your experiences with this release. You can contact us in a variety of ways:

post to our discussion group
chat with us on irc.mozilla.org #jetpack
report a bug
check out the source and contribute bug fixes, enhancements, or documentation

For more information on the Jetpack Project check out our wiki.

Add-ons Update – Week of 2014/03/26

I post these updates every 3 weeks to inform add-on developers about the status of the review queues, add-on compatibility, and other happenings in the add-ons world.

The Review Queues

  • Most nominations for full review are taking less than 2 weeks to review.
  • 77 nominations in the queue awaiting review.
  • Most updates are being reviewed within 10 days.
  • 65 updates in the queue awaiting review.
  • Most preliminary reviews are being reviewed within 1 week.
  • 83 preliminary review submissions in the queue awaiting review.

If you’re an add-on developer and would like to see add-ons reviewed faster, please consider joining us. Add-on reviewers get invited to Mozilla events and earn cool gear with their work. Visit our wiki page for more information.

Firefox 28 Compatibility

The add-on compatibility update for Firefox 28 is up, and the compatibility bump for AMO add-ons was run.

Firefox 29 Compatibility (Australis!)

This is a big one. The add-on compatibility update post is still pending, but we already have a few posts explaining some of what’s new:

More on this coming up. As usual we recommend using the Aurora and Beta branches to test your add-ons ahead of time.

Finally, we’re running a contest! If you’re an extension or complete theme developer, we have 3 categories you can compete in to win a Firefox OS phone and other goodies. Please visit the contest page for more information.

New Add-on SDK Australis UI features in Firefox 29

Update: the ability to attach a panel to a button, and the ability to include buttons in toolbars, are not included in Firefox 29 (the current Beta release). Both these features are in Firefox 30 (the current Aurora release). Note that it is still possible to add frames to toolbars in Firefox 29.


With Australis entering Beta, I’m pleased to introduce four new APIs for building your add-on’s user interface: the action button, the toggle button, the toolbar, and the frame.

Buttons, buttons everywhere

First up, we have two APIs for adding buttons to Firefox: action buttons and toggle buttons.

You give action buttons an icon, a label, and a click handler:

var ui = require("sdk/ui");
 
var action_button = ui.ActionButton({
  id: "my-button",
  label: "Action Button!",
  icon: "./icon.png",
  onClick: function(state) {
    console.log("You clicked '" + state.label + "'");
  }
});

Unless you add them to a toolbar of your own, they appear in the toolbar at the top right of the browser window:

action-button-toolbar

Toggle buttons are just the same, except they’re meant to represent an on/off state, like a checkbox. So they have a “checked” property which is toggled when the user clicks the button, and the icon gets a “pressed” look when the button is checked:

var ui = require("sdk/ui");
 
var toggle_button = ui.ToggleButton({
  id: "my-button",
  label: "my button",
  icon: "./icon.png",
  onChange: function(state) {
    console.log(state.label + " checked state: " + state.checked);
  }
});

You can also attach panels to toggle buttons, by passing the button into the panel’s constructor or its show() method.

panel-attach

Toolbars and frames

The toolbar API lets you create more complex persistent user interfaces. You can add buttons to a toolbar, and can also add frames, which are essentially iframes with message passing between page scripts and your main add-on code. You create a frame by specifying the local HTML content to load into it.

Here’s an example that defines a toolbar with a single frame and three action buttons:

var ui = require('sdk/ui');
 
var previous = ui.ActionButton({
  id: "previous",
  label: "previous",
  icon: "./icons/16-back.png"
});
 
var next = ui.ActionButton({
  id: "next",
  label: "next",
  icon: "./icons/16-next.png"
});
 
var play = ui.ActionButton({
  id: "play",
  label: "play",
  icon: "./icons/16-play.png"
});
 
var frame = ui.Frame({
  url: "./frame-player.html"
});
 
var toolbar = ui.Toolbar({
  title: "Player",
  items: [previous, next, play, frame]
});

Toolbars occupy a complete strip of the browser window, just above the content window:

toolbar2

Learning more

There’s full reference documentation on all these APIs on MDN, and I’ve created an example add-on to check out.

Australis for Add-on Developers – Part 2: CustomizableUI

In the previous Australis post, I covered what you would need to change in your extension to adapt to the new toolbars in the Australis theme. In this installment I’ll cover a very exciting addition that facilitates the creation of toolbar widgets: the CustomizableUI module.

While the size of the module and its docs may seem overwhelming, in reality it’s very easy to use if you just intend to add a button to one of the customizable areas in Firefox. I made a couple of simple extensions to try it out and demonstrate how it works.

The demos only work on Australis, so to try them out you need Firefox 29 (currently on Aurora) or Firefox 30 (Nightly).

1. Hello Demo

XPI. Code on Github.

For the first demo I went with the classic “Hello World” example. I also wanted to make it a restartless extension, and this is where I think CustomizableUI really shines. Creating a restartless add-on that adds a button to the toolbar has never been this easy.

First you need to import the module, of course:

Cu.import("resource:///modules/CustomizableUI.jsm");

Then you create the widget in your startup process using the create widget function:

CustomizableUI.createWidget(
  { id : "aus-hello-button",
    defaultArea : CustomizableUI.AREA_NAVBAR,
    label : "Hello Button",
    tooltiptext : "Hello!",
    onCommand : function(aEvent) {
      let win = aEvent.target.ownerDocument.defaultView;
 
      win.alert("Hello!");
    }
  });

The ID of the widget is the same ID that the button will have in the DOM. The default area is where the widget will be added, in this case the main toolbar. The list of possible areas can be found in the doc. You’ll usually want either AREA_NAVBAR or AREA_PANEL for the menu panel.

The command code is straightforward: use the event parameter to get to the browser window and then show a simple alert.

And then of course you want to clean it up in the shutdown process:

CustomizableUI.destroyWidget("aus-hello-button");

With only this you already have a functional toolbar button add-on. The button can be customized and moved around, and its position will be remembered. It works wherever you put it. But it’s missing all CSS, so it doesn’t have an icon yet (it’s also missing localization, but that can be added with a string bundle).

For a regular add-on that requires a restart, adding the styles is simple enough. Create a chrome.manifest file, declare a skin and then a style that applies to browser.xul:

style chrome://browser/content/browser.xul chrome://aus-hello/skin/toolbar.css

For a restartless add-on this is a little trickier because style manifest declarations aren’t supported. You still need the manifest and the skin, but the style needs to be injected, in this case using the stylesheet service:

let io =
  Cc["@mozilla.org/network/io-service;1"].
    getService(Ci.nsIIOService);
 
this._ss =
  Cc["@mozilla.org/content/style-sheet-service;1"].
    getService(Ci.nsIStyleSheetService);
this._uri = io.newURI("chrome://aus-hello/skin/toolbar.css", null, null);
this._ss.loadAndRegisterSheet(this._uri, this._ss.USER_SHEET);

This loads the stylesheet for all documents, so it’s prudent to limit the styles to the document we want in the CSS file:

@-moz-document url("chrome://browser/content/browser.xul") {
/* Code goes here*/
}

And then clean everything up:

if (this._ss.sheetRegistered(this._uri, this._ss.USER_SHEET)) {
  this._ss.unregisterSheet(this._uri, this._ss.USER_SHEET);
}

Note: loading the stylesheet this way is inefficient. The second demo takes a better approach using the loadSheet function, but it would have required too much additional code for this example.

That’s it! With the 16×16 and 32×32 icons as recommended in part 1, you should have a functional Hello World add-on.

2. View Demo

XPI. Code on Github.

Another type of widget you can create is a view. This is a button with a popup panel when in the toolbar, and a side panel when in the menu panel. The Bookmarks and History widgets in Australis versions are this type of widget.

To create the widget, the code is only slightly different:

CustomizableUI.createWidget(
  { id : "aus-view-button",
    type : "view",
    viewId : "aus-view-panel",
    defaultArea : CustomizableUI.AREA_NAVBAR,
    label : "Hello Button",
    tooltiptext : "Hello!",
    onViewShowing : function (aEvent) {
      // initialize code
    },
    onViewHiding : function (aEvent) {
      // cleanup code
    }
  });

The differences are the type (which defaults to button), the viewId and the onViewShowing and onViewHiding events.

viewId is the ID of a <panelview> that must exist in the browser window DOM. This is very easy to do in a regular extension where you can just create an overlay with the view and whatever content you want in it. For a restartless extension you’ll need a window listener and inject the view and its contents into the DOM for all windows. To make things simple, I decided to use a XUL iframe as the only child element, so I don’t have to build everything dynamically.

let panel = doc.createElement("panelview");
let iframe = doc.createElement("iframe");
 
panel.setAttribute("id", "aus-view-panel");
iframe.setAttribute("id", "aus-view-iframe");
iframe.setAttribute("type", "content");
iframe.setAttribute("src", "chrome://aus-view/content/player.html");
 
panel.appendChild(iframe);
doc.getElementById("PanelUI-multiView").appendChild(panel);

The onViewShowing and onViewHiding events should be used to set up the view before it appears, and to clean it up after it disappears.

This demo is meant to detect links to MP3 or OGG files on web pages and use the <audio> element to play them. So, the code in onViewShowing should scan the currently active page for these links and pass the paths of the audio files to the player inside the iframe. Should be easy, right?

There’s a small problem. When the view is shown, the view node is moved from where you put it to a different part of the DOM. This extraction and reinsertion resets the elements inside the panel. On top of that, this happens after onViewShowing is called. So, manipulating the iframe in onViewShowing is not going to work because all changes will be reset when the view is actually shown. There are a couple of ways of solving this:

  1. Instead of depending on onViewShowing, the code inside the iframe can detect when it is loaded and run the code itself. However, that also means stepping out of that document to obtain the links in the active tab, so it takes a lot of extra code.
  2. Add a timeout to the onViewShowing code so it runs slightly later and when the iframe is available for modifications. This is a hacky solution, but also the simplest, so I went with this one since it’s only a demo.

With that little hack in, the extension works well. You can try it out on Web Archive pages like this one.

Australis view

SDK Add-ons

SDK add-ons developers can use this module, which encapsulates what CustomizableUI does for the rest.

References

Add-ons Update – Week of 2014/03/05

I post these updates every 3 weeks to inform add-on developers about the status of the review queues, add-on compatibility, and other happenings in the add-ons world.

The Review Queues

  • Most nominations for full review are taking less than 2 weeks to review.
  • 72 nominations in the queue awaiting review.
  • Most updates are being reviewed within 10 days.
  • 67 updates in the queue awaiting review.
  • Most preliminary reviews are being reviewed within 1 week.
  • 90 preliminary review submissions in the queue awaiting review.

If you’re an add-on developer and would like to see add-ons reviewed faster, please consider joining us. Add-on reviewers get invited to Mozilla events and earn cool gear with their work. Visit our wiki page for more information.

BabelZilla

BabelZilla continues to be the top resource for add-on localization. It’s a free and open community of translators who will help you reach users in areas of the world you wouldn’t even imagine. As such, it is powered by the people who support it. So, if your native language is not English, and especially if you know Arabic, Persian (Farsi) or Hebrew, BabelZilla needs your help.

Please consider taking some time and contribute translating other add-ons. Many developers will be grateful for your help.

Firefox 28 Compatibility

The add-on compatibility update for Firefox 28 is up, and the compatibility bump for AMO add-ons was run.

We tried a new notification format where you should get only one email for all of your add-ons tested, instead of one for each. However, because of this we ran into a couple of problems. In some cases you might have not been notified, and if you did get notified, you got two messages. So, it’s likely we’ll run the validation again, so you’ll get even more email. Hopefully that’ll solve all pending issues and the next compatibility run will happen with minimal messaging for you.

As usual we recommend using the Aurora and Beta branches to test your add-ons ahead of time.

Australis

Australis (Firefox 29) is coming to Beta in less than two weeks! Make sure you test your add-on and stay up to date on Australis news. I published the first installment in a series of posts about it. Check it out: Part 1 – Toolbars. Part 2 is coming up shortly.

It’s very important that you test your add-on as soon as you can and figure out if there’s anything you need to do to make it compatible, or if you discover any bugs in the new theme. The blog post has instructions on how to report bugs for it effectively.

Themes in Australis

Firefox 29, scheduled for the end of April, includes significant design and customization improvements that you can read more about here. You can also experience the new design, nicknamed “Australis”, for yourself on the Aurora channel now. We’ve blogged about how the toolbar, menu, and button changes will affect add-ons, but we also wanted to mention how the changes will affect lightweight themes.

In Firefox 29, the amount of header image shown remains nearly the same, but it now stands out more because the area is less cluttered. You’ll notice that the foreground tab, URL bar, and toolbar are emphasized by a sheer overlay. This makes it easier to distinguish your active tab from non-active tabs, and it also happens to make themes look gorgeous.

Screenshot 2014-02-26 15.53.53

Since the add-on bar is going away, you will no longer see a footer image when you install a theme, unless you are using an extension that modifies your browser to include a bar on the bottom (for example, S3. Download Statusbar). A bug has been filed to make footer images optional when uploading a new theme, and in the future the option may go away altogether.

We hope you install Aurora and give it a try!

March Featured Add-ons

Pick of the Month: Keyword Search

Did you ever wish you could use a different search engine in the URL bar than you do in the search field? Keyword Search allows you to select any of your search engines to use in your URL bar.

This extension is an important sanity-saver.”

Get Keyword Search »

Also Featured

Slim Add-ons Manager
This add-on reduces the height of entries in the Add-on Manager, so you can display more of them at a time. Get it now »

YouTube Unblocker
Watch blocked YouTube Videos automatically with this high-speed Proxy Server. Get it now »

Video WithOut Flash
Fetch the video source of Flash-based media and play the video directly with Firefox, without the use of the Flash plug-in. Get it now »

QrCodeR
QrCodeR is a minimal and non-obtrusive add-on to convert text selections, links and images to QrCode with just a right-click. Get it now »

Nominate your favorite add-ons!

Featured add-ons are selected by a community board made up of add-on developers, users, and fans. Board members change every six months, so there’s always an opportunity to participate. If you’re interested, please follow this blog and look out for invitations that we send out every six months.

If you’d like to nominate an add-on for featuring, please send it to amo-featured@mozilla.org for the board’s consideration. We welcome you to submit your own add-on!

Downloading all of your code from Add-on Builder

Back in December I posted about our plan to turn off the Add-on Builder site. This plan is proceeding as planned and will happen in the beginning of April. In the meantime we’ve gotten some feedback from Builder users, and one common request was for us to provide the ability to download a project’s entire revision history.

I’m pleased to announce that this has been done, on a per-project basis. As of today, when you go to an add-on project on Builder there is an extra button labelled ‘Download All versions’:

Add-on Compatibility for Firefox 28

Firefox 28 will be released on March 18th. Here’s the list of changes that went into this version that can affect add-on compatibility. There is more information available in Firefox 28 for Developers, so you should read that too.

General

XPCOM

New!

Please let me know in the comments if there’s anything missing or incorrect on these lists. If your add-on breaks on Firefox 28, I’d like to know.

The automatic compatibility validation and upgrade for add-ons on AMO will happen soon, so keep an eye on your email if you have an add-on listed on our site with its compatibility set to Firefox 27.