» Suite «

La solution que je vais vous présenter ici ne fonctionne qu'à partir de la R6 de Domino, et n'a été testée que sur la version 6.0.1 win32. En d'autres termes, celle-ci reposant sur des faiblesses et fonctionnalités du système, je n'ai aucune idée de la façon dont elle se comporte sur les autres plateformes. Peut être bien (je l'espère) comme peut être moins bien (allez savoir). Voici en tout cas le principe de fonctionnement puis le code qui va bien :

Propriétés de la page

A la base, à la génération d'une page web (ou d'un masque, hein, ne soyons pas sectaires), Domino nous pond quelque chose du type :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<title>Page title</title>

Pas grand chose à en tirer, impossible de paramétrer quoi que ce soit, et aucune propriété disponible avant la balise <title>. Regardons maintenant d'un peu plus près à quoi ressemblent les échanges entre Domino et le client :

HTTP/1.x 200 OK
Server: Lotus-Domino
Date: Tue, 06 Jan 2004 10:26:09 GMT
Last-Modified: Tue, 06 Jan 2004 09:06:09 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 5381
Cache-Control: private
Etag: W/"MTAtODEw....yIEJPSVNTSU4vTz1GVEVM"

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<title>Page title</title>

Comme on peut le constater, avant la déclaration même du Doctype, il y a un paquet d'infos qui sont envoyées : les entêtes HTTP. Hors, depuis la R6 de Domino, il est possible de lire ou d'écrire dans lesdites entêtes, il existe même 2 formules pour ça : @SetHTTPHeader et @GetHTTPHeader. Autrement dit, on est capable d'écrire dans le flux envoyé au navigateur avant que le doctype soit écrit. Vous me voyez venir ? hmm ?

