Beginning development with Jetpack SDK 0.2
This article is a translation of a recent article in Japanese by fellow Jetpack Ambassador Gomita which was published on the Mozilla Labs Jetpack blog. I’m cross-posting it here for posterity.
Mozilla Labs recently released version 0.2 of the Jetpack SDK, which fixes some issues of the 0.1 release such as a glitch regarding development with Windows. SDK 0.2 doesn’t include the planned APIs for rapid development of new browser functionality, but you can still play with SDK 0.2 to get a flavor for development with the Jetpack SDK.
In this article we begin by setting up an SDK 0.2 development environment and explain the steps required to develop a simple, practical add-on using SDK 0.2. The instructions here are for Windows, but the basic steps are the same in every platform.
Installing Python
The first step to using the Jetpack SDK is to install Python. How to install Python depends on your OS, but in Windows you can choose the “Python 2.6.5 Windows installer” from the Python site and follow the installation wizard. Here, I’ll use C:\Python26\
as the installation path.
After the install, you can activate the python
command in your command line by adding C:\Python26
to the Windows Path
preference. (If there is already another value, delimit with a semicolon: “;”.) Run the command “cmd” from the Start menu to start the command prompt and run python -V
to confirm the Python version, Python 2.6.2
:
C:\>python -V Python 2.6.2
Note, the
Jetpack SDK Docs state that Python 2.5+ is required, but there seem to be some incompatibilities with Python 3.0.1 at this time. In addition, in my experience the SDK worked fine without the “Python for Windows extensions.”
Setting up the Jetpack SDK
Next, we set up the Jetpack SDK. Download the Jetpack SDK 0.2 package from the Jetpack site, unzip it, and place it somewhere convenient. Here, I used C:\jetpack-sdk-0.2
.
To use the Jetpack SDK, it must be “activated.” From the command prompt, go to the Jetpack SDK folder and run bin\activate
:
Next, run cfx docs
to open the SDK documentation in the browser. The SDK documentation starts a local server on port 8888.
The package directory structure
Addons built with the Jetpack SDK are called “packages.” Let’s try building a simple “hello world”-style package, but first let’s see what the final directory structure of this package will look like:
directory/file | Note |
---|---|
jetpack-sdk-0.2 | the Jetpack SDK folder |
packages | the main packages folder |
hello-world | package root |
package.json | package manifest file |
README.md | package documentation |
lib | the package code directory |
main.js | main program code |
simple-dialog.js | a custom code library |
The package’s root directory is placed in the “packages” directory in the Jetpack SDK folder, and includes the package.json
manifest file and the README.md
documentation file. The lib
folder includes the package’s main program code and any custom libraries used by our addon.
Creating the package
We begin by creating the hello-world
directory in C:\jetpack-sdk-0.2\packages
. Next the manifest file package.json
is created. The manifest file includes metadata about our package in JSON format. If you’ve ever created a XUL-style addon before, you can think of this as similar to the install.rdf
file. Here, I used the following as the manifest:
The id
property is used as a unique ID for all addons including Jetpack packages and is often formatted as an email address. This corresponds to XUL-based addons’ <em:id>
tag.
Next, reload the SDK documentation in the browser and confirm that “hello-world” shows up under “Package Reference.”
Writing the main code
The next step is to add some working code to the hello-world package. Create a lib
folder under the package root and create a main.js
under lib
with the following code:
The main program code is always loaded as a module called main
. This main
property is made accessible from outside code using the CommonJS-style code exports.main = ...
. console.log
is a global function made available by Jetpack and the SDK prints the string to the command prompt.
It’s worth noting that, in the current Jetpack SDK, calling “console.log("こんにちは");
” doesn’t yield the expected Japanese output. In the future such output will be handled through the planned localization API.
Testing our package
With some simple code in our main
function, it’s time to try this code out. To test this code, we run cfx run -a firefox
in the command prompt. By running cfx run
with the -a firefox
option, we load our package into a brand new Firefox profile and launch Firefox.
After Firefox loads, confirm that the command prompt reads info: Hello, World!
When you quit Firefox, the testing will end.
Using a standard library
Now we’ll edit our code to invoke the timer library which is one of the Jetpack SDK’s standard libraries. The timer library is a module which abstracts various timer-related functionality, similar to the DOM’s window.setTimeout
, window.clearTimeout
. Details on this library are available in the SDK documentation. Moreover, although not in the documentation, timer.setInterval
and timer.clearInterval
also work in this version.
To use this library in our main program code, we first must invoke this library with the CommonJS require function. We modify the main.js
file as follows:
After this change, run cfx run -a firefox
in the command prompt to test it. Check to make sure that the current time is being printed to the command prompt once a second:
Creating a custom library
Next we’ll create a custom library to add some functionality not currently included in the Jetpack standard library. Implementing advanced functionality in add-ons, like filesystem access, involves using XPCOM components. Jetpack encourages seprarating the use of XPCOM components into separate modules which are then used by the main program code. The Jetpack SDK doesn’t currently disallow direct XPCOM access within Jetpack add-on code, but such a restriction is forthcoming. Modularizing XPCOM code into separate libraries now allow you to easily migrate to equivalent standard libraries in the future.
Let’s create a simple-dialog
library to display a modal dialog much like window.alert
does. The Jetpack code’s runtime environment doesn’t include access to the regular window
or document
objects, so just calling window.alert
doesn’t work. To create an alert from this context, we use the <a href="https://developer.mozilla.org/en/nsIPromptService">nsIPromptService</a>
XPCOM component. In our package’s lib
folder, create a simple-dialog.js
file. Just like our main program code, we implement this library as a CommonJS module using exports.<em>methodname</em> = function(...){...}
.
The simple-dialog library will have these two methods:
Method | Note |
---|---|
`alert(<em>text</em>)` | Displays an alert dialog with the string in text and an OK button. Equivalent to the DOM’s `window.alert`. |
`confirmYesNo(<em>text</em>)` | Displays a confirmation dialog with the string in text and Yes and No buttons. The method returns `true` if the user presses “yes” and `false` if “no.” |
Here is the code for simple-dialog.js
:
Lines 1-2 are for calling nsIPromptService
. Note that Cc
, Ci
are aliases for Components.classes
and Components.interfaces
, respectively, and are made available by Jetpack as global variables. Lines 4-6 implement the alert method for showing alert dialogs using nsIPromptService
’s alert
method. Lines 8-14 implement simple-dialog
’s confirmYesNo
method using nsIPromptService
’s confirmEx
method to display the dialog with yes and no buttons. nsIPromptservice
’s confirmEx
method returns 0 if the user presses “yes” and 1 if “no”, so we modify this value and return it.
Using our custom library
Let’s call this new custom library from our main program code and verify that it works. Here’s our updated main.js
file:
Run cfx run -a firefox
and confirm that a confirmation dialog is displayed. Pressing “yes” and “no” should give you the appropriate alert dialogs as well.
Implementing a network status observer
Now let’s use this hello-world package as a foundation for a more practical add-on. Using the <a href="https://jetpack.mozillalabs.com/sdk/0.2/docs/#module/jetpack-core/observer-service">observer-service</a>
module included with the Jetpack SDK, we can monitor Firefox’s online/offline network status changes.
Firefox internally broadcasts various application events to observers via the <a href="https://developer.mozilla.org/ja/NsIObserverService">nsIObserverService</a>
XPCOM component. When Firefox goes offline, a network:offline-status-changed
notification is broadcast. To subscribe this notification and act on it, we use the observer-service
library’s add
method. add
’s first argument is the name of the notification we want to subscribe to and the second argument is a callback function. The callback function is given two arguments, of which the second is a string equal to either “online” or “offline.” In our add-on, we’ll check this value and display an appropriate alert using simple-dialog
.
Launch Firefox by running cfx run -a firefox
and then choose “File” > “Work Offline” and you should get a notification:
Adding documentation
If you add documentation to a package, you can view it by clicking that package in the SDK Documentation. To add documentation, create a README.md
file in the package root directory. README.md
is written in Markdown format which looks like this:
Now if you load the SDK documentation using cfx docs
and click on the “hello-world” link, you’ll see this documentation together with the package metadata.
Exporting an install package
Jetpack add-ons which are created in this way can then be exported into Firefox-standard XPI files. To export an XPI, go to the package’s root directory in the command prompt and run cfx xpi
.
This creates an XPI file called hello-world.xpi
. Opening this file in any Firefox profile will let you install it using the regular add-on install mechanism.