XPCOM
Implémentation du composant en JavaScript
Implémentation du composant
L'écriture du composant en JavaScript est très simple. Il suffit de créer une classe implémentant :
- les méthodes définies par l'interface
nsIPlop
; - la méthode
QueryInterface
.
Dans notre cas, la méthode QueryInterface
vérifie que l'IID de l'interface demandée correspond, soit à l'IID de l'interface nsIPlop
, soit à celui de l'interface nsISupports
.
Il ne faut pas seulement vérifier la correspondance avec l'IID des interfaces implémentées, mais également vérifier la correspondance avec les interfaces mères des interfaces implémentées (ici, nsISupports
, puisque nsIPlop
l'étend).
Enfin, la méthode display
est implémentée. Notons ici que la fonction dump
est utilisée pour afficher sur la console. Cette fonction n'est définie que lorsque Mozilla est compilé avec l'option debug (--enable-debug
en paramètre de configure
). Il ne faut donc pas l'utiliser dans un composant utilisé en production, mais uniquement pour débugger le composant.
Voici le code du composant :
function nsPlop() { }
nsPlop.prototype =
{
QueryInterface: function (iid) {
dump(" ----- Composant JavaSript: Appel de 'QueryInterface'"+"\n");
if (!iid.equals(Components.interfaces.nsIPlop) &&
!iid.equals(Components.interfaces.nsISupports)) {
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
display: function(message)
{
dump(" ----- Composant JavaSript: Appel de 'display' ---> '"+message+"'\n");
}
}
Création d'un objet module
Il faut maintenant définir l'objet module qui servira à l'enregistrement des composants. Nous allons enregistrer le composant créé plus haut avec les caractéristiques suivantes :
- Un Class ID égal à
24dcb953-de73-463d-8207-f36399185a09
. Il s'agit d'un UUID qui identifie l'implémentation, tout comme l'IID identifie l'interface ; - Un Contract ID égal à
@seigneurin.com/Plop_js;1
. Il s'agit du nom que l'on donne à l'objet.
Le code correspondant au module est le suivant :
var myModule = {
firstTime: true,
registerSelf: function (compMgr, fileSpec, location, type) {
if (this.firstTime) {
debug("*** Deferring registration of sample JS components\n");
this.firstTime = false;
throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
}
debug("*** Registering sample JS components\n");
compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
compMgr.registerFactoryLocation(this.myCID,
"Plop en JS",
this.myProgID,
fileSpec,
location,
type);
},
getClassObject: function (compMgr, cid, iid) {
if (!cid.equals(this.myCID))
throw Components.results.NS_ERROR_NO_INTERFACE;
if (!iid.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
return this.myFactory;
},
myCID: Components.ID("{24dcb953-de73-463d-8207-f36399185a09}"),
myProgID: "@seigneurin.com/Plop_js;1",
myFactory: {
createInstance: function (outer, iid) {
dump(" ----- Composant JavaSript: Appel de 'createInstance'"+"\n");
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return (new nsPlop()).QueryInterface(iid);
}
},
canUnload: function(compMgr) {
//debug("*** Unloading sample JS components\n");
return true;
}
};
Notons que ce code est issu d'un template que l'on peut trouver dans le répertoire xpcom
de Mozilla.
Enfin, il s'agit de définir la fonction qui sera appelée par Mozilla pour obtenir le module, et ainsi enregistrer les composants :
function NSGetModule(compMgr, fileSpec) {
dump(" ----- Initialisation du module JavaSript"+"\n");
return myModule;
}
Fichiers
Le code ici donné est placé dans le fichier MOZILLA/alexis/plop.js
. Pour que le composant puisse être utilisé, il faut que ce fichier soit placé dans le répertoire MOZILLA/dist/bin/components
.
Plutôt que de copier le fichier, nous allons réaliser un lien symbolique, et allons pour cela placer la règle suivante dans le Makefile
:
js: plop.js
ln -fs $(CURDIR)/$< ../dist/bin/components