6.0 KiB

Adding a Button to the Toolbar

To follow this tutorial you'll need to have [installed the SDK](dev-guide/tutorials/installation.html) and learned the [basics of `cfx`](dev-guide/tutorials/getting-started-with-cfx.html).

To add a button to the toolbar, use the widget module.

Create a new directory, navigate to it, and execute cfx init. Then open the file called "main.js" in the "lib" directory and add the following code to it:

var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");

var widget = widgets.Widget({
  id: "mozilla-link",
  label: "Mozilla website",
  contentURL: "http://www.mozilla.org/favicon.ico",
  onClick: function() {
    tabs.open("http://www.mozilla.org/");
  }
});

The widget is added to the "Add-on Bar" at the bottom of the browser window:

Mozilla icon widget

You can't change the initial location for the widget, but the user can move it to a different toolbar. The id attribute is mandatory, and is used to remember the position of the widget, so you should not change it in subsequent versions of the add-on.

Clicking the button opens http://www.mozilla.org.

Specifying the Icon

If you're using the widget to make a toolbar button, specify the icon to display using contentURL: this may refer to a remote file as in the example above, or may refer to a local file. The example below will load an icon file called "my-icon.png" from the add-on's data directory:

var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");
var self = require("sdk/self");

var widget = widgets.Widget({
  id: "mozilla-link",
  label: "Mozilla website",
  contentURL: self.data.url("my-icon.png"),
  onClick: function() {
    tabs.open("http://www.mozilla.org/");
  }
});

You can change the icon at any time by setting the widget's contentURL property. However, setting the contentURL property will break the channel of communication between this widget and any content scripts it contains. Messages sent from the content script will no longer be received by the main add-on code, and vice versa. This issue is currently tracked as bug 825434.

Responding To the User

You can listen for click, mouseover, and mouseout events by passing handler functions as the corresponding constructor options. The widget example above assigns a listener to the click event using the onClick option, and there are similar onMouseover and onMouseout options.

To handle user interaction in more detail, you can attach a content script to the widget. Your add-on script and the content script can't directly access each other's variables or call each other's functions, but they can send each other messages.

Here's an example. The widget's built-in onClick property does not distinguish between left and right mouse clicks, so to do this we need to use a content script. The script looks like this:

window.addEventListener('click', function(event) {
  if(event.button == 0 && event.shiftKey == false)
    self.port.emit('left-click');

  if(event.button == 2 || (event.button == 0 && event.shiftKey == true))
    self.port.emit('right-click');
    event.preventDefault();
}, true);

It uses the standard DOM addEventListener() function to listen for click events, and handles them by sending the corresponding message to the main add-on code. Note that the messages "left-click" and "right-click" are not defined in the widget API itself, they're custom events defined by the add-on author.

Save this script in your data directory as "click-listener.js".

Next, modify main.js to:

  • pass in the script by setting the contentScriptFile property
  • listen for the new events:
var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");
var self = require("sdk/self");

var widget = widgets.Widget({
  id: "mozilla-link",
  label: "Mozilla website",
  contentURL: "http://www.mozilla.org/favicon.ico",
  contentScriptFile: self.data.url("click-listener.js")
});

widget.port.on("left-click", function(){
  console.log("left-click");
});

widget.port.on("right-click", function(){
  console.log("right-click");
});

Now execute cfx run again, and try right- and left-clicking on the button. You should see the corresponding string written to the command shell.

Attaching a Panel

Panel attached to a widget

If you supply a panel object to the widget's constructor, then the panel will be shown when the user clicks the widget:

data = require("sdk/self").data

var clockPanel = require("sdk/panel").Panel({
  width:215,
  height:160,
  contentURL: data.url("clock.html")
});

require("sdk/widget").Widget({
  id: "open-clock-btn",
  label: "Clock",
  contentURL: data.url("History.png"),
  panel: clockPanel
});

To learn more about working with panels, see the tutorial on displaying a popup.

Learning More

To learn more about the widget module, see its API reference documentation.

To learn more about content scripts, see the content scripts guide.