How to create a JavaScript XPCOM component on bootstrapped addon
This post describes how to create a JavaScript XPCOM component on bootstrapped (restartless) addon.
On bootstrapped extension
- Define the component name such as
@mozilla.org/foo/bar;1
; - Generate GUID for the component.
- If you have Visual Studio, you may use
guidgen
. -
On linux, you may use
uuidgen
(1).$ uuidgen 22e1de77-790a-4a78-9ed4-8a8fca8c9f0f
- If you have Visual Studio, you may use
-
Create the component code (in the bootstrap.js).
const Cc = Components.classes; const Ci = Components.interfaces; const Cu = Components.utils; const Cr = Components.results; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); function ComponentFooBar() { } ComponentFooBar.prototype = { classDescription: "foobar class", contractID: "@mozilla.org/foo/bar;1", classID: Components.ID("{22e1de77-790a-4a78-9ed4-8a8fca8c9f0f}"), QueryInterface: XPCOMUtils.generateQI([]), // members to implement... }; // const ComponentFooBarFactory = Object.freeze({ createInstance: function(aOuter, aIID) { if (aOuter) { throw Cr.NS_ERROR_NO_AGGREGATION; } return new ComponentFooBar(); }, loadFactory: function (aLock) { /* unused */ }, QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]) });
- You may specify base interface to
ComponentFooBar.prototype.QueryInterface
and implement methods.
- You may specify base interface to
-
To regist the component on startup, add the following codes to the
startup()
in bootstrap.js:function startup(params, aReason) { const registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); registrar.registerFactory(ComponentFooBar.prototype.classID, ComponentFooBar.prototype.classDescription, ComponentFooBar.prototype.contractID, ComponentFooBarFactory); }
-
To release the component on shutdown, add the following codes to the
shutdown()
in bootstrap.js:function shutdown(params, aReason) { const registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); registrar.unregisterFactory(ComponentFooBar.prototype.classID, ComponentFooBarFactory); }
- Note: bootstrapped add-ons must take care to clean up any component registrations at shutdown. So you must not miss this clean-up code.
NOTE: On non-bootstrap extension
If not bootstrapped add-on, you can use chrome.manifest
and do same thing without using nsIComponentRegistrar
.
-
Add following lines to chrome.manifest:
component {22e1de77-790a-4a78-9ed4-8a8fca8c9f0f} components/FooBar.js contract @mozilla.org/foo/var;1 {22e1de77-790a-4a78-9ed4-8a8fca8c9f0f}
-
Create the component code in components/FooBar.js
const Cc = Components.classes; const Ci = Components.interfaces; const Cu = Components.utils; const Cr = Components.results; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); function ComponentFooBar() { } ComponentFooBar.prototype = { classDescription: "foobar class", contractID: "@mozilla.org/foo/bar;1", classID: Components.ID("{22e1de77-790a-4a78-9ed4-8a8fca8c9f0f}"), QueryInterface: XPCOMUtils.generateQI([]), // members to implement... }; this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ComponentFooBar]);
Reference
- resource://gre/modules/XPCOMUtils.jsm
- How to implement XPCOM component (nsIContentPolicy) in bootstrapped Firefox extension - Stack Overflow
- https://bitbucket.org/cat_in_136/configuration-mania/commits/fe98ca888a84 “use about:confmania for in-content configuration mania URL”