Sommaire
Depuis que le World Wide Web Consortium a lancé la Web Accessibility Initiative, les problématiques de validation XML et d’accessibilité du Web aux déficients visuels ont convergé. SPIP s’est très tôt intéressé aux problèmes d’accessibilité, avec la version 1.5 en 2002. En revanche, il a longtemps récusé XML eu égard à la rareté des pages conformes : l’abondance de pages HTML non XHTML fait que les navigateurs ont leur propre analyseur, et les langages basés sur XML, comme SVG, MathML et XQuery, ont connu un démarrage très lent. Toutefois, la convergence des problématiques d’accessibilité et de validation d’une part, et l’implémentation en natif de SVG dans plusieurs navigateurs de l’autre, a amené SPIP, dans sa version 1.8.1, à offrir une interface avec des outils de validation comme Tidy ou le validateur officiel du W3C. Ces outils, comme l’indiquent sans détour les pages d’accueil de leur site, souffrent de quelques limitations, révèlent des divergences dans leurs messages d’erreur, et ne sont pas installables par l’internaute moyen [1]
Ils sont de plus inopérants face aux nouvelles technologies comme Ajax, qui modifient incrémentalement le contenu d’une page Web.
Plus grave encore, les Document Type Definition du W3C ont elles aussi des limitations, y compris la DTD XHTML 1.0 dite stricte : alors que la spécification officielle interdit l’emboîtement des balises a, label ou form, la définition formelle de la grammaire décrite considère comme valides les constructions <label for='x'><label...
ou <form action='.'><div><form...
par exemple [2].
Face à cette situation, SPIP 1.9.2 innove radicalement en proposant un validateur extensible, intégré, incrémental et optionnel, fondé sur le Simple Analyzer for XML fourni en standard par PHP. Cette pluralité d’aspects le destine autant aux webmestres qu’aux graphistes et aux développeurs d’extensions de SPIP avec évidemment des manipulations différentes.
Validation pour les webmestres
Pour les webmestres, mettre simplement dans le fichier mes_options.php
l’instruction $xhtml = 'sax';
provoquera une remise en page du code HTML produit par un squelette, chaque ligne comportant une seule balise ouvrante et au plus un attribut, avec renfoncement de la marge gauche proportionnellement au nombre de balises ouvrantes non fermées. Dans le cas où la page se révèle invalide, ce travail sera finalement ignoré, et le texte initial sera envoyé au client HTTP. Dans les ceux cas, la mise en cache éventuelle a évidemment lieu après l’action du validateur, qui se contente donc ici d’une simple mise en page.
Quelques précisions en ce qui concerne le traitement des attributs.
Leur valeur sera systématiquement entourée d’une apostrophe, sauf si elle contient une apostrophe auquel cas elle sera entourée de guillemets (et si elle contient aussi des guillemets, ils seront écrits "
). En raison d’une erreur de conception de SAX [3], les entités XML seront préalablement converties dans le charset du site à l’exception de &
amp; < >
et "
qui sont correctement traitées par SAX (car c’est indispensable). La liste des entités et leur valeur seront déduites du DOCTYPE indiqué par le squelette ; à défaut SPIP prendra un ensemble prédéfini équivalent à la DTD du latin1 enrichie de €
, œ
et Œ
définis dans la DTD des symboles spéciaux.
Validation pour les graphistes
Pour les créateurs de squelettes, le validateur est disponible à travers le débusqueur introduit en SPIP 1.8. Cet outil n’est visible que des administrateurs du site, car ils disposent des boutons d’administration lorsqu’ils visitent les pages de l’espace public. L’un de ces boutons se nomme Analyse XML et déclenche explicitement la demande de validation de la page visitée. Cette analyse est d’abord confiée à SAX qui, même en l’absence de DOCTYPE
, repère :
- les mauvais emboîtements de balises ouvrantes et fermantes ;
- les attributs sans valeur ;
- les attributs sans délimiteur ;
- les attributs sans espace avant le suivant ;
- les entités XML mal écrites (notamment un
&
littéral, alors que XML impose d’écrire &
).
À la première erreur rencontrée, le débusqueur de SPIP essaiera immédiatement de retrouver de quel squelette provient l’erreur (il y en a plusieurs en cas d’inclusion) et à quelle ligne, en donnant des liens vers les fichiers sources (cette détermination ne peut pas toujours aboutir, une marge d’erreur est à prendre en compte).
Si cette première analyse est correcte, cette nouvelle version de SPIP va plus loin en prenant en compte le DOCTYPE de la page. Il peut être de type PUBLIC
ou SYSTEM
, et dans le premier cas la DTD sera mise en cache pour accélérer les analyses ultérieures. Chaque DTD peut en inclure d’autres, qui seront chargées pareillement. Afin d’éviter les redondances de calcul tout en tenant compte du système d’inclusion conditionnelle des DTD, SPIP met également en cache une structure de données spécifique qu’il déduit de la lecture de toutes les définitions d’éléments, d’attributs et d’entités issus du DOCTYPE indiqué.
A l’aide de cette structure, SPIP valide la page, autrement dit vérifie que :
- tous les noms d’attributs utilisés dans une balise sont acceptés par la DTD ;
- tous les attributs obligatoires d’une balise sont présents ;
- toutes les valeurs d’attributs sont conformes au motif indiqué éventuellement dans la DTD ;
- tous les attributs de type ID ont une valeur composée de lettres, chiffres, souligné, tiret et deux-points ;
- tous les attributs de type IDREF ou IDREFS référencent des ID effectivement présents dans la page ;
- toutes les entités XML utilisées sont définies dans la DTD ;
- tous les noms de balises utilisées sont définis dans la DTD ;
- toute balise non vide est autorisée à l’être par la DTD (par exemple un
img
non vide sera dénoncé) ; - toute balise vide est autorisée à l’être par la DTD (par exemple un
tr
vide sera dénoncé) ; - toute balise utilisée est fille d’une balise l’admettant comme telle dans la DTD ;
- toute balise devant apparaître avant une de ces sœurs apparaît effectivement ainsi (par exemple
head
avantbody
) - toute balise devant apparaître un nombre fixe de fois apparait effectivement ainsi (par exemple
title
une unique fois danshead
).
Si des erreurs sont détectées, le validateur affichera un tableau de toutes les erreurs, avec leur nombre d’occurrences, des liens vers les lignes incriminées et des suggestions de corrections déduites automatiquement des constructions autorisées par la DTD. En l’absence d’erreur, le débusqueur affichera le code selon la mise en page décrite précédemment.
Validation pour les développeurs
Les pages Web en accès restreint ont particulièrement besoin d’un validateur intégré pour être mises au point, puisque les outils de validation externes n’ont par définition pas accès à ces pages. En ce qui concerne les scripts, standards ou venant d’extension, de l’espace de rédaction de SPIP on leur applique la validateur XML en plaçant $GLOBALS['transformer_xml'] = 'valider_xml';
dans le fichier mes_options.php.
L’espace privé de SPIP 1.9.2 a été rendu conforme XHTML 1.0 grâce à ce mécanisme. Affecter cette variable globale à 'indenter_xml'
provoquera l’indentation du source HTML si celui-ci est conforme XML, sans chercher à le valider.
Il est également possible de lancer, avec la souris, l’analyse XML du résultat d’un script Ajax activé dans l’espace de rédaction. Un tel script ne retournant pas une page HTML complète mais seulement un fragment, le validateur intégré fabriquera une page avec le DOCTYPE courant, un en-tête réduit à la balise Title, et une balise Body composée de ce fragment. Une fenêtre s’ouvrira avec le résultat de l’analyse, comme pour une page normale, pendant que la fenêtre initiale recevra le résultat du script Ajax comme d’habitude. En raison d’une spécification du W3C inutilisable quant au modèle d’événements [4], ce lancement du validateur n’est pas provoqué par un bouton spécifique de la souris, mais par un clic pendant lequel une au moins des deux touches Alt ou Meta est enfoncée.
Par ailleurs, le validateur de SPIP peut être appliqué à n’importe page présente sur le Web. Tout site SPIP installé à l’URL http://u contient la page http://uecrire/valider_xml que les auteurs du site peuvent invoquer explicitement pour valider des pages non limitées à celle du site. Ce validateur ne s’applique cependant qu’à des documents XML ; en l’absence de DOCTYPE, la DTD XHTML1.0 transitionnal sera prise.
Comme le suggèrent les lignes ci-dessus, le validateur s’applique à n’importe quel DOCTYPE, y compris ceux référençant des DTD résidantes sur le site.
Rendre accessibles des pages Web, c’est être plus rigoureux dans l’utilisation des attributs et des balises, on peut donc facilement se construire un outil de validation d’accessibilité en écrivant des DTD moins laxistes que la XHTML 1.0 dite stricte. Remplacer #IMPLIED
par #REQUIRED
dans les attributs jugés indispensables est immédiat. Forcer input, select, textarea
et button
a être exclusivement des filles de la balise label
est à peine plus difficile. En outre, le validateur accepte n’importe quel motif (au sens de PCRE) comme type d’attribut, il sera alors appliqué à chaque occurrence de cet attribut dans la page analysée.
Enfin, il est possible de définir ses propres règles de validation associées à un attribut. Les types usuels ID, IDREF et IDREFS sont implémentés par les fonctions validerAttribut_ID, validerAttribut_IDREF, validerAttribut_IDREFS. Il suffit d’introduire de nouveau type S1 ... Sn dans la DTD, et de définir les fonctions associées dans le fichier mes_options pour provoquer des contrôles personnalisés. En fin d’analyse, la fonction surchargeable inc_valider_passe2
est appelée, afin d’effectuer les contrôles rétrospectifs (c’est ici que les attributs IDREF sont vérifiés comme référençant des attributs effectivement présents).
Cette interface de programmation est encore un peu frustre et sera revisée après expérimentation. Mais elle permet dès à présent de mettre sur pied très rapidement de nouvelles spécifications d’accessibilité.