Category Archives: addons

Mozilla addons: jQuery Injection / Script File Injection

UPDATE: @ZER0 suggested to use data.url instead of data.load

In my last blog post I described different ways of interaction between content scripts and pages. One of them was to inject inline scripts in the page. Today I describe a way to inject scripts files such as jQuery in a page.

If the value or function you want to insert in the page is not dynamically generated (i.e. it never changes), you’d better put it in its own file. To do that, you simply need to retrieve the url of the script file from the addon code, pass it to the content script and then inject it.

Passing The URL

The script that you want to inject in the page should be stored in the “data” folder, just like a content script. The URL is retrieved with the usual data.url utility and then passed to a content script using “port.emit” / “port.on“.

// in main.js
  include: "",
  contentScriptWhen: "start",
  contentScriptFile: data.url( "injecter.js" ),
  onAttach: function( worker ) {
    	worker.port.emit( "init", data.url( "toBeInjected.js" ) );
// in injecter.js
self.port.on("init", function( scriptURL ) {
  // use the URL

Using an “init” event just to pass a value is rather annoying, but a “contentScriptGlobals” should be added to a future version of the SDK to simplify this, see bug 688127.

Injecting the Script

The code of the injecter is pretty straightforward.

// injecter.js
var script = document.createElement( "script" );
script.type = "text/javascript";

self.port.on("init", function( scriptURL ) {
  script.src = scriptURL;
  window.document.body.appendChild( script );

If you have a cleaner way to inject a script in a page, I’d love to hear from it!

Mozilla addons: Interactions between Content Scripts and pages

Addons created with Mozilla’s Addon SDK have a secure mean of communication with web pages: Content Scripts. Although the interaction between addons and content scripts is fairly well documented, this doc lacks some details about the range of possible interactions between content scripts and the page itself.

The window Wrapper

Content scripts have access to a window object which is actually only a wrapper around the DOM of the page. The entire DOM API is available, so you can manipulate the page at will, but variables and functions stored in the global scope of the page aren’t available:

// inline script in
window.test = "value";
// main.js, our addon
  include: ["*"],
  contentScriptWhen: "end",
  contentScript: "console.log( 'test: ' + window.test );"

When loading, the previous page-mod will display “test: undefined” in the error console. Likewise, it is impossible to create a variable in the content script, and access it in the page.

// main.js, our addon
  include: ["*"],
  contentScriptWhen: "start",
  contentScript: "window.test = 'value';"
// inline script in
console.log( "test: " + window.test );

Again, the inline script will log “test: undefined“.

The SDK docs also demonstrates how easy it is to listen to mouse events in the page and pass them to the addon:

// content script loaded by the page-mod
contentScript =
  "window.addEventListener('click', function( event ) {"+
  "  self.port.emit('click',;"+

Moar Interaction Pliz

Manipulating the DOM and waiting for mouse or key events is good, but what if you want to pass data to your page or receive data from it? what if you absolutely need to create variables or functions in the page?

The wrong way of doing so is to use the undocumented unsafeWindow object instead of the wrapped and secure window one. This completely defeats the security model of the addon SDK, and since it’s an undocumented feature, it could well disappear in a future update of the SDK.

The right way of doing so is to inject inline scripts in the page and/or use customEvents:

Inline Script Injection

Inline scripts are a third level of scripts (where 1O hours are a minute) that can be used to create variables or functions in the global scope:

// Quotes nesting would be a real mess now,
// let's use a separate file loaded as a contentScriptFile
var script = document.createElement( "script" );
script.innerHTML = "var test =" + JSON.stringify( anyValue )+";";
document.body.appendChild( script );

Validation of this code will output warnings, as addons shouldn’t create script tags. But this is still the safest alternative to the unsafeWindow.


customEvents are very similar to mouse events, except that they are programmatically triggered, and that they can transport arbitrary (jsonable) data between content scripts and pages, in both directions:

// inline script in
var evt = document.createEvent("CustomEvent");
evt.initCustomEvent( "transData", true, false, jsonableValue );
// in contentScript.js
window.addEventListener( "transData", function( event ) {
  // the data is available in the detail property of the event
  self.port.emit( "transData", event.detail );

I had to use both of these technics in my geolocation debugging addon (geo-devtool) to interact with the Google Maps API, and I’m pretty sure there are much more use cases.

PS: I’m willing to propose improvements to the SDK docs on this topic once the content of this blog post is validated by someone in the addon team.