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 :

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 :

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