2004-07

2004-07-20

Xhtml et élément object

J'ai mis à jour mon formulaire pour écrire des billets, désormais il permet de faire automatiquement de la coloration syntaxique de code xhtml. J'en profite alors pour écrire ce billet que j'avais en tête depuis quelques temps.

On peut avoir envie d'insérer du contenu multimédia dans son document xhtml : une animation Flash, une vidéo ou toute autre friandise offerte par un plug-in de votre navigateur web.

Je me suis penché sur la question, sachant à l'avance que je nagerais dans le flou : je remarque souvent des problèmes de compatibilité sur certains sites avec tel ou tel navigateur, et quand on regarde de plus près sur comment intégrer ce contenu, on remarque qu'il y a deux éléments utilisés : l'élément object, et l'élément embed. Voici un exemple typique :

<object id="flash00" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="400" height="300">
  <param name="movie" value="plop.swf">
  <embed src="plop.swf" width="400" height="300" type="application/x-shockwave-flash"></embed>
</object>

Mais c'est quoi tous ces trucs ? Pourquoi est-ce si compliqué ? Le classid c'est quoi ? Et pourquoi un élément embed dans un élément object ? N'y a-t-il pas double emploi ? Pourquoi on indique le type dans l'élément embed et pas dans l'élément object ? Et si on souhaite scripter facilement le contenu, comment faire vu qu'on a un élément imbriqué dans l'autre ?

Quand je vois un truc trop compliqué, ça m'énerve, et je tente de comprendre pourquoi les choses sont faites ainsi. Procédons par ordre. J'ai dans un premier temps consulté la documentation xhtml, et ô joie, j'ai eu déjà des réponses. Ainsi, en xhtml, l'élément embed n'existe pas. Zouuuuuuuu, aux oubliettes le embed. Mon code devient alors minimal et plus compréhensible :

<object id="flash00" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="400" height="300">
  <param name="movie" value="plop.swf" />
</object>

Heu, sauf que ça fonctionne bien sous IE, mais pas sous Gecko, le moteur de rendu de Mozilla. Je tâche alors de me renseigner sur la question, et je découvre que la syntaxe qui fonctionne sous Gecko est la suivante :

<object id="flash00" type="application/x-shockwave-flash" data="plop.swf" width="400" height="300">
</object>

Malheureusement j'obtiens alors l'effet inverse, ça fonctionne sous Gecko mais plus sous IE. Je tripatouille le code dans tous les sens, en faisant une fusion des deux techniques, et ça ne passe pas. Soit ça fonctionne dans IE, soit dans Gecko. Je vous épargne les étapes du processus, mais j'en viens à la conclusion qu'il convient d'avoir une syntaxe différente pour IE et pour Gecko. Reste alors à trouver la solution pour proposer une syntaxe ou l'autre selon le navigateur.

La première idée qui me vient en tête c'est d'utiliser du javascript. Au déclenchement de l'événement onload de la page, j'appelle une fonction qui va me rajouter au document un élément object avec les paramètres qui vont bien, selon le navigateur. Malheureusement je me casse les dents sur cette solution, j'ai l'impression que mes navigateurs ont du mal avec la création d'éléments object dynamiques (autrement que par une méthode document.write, malvenue pour du xhtml). De plus, quid des navigateurs qui ont le javascript désactivé ? Et puis le javascript est une technologie que je préfère employer uniquement quand je n'ai pas le choix, quand une solution xhtml ou css n'existe pas.

J'ai enfin trouvé la solution. En fin de compte, après réflexion, la méthode qui fonctionne sous Gecko est la méthode conforme aux standards web. Quant à IE, ce qui fonctionne avec lui est une méthode qui lui est propre. J'ai donc décidé d'utiliser les propres armes d'IE pour lui montrer du code qu'il aime bien, et lui cacher ce qu'il aime moins (du code aux normes !). Cette arme ce sont les commentaires conditionnels. Voilà ce que ça donne :

<!--[if !IE]> Standard XHTML object instanciation <!-->
<object id="flash00" type="application/x-shockwave-flash" data="plop.swf" width="400" height="300">
<!--><![endif]-->

<!--[if IE]>
<object id="flash00" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="400" height="300">
<![endif]-->

<param name="movie" value="plop.swf" />
</object>

Grâce à ça, on n'a qu'un seul élément object, au même niveau, avec le même id. Ça fonctionne avec le javascript désactivé. Et si on souhaite travailler avec cet object, on utilisera le même code javascript ou le même code css selon qu'on est sous IE ou un navigateur conforme aux standards ! ^^,

