xulfr.org

10.5 Ajout de méthodes

Écrit par Neil Deakin. Traduit par Nadine Henry (18/08/2004).
Page originale : http://www.xulplanet.com/tutorials/xultu/xblmethods.html xulplanet.com

Nous allons voir comment ajouter des méthodes personnalisées aux éléments définis en XBL.

Les méthodes

En plus d'ajouter des propriétés de script à l'élément définis en XBL, vous pouvez aussi ajouter des méthodes. Ces méthodes peuvent être appelées à partir d'un script. Les méthodes sont des fonctions d'objets, comme window.open(). Vous pouvez définir des méthodes personnalisées pour vos éléments en utilisant l'élément method. La syntaxe générale des méthodes est comme suit :


<implementation>
  <method name="method-name">
    <parameter name="parameter-name1"/>
    <parameter name="parameter-name2"/>
    .
    .
    .
    <body>

      -- le script de la méthode vient ici --
    </body>
  </method>
</implementation>

Une déclaration de méthode se fait au travers de l'élément implementation, comme pour les champs et les propriétés. L'élément method contient deux types d'éléments fils, les éléments parameter qui décrivent les paramètres de la méthode et body qui contient le script de la méthode.

La valeur de l'attribut name devient le nom de la méthode. Similairement, l'attribut name des éléments parameter devient les noms de chaque paramètre. Chaque élément parameter est utilisé pour déclarer l'un des paramètres pour la méthode. Par exemple, si la méthode a trois paramètres, il y aura trois éléments parameter. Si vous n'avez pas besoin d'en avoir, la méthode n'aura pas de balise parameter.

L'élément body contient le script qui est exécuté lorsque la méthode est appelée. Les noms des paramètres sont définis comme des variables dans le script comme s'ils étaient passés en paramètre. Par exemple, la fonction JavaScript suivante serait écrite en tant que méthode XBL comme suit :


function getMaximum(num1,num2)
{
  if (num1<=num2) return num2;
  else return num1;
}

XBL:

<method name="getMaximum">
  <parameter name="num1"/>
  <parameter name="num2"/>
  <body>

    if (num1&lt;=num2) return num2;
    else return num1;
  </body>
<method>

Cette fonction, getMaximum, retourne les valeurs les plus grandes, chacune étant passée comme un paramètre dans la méthode. Notez que le symbole inférieur doit être un caractère d'échappement parce qu'autrement il ressemblerait au commencement d'une balise. Vous pouvez aussi utiliser une section CDATA pour échapper le bloc entier de code. Vous pouvez appeler la méthode en utilisant un code comme element.getMaximum(5,10)element est une référence à un élément défini par l'élément XBL contenant la méthode getMaximum. (L'élément attaché.)

La balise parameter vous permet de définir des paramètres pour une méthode. Parce que Mozilla utilise JavaScript comme son langage de script, et que JavaScript est un langage non typé, vous n'avez pas besoin de spécifier le type de paramètres. Cependant, dans le futur, d'autres langages devraient être utilisés avec XBL.

Accéder au contenu anonyme

Il peut y avoir des fois où vous voulez modifier certains aspects des éléments définis dans l'élément content, que ce soit à partir d'une méthode body ou d'ailleurs. Ces éléments sont créés anonymement et ne sont pas accessibles à partir des fonctions régulières du DOM. Elles sont cachées de telle sorte que les développeurs n'aient pas besoin de savoir comment l'élément est implémenté, pour l'utiliser. Cependant, il y a un moyen spécial pour obtenir ce contenu anonyme.

Les éléments auxquels un comportement XBL est attaché, ont une propriété spéciale qui contient un tableau des éléments fils anonymes. Chaque élément du tableau stocke chaque élément fils direct de l'élément XBL défini. Cette propriété spéciale ne peut pas être accessible directement. À la place, vous devez appeler la méthode getAnonymousNodes du document.


var value=document.getAnonymousNodes(element);

Ici, element devrait être une référence à l'élément dont vous voulez obtenir le contenu anonyme. La fonction retourne un tableau d'éléments, qui est le contenu anonyme. Pour obtenir des éléments en-dessous de celui-ci, vous pouvez utiliser les fonctions régulières du DOM car elles ne sont pas cachées. Notez qu'il est possible pour un élément XBL attaché d'être placé à l'intérieur d'un autre, auquel cas vous aurez une nouvelle fois à utiliser la fonction getAnonymousNodes.

L'exemple suivant crée une rangée de boutons :


<binding id="buttonrow">
  <content>

    <button label="Yes"/>
    <button label="No"/>
    <button label="Sort Of"/>
  </content>
</binding>

Pour vous référer à chaque bouton, vous pouvez utiliser la fonction getAnonymousNodes, en lui passant une référence à l'élément auquel la liaison est attachée, en tant que paramètre. Dans le tableau renvoyé, le premier bouton est stocké dans le premier élément de tableau (getAnonymousNodes(element)[0]), le deuxième bouton est stocké dans le deuxième élément de tableau et le troisième est stocké dans le troisième élément de tableau. Pour coder à l'intérieur d'une méthode de liaison, vous pouvez passer this comme paramètre à getAnonymousNodes.

Le prochain exemple peut être utilisé pour créer un texte avec une étiquette. La méthode showTitle peut être utilisée pour montrer ou cacher une étiquette. Elle fonctionne en obtenant une référence à l'élément titre qui utilise le tableau anonyme et en changeant sa visibilité.


XUL:

<box id="num" class="labeledbutton" title="Number of Things:" value="52"/>

<button label="Show" oncommand="document.getElementById('num').showTitle(true)"/>

<button label="Hide" oncommand="document.getElementById('num').showTitle(false)"/>

XBL:

<binding id="labeledbutton">
  <content>
    <xul:label xbl:inherits="value=title"/>
    <xul:label xbl:inherits="value"/>

  </content>
  <implementation>
    <method name="showTitle">
      <parameter name="state"/>
      <body>
        if (state) document.getAnonymousNodes(this)[0].
          setAttribute("style","visibility: visible");
        else document.getAnonymousNodes(this)[0].
          setAttribute("style","visibility: collapse");
      </body>

    </method>
  </implementation>
</binding>

Deux boutons ajoutés dans le contenu XUL ont des gestionnaires oncommand qui sont utilisés pour changer la visibilité de l'étiquette. Chacun d'eux appelle la méthode showTitle. Cette méthode vérifie le paramètre state pour voir si l'élément sera caché ou montré. Dans un cas comme dans l'autre, il récupère le premier élément du tableau anonyme. Il se rapporte au premier fils de l'élément content, qui ici est le premier élément label de l'élément graphique. Cette visibilité est changée en modifiant le style de l'élément.

Pour aller dans l'autre sens, et obtenir l'élément XUL liée, à partir de l'intérieur du contenu anonyme, utilisez la propriété parentNode du DOM. Elle fait obtenir l'élément parent d'un élément. Par exemple, nous pourrions déplacer les boutons "Show" et "Hide" dans le fichier XBL et faire la chose suivante :

Exemple 10.5.1 :Source


<binding id="labeledbutton">
  <content>
    <xul:label xbl:inherits="value=title"/>

    <xul:label xbl:inherits="value"/>
    <xul:button label="Show" oncommand="parentNode.showTitle(true);"/>
    <xul:button label="Hide" oncommand="parentNode.showTitle(false);"/>
  </content>
  <implementation>
    <method name="showTitle">

      <parameter name="state"/>
      <body>
        if (state) document.getAnonymousNodes(this)[0].setAttribute("style","visibility: visible");
        else document.getAnonymousNodes(this)[0].setAttribute("style","visibility: collapse");
      </body>
    </method>
  </implementation>
</binding>

Les gestionnaires oncommand obtiennent ici d'abord une référence à leur élément parent. Ce n'est pas l'élément content mais l'élément XUL auquel l'élément XBL est lié. (Dans cet exemple, c'est la boîte avec la classe labeledbutton). Ainsi, la méthode 'showTitle' est appelée, et fonctionne comme avant.

