Exposing Extension Functionality to Web-Page Javascript

In this article, I describe how to implement a scriptable XPCOM Component. This type of component exposes some extra functionality to untrusted web-page JavaScript running inside a Gecko-based browser such as Firefox. The implementation itself will be done in JavaScript.


Before we start

First of all, you will need to download a recent version of the Mozilla source code. The Mozilla source code can be obtained either by downloading a source archive, or by using a CVS (source control) client. For our project, downloading a source archive is recommended, but if you wish to go down the CVS road, you should read this MDC article first. In my case, I simply downloaded a tarball of the Firefox 2.0.0.5 source code. Untar it using

tar xjfv <source-file.tar.bz2>

XPCOM uses its own variant of the CORBA OMG Interface Definition Language (IDL) called XPIDL. You will need a special compiler to process your XPIDL files. You can build the compiler yourself (the source for the compiler is under mozilla/xpcom/typelib/xpidl). If you’re on Windows (XP or Vista), you can simply download a statically linked Windows binary here.

Define the component interface

Let’s define the interface of our component. I will not delve into details about the actual XPIDL syntax. You can find more information on this here. This interface resides in a file named nsSimple.idl. The GUID was generated using Microsoft’s GUIDGen.exe.

#include "nsISupports.idl"
[scriptable, uuid(B2A56E5E-CF18-4a8e-8EE9-CE228098516A)]
interface nsISimple : nsISupports {
    // Version string. Readonly!
    readonly attribute string version;
    // Dummy test function.
    string doSomething( in string value );
};

Compile the interface file

This file must be compiled using the XPIDL compiler using the following command line. This should generate a file name nsISimple.xpt.

xpidl -m typelib -w -v -I <path-to-mozilla-source>/mozilla/xpcom/base -o nsISimple nsISimple.idl

Interface implementation

Once you have successfuly created an interface file that publicly defines the component’s methods and attributes, the next step is to implement those methods and attributes in a separate source file named nsSimple.js. The nsSimple object implements the nsISimple interface of course, but also the nsISupports interface (because nsISimple inherits from it) and the nsIClassInfo interface (this is needed because we are writing a scriptable component).

Component registration and instantiation

The second half of the file nsSimple.js contains the code necessary for the component instantiation and automatic registration. This code is fairly generic and does not change much from one component to another.

Install the component and test it

Copy the two files nsISimple.xpt and nsSimple.js to

<path-to-your-firefox-install>/components/

and restart Firefox. Create a simple HTML file as follows:

<html>
  <head>
    <title>XPCOM test page</title>
  </head>
  <body>
    <script>
if (window.simpleObj) {
    alert(simpleObj.version);
    alert(simpleObj.doSomething("foo"));
}
    </script>
  </body>
</html>

and open it up in Firefox. You should see a couple of alerts.

Downloads

I put together a complete archive that contains all the necessary files.

5 thoughts on “Exposing Extension Functionality to Web-Page Javascript

  1. Pingback: Ajax Girl » Blog Archive » YUI-based Image Cropper Widget

  2. Pingback: YUI-based Image Cropper Widget « outaTiME

  3. Pingback: YUI-based Image Cropper Widget » D’ Technology Weblog: Technology News & Reviews

  4. Pingback: All in a days work…

  5. dima Q

    Hey, good article, however it doesn’t really work in FF3 anymore. well technically your code works alright, but doSomething() function is not allowed to do anything useful… just try accessing Components.classes in it and you get an execption. I’m guessing it has something to do with new xpcom wrappers introduced in FF3.

    I’d really like to see this work though :)

Comments are closed.