This article explains the basics of creating an add-on for FireFox using the FireFox Add-on Builder and Add-on SDK. Read more about them on the Mozilla website.
As an example, I’ll use the GroupDocs add-on. (You can download the source code from Github.) It’s an advanced extension so I’ll focus on the basics and highlight a couple of interesting aspects communication between scripts. I’ll mainly look at the add-on folders data and lib in the /resources/groupdocsviewer/ folder.
Creating an add-on: main.js
The main.js file, located in the lib folder, is the entry point for the extension. It is executed when you install the add-on and then each time the browser is launched. At the top of the file is a ;ist of libraries linked in using the SDK command require():
- The widget library is used to create the icon that users click to open the GroupDocs add-on’s main window.
- The panel library creates the GroupDocs window that contains the add-on interface.
- The passwords library stores personal information in the FireFox Password Manager.
Once the panel is created, the script creates a widget. The widget is a button that can be seen in FireFox’s add-ons panel. To create the widget, define an ID, a label and an image. The image is the icon that users click to start the GroupDocs extension. Lastly, define the panel that will be launched when the icon is clicked. The code that follows the widget definition consists of message handlers.
Communication between scripts
I mentioned that the scripts that run in the add-on interface do not have access to the main.js file’s context. They also can’t call the FireFox API: the FireFox API only works within the main.js context. This means that the add-on has two execution contexts: the main.js file, which as access to the FireFox API, and script files that work with the add-on window’s DOM model.
Since main.js and the scripts that run in the panel don’t have direct access to each other’s content, we need to use messages to communicate between the two. To send a messages from main.js, use the panel object’s port.emit() method. It takes two parameters: the message, as a string, and the object the message is for.
To receive messages from the main.js file, use the panel class’ port.on() method. This too takes two parameters: the message, as a string, and the parameter handling function. When a message arrives, this function can take the second parameter of the sent object – port.emit().
GroupDocs defines a message handler for storing and removing credentials in FireFox’s Password Manager. This process illustrates how to pass messages between main.js and the GroupDocs window.
The first message is received when a user logs in and has selected the Remember me option. The second message is received when a user clicks Logout. You’ll notice, in the main.js file, in the first function, that the script checks whether the user is already logged in. If they are, the panel sends a message containing the login data. This way, users do not have to log in every time they restart the browser.
Messages to other Scripts
Sending and receiving messages here is a little more complicated. The methods port.on() and port.emit() are located within the object itself, and the object is available in the global context, that is, it’s not visible to other functions or objects. Keep a reference to the object so that you can use it when you run the file. It is worth noticing that to start carrying out any actions in the popup.js file follows not in the first line of the file, but in the method which has received the message from the main.js file.
This is how it works: widgets and panels are created in main.js. Then we have a message handler that ensures that a “show” message is generated when the panel is displayed. Code in main.js catches the message and sends a similar message to popup.js. Code in popup.js catches the message and initialises the extension.
To interact with the FireFox API, send a message to main.js which, after working with the FireFox API, sends a message back to popup.js with the results.