À noter que ce code a du mal dans Opera, ce dernier ne sachant pas gérer l'élément object. Ma position est de laisser Opera s'adapter. Cette attitude m'avait donné raison lorsque je m'étais rendu compte que ce navigateur de savait pas interpréter le javascript pour des documents xhtml desservis en application/xhtml+xml. Après la sortie de Opera 7.50, c'était chose faite, le javascript était bien géré :)

2004-07-13

PngOptimizer 1.4

Voici la nouvelle version de mon utilitaire de conversion/recompression d'images. J'avais déjà entamé la nouvelle version en début d'année, mais je souhaitais ajouter la possibilité d'appeler PngOptimizer en ligne de commande depuis une fenêtre console. J'avais été confronté à un problème de design de Windows qui m'empêchait de faire ce que je voulais.

Après plusieurs mois de réflexion, j'ai décidé de livrer deux versions de PngOptimizer dans la même archive. La première fonctionne en mode graphique, la deuxième en mode console. Vous pourrez lire le fichier Readme pour plus d'information sur les paramètres de la version console.

PngOptimizer compresse aussi un peu mieux, notamment les images en mode palette.

Enfin, PngOptimizer gère les chaines de caractères en Unicode, par conséquent vous pouvez avoir des noms de fichier avec pleins de caractères bizarres dedans (même s'il vaut mieux se limiter à l'ascii dans le cadre d'images allant sur le Web).

En passant PngOptimizer en Unicode, j'ai dû améliorer la dkstd pour y inclure davantage de fonctions utilisant les chaines Unicode. Le plus difficile pour moi a été une fonction qui permet de mettre en bas de casse ou haut de casse n'importe quel caractère Unicode. J'en parlerai plus en détail dans un prochain billet.

Enfin, je tiens à déclarer que Windows 98 est une catastrophe. Après m'être bien embêté à rendre PngOptimizer 100% Unicode, je me suis rendu compte qu'il ne fonctionnait plus sous ce « système d'exploitation » ! En fait, Windows 98, au lieu de mettre un message d'erreur pour dire que les fonctions ne sont pas disponibles, il ne dit rien. Seulement, toutes les fonctions Unicode appelées ne font rien... XD

Deux solutions s'offraient à moi : jeter la compatibilité avec les Windows au noyau 9x, ou me prendre la tête pour rendre PngOptimizer compatible avec les vieilles chaines de caractères. Dans un élan de bonté j'ai choisi la deuxième solution. Comme Windows 98 ne me donne aucune erreur au lancement sur le manque de support de telle ou telle fonction Unicode, j'ai dû passer en revue toutes les sources, à la main, pour déterminer dans quels cas j'avais besoin d'écrire une couche de compatibilité.

Comme j'ai aucun Windows 98 à portée de main, j'ai effectué tous mes tests avec VMWare (un outil fantastique d'émulation de PC). J'espère que je n'ai pas fait d'erreurs. Si vous êtes sous Windows 98, n'hésitez pas à me faire remonter d'éventuels problèmes, avant de désinstaller ce système de malheur et passer à un Windows avec un noyau NT (NT4, 2000, XP, etc.).

Sinon je tiens à remercier Anubis et Denis qui ont mis en péril leurs images pour leurs beta tests ^^,

2004-07-12

Mon premier billet

Ça y'est, j'ai mis en place un formulaire sur mon site pour pouvoir créer et éditer des billets facilement ! ^^

Ça va faciliter les choses pour aborder pleins de sujets divers et variés. Avant, j'éditais tous mes billets à la main. Cela me permettait une grande finesse de composition, mais c'était super long pour écrire un billet.

Alors pour l'instant j'ai un truc très simple qui ne gère que les paragraphes, mais je ne peux m'empêcher d'écrire un nouveau billet. Petit à petit je mettrai de quoi gérer différents formattages : des liens, des emphases, des images... le tout avec une syntaxe Wiki.

Le site restera rapide à s'afficher, car je stocke mes billets en xhtml. C'est l'avantage du xhtml valide : on peut l'analyser sans crainte. Au moment de l'édition d'un billet, je convertis le xhtml en syntaxe Wiki. À l'enregistrement, je fais l'inverse.

Dans la foulée j'utilise maintenant massivement l'option Apache « Multiviews » sur ce serveur. Cela permet de retirer le « .php » disgracieux des URL.