Utilisation des composants XPCOM

Cette traduction est incomplète. Aidez à traduire cet article depuis l'anglais.

Une des meilleures façons de commencer à travailler avec XPCOM - surtout quand vous concevez l'interface d'un composant qui sera utilisé par d'autres(WebLock) - est de regarder comment les clients utilisent déjà des composants XPCOM.

Les applications sophistiqués comme le navigateur Mozilla sont des utilisateurs de modules XPCOM. En fait, la quasi-totalité des fonctionnalités associees au navigateur - la navigation, la gestion des fenêtres, la gestion des cookies, les signets, la sécurité, la recherche, de rendu et d'autres caractéristiques - sont définies par des composants XPCOM et consultée par le biais de leurs interfaces. Mozilla est fait de composants XPCOM.

Ce chapitre montre comment Mozilla utilise certains de ces objets XPCOM, tels que le CookieManager, et explique comment l'accès au composant de Weblock sera défini.

Exemples de composants

Pour en savoir plus sur l'utilisation de composant particulier référez vous à API XPCOM référence . Pour l'instant, ili est important de comprendre comment un composant est  utilisé par le navigateur Mozilla.

Gestionnaire de Cookies

Gestion des cookies est l'une des nombreux fonctionnalités qui est mise disposition du navigateur sous la forme de composant XPCOM et qui peut être réutilisé par les développeurs qui veulent des fonctionnalités similaires dans leurs applications. Chaque fois qu'un utilisateur accède à la boîte de dialogue de Cookie Manager pour afficher, organiser, ou supprimer les cookies qui ont été stockées sur le système, ils utilisent le composant CookieManager en coulisses. La boite de dialogue du gestionnaire de cookies montre interface utilisateur qui est présenté à l'utilisateur dans Mozilla pour l'utilisation du composant CookieManager.

Boite de dialogue du gestionnaire de cookies

Image:cookie_mgr_dlog.png

Cette boite de dialogue est écrit en XUL et en JavaScript, et utilise une partie de XPCOM appelé XPConnect pour se connecter de manière transparente au composant CookieManager (voir Connexion à des interfaces de composants ci-dessous). XUL expose les fonctionnalités du composant CookieManager, il est tres utilisé dans l'environement Mozilla.

La fonctionnalité du composant CookieManager est disponible à travers l'interface nsICookieManager, ses méthodes publiques sont exposées dans le tableau ci-dessous.

Interface nsICookieManager

removeAll Retirez tous les cookies de la liste des cookies.
enumerator Énumérer la liste des cookies.
remove Retirer un cookie particulier de la liste.

Linterface XPCOM garanti la stabilitée, même si il y a des changements sous-jacentes. Les interfaces sont publics et les implémentations sont privés. Lorsque l'utilisateur sélectionne l'un des cookies affichés dans la liste, puis clique sur le bouton Supprimer, la méthode Remove de nsICookieManager est appelée. La fonction est réalisée par le composant CookieManager, et le cookie sélectionné est supprimé du disque et retiré de la liste affichée.

L'extrait Utiliser le composant CookieManager en JavaScript montre comment Remove() peut être appelé à partir de JavaScript:

Utiliser le composant CookieManager en JavaScript

// xpconnect to cookiemanager
// get the cookie manager component in JavaScript
var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
                     .getService();
cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);

// called as part of a largerDeleteAllCookies() function
function FinalizeCookieDeletions() {
  for (var c=0; c<deletedCookies.length; c++) {
    cmgr.remove(deletedCookies[c].host,
                deletedCookies[c].name,
                deletedCookies[c].path);
  } 
  deletedCookies.length = 0;
}

Connexion à l'interface d'un composant

L'interface Mozilla utilise JavaScript pour accèder aux composants XPCOM par l'intermediaire de XPConnect.

XPConnect via XPIDL est appeler à partir d'objets JavaScript, qui représentent des instances de composants comme CookieManager.

XPConnect lie le code d'application de l'interface utilisateur du navigateur Mozilla(XUL basé sur Gecko), à l'environnement JavaScript(comme xpcshell)..

Les arrangements contractuels que permet XPCOM ouvre la voie à l'interopérabilité binaire, pour l'accès, l'utilisation et la réutilisation des composants XPCOM. Ils permettent d'utiliser des composants écrits dans d'autres langages tels que JavaScript, Python et autres.

Dans le navigateur Mozilla, les composants sont souvant utilisés à partir de JavaScript. En fait, une recherche du code source Mozilla révèle que le composant CookieManager est appelée seulement à partir de JavaScript. C'est ce que nous allons faire dans ce tutoriel.

JavaScript et Mozilla

