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.

28 responses

  1. Oleg wrote on :

    Is it possible to detect which button was pressed on the ActionButton?

    1. ZER0 wrote on :

      You can simply set the same handler for all your buttons, and then inside check the `state.id` or the `this`, it depends by your needs. For example:

      function onClickHandler(state) {
      console.log(‘button clicked: ‘, state.id);
      console.log(‘is button1:’, this === button1);
      }

      let button1 = ActionButton({
      id: “button-one”,
      label: “My first shiny button”,
      icon: “./addon.png”,
      onClick: onClickHandler
      });

      let button2 = ActionButton({
      id: “button-two”,
      label: “My second shiny button”,
      icon: “./addon.png”,
      onClick: onClickHandler
      });

      1. Oleg wrote on :

        Sorry, I meant how can I detect which mouse button (right, middle or left) was pressed on a button?

        1. ZER0 wrote on :

          As also Will noted, the Firefox UI currently permit only left clicking on a button, reserving right-clicking for the toolbar’s context menu. The new API are meant to provide a good and a consistent user experience across add-ons; if the UX policy about that will change – so, any buttons could have at least it’s on context menu or perform a different actions based on click – the API would be updated as well.

          On technical details, in fact, we’re not using the “click” handler, but the “command” ones (see: https://developer.mozilla.org/en-US/docs/XUL/Attribute/oncommand), so we just rely on what the platform itself consider as “execution of a command”.

          However, in your custom `toolbar`, you can create a `frame` where the document would handle the click listener – and therefore react in any way you want to, because you’re loading a HTML document, your not creating any Firefox standard components.

  2. Vitaly Tomilin wrote on :

    Please make SDK documentation available offline, as a part of SDK, just like it is now a part of ASDK-1.15. Thank you.

    1. wbamberg wrote on :

      I don’t think we’ll ever go back to the place where the docs shipped “as a part of the SDK”, simply because most of the SDK now ships in Firefox itself, and independent SDK releases are quite rare and irregular these days, and are likely to become more so rather than less.

      As for making the docs available offline: now that all the SDK docs are on MDN, this is something that would need to be done in the MDN platform itself. It’s a long-requested feature over there, see: https://bugzilla.mozilla.org/show_bug.cgi?id=665750.

      It’s a pity that the offline feature for the SDK docs has been lost, for sure, but there are other benefits to having the docs on MDN.

  3. Mardeg wrote on :

    Which type of button is best for using a modifier key while right/middle-clicking the button to get to a third/forth/fifth state?

    1. wbamberg wrote on :

      As far as I know, using right-clicking in buttons is against the Australis UX policy, since that should be reserved for the toolbar’s context menu.

  4. patricia white wrote on :

    how do i delete proxy server

  5. Jonah Bishop wrote on :

    I have an old-school Firefox extension that adds a toolbar (with an embedded toolbaritem) to the browser. Is there a way I can prevent this toolbaritem element from being moved to the menu panel area? I don’t mind it living on a toolbar (where I intend), or in the customize palette (if the user chooses to hide it for some reason), but it shouldn’t live in the new menu panel. In my particular case, that location doesn’t make sense for the UI I provide (there’s simply not enough room). I haven’t seen any mention of ways that existing items can be prevented from being moved to the panel, but perhaps I’ve simply missed something.

  6. Franz wrote on :

    How can I use those exact APIs in non-SDK addons? As the SDK now ships with Firefox this should surely be possible, but how?

    1. Jeff Griffiths wrote on :

      You need to use Firefox 29 or higher ( 29 is the ‘Australis’ release, currently in Beta, that includes these new apis )

      1. Franz wrote on :

        That’s all, really? Firefox also has the require() function built-in?

        1. Jeff Griffiths wrote on :

          Yes, if you’re using the Add-on SDK it uses CommonJS modules and `require()`, similar to how node.js works.

          1. Franz wrote on :

            Yeah but my addon’s a siimple bootstrapped addon, that’s not built with the Addon SDK. Can I still use SDK APIs?

  7. Jeff Griffiths wrote on :

    This is still possible, you would need to get access to the loader yourself. The loader is documented here:

    https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/_loader

    As this is advanced usage of the SDK, your best bet might be to ask in #jetpack on irc.mozilla.org for help.

    1. Franz wrote on :

      Thanks!

  8. Mikhail Khvoinitsky wrote on :

    Will this work on Firefox for Android?

    1. Jeff Griffiths wrote on :

      No, these apis are specific to the new UI features in desktop Firefox.

    2. ZER0 wrote on :

      The button API at least, were designed to be “Firefox for Android friendly”, compared to the Widget that weren’t. But so far there is no plan to implement that platform – not only on SDK side, but on Fennec side too: I pinged from time to time, but define a “space” in the Fennec UI where put add-ons buttons seems not a priority so far.

      My hope is that soon or later we could support Firefox for Android too.

  9. Alexander wrote on :

    ActionButtons that are moved from toolbar to menu panel seem to ignore changes to the “disabled” property from then on. Couldn’t find this in Bugzilla, is this a known problem?

    1. wbamberg wrote on :

      Alexander, thanks for reporting this. I can reproduce it in Firefox 29 but it seems to be fixed in Firefox 30. There were some bugs around disabled state, and I guess this fix did not make it into Firefox 29.

  10. karthik wrote on :

    i have retrieved data from the indexed db and have stored it in a variable.
    1)how do i display this entire string on the panel?
    2) can we give an id for a panel?

    please help.
    thank in advance

  11. Рамиль wrote on :

    Where can I find documentation that describes the testing add-on? restart your browser after every save the script, very tiring.

    1. Jeff Griffiths wrote on :

      If I understand you correctly, you might be interested in this add-on: http://adblockplus.org/blog/faster-extension-development-cycle-install-changes-automatically

  12. buwuwei wrote on :

    How do i combine two action buttons into one ‘unit/button’ the same way the firefox bookmark addon does ? Thanks in advance

  13. Nishanth wrote on :

    How do I have the button hidden by default, so that the user can get it from the customizable toolbar later if he desires? I am aware of the `disabled`, but I’m looking to completely hide it from view by default. Thanks.

    1. Jeff Griffiths wrote on :

      I’ve logged this bug to document that. I suspect there is a way to do this ( and we should document how ) but I do not know myself.