Mozilla's getting a new look. What do you think? https://mzl.la/brandsurvey

Implementing the widget

Deprecated in Firefox 29 and removed in Firefox 38.

Warning: this tutorial relies on the since-removed Widget API and no longer works with Firefox.

The widget API is deprecated from Firefox 29 onwards. Please see the ui module for replacements. In particular, for a simple button, try the action button or toggle button APIs, and for a more complex widget try the toolbar or sidebar APIs.

We want the widget to do two things:

  • On a left-click, the widget should activate or deactivate the annotator.
  • On a right-click, the widget should display a list of all the annotations the user has created.

Because the widget's click event does not distinguish left and right mouse clicks, we'll use a content script to capture the click events and send the corresponding message back to our add-on.

The widget will have two icons: one to display when it's active, one to display when it's inactive.

So there are three files we'll need to create: the widget's content script and its two icons.

Inside the data subdirectory create another subdirectory widget. We'll keep the widget's files here. This hierarchy isn't mandatory; you could just keep them all under data. But it seems tidier this way.

The widget's content script

The widget's content script just listens for left- and right- mouse clicks and posts the corresponding message to the add-on code:

this.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);

Save this in your data/widget directory as widget.js.

The widget's icons

You can copy the widget's icons from here:

Or, if you're feeling creative, you can make your own icons.  Either way, save them in your data/widget directory.

main.js

Now in the lib directory open main.js and add the following code:

var widgets = require('sdk/widget');
var data = require('sdk/self').data;

var annotatorIsOn = false;

function toggleActivation() {
  annotatorIsOn = !annotatorIsOn;
  return annotatorIsOn;
}

exports.main = function() {

  var widget = widgets.Widget({
    id: 'toggle-switch',
    label: 'Annotator',
    contentURL: data.url('widget/pencil-off.png'),
    contentScriptWhen: 'ready',
    contentScriptFile: data.url('widget/widget.js')
  });

  widget.port.on('left-click', function() {
    console.log('activate/deactivate');
    widget.contentURL = toggleActivation() ?
              data.url('widget/pencil-on.png') :
              data.url('widget/pencil-off.png');
  });

  widget.port.on('right-click', function() {
      console.log('show annotation list');
  });
}

The annotator is inactive by default. It creates the widget and responds to messages from the widget's content script by toggling its activation state. Since we don't have any code to display annotations yet, we just log the right-click events to the console.

Now from the annotator directory type cfx run. You should see the widget in the add-on bar:

Left- and right-clicks should produce the appropriate debug output, and a left-click should also change the widget icon to signal that it is active.

Next we'll add the code to create annotations.

Document Tags and Contributors

 Contributors to this page: wbamberg, Canuckistani, Sheppy
 Last updated by: wbamberg,