XPCOMUtils.jsm

  • Revision slug: JavaScript_code_modules/XPCOMUtils.jsm
  • Revision title: XPCOMUtils.jsm
  • Revision id: 45619
  • Created:
  • Creator: Sheppy
  • Is current revision? No
  • Comment 83 words added

Revision Content

{{ gecko_minversion_header("1.9") }}

The XPCOMUtils.jsm JavaScript code module offers utility routines for JavaScript components loaded by the JavaScript component loader.

To use this, you first need to import the code module into your JavaScript scope:

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

Using XPCOMUtils

Exposing a JavaScript class as a component using these utility methods requires four key steps:

  1. Import XPCOMUtils.jsm, as explained previously.
  2. Declare the class (or multiple classes) implementing the component(s).
  3. Create an array of component constructors.
  4. Define the NSGetModule entry point.

Pseudocode

This section provides some pseudocode that demonstrates how to put together a JavaScript class based on the steps listed above.

Constructor

The constructor is a simple method that handles any required initialization tasks.

function MyComponent() {
  // initialize the component here
} 

Class declaration

Declare the class prototype, using a form similar to this.

MyComponent.prototype = {
  // properties required for XPCOM registration:
  classDescription: "unique text description",
  classID:          Components.ID("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"),
  contractID:       "@example.com/xxx;1",

  // [optional] custom factory (an object implementing nsIFactory). If not
  // provided, the default factory is used, which returns
  // |(new MyComponent()).QueryInterface(iid)| in its createInstance().
  _xpcom_factory: { ... },

  // [optional] an array of categories to register this component in.
  _xpcom_categories: [{
    // Each object in the array specifies the parameters to pass to
    // nsICategoryManager.addCategoryEntry(). 'true' is passed for
    // both aPersist and aReplace params.
    category: "some-category",
    // optional, defaults to the object's classDescription
    entry: "entry name",
    // optional, defaults to the object's contractID (unless
    // 'service' is specified)
    value: "...",
    // optional, defaults to false. When set to true, and only if 'value'
    // is not specified, the concatenation of the string "service," and the
    // object's contractID is passed as aValue parameter of addCategoryEntry.
    service: true
  }],

  // QueryInterface implementation, e.g. using the generateQI helper
  QueryInterface: XPCOMUtils.generateQI(
    [Components.interfaces.nsIObserver,
     Components.interfaces.nsIMyInterface,
     "nsIFoo",
     "nsIBar" ]),

  // ...component implementation...
};

Notice that the QueryInterface() method implemented by the component simply calls the generateQI() method provided by the XPCOMUtils code module.

Create an array of component constructors

You need to create an array that lists the constructors for each component. This array can of course have just one entry:

var components = [MyComponent];

Here, we're calling the array components.

Create the NSGetModule() entry point

Finally, you need to implement the NSGetModule() entry point so Gecko can start up your component:

functionNSGetModule(compMgr, fileSpec) {
  // "components" is the array created in the previous section

  return XPCOMUtils.generateModule(components);
}

Method overview

function defineLazyGetter(aObject, aName, aLambda); {{ gecko_minversion_inline("1.9.3") }}
function defineLazyServiceGetter(aObject, aName, aContract, aInterfaceName); {{ gecko_minversion_inline("1.9.3") }}
nsIModule generateModule(componentsArray, postRegister, preUnregister);
function generateNSGetModule(componentsArray, postRegister, preUnregister);
function generateQI(interfaces);

Methods

{{ method_gecko_minversion("defineLazyGetter", "1.9.3") }}

Defines a function on a specified object that acts as a getter which will be created the first time it's used.

function defineLazyGetter(
  aObject,
  aName,
  aLambda
);
Parameters
aObject
The object into which to add the new lazy getter function.
aName
The name of the getter function to create.
aLambda
A function that returns the value the getter should return. This function is called exactly once.
Return value

The created function, which has been added to aObject using the name aName.

{{ method_gecko_minversion("defineLazyServiceGetter", "1.9.3") }}

Defines a function on a specified object which acts as a getter for a service. The service isn't obtained until the first time it's used.

function defineLazyServiceGetter(
  aObject,
  aName,
  aContract,
  aInterfaceName
);
Parameters
aObject
The object into which to ad the new lazy service getter function.
aName
The name of the getter function to create.
aContract
The contract to use to obtain the service.
aInterfaceName
The name of the interface to query the service to.
Return value