JavaScript est la lingua franca du navigateur Mozilla, et les liaisons entre elle et XPCOM sont forts et bien définie. scriptabilité , cette capacité à obtenir et utiliser des composants XPCOM à partir de JavaScript et d'autres langages pour lesquels fixations XPConnect ont été créés, est une caractéristique essentielle de XPCOM.

Le composant WebBrowserFind

Les composants sont utilisés partout - dans les fonctionnalités du navigateur de haut niveau tels que nsWebBrowserFind , qui fournit les méthodes find() et findNext() pour trouver du contenu dans les pages Web, et dans les tâches de bas niveau tels que la manipulation des données.

En plus du composant CookieManager, le composant WebBrowserFind est une autre partie d'un grand ensemble d'interfaces du navigation Web que vous pouvez utiliser. Son interface nsIWebBrowserFind est présentée dans L'interface nsIWebBrowserFind .

Les méthodes de nsIWebBrowserFind

findNext Trouver la prochaine occurrence de la chaîne recherchée.
findBackwards Attribut booléen qui ajuste findNext() pour rechercher vers le début du document.
searchFrames Attribut booléen qui indique si la recherche s'efectue dans les sous-fenêtres du document actuel.
matchCase Attribut booléen qui indique la sensibilité à la casse.
entireWord Attribut booléen qui indique si le mot entier doit correspondre.

Quand vous utilisez l'interface d'un composant, vous pouvez demander si il suportr d'autres interfaces. Ce service, qui est défini dans nsISupports est mis en œuvre par tous les composants XPCOM, vous permet d'interroger et de passer d'une interface à un composant dans le cadre des runtime object typing. Il est géré par QueryInterface, qui a été introduit dans le chapitre Vue d'ensemble du XPCOM . L'API de référence XPCOM fournit une référence complète des composants XPCOM disponibles dans Mozilla.

The WebLock Component

Now it's time to look at the WebLock component as another example of XPCOM components (since you'll be creating it shortly). In object-oriented programming, it's typical to design the interface first-to define the functionality that's going to be provided in the abstract, without worrying about how this functionality will be achieved. So we'll put aside the details of the implementation until the next chapter and look at the component from the outside-at the interface to the WebLock component.

The IWebLock Interface

lock Lock the browser to the current site (or to the whitelist of approved sites read from disk).
unlock Unlock the browser for unrestricted use.
addSite Add a new site to the whitelist.
removeSite Remove a given site from the whitelist.
sites Enumerator for the list of approved sites read in from the whitelist.

The WebLock component is software that implements all of these methods in the way described by the interface definition. It registers itself for use when the browser starts up, and provides a factory that creates an instance of it for use when the user or administrator clicks the weblock icon in the browser's user interface.

Component Use in Mozilla

So how are components obtained and used in Mozilla? You've seen some enticing snippets of JavaScript in earlier sections of this chapter, but we haven't explained how XPCOM makes components available in general.

This section discusses practical component use in Mozilla. It's divided into three subsections: one about actually finding all these binary components in Mozilla and two others corresponding to the two main ways that clients typically access XPCOM components:

Finding Mozilla Components

This book attempts to provide reference information for XPCOM components and their interfaces that are frozen as of the time of this writing. The Mozilla embedding project tracks the currently frozen interfaces.

Mozilla also has some tools that can find and display information about the interfaces available in Gecko such as the XPCOM Component Viewer, described below, and MXR, which is a web-based source code viewing tool.

The challenge to making good information about XPCOM components available to prospective clients, however, is that the process of freezing the interfaces that are implemented by these components is still ongoing. The Component Viewer does not distinguish between components that are frozen and those that are not. In the source code you view in MXR, interfaces that have been frozen are marked at the top with @status frozen.

The XPCOM Component Viewer

The XPCOM Component Viewer is an add-on you can install in your browser (in sandbox, not available for now).
Alternatively, you can try XPCOMViewer, a similar add-on.

XPCOM Component Viewer

Image:using-component-viewer.png

The left column shows the components - in this case a subset returned from a search on "gfx" as part of the contract ID and the right column a list of the interfaces. When you open a component on the left, you can see the interfaces it implements along with a list of the methods provided by each interface.

The XPCOM Component Viewer can be extremely useful for this sort of gross interrogation, but again: it displays all of the components and interfaces in your build, many of which are not practical for actual reuse or stable enough to be used reliably in your own application development. Use comprehensive lists like this with caution.

 

Using XPCOM Components in Your Cpp

XPConnect makes it easy to acecss XPCOM components as JavaScript objects, but using XPCOM components in C++ is not much more difficult.

Managing Cookies from Cpp duplicates code from Getting the CookieManager Component in JavaScript, but in C++ instead of JavaScript.

Managing Cookies from Cpp

nsCOMPtr<nsIServiceManager> servMan;
nsresult rv = NS_GetServiceManager(getter_AddRefs(servMan));
if (NS_FAILED(rv))
  return -1;