Les propriétés et méthodes personnalisées sont ajoutées seulement à l'élément XUL externe auquel l'élément XBL est lié. Aucun des éléments déclarés au sein de la balise content n'ont ces propriétés ou méthodes. C'est pourquoi nous devons obtenir l'élément parent d'abord.

Les fils d'un élément placés dans le fichier XUL peuvent être récupérés par la voie normale et ne bougent pas même si vous utilisez la balise children. Par exemple :


XUL:

<box id="outer" class="container">
  <button label="One"/>
  <button label="Two"/>
  <button label="Three"/>
  <button label="Four"/>
</box>

XBL:

<binding id="labeledbutton">
  <content>
    <description value="A stack:"/>
    <stack>
      <children/>

    </stack>
  </content>
</binding>

Si vous utilisez les fonctions du DOM telles que childNodes pour obtenir les fils d'un élément, vous verrez que la boîte XUL qui a l'id outer, a 4 fils. Ceux-ci correspondent à ses 4 boutons, même si ces boutons sont dessinés à l'intérieur de la pile(stack). La pile n'a qu'un seul fils, l'élément children lui-même. La longueur du tableau anonyme de la boîte externe est de deux, le premier élément étant l'élément description et le second, l'élément stack.

Constructeurs et Destructeurs

XBL supporte deux méthodes spéciales créées avec des balises séparées, constructor et destructor. Un constructeur est appelé chaque fois qu'une liaison est attachée à un élément. Il est utilisé pour initialiser le contenu tel que le chargement de préférences ou l'initialisation des valeurs par défaut des champs. Le destructeur est appelé lorsqu'une liaison est enlevée d'un élément. Cela pourrait être utile pour sauver des informations.

Il y a deux points à savoir lorsqu'une liaison est attachée à un élément. Le premier se produit lorsqu'une fenêtre est affichée. Tous les constructeurs des éléments qui ont un contenu XBL attaché seront invoqués. L'ordre dans lequel ils sont appelés ne devrait pas être pris en compte, car ils sont chargés à partir divers fichiers. Le gestionnaire de chargement de la fenêtre (onload) n'est pas appelée tant que toutes les liaisons n'ont pas été attachées et leurs constructeurs exécutés. Le second point quand une liaison est attachée, est lorsque vous changez la propriété de style -moz-binding d'un élément. Après que son destructeur ait été appelé, la liaison existante sera enlevée. Ainsi, la nouvelle liaison sera ajoutée à sa place et son constructeur sera invoqué.

Le script pour un constructeur ou un destructeur devrait être placé directement à l'intérieur de la balise appropriée. Il ne devrait y avoir tout au plus qu'un seul de chaque par liaison et ils ne prennent aucun argument. Voici quelques exemples :


<constructor>
  if (this.childNodes[0].getAttribute("open") == "true"){
    this.loadChildren();
  }
</constructor>

<destructor action="saveMyself(this);"/>

La prochaine section montre comment ajouter des gestionnaires d'évènements aux élément XBL définis.