This section of the tutorial takes you through the process of implementing, running and packaging a simple add-on using the SDK. The add-on will add a menu item to Firefox's context menu, to appear when anything in the page is selected. The menu item displays a popup dialog containing the Wikipedia entry for the selected text.
Create a directory called wikipanel
. This is where we will keep all the
files for this add-on.
You do not have to create this directory under the SDK root: once you have
called source bin/activate
from the SDK root, cfx
will remember where the
SDK is, and you will be able to reference SDK packages from any directory.
Keeping your add-on code outside the SDK is good practice as it makes it easier for you to update the SDK and to manage your code using a version control system.
Next we'll use cfx init
to create a skeleton structure for your add-on.
Navigate to the wikipanel
directory and execute cfx init
. You should see
something like this:
* lib directory created * data directory created * test directory created * doc directory created * README.md written * package.json written * test/test-main.js written * lib/main.js written * doc/main.md written Your sample add-on is now ready for testing: try "cfx test" and then "cfx run". Have fun!"
First, cfx init
creates the directory structure your add-on needs:
-
/data
contains resources such as icons or HTML files, as well as any content scripts included with your add-on. You can access the content of thedata
subdirectory from within your add-on's code using the Add-on SDK'sself
module. -
/doc
contains any documentation for your add-on. -
/lib
contains the JavaScript modules implementing your add-on. -
/test
contains unit test code.
Next, cfx init
creates a file called package.json
in the root wikipanel
directory. This contains information about your add-on and should look
something like this:
{ "name":"wikipanel", "fullName":"wikipanel", "description":"This is an example of addon description.", "author":"", "license":"MPL", "version":"0.1" }
Finally, cfx init
creates some example files under doc
, lib
, and
test
: we will replace those.
In the lib
directory, open the file called main.js
and replace its
contents with the following:
// Import the APIs we need.
var contextMenu = require("context-menu");
var panel = require("panel");
exports.main = function(options, callbacks) {
console.log(options.loadReason);
// Create a new context menu item.
var menuItem = contextMenu.Item({
label: "What's this?",
// Show this item when a selection exists.
context: contextMenu.SelectionContext(),
// When this item is clicked, post a message back with the selection
contentScript: 'self.on("click", function () {' +
' var text = window.getSelection().toString();' +
' self.postMessage(text);' +
'});',
// When we receive a message, look up the item
onMessage: function (item) {
console.log('looking up "' + item + '"');
lookup(item);
}
});
};
function lookup(item) {
wikipanel = panel.Panel({
width: 240,
height: 320,
contentURL: "http://en.wikipedia.org/w/index.php?title=" +
item + "&useformat=mobile"
});
wikipanel.show();
}
The first two lines are used to import two SDK modules from the addon-kit package:
context-menu
enables add-ons to add new items to the context menupanel
enables add-ons to display popup windows
Next, this code constructs a context menu item. It supplies:
- the text to appear in the menu: "What's this?"
- a context in which the item should be displayed:
SelectionContext()
, meaning: include this item in the context menu whenever some content on the page is selected - a script to execute when the item is clicked: this script sends the selected
text to the function assigned to the
onMessage
property - a value for the
onMessage
property: this function will now be called with the selected text, whenever the user clicks the menu.
The supplied function loads the Wikipedia entry for the selection into a panel.
The code which creates the context menu is wrapped in a function which we have
assigned to the main
property of the global exports
object.
If your add-on exports a function called main
, that function will be called
when the add-on is loaded.
exports.main = function (options, callbacks) {};
options
is an object describing the parameters with which your add-on was
loaded. In particular, options.loadReason
is one of the following strings
describing the reason your add-on was loaded: install
, enable
, startup
,
upgrade
, or downgrade
.
Conversely, if your add-on exports a function called onUnload
, that function
will be called when the add-on is unloaded.
exports.onUnload = function (reason) {};
reason
is one of the following strings describing the reason your add-on was
unloaded: uninstall
, disable
, shutdown
, upgrade
, or downgrade
.
You don't have to use exports.main
or exports.onUnload
. You can just place
your add-on's code at the top level instead of wrapping it in a function
assigned to exports.main
: it will be loaded in the same circumstances, but
you won't get access to the options
or callbacks
arguments.
This particular add-on doesn't need to use exports.main
for anything, and
only includes it to illustrate its use.
Note the calls to console.log()
here. console
is a global object accessible
by any module, which you can use to write error, warning, or informational
messages.
For an add-on which has been packaged as an XPI file and installed into
Firefox, the messages are sent to Firefox's
Error Console. If you are
launching Firefox from the command line using cfx
, as you will be for
development and debugging, then the messages are sent to the command shell
from which you launched Firefox.
For more information on the console
object see its
documentation page.
To run your program, navigate to the wikipanel
directory and type:
cfx run
The first time you do this, you'll see a message like this:
No 'id' in package.json: creating a new ID for you. package.json modified: please re-run 'cfx run'The ID that `cfx` generated the first time you executed `cfx run` is a unique identifier for your add-on. To learn more about it refer to the [Program ID](dev-guide/addon-development/program-id.html) document.
Run it again, and it will run an instance of Firefox with your add-on installed.
Once cfx run
has launched Firefox you can try out the new add-on. Load a
page containing some text that is not in English, for example:
http://www.mozilla.org/about/manifesto.fr.html
Select some text on that page and right-click to activate the context menu. You should see a new item labeled "What's this?":
Select that item and you'll see a popup panel showing the Wikipedia entry for the selection:
You will also see output like this appear in your command shell:
info: looking up "Jetpack"
Once you have finished testing your add-on you can package it for deployment like any other Firefox add-on, as a XPI file. The Add-on SDK simplifies the packaging process by generating this file for you.
You can specify an icon for your add-on. This icon will appear beside your add-on in Firefox's Add-ons Manager and on addons.mozilla.org.
To specify an icon, save it as "icon.png" in your add-on's root directory. To
give the icon a different name or to store it in a different location
under the root, use the "icon" key in your package.json
file. See the
Package Specification
for more details.
To package your program as a XPI, navigate to the root of your package
directory in your shell and run cfx xpi
. You should see a message like:
Exporting extension to wikipanel.xpi.
The wikipanel.xpi
file can be found in the directory in which you ran
the command.
Test that the package installs correctly by adding it to your own Firefox installation.
You can do this by pressing the Ctrl+O key combination (Cmd+O on Mac) from
within Firefox. This will bring up a file selection dialog: navigate to the
wikipanel.xpi
file, open it and follow the prompts to install the
add-on.
Alternatively:
-
Open the Firefox Add-ons Manager from within Firefox, either from the Add-ons item on the Tools menu, or by typing
about:addons
into the address bar. -
In the Firefox Add-ons Manager there is a gears icon next to the search bar. Click the icon and select "Install Add-on From File..." from the menu that appears. Again, this will bring up a file selection dialog which you can use to find and open the XPI file.
Once you have installed the add-on you can test it in exactly the same way as in the "Running It" section above.
To distribute your program, you can upload it to addons.mozilla.org. Eventually, this step may be automated via the SDK, streamlining the distribution process further.
In the next section we'll introduce CommonJS, which provides the infrastructure for the SDK.