Écrit par Neil Deakin.
Traduit par Nadine Henry (18/08/2004).
Page originale :
http://www.xulplanet.com/tutorials/xultu/xblmethods.html
Nous allons voir comment ajouter des méthodes personnalisées aux éléments définis en XBL.
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<=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)
où 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.
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
.
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.