Écrit par Neil Deakin
,
mise à jour par les contributeurs à MDC
.
Traduit par Laurent Jouanneau (15/11/2004), mise à jour par Alain B. (04/04/2007) .
Page originale :
http://developer.mozilla.org/en/docs/XUL_Tutorial/Commands
Attention : Ce tutoriel est ancien et n'est pas mis à jour. Bien que beaucoup d'informations soient encore valables pour les dernières versions de gecko, beaucoup sont aussi obsolètes. Il est préférable d'aller consulter cette page sur la version française de ce tutoriel sur developer.mozilla.org.
Une commande est une opération qui peut être invoquée.
L'élément command
est utilisé pour créer des commandes qui pourront être utilisées pour exécuter des opérations.
Vous n'avez pas besoin d'utiliser les commandes si vous avez juste à appeler un script pour manipuler des choses.
Cependant, une commande a l'avantage de pouvoir être désactivée automatiquement quand c'est nécessaire,
et de pouvoir être invoquée de l'extérieur sans avoir besoin de connaître les détails de son implémentation.
Les commandes fournissent un moyen pour séparer de façon abstraite les opérations et le code.
Elles deviennent très utiles pour les grosses applications.
Par exemple, pour implémenter les commandes de menus du presse-papiers, couper, copier et coller, vous pouvez utiliser les commandes. Si vous ne les utilisiez pas, vous devriez trouver quel champ a le focus, ensuite s'assurer que l'opération est valable pour cet élément. De plus, les commandes de menus devraient être activées ou désactivées selon que l'élément cible a du texte sélectionné ou pas, et pour les opérations de collage, si le presse-papiers contient quelque chose qui peut être collé. Comme vous pouvez le voir, cela devient compliqué. En utilisant les commandes, votre travail est simplifié.
Vous pouvez utiliser une commande pour n'importe quelle opération. Mozilla les utilise la plupart du temps pour les menus. De plus, les champs de saisie de texte et autres composants graphiques disposent de plusieurs commandes natives que vous pouvez invoquer. Vous devriez les utiliser quand les opérations dépendent de l'élément sélectionné.
Une commande est identifiée par son attribut id
.
Mozilla utilise une convention : les id de commandes commencent par cmd_.
Vous voudrez probablement utiliser le même identifiant que celui d'une commande déjà utilisée, cependant,
pour vos propres commandes, vous pouvez utiliser n'importe quel id de commande souhaité.
Pour éviter les conflits, il est préférable d'inclure le nom de l'application dans l'id de la commande.
Un moyen simple d'utilisation des commandes est montré ci-après :
command
simple<command id="cmd_openhelp" oncommand="alert('Aide !');"/>
<button label="Aide" command="cmd_openhelp"/>
Dans cet exemple, au lieu de placer l'attribut oncommand
sur l'élément button
,
nous le plaçons sur un élément command
.
Les deux sont alors liés en utilisant l'attribut command
qui a la valeur de l'id de la commande.
Ainsi, quand le bouton est pressé, la commande cmd_openhelp est invoquée.
Cette approche présente deux avantages.
De plus,
disabled
sur une commande, elle sera désactivée et ne pourra pas être invoquée.command
<command id="cmd_openhelp" oncommand="alert('Aide');"/>
<button label="Aide" command="cmd_openhelp"/>
<button label="Plus d'aide" command="cmd_openhelp"/>
<button label="Désactiver"
oncommand="document.getElementById('cmd_openhelp').setAttribute('disabled','true');"/>
<button label="Activer"
oncommand="document.getElementById('cmd_openhelp').removeAttribute('disabled');"/>
Dans cet exemple, les deux boutons utilisent la même commande. Quand le bouton « Désactiver » est pressé, la
commande est désactivée en définissant son attribut disabled
, et les deux
boutons seront aussi désactivés.
Habituellement, un groupe de commandes se place à l'intérieur d'un élément
commandset
,
près du début du fichier XUL, comme dans l'exemple suivant :
<commandset>
<command id="cmd_open" oncommand="alert('Ouvrir !');"/>
<command id="cmd_help" oncommand="alert('Aide !');"/>
</commandset>
Une commande est invoquée quand l'utilisateur active le bouton ou les autres éléments
rattachés à la commande. Vous pouvez aussi invoquer une commande en appelant
la méthode doCommand
, que ce soit de l'élément
command
ou d'un élément rattaché à la commande, comme un bouton.
Vous pouvez aussi utiliser les commandes sans utiliser l'élément
command
,
ou, au moins, sans ajouter un attribut oncommand
sur la commande.
Dans ce cas, la commande n'invoquera pas un script directement, mais recherchera plutôt
un élément ou une fonction qui traitera la commande.
Cette fonction peut être séparée du XUL lui-même, et peut être embarquée par un élément graphique en interne.
Afin de trouver ce qui traitera la commande, XUL utilise un objet appelé répartiteur de commande
(NdT : command dispatcher).
Cet objet localise le gestionnaire d'une commande. Le gestionnaire d'une commande est appelé contrôleur.
Ainsi, quand une commande est invoquée, le répartiteur de commande localise un
contrôleur qui traite la commande. Vous pouvez déduire que l'élément
command
est un type de contrôleur pour une commande.
Le répartiteur de commandes localise un contrôleur en regardant l'élément sélectionné pour voir s'il
a un contrôleur qui gère la commande. Les éléments XUL ont une propriété controllers
qui
est utilisée pour la vérification. Vous pouvez l'utiliser pour ajouter vos propres contrôleurs.
Vous pourriez l'utiliser pour avoir une boîte de liste qui répond aux opérations de couper, copier et
coller. Un exemple sera fourni plus tard.
Par défaut, seuls les champs de saisie (textbox
) ont un contrôleur fonctionnel.
Ce contrôleur gère aussi bien les opérations de presse-papiers, sélection, défaire et refaire,
que les opérations d'édition. Notez qu'un élément peut avoir plusieurs contrôleurs, qui
seront alors tous pris en compte.
Si l'élément courant sélectionné n'a pas le contrôleur attendu, la fenêtre sera alors vérifiée.
L'élément window
a aussi une propriété controllers
que vous
pouvez modifier comme bon vous semble. Si le focus est à l'intérieur d'un cadre frame, chaque cadre parent
est également vérifié. Ainsi, les commandes
fonctionneront même si le focus est à l'intérieur d'un cadre.
Ce mécanisme fonctionne bien pour un navigateur ; les commandes d'édition invoquées
à partir du menu principal fonctionneront à l'intérieur de la zone de contenu.
Notez que HTML a aussi un système de commandes et de contrôleur, bien que vous
ne puissiez pas l'utiliser sur des pages Web sans privilèges. Mais vous pouvez
l'utiliser, par exemple, dans une extension du navigateur. Si la fenêtre
ne fournit pas un contrôleur capable de gérer la commande, rien ne se passera.
Vous pouvez récupérer le répartiteur de commande en utilisant la propriété
commandDispatcher
de l'objet document
, ou à partir des contrôleurs listés dans un élément ou la fenêtre.
Le répartiteur de commande contient des méthodes pour récupérer les contrôleurs
pour les commandes et pour récupérer et modifier le focus.
Vous pouvez implémenter vos propres contrôleurs pour répondre aux commandes. Vous pouvez tout aussi bien surcharger la gestion par défaut d'une commande en plaçant le contrôleur correctement. Un contrôleur doit implémenter quatre méthodes qui sont listées ci-dessous :
supportsCommand (command)
isCommandEnabled (command)
doCommand (command)
onEvent (event)
Imaginons que nous voulions implémenter une boîte de liste
(listbox
)
qui gère la commande « Supprimer ». Quand un utilisateur sélectionne « Supprimer »
dans le menu, la boîte de liste efface la ligne sélectionnée.
Dans ce cas, vous avez juste à attacher un contrôleur à l'élément
listbox
qui exécutera l'action correspondante dans sa méthode doCommand
.
Essayez d'ouvrir l'exemple qui suit dans une fenêtre du navigateur et sélectionnez des items de la liste. Vous noterez que la commande « Supprimer » du menu « Edition » du navigateur est activée et qu'elle effacera la ligne sélectionnée. L'exemple n'est cependant pas complet. Nous devrions nous assurer que la sélection et le focus soient ajustés comme il faut après l'effacement.
Exemple : voir
<window id="controller-example" title="Exemple de contrôleur" onload="init();"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script>
function init()
{
var list = document.getElementById("theList");
var listController = {
supportsCommand : function(cmd){ return (cmd == "cmd_delete"); },
isCommandEnabled : function(cmd){
if (cmd == "cmd_delete") return (list.selectedItem != null);
return false;
},
doCommand : function(cmd){
list.removeItemAt(list.selectedIndex);
},
onEvent : function(evt){ }
};
list.controllers.appendController(listController);
}
</script>
<listbox id="theList">
<listitem label="Océan"/>
<listitem label="Désert"/>
<listitem label="Jungle"/>
<listitem label="Marécage"/>
</listbox>
</window>
Le contrôleur listController
implémente les quatre fonctions
décrites plus haut. La méthode supportsCommand
renvoie
true pour la commande cmd_delete, qui est le nom de
la commande utilisée lorsque l'item de menu « Supprimer » est sélectionné.
Pour les autres commandes, false est renvoyé puisque le contrôleur
ne gère aucune autre commande. Si vous voulez gérer d'autres commandes, vous devrez les
tester ici, car il est fréquent d'un simple contrôleur gère de multiples commandes apparentées.
La méthode isCommandEnabled
renvoie
true si la commande est activée. Dans le cas présent, nous vérifions
s'il y a un item sélectionné dans la liste et renvoyons true
si c'est le cas. S'il n'y a pas de sélection, false est renvoyé.
Si vous effacez toutes les lignes dans l'exemple, la commande « Supprimer » deviendra
inactive. Vous devrez cliquer sur la liste pour mettre à jour le menu dans cet
exemple simple. La méthode doCommand
sera appelée lorsque l'item de menu « Supprimer » sera
sélectionné, et elle provoquera l'effacement de la ligne sélectionnée dans la liste.
Rien ne doit se produire pour la méthode onEvent
, aussi nous n'ajouterons pas
de code pour celle-ci.
Nous attachons ce contrôleur à l'élément
listbox
en appelant
la méthode appendController
des objets contrôleurs de la liste.
L'objet controller
a un certain nombre de méthodes qui peuvent être utilisées pour manipuler les contrôleurs.
Par exemple, il possède une méthode insertControllersAt
qui insère un contrôleur
dans un élément avant les autres. Elle peut être utile pour surcharger des commandes. Par exemple,
le code suivant désactivera le collage du presse-papiers dans un champ de saisie.
var tboxController = {
supportsCommand : function(cmd){ return (cmd == "cmd_paste"); },
isCommandEnabled : function(cmd){ return false; },
doCommand : function(cmd){ },
onEvent : function(evt){ }
};
document.getElementById("tbox").controllers.insertControllerAt(0,tboxController);
Dans cet exemple, nous insérons le contrôleur à l'index 0,
c'est-à-dire avant tous les autres. Le nouveau contrôleur supporte la commande
'cmd_paste' et indique qu'elle est désactivée. Le contrôleur par défaut de
textbox
ne sera jamais appelé parce que le répartiteur de commande trouve un contrôleur avant celui-ci, prenant
en charge la commande en premier.
Dans la section suivante, nous allons voir comment mettre à jour les commandes.
Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™
sont des marques de la fondation Mozilla.