This is a proposal for a system that got implemented, but it may differ from the actual implementation. See the status document for more recent info on the status of this proposal.
The overriding principle is to make this work as much like native components as possible. XJS Components will 'live' in.js files. Just as with native component modules each of these .js files will be expected to have the functions:
- NSUnregisterSelf (optional)
- NSCanUnload (optional)
Each .js file might implement one or more components.
We will have one native module - called the XPJSManager - which holds this system together. The XPJSManager is in charge of loading these .js files, helping them register themselves, and acting as an intermediary between the xpcom component manager and the JS code.
XJS Components are not run in browser windows. Each .js file (let's call it a module) is started up and run in the context of a relatively 'raw' JS global object. The standard (non-DOM) JS classes will be available. The xpconnectComponents object will be available. And some additional yet to be defined objects may be available. The xpconnectComponents object allows access to the whole repository of native and JS xpcom components, so this is not as isolated an environment as it might at first sound.
A 'load' or 'import' function will also be provided to let the JS code import other .js files where libraries of code might be stored. This is akin to 'static' libraries. Accessing other components/services via xpcom/xpconnect is more akin to 'dynamic' libraries.
When a XPJS Component module is first installed - or at autoregistration time - the XPJSManager will load the .js file into a fresh JS environment, let its top level script run to do whatever initialization it wants to do, and then it will call the module's NSRegisterSelf function (passing the filespec of the .js file). At this point the module will use the (new) methods on the Components object to register itself with the component manager as a factory module for one or more classid or progid.
This registration function that the JS code calls (e.g. Components.RegisterComponentSpec) will be provided by the XPJSManager. The XPJSManager will receive this call from the JS code, store the mapping of clsid to .js filespec in the registry for its own use later, and then call the real component manager to do the registration. However, the XPJSManager will pass the component manager its *own* filespec.
So, at some future point some chunk of code will ask the component manager to create an object instance for some clsid (or progid). The component manager will load up the XPJSManager's module and call the native NSGetFactory it finds there. That native NSGetFactory function will check the information it stored in the registry to see that the JS factory for the given clsid is in a given .js file. It will load that .js file (if not already loaded) and call the NSGetFactory function.
Our friend XPConnect will convert the JS object returned from the JS module's NSGetFactory function into an xpcom object. The component manager (and anyone else with a reference to that factory) can then call the factory's CreateInstance method at will.
The JS module is free to implement factories and components and services that the factories construct on command. Any code anywhere and implemented in any language can get to these things via the component and service managers.
So when will it be ready?
I was thinking that I'd get on this pretty soon. I think that it is all very straightforward.
Comments and suggestions welcome!
- Author: John Bandhauer
- Last Updated Date: 1 July 1999