Voici donc les différentes étapes à réaliser pour mener à bien notre opération :

  1. Se positionner après les entêtes HTTP générées par Domino
  2. Insérer notre doctype et diverses déclarations si nécessaires
  3. Court-circuiter les données générées automatiquement par Domino (c'est-à-dire son doctype)
  4. Reprendre le cours normal de la page

Dans la pratique, Domino est assez capricieux et la marge de manoeuvre très restreinte. Sachant que Domino filtre les entêtes HTTP spécifiée par le développeur, l'idée va être d'ajouter une entête HTTP autorisée "bateau" (ici "Expires"), qui ne modifie en rien le comportement de la page, mais dans laquelle on va pouvoir spécifier d'autres entêtes HTTP quant à elles prohibées, ainsi que le doctype désiré, en reconstruisant la structure du document via des retours à la ligne. Le retour à la ligne classique (@NewLine) est également interdit, néamoins le code @Char(10) (Codepage IBM 850 - un retour à la ligne également) a été épargné, nous pouvons donc en user et en abuser à volonté.

A ce niveau, les deux premières étapes de l'opération sont réalisées, reste maintenant les deux dernières. Cela va être en réalité très simple ; après avoir précisé notre doctype, on ouvre la balise de commentaire HTML (<!--), que l'on ferme dès que possible, dans une propriété de la page (ou du masque, toujours). Nous la fermerons dans la propriété "HTML Head Content", puisque dans "Window Title", qui arrive juste avant, les caractères sont échappés (et il est par conséquent impossible d'y mettre de l'HTML). De cette manière, toutes les déclarations générées automatiquement par Domino sont mises en commentaires, et on obtient une belle page HTML toute propre et qui, selon le doctype qu'on aura pris soin de lui spécifier, sera en mode de conformité aux standards du W3C ou non :

HTTP/1.x 200 OK
Server: Lotus-Domino
Date: Tue, 06 Jan 2004 10:26:09 GMT
Last-Modified: Tue, 06 Jan 2004 09:06:09 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 5381
Cache-Control: private
Expires: Mon, 05 Jan 2004 17:36:14 GMT
Connection: close

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1
-transitional.dtd">

<html>
<head>
<!--

ETag: W/"MTAtODEw....yIEJPSVNTSU4vTz1GVEVM"

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>

//-->
<title>Page title</title>

Comme vous pouvez le constater, le gros défaut de cette solution est qu'elle rend caduque le système de cache serveur de Domino (entête "ETag"). Malheureusement, je n'ai trouvé aucune entête HTTP que Domino écrivait après celle-ci, et comme il est difficile de reproduire ce mécanisme de cache manuellement, autant l'écarter purement et simplement. Après c'est un choix, conformité des pages ou cache serveur, mais dans tous les cas, le cache coté client lui restant bien actif..

Voici donc l'ensemble du code à spécifier pour mettre en oeuvre cette solution :

Computed Value
Le code du Computed Value (cliquer pour agrandir)

HTMLHeadContent
Et la fermerture du commentaire en début de "HTML Head Content"
(cliquer pour agrandir)

Le "Computed Value" doit être le plus en haut possible de la page/du masque, et il ne doit y avoir impérativement aucun élément avant (ni texte, ni ressource, rien). Le "HTML Head Content" quant à lui, et bien, pas grand chose à préciser, son rôle est juste d'ajouter la balise de fermeture des commentaires. Notez que le titre de la page est indiqué dans cette propriété et non dans "Window Title", vu que le contenu de cette propriété, si tant est qu'elle en ait un, se retrouverait commenté !

Petite remarque : la taille indiquée par l'entête HTTP "Content-Length" est la taille nominale du contenu de la page et non sa taille effective, sachant qu'à la taille nominale nous devons ajouter taille du code HTML inséré au travers des entêtes HTTP pour obtenir la taille effective. En pratique, on envoit au navigateur un contenu plus grand que la taille qu'on lui demande de lire. En résulte que les pages étaient, à l'origine, tronquées et qu'il manquait les derniers tags HTML. Néanmoins, en ajoutant l'entête prohibée "Connection" avec pour valeur "close" (entête qui autrement avec Domino n'est accessible qu'en lecture seule ), on indique au navigateur de fermer proprement la connexion avec le serveur, ce qui à pour effet de charger malgré tout les derniers octets de la page. Que demande le peuple ?

Nous avons donc vu comment mettre en place relativement aisément une solution permettant de choisir son propre doctype et ainsi rendre les pages web générées par Notes potentiellement (au gré du développeur) en mode conformité aux standards du W3C ou non. Et cela fait de moi le plus heureux des hommes (ou presque :)

[08/01/2004] : Patch v1.1

Je me suis aperçu à l'usage que tous les navigateurs n'interprétaient pas bien, ou de manière aléatoire, l'entête "Connection: close". Ainsi, Mozilla semble passer quelquefois à coté (rarement, mais quelquefois), là ou IE offre a priori 100% de réussite. Quant à Opera, c'est relativement aléatoire.. La conséquence de tout ça, c'est que lorsqu'une telle situation se produit, la fin de la page est tronquée, ce qui, au mieux, retire derniers tags de fermeture, au pire, pourrait interrompre un traitement javascript.

Il n'y aura pas de miracle ce coup-ci, l'unique solution qui permettrait de résoudre ce problème proprement (car des solutions crades, j'en ai un paquet en stock, ne vous inquiétez pas) serait de spécifier la bonne taille de document dans l'entête "Content-Length". Ce que je n'ai pas réussi à faire, malgré une vaine demi-journée de recherche.

Je propose donc est de limiter les dégats, en s'arrangeant pour que, dans le pire des cas, seuls les tags "</form></body></html>" soient tronqués, ce qui, dans 99.9% des navigateurs, n'aura aucun impact visuel ni fonctionnel. Pour ce faire, l'idée consiste à ajouter un nombre conséquent d'espaces (nombre supérieur au nombre de caractères ajoutés via l'entête HTTP) avant la fermeture (automatique, puisque par Domino) de la page. De cette manière, seuls les tags suscités seraient tronqués dans une telle situation. Et dans le cadre d'un comportement normal, ces quelques espaces supplémentaires passeront inaperçus et représenteront juste quelques octets supplémentaires à télécharger. D'un point de vue plus concret, un "Computed Text" en fin de page fera l'affaire :

2e Computed Value

Et voilà.. dans l'ensemble, on aura vu plus propre et empirique comme astuce, mais quitte à choisir, entre zapper occasionnellement (ce qui reste rare malgré tout) les tags de fermeture de la page ou devoir développer des applications Web en mode Quirks, je choisis mille fois la première proposition..