The created function, which has been added to aObject with the name aName.

generateModule()

Generates a module implementation.

nsIModule generateModule(
  componentsArray,
  postRegister,
  preUnregister
); 
Parameters
componentsArray
An array of component constructors.
postRegister
An optional function that is called after the module is registered. See Post-registration callback.
preUnregister
An optional function that's called before the module is unregistered. See Pre-unregistration callback.
Return value

An {{ interface("nsIModule") }} that implements the module.

generateNSGetModule()

Generates the NSGetModule() function along with the module definition. You can use this instead of generateModule() to create both the module and the NSGetModule() function at the same time.

nsIModule generateNSGetModule(
  componentsArray,
  postRegister,
  preUnregister
); 
Parameters
componentsArray
An array of component constructors.
postRegister
An optional function that is called after the module is registered. See Post-registration callback.
preUnregister
An optional function that's called before the module is unregistered. See Pre-unregistration callback.
Return value

An {{ interface("nsIModule") }} that implements the module.

generateQI()

Generates a QueryInterface() function implementation. You need to assign the returned function to the QueryInterface property of a JavaScript object.

When the generated method is invoked on that object, it checks to see if the specified IID is listed in the array specified by the interfaces parameter; if it is, this (that is, the object itself) is returned. Otherwise, null is returned.

function generateQI(
  interfaces
); 
Parameters
interfaces
An array of interfaces implemented by the component.
Return value

A QueryInterface() function implementation.

Post-registration callback

The post-registration callback called by generateModule() should have the following signature:

postRegister(
  nsIComponentManager mgr,
  nsIFile file,
  componentsArray
);
Parameters
mgr
An {{ interface("nsIComponentManager") }} instance to use for managing the component.
file
An {{ interface("nsIFile") }} instance for... what?
componentsArray
An array of the components, as passed to generateModule().

The function doesn't need to return a value.

Pre-unregistration callback

See also

{{ languages( { "es": "es/XPCOMUtils.jsm", "ja": "ja/XPCOMUtils.jsm" } ) }}

Revision Source

