We are planning to deprecate the use by Firefox add-ons of the techniques described in this document.

Don't use these techniques to develop new add-ons. Use WebExtensions instead.

If you maintain an add-on which uses the techniques described here, consider migrating it to use WebExtensions instead.

Add-ons developed using these techniques might not work with multiprocess Firefox (e10s), which is already the default in Firefox Nightly and Firefox Developer Edition, and will soon be the default in Beta and Release versions of Firefox. We have documentation on making your add-ons multiprocess-compatible, but it will be more future-proof for you to migrate to WebExtensions.

A wiki page containing resources, migration paths, office hours, and more, is available to help developers transition to the new technologies.

To follow this tutorial you'll need to have learned the basics of jpm.

To add items and submenus to the Firefox context menu, use the context-menu module.

Here's an add-on that adds a new context menu item. The item is displayed whenever something in the page is selected. When it's clicked, the selection is sent to the main add-on code, which just logs it:

var contextMenu = require("sdk/context-menu");
var menuItem = contextMenu.Item({
  label: "Log Selection",
  context: contextMenu.SelectionContext(),
  contentScript: 'self.on("click", function () {' +
                 '  var text = window.getSelection().toString();' +
                 '  self.postMessage(text);' +
                 '});',
  onMessage: function (selectionText) {
    console.log(selectionText);
  }
});

Try it: run the add-on, load a web page, select some text and right-click. You should see the new item appear:

Click it, and the selection is logged to the console (or the shell, if you're running an instance of Firefox from the command line):

info: elephantine lizard

Details

All this add-on does is to construct a context menu item. You don't need to add it: once you have constructed the item, it is automatically added in the correct context. The constructor in this case takes four options: label, context, contentScript, and onMessage.

label

The label is just the string that's displayed.

context

The context describes the circumstances in which the item should be shown. The context-menu module provides a number of simple built-in contexts, including this SelectionContext(), which means: display the item when something on the page is selected.

If these simple contexts aren't enough, you can define more sophisticated contexts using scripts.

contentScript

This attaches a script to the item. In this case the script listens for the user to click on the item, then sends a message to the add-on containing the selected text.

onMessage

The onMessage property provides a way for the add-on code to respond to messages from the script attached to the context menu item. In this case it just logs the selected text.

So:

  1. the user clicks the item
  2. the content script's click event fires, and the content script retrieves the selected text and sends a message to the add-on
  3. the add-on's message event fires, and the add-on code's handler function is passed the selected text, which it logs

More options

Adding an image

You can add an image to a context menu item with the image option. This is a URL pointing to a 16x16 icon that's displayed at the left side of the context menu item. Typically you'd store the image in your add-on's "data" directory, and construct the URL using self.data.url():

var self = require("sdk/self");

var contextMenu = require("sdk/context-menu");
var menuItem = contextMenu.Item({
  label: "Log Selection",
  context: contextMenu.SelectionContext(),
  contentScript: 'self.on("click", function () {' +
                 '  var text = window.getSelection().toString();' +
                 '  self.postMessage(text);' +
                 '});',
  image: self.data.url("icon-16.png"),
  onMessage: function (selectionText) {
    console.log(selectionText);
  }
});

Adding an access key

New in Firefox 35.

From Firefox 35 you can specify an access key using the accesskey option. This must be a single-character string. Pressing the key selects the option when the context menu is open:

var contextMenu = require("sdk/context-menu");
var menuItem = contextMenu.Item({
  label: "Log Selection",
  context: contextMenu.SelectionContext(),
  contentScript: 'self.on("click", function () {' +
                 '  var text = window.getSelection().toString();' +
                 '  self.postMessage(text);' +
                 '});',
  accesskey: "l",
  onMessage: function (selectionText) {
    console.log(selectionText);
  }
});

 

Learning More

To learn more about the context-menu module, see the context-menu API reference.

Document Tags and Contributors

 Last updated by: wbamberg,