Add-ons using the techniques described in this document are considered a legacy technology in Firefox. 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.
From Firefox 53 onwards, no new legacy add-ons will be accepted on addons.mozilla.org (AMO).
From Firefox 57 onwards, WebExtensions will be the only supported extension type, and Firefox will not load other types.
Even before Firefox 57, changes coming up in the Firefox platform will break many legacy extensions. These changes include multiprocess Firefox (e10s), sandboxing, and multiple content processes. Legacy extensions that are affected by these changes should migrate to WebExtensions if they can. See the "Compatibility Milestones" document for more.
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:
- the user clicks the item
- the content script's
click
event fires, and the content script retrieves the selected text and sends a message to the add-on - 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.