Longtemps, les applications web n'ont été en fait que des sites web proposant un minimum d'interactions. On affichait des contenus et on proposait à l'utilisateur un nombre restreint d'actions sur ces contenus[1]. Les logiciels clients imposaient des contraintes très fortes: HTML est fait pour afficher des documents, pas l'interface d'une application; la personnalisation de l'affichage est limitée au support de normes CSS encore assez pauvres (vivement CSS 3!); JavaScript est un langage qui a mauvaise réputation chez bon nombre de développeurs et développeuses. Et surtout, les principaux clients du marché avaient chacun leur façon d'implémenter ou de ne pas implémenter les normes. Ces contraintes guidaient la conception des applications. On s'y pliait au lieu de se concentrer sur les fonctionnalités.

Heureusement, la situation évolue. Que ce soit par l'apparition de nouvelles technologies (XUL (standard ouvert et clients libres), Flex (propriétaire), Apollo (propriétaire)...) ou de frameworks JavaScript, les limites de ce qu'il est possible de faire au sein d'un navigateur reculent sans cesse, les contraintes tombent, et on peut enfin réaliser des applications avec des interfaces riches (RIA), comme au temps du client-serveur. Des applications où les interactions avec les utilisateurs sont nombreuses et variées.

Le billet de Christian Heilmann conseille de prendre un compte cette évolution pour revoir la façon de concevoir les applications web, en adoptant une approche centrée sur ces interactions, en l'occurence sur les évènements.

Le W3C a définit un modèle de gestion des évènements au sein d'un document. Quand un évènement survient, il déclenche un processus en 2 étapes: il faut d'abord déterminer quel élément l'a provoqué: on "descend" dans l'arborescence depuis la racine jusqu'à la source de l'évènement. Une fois celle-ci atteinte, on "remonte" jusqu'à la racine en informant chaque parent de l'élément de l'évènement. D'après ce modèle, on peut gérer les évènements à chacune des deux étapes via des "listeners". Un listener définit une fonction à exécuter lorqu'un évènement survient. On peut par exemple ajouter un listener pour l'évènement "clic" sur un bouton. Ce listener appellera une fonction quand le bouton sera cliqué. Mais le listener peut aussi être définit sur n'importe quel parent du bouton. Il devra alors définir le ou les éléments fils et le ou les évènements fils auquel il s'applique. On peut également préciser s'il doit se déclencher lors de la phase descendante ou montante. Enfin, le listener peut stopper la propagation de l'évènement, ou être transparent.

L'avantage de cette solution est que l'on peut définir des listeners à un niveau élevé, le document ou une zone par exemple, et qu'ils seront relativement indépendants de modifications du document. Il vaut mieux gérer le choix d'un item dans un menu au niveau de la barre de menu que de chaque item.

C'est intéressant, mais impose encore une limite: on ne gère que les évènements déclenchés par le DOM, qui sont souvent de bas niveau.

C'est là qu'intervient la bibliothèque Yahoo! User Interface Library: elle permet la création d'évènements personnalisés. Ces évènements définis, on peut les utiliser comme ceux du DOM, les déclencher à la demande, les intercepter pour les traiter, etc.

Dès lors, durant la phase de conception de l'application, on peut adopter une approche événementielle: on définit les évènements susceptibles de survenir et la réaction attendue, et on construit ainsi une logique applicative indépendante de la façon dont l'application sera implémentée. Les évènements peuvent être déclenchés par l'humain (connection, action sur un contenu), la machine (un timer par exemple), le serveur (annonce de la disponibilité d'un nouvel objet), l'application se contente d'y répondre. Cette approche n'est certes pas nouvelle, YUI permet juste de l'utiliser pour des développements dont la cible est (X)HTML/EcmaScript.

Cet article m'a particulièrement intéressé. Je m'attaque régulièrement à la réalisation de mini-applis web (jamais finies, je n'ai toujours pas trouvé de mécène pour m'abstenir de passer l'essentiel de mon temps à le vendre à un patron), et je me pose sans arrêt la question de l'interface: HTML classique ? XUL ? essayer autre chose ? Avec l'approche "événementielle", je peux réaliser l'essentiel de la logique de l'appli avec un framework Javascript, sans me soucier de l'interface. Il sera toujours temps de brancher après une ou plusieurs IHM via quelques connecteurs spécifiques. Bref, je vais essayer de mettre ça en pratique cette année. Espérons que j'aurai un truc à montrer d'ici quelques mois.

Notes

[1] séquence nostalgie, ça me rappelle un peu le mainframe. Ah CICS ;-)