<p>{{ gecko_minversion_header("1.9") }}</p>
<p>The <span style="font-family: monospace;">XPCOMUtils</span><code>.jsm</code> JavaScript code module offers utility routines for JavaScript components loaded by the JavaScript component loader.</p>
<p>To use this, you first need to import the code module into your JavaScript scope:</p>
<pre class="eval"><span class="nowiki">Components.utils.import("</span><a class=" external" href="resource://gre/modules/XPCOMUtils.jsm" rel="external nofollow" target="_blank" title="resource://gre/modules/XPCOMUtils.jsm"><span class="nowiki">resource://gre/modules/XPCOMUtils.jsm</span></a><span class="nowiki">");</span>
</pre>
<h2>Using XPCOMUtils</h2>
<p>Exposing a JavaScript class as a component using these utility methods requires four key steps:</p>
<ol> <li>Import <code>XPCOMUtils.jsm</code>, as explained previously.</li> <li>Declare the class (or multiple classes) implementing the component(s).</li> <li>Create an array of component constructors.</li> <li>Define the NSGetModule entry point.</li>
</ol>
<h3>Pseudocode</h3>
<p>This section provides some pseudocode that demonstrates how to put together a JavaScript class based on the steps listed above.</p>
<h4>Constructor</h4>
<p>The constructor is a simple method that handles any required initialization tasks.</p>
<pre class="brush: js">function MyComponent() {
  // initialize the component here
} 
</pre>
<h4>Class declaration</h4>
<p>Declare the class prototype, using a form similar to this.</p>
<pre class="brush: js">MyComponent.prototype = {
  // properties required for XPCOM registration:
  classDescription: "unique text description",
  classID:          Components.ID("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"),
  contractID:       "@example.com/xxx;1",

  // [optional] custom factory (an object implementing nsIFactory). If not
  // provided, the default factory is used, which returns
  // |(new MyComponent()).QueryInterface(iid)| in its createInstance().
  _xpcom_factory: { ... },

  // [optional] an array of categories to register this component in.
  _xpcom_categories: [{
    // Each object in the array specifies the parameters to pass to
    // nsICategoryManager.addCategoryEntry(). 'true' is passed for
    // both aPersist and aReplace params.
    category: "some-category",
    // optional, defaults to the object's classDescription
    entry: "entry name",
    // optional, defaults to the object's contractID (unless
    // 'service' is specified)
    value: "...",
    // optional, defaults to false. When set to true, and only if 'value'
    // is not specified, the concatenation of the string "service," and the
    // object's contractID is passed as aValue parameter of addCategoryEntry.
    service: true
  }],

  // QueryInterface implementation, e.g. using the generateQI helper
  QueryInterface: XPCOMUtils.generateQI(
    [Components.interfaces.nsIObserver,
     Components.interfaces.nsIMyInterface,
     "nsIFoo",
     "nsIBar" ]),

  // ...component implementation...
};
</pre>
<p>Notice that the <code>QueryInterface()</code> method implemented by the component simply calls the <a href="/en/JavaScript_code_modules/XPCOMUtils.jsm#generateQI()" title="en/JavaScript code modules/XPCOMUtils.jsm#generateQI()"><code>generateQI()</code></a> method provided by the XPCOMUtils code module.</p>
<h4>Create an array of component constructors</h4>
<p>You need to create an array that lists the constructors for each component. This array can of course have just one entry:</p>
<pre>var components = [MyComponent];
</pre>
<p>Here, we're calling the array <code>components</code>.</p>
<h4>Create the NSGetModule() entry point</h4>
<p>Finally, you need to implement the <code>NSGetModule()</code> entry point so Gecko can start up your component:</p>
<pre>functionNSGetModule(compMgr, fileSpec) {
  // "components" is the array created in the previous section

  return XPCOMUtils.generateModule(components);
}</pre>
<h2>Method overview</h2>
<table class="standard-table"> <tbody> <tr> <td><code>function <a href="/en/JavaScript_code_modules/XPCOMUtils.jsm#defineLazyGetter()" title="en/JavaScript code modules/XPCOMUtils.jsm#defineLazyGetter()">defineLazyGetter</a>(aObject, aName, aLambda);</code> {{ gecko_minversion_inline("1.9.3") }}</td> </tr> <tr> <td><code>function <a href="/en/JavaScript_code_modules/XPCOMUtils.jsm#defineLazyServiceGetter()" title="en/JavaScript code modules/XPCOMUtils.jsm#defineLazyServiceGetter()">defineLazyServiceGetter</a>(aObject, aName, aContract, aInterfaceName);</code> {{ gecko_minversion_inline("1.9.3") }}</td> </tr> <tr> <td><code>nsIModule <a href="/en/JavaScript_code_modules/XPCOMUtils.jsm#generateModule()" title="en/JavaScript code modules/XPCOMUtils.jsm#generateModule()">generateModule</a>(componentsArray, postRegister, preUnregister);</code></td> </tr> <tr> <td><code>function <a href="/en/JavaScript_code_modules/XPCOMUtils.jsm#generateNSGetModule()" title="en/JavaScript code modules/XPCOMUtils.jsm#generateNSGetModule()">generateNSGetModule</a>(componentsArray, postRegister, preUnregister);</code></td> </tr> <tr> <td><code>function <a href="/en/JavaScript_code_modules/XPCOMUtils.jsm#generateQI()" title="en/JavaScript code modules/XPCOMUtils.jsm#generateQI()">generateQI</a>(interfaces);</code></td> </tr> </tbody>
</table><h2>Methods</h2>
<p>{{ method_gecko_minversion("defineLazyGetter", "1.9.3") }}</p>
<p>Defines a function on a specified object that acts as a getter which will be created the first time it's used.</p>
<pre><code>function defineLazyGetter(<br>  aObject,<br>  aName,<br>  aLambda<br>);</code> </pre>
<h6>Parameters</h6>
<dl> <dt><code>aObject<br> </code></dt> <dd>The object into which to add the new lazy getter function.</dd> <dt><code>aName</code></dt> <dd>The name of the getter function to create.</dd> <dt><code>aLambda</code></dt> <dd>A function that returns the value the getter should return. This function is called exactly once.</dd>
</dl>
<h6>Return value</h6>
<p>The created function, which has been added to <code>aObject</code> using the name <code>aName</code>.</p>
<p>{{ method_gecko_minversion("defineLazyServiceGetter", "1.9.3") }}</p>
<p>Defines a function on a specified object which acts as a getter for a service. The service isn't obtained until the first time it's used.</p>
<pre>function defineLazyServiceGetter(
  aObject,
  aName,
  aContract,
  aInterfaceName
);
</pre>
<h6>Parameters</h6>
<dl> <dt><code>aObject</code></dt> <dd>The object into which to ad the new lazy service getter function.</dd> <dt><code>aName</code></dt> <dd>The name of the getter function to create.</dd> <dt><code>aContract</code></dt> <dd>The contract to use to obtain the service.</dd> <dt><code>aInterfaceName</code></dt> <dd>The name of the interface to query the service to.</dd>
</dl>
<h6>Return value</h6>
<p>The created function, which has been added to <code>aObject</code> with the name <code>aName</code>.</p>
<h3>generateModule()</h3>
<p>Generates a module implementation.</p>
<pre>nsIModule generateModule(
  componentsArray,
  postRegister,
  preUnregister
); 
</pre>
<h6>Parameters</h6>
<dl> <dt><code>componentsArray</code></dt> <dd>An array of component constructors.</dd> <dt><code>postRegister</code></dt> <dd>An optional function that is called after the module is registered. See Post-registration callback.</dd> <dt><code>preUnregister</code></dt> <dd>An optional function that's called before the module is unregistered. See Pre-unregistration callback.</dd>
</dl>
<h6>Return value</h6>
<p>An {{ interface("nsIModule") }} that implements the module.</p>
<h3>generateNSGetModule()</h3>
<p>Generates the <code>NSGetModule()</code> function along with the module definition. You can use this instead of <a href="/en/JavaScript_code_modules/XPCOMUtils.jsm#generateModule()" title="en/JavaScript code modules/XPCOMUtils.jsm#generateModule()"><code>generateModule()</code></a> to create both the module and the <code>NSGetModule()</code> function at the same time.</p>
<pre>nsIModule generateNSGetModule(
  componentsArray,
  postRegister,
  preUnregister
); 
</pre>
<h6>Parameters</h6>
<dl> <dt><code>componentsArray</code></dt> <dd>An array of component constructors.</dd> <dt><code>postRegister</code></dt> <dd>An optional function that is called after the module is registered. See Post-registration callback.</dd> <dt><code>preUnregister</code></dt> <dd>An optional function that's called before the module is unregistered. See Pre-unregistration callback.</dd>
</dl>
<h6>Return value</h6>
<p>An {{ interface("nsIModule") }} that implements the module.</p><h3>generateQI()</h3>
<p>Generates a <code>QueryInterface()</code> function implementation. You need to assign the returned function to the <code>QueryInterface</code> property of a JavaScript object.</p>
<p>When the generated method is invoked on that object, it checks to see if the specified IID is listed in the array specified by the <code>interfaces</code> parameter; if it is, <code>this</code> (that is, the object itself) is returned. Otherwise, <code>null</code> is returned.</p>
<pre>function generateQI(
  interfaces
); 
</pre>
<h6>Parameters</h6>
<dl> <dt>interfaces</dt> <dd>An array of interfaces implemented by the component.</dd>
</dl>
<h6>Return value</h6>
<p>A <code>QueryInterface()</code> function implementation.</p>
<h2>Post-registration callback</h2>
<p>The post-registration callback called by <a href="/en/JavaScript_code_modules/XPCOMUtils.jsm#generateModule()" title="en/JavaScript code modules/XPCOMUtils.jsm#generateModule()"><code>generateModule()</code></a> should have the following signature:</p>
<pre>postRegister(
  nsIComponentManager mgr,
  nsIFile file,
  componentsArray
);
</pre>
<h6>Parameters</h6>
<dl> <dt>mgr</dt> <dd>An {{ interface("nsIComponentManager") }} instance to use for managing the component.</dd> <dt>file</dt> <dd>An {{ interface("nsIFile") }} instance for... what?</dd> <dt>componentsArray</dt> <dd>An array of the components, as passed to <code>generateModule()</code>.</dd>
</dl>
<p>The function doesn't need to return a value.</p><h2>Pre-unregistration callback</h2>
<h2>See also</h2>
<ul> <li><a class="internal" href="/en/JavaScript_code_modules/Using_JavaScript_code_modules" title="en/JavaScript code modules/Using JavaScript code
    modules">Using JavaScript code modules</a></li> <li><a class="internal" href="/en/JavaScript_code_modules" title="en/JavaScript code
    modules">JavaScript code modules</a></li>
</ul>
<p>{{ languages( { "es": "es/XPCOMUtils.jsm", "ja": "ja/XPCOMUtils.jsm" } ) }}</p>
Revert to this revision