nsCOMPtr<nsICookieManager> cookieManager;
rv = servMan->GetServiceByContractID("@mozilla.org/cookiemanager",
                                     NS_GET_IID(nsICookieManager),
                                     getter_AddRefs(cookieManager));

if (NS_FAILED(rv))
  return -1;

PRUint32 len;
deletedCookies->GetLength(&len);

for (int c=0; c<len; c++)
    cookieManager->Remove(deletedCookies[c].host,
                          deletedCookies[c].name,
                          deletedCookies[c].path,
                          PR_FALSE);

XXX: In the original document, there were only the first three parameters to the |Remove| call. I added |PR_FALSE| as a fourth parameter because the interface seems to require it: http://lxr.mozilla.org/mozilla/source/netwerk/cookie/public/nsICookieManager.idl#64 This problem also appears in the JavaScript version below, and I've added |false| as a fourth parameter there as well.

If your application is written in C++, then Managing Cookies from Cpp shows the steps you take to get an XPCOM component, specify the interface on that component you want to use, and call methods on that interface.

XPConnect: Using XPCOM Components From Script

The CookieManager component we discussed at the beginning of this chapter provides a good opportunity to talk further about using components from JavaScript. In the following code fragment from the Cookie Manager dialog in Mozilla, you can see a singleton of the CookieManager component being created with the getService() method and used to provide the functionality that lets users load and remove cookies from the user interface.

Managing Cookies from JavaScript

var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
                     .getService();
cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);

function loadCookies() {
  // load cookies into a table
  var enumerator = cmgr.enumerator;
  var count = 0;
  var showPolicyField = false;
  while (enumerator.hasMoreElements()) {
    var nextCookie = enumerator.getNext();
    nextCookie = nextCookie.QueryInterface(Components.interfaces.nsICookie);
    /* .... */
}
function FinalizeCookieDeletions() {
  for (var c=0; c<deletedCookies.length; c++) {
    cmgr.remove(deletedCookies[c].host,
                deletedCookies[c].name,
                deletedCookies[c].path,
                false);
  } 
  deletedCookies.length = 0;
}

XXX: In the original document, there were only the first three parameters to the |remove| call. I added |false| as a fourth parameter because the interface seems to require it: http://lxr.mozilla.org/mozilla/source/netwerk/cookie/public/nsICookieManager.idl#64 This problem also appears in the C++ version above, and I've added |PR_FALSE| as a fourth parameter there as well.

Beyond the methods that are being called on the CookieManager itself (e.g., cookiemanager.remove, which maps to the remove() function in The nsICookieManager Interface), note the special XPConnect objects and methods that reflect the XPCOM component into JavaScript.

Components is the JavaScript object that controls the connection to components, and classes is an array of all of the classes you can ask for by contract ID. To instantiate an XPCOM component in JavaScript, you create a new Component object and pass in the contract ID for the component you want and ask for either a singleton or an instance of that component to be returned:

var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
                     .getService();

The resulting cookiemanager object then provides access to all of the methods for that component that have been defined in IDL and compiled into the type library. Using the CookieManager component, you could write code like this to delete all cookies from the system:

cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
                 .getService();
cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);

// delete all cookies
function trashEm() {
   cmgr.removeAll();
}

Another vital feature of the XPConnect glue this example shows is the availability of the QueryInterface method on all objects that are reflected into JavaScript from XPCOM. As in C++, you can use this method to ask for other interfaces that are available on the given object.

Services Versus Regular Instances

Whether to have clients use your component as an instance or a service is a design question, really, and something you should be clear about in the documentation for your component. Actually, the getService() method in the example here calls through to the createInstance() method that is also available from the Component object and caches the result, making it a singleton rather than a normal instance.

The singleton design pattern that is used to create services is described in XPCOM Services.

Remember, QueryInterface allows you to query an object for the interfaces it supports. In the case of the snippet in The nsICookieManager Interface, the QueryInterface method is being used to get the nsICookie interface from the enumerator so that, for instance, the JavaScript code can access the value and name attributes for each cookie.

  1. Note : cookie-manager-ui
    Note that the interface is not part of the component itself. XPCOM makes it easy to use components like CookieManager from Mozilla's Cross Platform Front End (XPFE) and other user interfaces, but the component itself doesn't provide its own UI.
  2. Note : private-xpcom-interfaces
    There are exceptions to this. Some XPCOM interfaces are also private and not made for general use. Private interfaces do not have the same requirements as the ones that are made available publicly in IDL.
  3. Note : cookie-manager-in-tutorial
    The CookieManager component is used to persist for the web locking functionality described in this tutorial.

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : SphinxKnight, jmh
 Dernière mise à jour par : SphinxKnight,