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
require("page-mod").PageMod({
  include: "http://example.com/",
  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!

12 thoughts on “Mozilla addons: jQuery Injection / Script File Injection

  1. Pingback: Jetpack Project: weekly update for Dec. 13th, 2011 | Mozilla Add-ons Blog

  2. Irvin

    Did you know what’s the different between the method above and following, it works for me perfectly.:
    exports.main = function() {
    var data = require(“self”).data;
    var tabs = require(“tabs”);
    tabs.on(‘ready’, function(tab) {
    tab.attach({ contentScriptFile: [data.url("jquery-1.7.1.min.js"), data.url("script.js")] });
    });
    };

      1. louisremi Post author

        I should’ve made it clearer that the technique described here makes it possible to create variables and functions in the execution context of the page. Normally content scripts operate in an isolated context.

    1. louisremi Post author

      The page-mod module provides options to filter in which tabs the content-script is actually loaded, and when (during page-load).

  3. Simon BdM

    That’s a wonderful web site, full of numerous enlightments !
    Thanks a lot,
    Keep faith.
    Sim BdM
    (and also you’re cute)

  4. Ernesto

    worker is good to communicate in two ways. In this case it is easier to use contentScriptOptions:

    // in main.js
    require("page-mod").PageMod({
    include: "http://example.com/",
    contentScriptWhen: "ready",
    contentScriptFile: data.url( "injecter.js" ),
    contentScriptOptions: {
    showOptions: true,
    toBeInject: data.url("toBeInjected.js")
    }
    });

    // injecter.js
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = self.options.toBeInject;
    window.document.body.appendChild(script);

Comments are closed.