XPCOM components work like Microsoft COM components in that communication between the client and the component is through interfaces. The basic interface for XPCOM is nsISupports. You use the QueryInterface method of nsISupports to retrieve the information regarding your specialized interface (these are the methods and properties that your interface supports).
There are three layers of components: the XPCOM object layer, the nsIFactory layer, and the nsIModule layer. The XPCOM object layer is the guts of the system; this is where you'll put your business logic. The nsIFactory layer is the layer responsible for instantiating the XPCOM object. The nsIModule layer is responsible for registration and providing abstraction to the nsIFactory layer. These three layers are required, and each layer requires certain methods as you can see in Listing A.
The XPCOM component is registered under a friendly name. The Contract ID for XPCOM is like the ProgID for Microsoft COM components. In my example, this is '@mozilla.org/MyComponent;1'.
Contract IDs use the concept of namespaces to identify themselves, so it's important to precede your Contract ID with '@mozilla.org/'. A component's CID is a 128-bit UUID that uniquely identifies the component. The ID() on the Components object accepts a UUID string and returns an nsID object, which is used for registration and instantiation. (I created my UUID by using guidgen.exe on Windows.) Then, there's the component's Interface ID (IID), which is the name of the interface described in the XPT file. In this example, it's nsIMyComponent.
If you examine the code, you'll notice that the actual custom business logic is the reverseIt() method on the nsMyComponent class. The rest of the code is required to make the component work within XPCOM. If you were to create your own component from my example code, you would copy everything as it appears, but you would add your own methods and properties to the nsMyComponent class.
In order for the XPCOM system to acknowledge the nsIMyComponent interface and the exported method, you must provide an XPT type library. You'll do this by creating an IDL file and compiling it with xpidl.exe. Listing B contains the IDL for MyComponent.
The IDL file includes the nsISupports.idl file in order to implement the nsISupports interface on the nsIMyComponent interface. The reverseIt() method is declared, specifying its return type and the parameter it accepts.
I couldn't find a generic download for xpidl.exe, so I created one from bits and pieces that I downloaded from Mozilla.org. I've successfully run this on Windows 2000 and XP. (Here's my generic download.) If you unpack this into a separate directory, you can use the -h on xpidl.exe to get information on its use.
To get this example working, you need to save the source code to the component under "nsMyComponent.js" in the "components" directory under Mozilla in your system. You then save the IDL file as "MyComponent.idl" under the directory where you unpacked the xpidl.zip file. From the command line, navigate to that directory and enter:xpidl -m typelib -w -v -e [path to IDL file]\MyComponent.xpt [path to IDL
This should create a file called "MyComponent.xpt". Copy this file to the "components" directory under Mozilla.
From the command line, navigate to the Mozilla directory and look for "regxpcom.exe". Type in "regxpcom" and enter. This will register all your components for Mozilla. Then, you can look in the "compreg.dat" file to see if your component was registered successfully. Do not edit this file--this is a generated file. If you have Mozilla windows open, you should close all Mozilla windows before attempting to use new components. To test this component, save the HTML in Listing C to a file and open it within Mozilla.
Phillip Perkins is a contractor with Ajilon Consulting. His experience ranges from machine control and client/server to corporate intranet applications.