<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>La Case de l&#039;Oncle Tom &#187; dom</title>
	<atom:link href="http://case.oncle-tom.net/tag/dom/feed/" rel="self" type="application/rss+xml" />
	<link>http://case.oncle-tom.net</link>
	<description>Développement Web, bonnes pratiques et performances</description>
	<lastBuildDate>Sun, 25 Dec 2011 19:33:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<atom:link rel="search"
           href="http://case.oncle-tom.net/opensearch"
           type="application/opensearchdescription+xml"
           title="Content Search" />		<item>
		<title>Canalblog Importer : migrer de Canalblog vers WordPress en 5 clics</title>
		<link>http://case.oncle-tom.net/2010/canalblog-importer-migrer-canalblog-wordpress/</link>
		<comments>http://case.oncle-tom.net/2010/canalblog-importer-migrer-canalblog-wordpress/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 09:00:46 +0000</pubDate>
		<dc:creator>Oncle Tom</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[canalblog]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[import]]></category>
		<category><![CDATA[logiciels libres]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[php5]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[xpath]]></category>
		<guid isPermaLink="false">http://case.oncle-tom.net/?p=1519</guid>
		<description><![CDATA[Canalblog, en 2010, c'est près de 700 000 blogs et près de 17 millions d'articles publiés depuis l'année 2003. À ce stade, difficile de considérer cette plateforme comme négligeable puisqu'elle a bénéficié d'une capacité d'attraction suffisante pour séduire plusieurs centaines de millier d'utilisateurs.
Seul problème : ces blogs sont captifs de leur plateforme. L'extension WordPress <strong>Canalblog Importer</strong> permet de sauver votre blog Canalblog dans WordPress.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.canalblog.com/">Canalblog</a>, en 2010, c&#8217;est près de 700 000 blogs et près de 17 millions d&#8217;articles publiés depuis l&#8217;année 2003. À ce stade, difficile de considérer cette plateforme comme négligeable puisqu&#8217;elle a bénéficié d&#8217;une capacité d&#8217;attraction suffisante pour séduire plusieurs centaines de millier d&#8217;utilisateurs.</p>
<p><img class="aligncenter size-full wp-image-1521" title="Logo Canalblog" src="http://case.oncle-tom.net/images/2010/02/canalblog.png" alt="" width="217" height="95" /></p>
<p>J&#8217;ai contacté le support à plusieurs reprises pour prendre connaissance de la mise en place de noms de domaine personnalisés et de la mise en place de nouvelles fonctionnalités. Bénéficier d&#8217;une adresse en <em>monblog.fr</em> au lieu de <em>monblog.canalblog.fr</em> est intéressant, en terme d&#8217;image mais aussi d&#8217;indépendance.</p>
<p>Le gros problème est que <strong>Canalblog ne m&#8217;a jamais répondu</strong>. Ni à moi ni à plusieurs utilisateurs.<br />
En 2010, ce sont donc plus de<strong> 700 000 blogs qui se retrouvent captifs</strong> d&#8217;une plateforme avec une seule porte de sortie : le copié/collé de leurs articles. Difficilement acceptable.</p>
<h3><span id="more-1519"></span>Canalblog Importer : plugin d&#8217;import de Canalblog vers WordPress</h3>
<p>Las de ce mutisme de la part de Canablog, j&#8217;ai donc décide de me mettre à l&#8217;ouvrage pour offrir une extension WordPress répondant à ces 2 critères :</p>
<ul>
<li>importer un maximum d&#8217;éléments</li>
<li>en demander le moins possible à l&#8217;utilisateur</li>
</ul>
<p>Une fois le <em>plugin</em> activé, une nouvelle entrée fait son apparition dans la rubrique d&#8217;administration Outils &gt; Importer : <a href="http://wordpress.org/extend/plugins/canalblog-importer/">Canalblog Importer</a>.</p>
<h3>L&#8217;import Canalblog en 5 étapes</h3>
<p>L&#8217;import de son blog Canalblog se déroule par la suite en 5 étapes :</p>
<ol>
<li>Configuration</li>
<li>Import des mots-clefs</li>
<li>Import des catégories</li>
<li>Import des articles
<ul>
<li>Import des articles</li>
<li>Import des commentaires</li>
<li>Import des médias</li>
</ul>
</li>
<li>Nettoyage</li>
</ol>
<p>La configuration de l&#8217;import est le moment requérant toutes vos capacités pour taper l&#8217;<strong>adresse de votre blog</strong>. Oui c&#8217;est tout. S&#8217;ensuit alors une suite de recommandations, entre autre pour s&#8217;assurer du bon déroulement de l&#8217;import. Ça concerne la configuration des permaliens et le format de dates sur Canalblog.</p>
<p>Une fois le bouton d&#8217;import cliqué, il faudra réitérer le clic au début de chaque étape clé, la plus longue étant l&#8217;import des articles.<br />
Techniquement, sur un blog possédant plusieurs milliers d&#8217;articles sur 5 ans, il m&#8217;aura fallu à peine<strong> 20 minutes de patience et 5 clics</strong>.<br />
Difficile d&#8217;en demander plus à quelqu&#8217;un n&#8217;ayant aucune notion technique.</p>
<div id="attachment_1523" class="wp-caption aligncenter" style="width: 310px"><a href="http://case.oncle-tom.net/images/2010/02/screenshot-11.png"><img class="size-medium wp-image-1523" title="Écran de configuration de Canalblog Importer" src="http://case.oncle-tom.net/images/2010/02/screenshot-11-300x123.png" alt="" width="300" height="123" /></a><p class="wp-caption-text">Écran de configuration de Canalblog Importer</p></div>
<h3>Canalblog Importer : les fonctionnalités</h3>
<p>Les différentes étapes de l&#8217;import résument à elles seules les fonctionnalités de cet outil d&#8217;import :</p>
<ul>
<li>import des mots-clefs</li>
<li>import des catégories</li>
<li>import des articles</li>
<li>import des commentaires</li>
<li>import des médias</li>
<li>import des auteurs</li>
<li>correction des liens inter-articles</li>
<li>intégration des médias dans le gestionnaire de médias de WordPress − avec génération de vignettes à la clé et utilisation de celles-ci au sein des articles</li>
<li>reprise de l&#8217;intégration et tolérance à l&#8217;erreur : l&#8217;import peut être relancé indéfiniment, les contenus ne seront pas réimportés en double</li>
</ul>
<p>En gros, ce que cette extension ne fait pas, c&#8217;est le café, la récupération de la <em>blogroll</em> et la migration du référencement vers votre nouveau blog − faute au manque de nom de domaine et à l&#8217;impossibilité de dire aux moteurs de recherche les nouvelles adresses des articles hébergés sur Canalblog.</p>
<p>J&#8217;ai essayé de rendre toutes les <strong>étapes conviviales, explicatives et rassurantes</strong> sur le processus en cours et restant. C&#8217;est encore plus simple que de rédiger un article de blog. Enfin, je trouve <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<div id="attachment_1524" class="wp-caption aligncenter" style="width: 310px"><a href="http://case.oncle-tom.net/images/2010/02/screenshot-2.png"><img class="size-medium wp-image-1524" title="Écran d'aide à la fin d'import" src="http://case.oncle-tom.net/images/2010/02/screenshot-2-300x142.png" alt="" width="300" height="142" /></a><p class="wp-caption-text">Écran d&#39;aide à la fin d&#39;import</p></div>
<h3>La clé de la réussite : cURL et XPath</h3>
<p>Sous le capot, la dépendance à <acronym title="Pre-Hypertext Processing">PHP</acronym> 5.1+ s&#8217;explique par 3 choses :</p>
<ul>
<li>l&#8217;autoloading <acronym title="Pre-Hypertext Processing">PHP</acronym><br />
J&#8217;en ai un peu marre de faire des require à tour de bras donc je fais fi des recommandations de WordPress : PHP4 est mort, faut arrêter avec ce délire de compatibilité, pas en 2010 (ni même en 2008 ou 2009).</li>
<li><a href="http://fr.php.net/manual/en/book.curl.php">cURL</a><br />
C&#8217;est vraiment la boîte à outil de la manipulation <acronym title="HyperText Transfer Protocol">HTTP</acronym>. Elle est abstraite dans la classe WP_Http. Son utilité ? Récupérer du contenu distant. Pratique pour rapatrier le contenu de pages <acronym title="HyperText Markup Language">HTML</acronym>, entre autre.</li>
<li><a href="http://fr.php.net/manual/en/class.domxpath.php">DOMXPath</a><br />
Associé au <a href="http://fr.php.net/manual/en/book.dom.php"><acronym title="Document Object Model">DOM</acronym> PHP5</a>, c&#8217;est un outil formidable pour requêter au sein d&#8217;un document <acronym title="HyperText Markup Language">HTML</acronym> &#8230; disons, récupéré à distance ? La structure des thèmes Canalblog étant identique (pour peu qu&#8217;ils n&#8217;aient pas été retouchés en mode avancé), le travail de constitution des sélecteurs XPath n&#8217;en était que plus facilitée.</li>
</ul>
<p>Donc clairement, cette extension effectue un <strong>travail bête et méchant de <em>crawl</em> des pages d&#8217;un blog</strong>, de manière structurée afin de peupler tranquillement un blog WordPress de ce même contenu.<br />
Je me suis basé au maximum par les outils déjà existants &#8230; y compris la classe d&#8217;import WordPress.com ! Je l&#8217;ai réutilisé pour l&#8217;import des médias vu qu&#8217;elle correspondait parfaitement au besoin.</p>
<h3>Le pouvoir aux utilisateurs</h3>
<p>Au-delà du simple aspect technique de la réalisation de l&#8217;extension (qui a demandé quelques heures de travail tout de même), il faut comprendre une chose : capturer ses utilisateurs pour éviter leur fuite en cas de déclin d&#8217;un produit n&#8217;empêchera pas les utilisateurs de trouver une solution à leur problème.</p>
<p><strong>La réponse au problème de la communauté est venue de la communauté elle-même</strong> : elle veut partir ? Elle part et s&#8217;en donne les moyens.</p>
<p>Le seul moyen pour Canalblog de conserver ses utilisateurs, après cette porte de sortie offerte à tous les usagers, c&#8217;est d&#8217;innover et de les reconsidérer comme le moteur de leur croissance. Tout effort pour entraver cette démarche serait une pure perte de temps, n&#8217;ajoutant que trop de douleurs à une agonie certaine.</p>
<p><a href="http://wordpress.org/extend/plugins/canalblog-importer/">Canalblog Importer</a> est une extension gratuite pour WordPress, libre de téléchargement, d&#8217;utilisation et de modification (sous réserve que le code modifié soit republié sous la même licence). L&#8217;extension constitue ainsi une bonne base pour constituer de nouveaux imports d&#8217;autres plateformes, fermées elles aussi.</p>]]></content:encoded>
			<wfw:commentRss>http://case.oncle-tom.net/2010/canalblog-importer-migrer-canalblog-wordpress/feed/</wfw:commentRss>
		<slash:comments>207</slash:comments>
		</item>
		<item>
		<title>Firebug : bonnes pratiques pour le développement Web</title>
		<link>http://case.oncle-tom.net/2007/bonnes-pratiques-firebug-developpement-web/</link>
		<comments>http://case.oncle-tom.net/2007/bonnes-pratiques-firebug-developpement-web/#comments</comments>
		<pubDate>Tue, 25 Dec 2007 07:00:44 +0000</pubDate>
		<dc:creator>Oncle Tom</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[Standards du Web]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[logiciels libres]]></category>
		<category><![CDATA[optimisation]]></category>
		<category><![CDATA[performances]]></category>
		<category><![CDATA[yslow]]></category>
		<guid isPermaLink="false">http://case.oncle-tom.net/2007/12/25/bonnes-pratiques-firebug-developpement-web/</guid>
		<description><![CDATA[Firebug fait partie de mes extensions préférées depuis un bon moment. Je l&#8217;estime aujourd&#8217;hui même plus importante que l&#8217;extension Web Developer, c&#8217;est dire. J&#8217;ai pourtant constaté que la plupart de ses utilisateurs la sous-exploitait en se limitant à la console pour consulter les erreurs et éventuellement à l&#8217;inspecteur HTML pour remonter rapidement dans l&#8217;arborescence des [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/12/firebug-logo.gif" alt="Logo Firebug" /></p>
<p><a href="http://case.oncle-tom.net/2007/08/07/facebook-rock-your-firefox/">Firebug fait partie de mes extensions préférées</a> depuis un bon moment. Je l&#8217;estime aujourd&#8217;hui même plus importante que l&#8217;extension <a href="https://addons.mozilla.org/fr/firefox/addon/60">Web Developer</a>, c&#8217;est dire.</p>
<p>J&#8217;ai pourtant constaté que la plupart de ses utilisateurs la sous-exploitait en se limitant à la console pour consulter les erreurs et éventuellement à l&#8217;inspecteur <acronym title="HyperText Markup Language">HTML</acronym> pour remonter rapidement dans l&#8217;arborescence des balises en 1 clic. C&#8217;est bien mais pas assez.<br />
Firebug est tout simplement énorme ! Suffisamment énorme pour <strong>gagner un temps incroyable</strong> dans le développement d&#8217;applications JavaScript et pour <strong>mieux comprendre les incohérences</strong> des <acronym title="Cascading Style Sheets">CSS</acronym> dans une page, entre autre.</p>
<p>Je vous offre aujourd&#8217;hui mon cadeau de Noël pour gagner en productivité et maîtriser cet outil ô combien indispensable.<br />
<span id="more-819"></span><br />
Le plus amusant dans l&#8217;histoire c&#8217;est que le site officiel de Firebug dévoile (succinctement certes) tous les petits <em>plus</em> qui simplifient la vie. Je vais m&#8217;atteler à les éplucher en fonction des domaines d&#8217;utilisation :</p>
<ol>
<li><a href="#firebug-html">pour le <acronym title="HyperText Markup Language">HTML</acronym> et les <acronym title="Cascading Style Sheets">CSS</acronym></a></li>
<li><a href="#firebug-javascript">pour le JavaScript</a></li>
<li><a href="#firebug-performances">pour gagner en performances</a></li>
</ol>
<h3 id="firebug-html">Firebug pour le <acronym title="HyperText Markup Language">HTML</acronym></h3>
<h4>L&#8217;inspection <acronym title="HyperText Markup Language">HTML</acronym></h4>
<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/12/firebug-html-inspector.png" alt="Inspecteur HTML Firebug" /></p>
<p>J&#8217;apprécie l&#8217;inspection <acronym title="HyperText Markup Language">HTML</acronym> car elle me permet de retrouver simplement le code lié au visuel. Après avoir activé l&#8217;inspecteur, je survole l&#8217;élément sur lequel je veux travailler, je clique dessus et le volet Firebug se fige dessus en m&#8217;indiquant <strong>toutes ses propriétés <acronym title="Cascading Style Sheets">CSS</acronym>, le modèle de boîte et ses propriétés <acronym title="Document Object Model">DOM</acronym></strong>. On en reparle tout de suite après.<br />
L&#8217;inverse est également possible. C&#8217;est à dire qu&#8217;en survolant le code, la correspondance visuelle dans la page est établie. C&#8217;est rudement pratique pour repérer des éléments qui sortent du flux. Ça l&#8217;est d&#8217;autant plus que les différentes marges (internes, externes, bordures) sont elles aussi mises en surbrillance.</p>
<p>Le gros atout de cet inspecteur c&#8217;est également l&#8217;<strong>édition à la volée de toutes les balises</strong> ! Idéal pour tester diverses classes d&#8217;un objet ayant un impact visuel fort sur son affichage. Cet outil présente un gain de temps énorme par rapport à la modification du code dans son éditeur et un petit coup de touche <kbd>F5</kbd> dans la foulée.</p>
<p>Il faut également retenir que <strong>toute balise est sélectionnable en cliquant sur son nom</strong> (<code>div</code>, <code>h3</code> etc.). Cela a a pour effet de mettre à jour le panneau latéral de Firebug. Panneau latéral qui est également fort utile.</p>
<h4>L&#8217;inspection <acronym title="Cascading Style Sheets">CSS</acronym>, Layout et <acronym title="Document Object Model">DOM</acronym></h4>
<p>Le panneau latéral de l&#8217;inspecteur <acronym title="HyperText Markup Language">HTML</acronym> se compose de 3 onglets, tous très utiles.</p>
<h5>Inspecteur <acronym title="Cascading Style Sheets">CSS</acronym></h5>
<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/12/firebug-css-inspector.png" alt="Inspecteur CSS Firebug" /></p>
<p>Les propriétés <acronym title="Cascading Style Sheets">CSS</acronym> affichées concernent uniquement l&#8217;objet actif et c&#8217;est ce qui en fait sa force. Ce panneau indique en effet la <strong>cascade <acronym title="Cascading Style Sheets">CSS</acronym> en cours</strong> ce qui permet de comprendre rapidement pourquoi sa feuille de style n&#8217;est pas appliquée comme il faudrait. Elle a la bonne idée de mentionner quelle feuille de style est utilisée et quelle ligne. De quoi corriger ça dans son éditeur favori rapidement.</p>
<p>Ou pas. En effet l&#8217;inspecteur <acronym title="Cascading Style Sheets">CSS</acronym> permet, tout comme l&#8217;inspecteur <acronym title="HyperText Markup Language">HTML</acronym>, de <strong>modifier les propriétés à la volée et sans fioriture</strong>. Si je précise sans fioriture c&#8217;est parce que l&#8217;éditeur à la volée de <em>Web Developer</em> rend parfois l&#8217;affichage de la page bancale en décalant des éléments. Là vous pouvez totalement compter sur l&#8217;éditeur intégré et ce n&#8217;est pas un luxe !<br />
Désactiver, supprimer, modifier ou ajouter des propriétés sont quelques-unes des actions que vous pourrez effectuer à même la page.</p>
<p>Là encore c&#8217;est une des parties où les gains de temps sont énormes. On peut en effet <strong>modifier ses <acronym title="Cascading Style Sheets">CSS</acronym> et les tester tout en observant l&#8217;impact immédiat de ses modifications</strong>.</p>
<h5>Inspecteur du modèle de boîte (<em>Layout</em>)</h5>
<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/12/firebug-layout-inspector.png" alt="Modèle de boîte avec Firebug" /></p>
<p>Le <a href="http://www.yoyodesign.org/doc/w3c/css2/box.html">modèle de boîte <acronym title="Cascading Style Sheets">CSS</acronym></a> peut vite devenir pénible à gérer et plus particulièrement quand on visualise mal le <strong>cumul des différentes marges</strong>.<br />
Dans tous les cas c&#8217;est appréciable de pouvoir constater les marges en présence et encore, de pouvoir <strong>modifier leurs dimensions à la volée</strong>. Firebug a la bonne idée de colorer les marges intérieures (<code>padding</code>), extérieures (<code>margin</code>) et les bordures (<code>border</code>) d&#8217;une couleur différente.</p>
<p>Il a également la bonne idée d&#8217;afficher une <strong>double règle millimétrée</strong> au survol du panneau <em>layout</em>. Très pratique dans le cas de design en grilles ou nécessitant un certain rythme de visualisation.</p>
<h5>Inspecteur <acronym title="Document Object Model">DOM</acronym></h5>
<p>Ah l&#8217;inspecteur <acronym title="Document Object Model">DOM</acronym> ! S&#8217;il n&#8217;existait pas il faudrait l&#8217;inventer. Firefox proposait déjà un tel outil à la différence près qu&#8217;il était moins pratique d&#8217;utilisation.<br />
L&#8217;inspecteur <acronym title="Document Object Model">DOM</acronym> m&#8217;est moyennement utile dans le cas d&#8217;une simple inspection du code <acronym title="HyperText Markup Language">HTML</acronym> bien que ce soit toujours pratique de visualiser la présence ou pas d&#8217;objets JavaScript dans tel ou tel élément. C&#8217;est fortement appréciable pour la <a href="http://www.prototypejs.org">librairie Prototype</a> étant donné les dégâts causés par son extension du <acronym title="Document Object Model">DOM</acronym> à gogo.</p>
<h3 id="firebug-javascript">Firebug pour le JavaScript</h3>
<h4>L&#8217;inspecteur JavaScript</h4>
<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/12/firebug-javascript-watcher.png" alt="Inspecteur JavaScript Firebug" /></p>
<p>C&#8217;est l&#8217;autre <strong>outil indispensable de Firebug</strong>. Avec lui, c&#8217;en est fini des <code>alert(mavariable);</code>. L&#8217;inspecteur <acronym title="Document Object Model">DOM</acronym> prend avec lui toute son utilité.</p>
<p>J&#8217;illustre sur l&#8217;image ci-dessus l&#8217;utilisation des points d&#8217;arrêt (<em>breakpoints</em>). Il suffit d&#8217;un clic à gauche d&#8217;un numéro de ligne pour en placer/retirer un. Concrètement quand l&#8217;exécution du JavaScript arrivera au premier point d&#8217;arrêt, elle va se stopper.<br />
Quel intérêt ? Observer. En agissant ainsi, vous avez la main sur toutes les variables connues au sein de votre code/fonction. Très utile pour <strong>connaître les paramètres passées à la fonction et détecter les erreurs</strong>. C&#8217;est pour cette raison que les <code>alert()</code> deviennent inutiles : tout est à portée de main. Vous ne pesterez plus contre un <code>undefined</code> mal placé <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>En parallèle de ça, l&#8217;inspecteur <acronym title="Document Object Model">DOM</acronym> est à utiliser pour <strong>visualiser d&#8217;un coup d&#8217;œil les différentes variables actives ainsi que leur arborescence</strong>. Comme tout est cliquable, l&#8217;inspecteur vous transporte sur n&#8217;importe quel objet pour en étudier le contenu.</p>
<h4>La console Firebug <em>alias</em> <code>console.*</code></h4>
<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/12/firebug-console.png" alt="Console Firebug" /></p>
<p><strong>La console Firebug est l&#8217;autre tueuse d&#8217;<code>alert()</code></strong> et s&#8217;utilise de deux manières.</p>
<p>La plus accessible est d&#8217;<strong>interagir avec</strong>. Vous saisissez votre code, la console l&#8217;exécute et retourne le ou les résultats. Encore une fois les objets sont cliquables et navigable au travers de l&#8217;inspecteur <acronym title="Document Object Model">DOM</acronym>.<br />
La console est utile pour utiliser des fonctions sorties du contexte de l&#8217;initialisation : il devient tout à fait possible de piloter des éléments après le chargement de la page. Ça évite encore une fois des <kbd>F5</kbd> inutiles et consommateurs de temps.</p>
<p>L&#8217;autre manière d&#8217;utiliser la console c&#8217;est de ne pas l&#8217;utiliser. Ou pas de manière active tout du moins puisqu&#8217;<strong>elle est également un objet JavaScript</strong> (<code>console</code>) utilisable dans votre code auquel sont rattachées plusieurs fonctions au nom explicite :</p>
<ul>
<li><code>console.log()</code> : affiche une information standard</li>
<li><code>console.info()</code> : affiche une information de type &laquo;&nbsp;information&nbsp;&raquo;</li>
<li><code>console.warn()</code> : affiche une information de type &laquo;&nbsp;avertissement&nbsp;&raquo;</li>
<li><code>console.error()</code> : affiche une information de type &laquo;&nbsp;erreur&nbsp;&raquo;</li>
<li><code>console.debug()</code> : débogue le contenu d&#8217;un objet directement dans la console</li>
</ul>
<p>Autrement dit, si l&#8217;inspecteur ne suffisait pas, au lieu de lancer un <code>alert(mavariable)</code> (potentiellement dangereux dans une grande boucle <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  qui n&#8217;a jamais cliqué 50 fois sur &laquo;&nbsp;OK&nbsp;&raquo; à cause de ça ?), il vaudra mieux utiliser <code>console.log(mavariable)</code>. Il y a de quoi faire, surtout avec la possibilité de créer des groupes de messages et l&#8217;utilisation de la syntaxe <code>printf</code>.</p>
<p>Et top du top, en cas d&#8217;erreur JavaScript, la console affiche un petit cercle rouge qui rappelle fortement le point d&#8217;arrêt. Normal puisque c&#8217;en est un. Un clic et on évite de rechercher la ligne problématique dans le code. Encore une fois, du temps de gagné.</p>
<h3 id="firebug-performances">Firebug pour les performances</h3>
<p>Après avoir bien développé, Firebug propose de mieux développer. L&#8217;extension magique propose quelques outils sympathiques pour rapidement déceler les problèmes, notamment de scripts trop gourmands ou à optimiser.</p>
<h4>Le traceur réseau</h4>
<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/12/firebug-net-tracer.png" alt="Traceur réseau Firebug" /></p>
<p>Avec le traceur réseau c&#8217;est simple, tout ce qui est chargé sur la page est chronométré. Si un élément est systématiquement long à charger en tête de liste, pourquoi ne pas essayer de le déplacer dans le bas de la pile ? Je pense notamment aux appels vers des fichiers JavaScripts externes. Les appeler en bas de page permet d&#8217;éviter des gels de page. C&#8217;est ce que YSlow nous recommandera <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Outre une petite prévisualisation des contenus, le traceur affiche aussi les <strong>statuts des contenus</strong> s&#8217;ils sont différent du statut 200 (<em>found</em>). Et de surligner ça en rouge en cas de fichier introuvable.</p>
<p>J&#8217;aime beaucoup le traceur pour le <strong>suivi des requêtes XHR (appels <acronym title="Asynchronous JavaScript and XML">AJAX</acronym>)</strong>. Un clic sur un appel affiche à la fois les entêtes, les données transmises au serveur et sa réponse. Fini les requêtes <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> qui ne produisent rien sans qu&#8217;on puisse savoir pourquoi. Le clic droit sera également un fidèle allié, notamment pour ouvrir l&#8217;appel <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> dans un nouvel onglet. C&#8217;est plus lisible pour déboguer quand même <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h4>Le profileur JavaScript</h4>
<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/12/firebug-profiler.png" alt="Profileur JavaScript Firebug" /></p>
<p>Le profileur (<em>profiler</em>) JavaScript s&#8217;utilise un peu à la manière de la console : de manière active ou au travers de l&#8217;objet <code>console</code>.</p>
<p><strong>Le profileur enregistre tout ce qui se passe entre le moment où il est enclenché et le moment où il est stoppé</strong>. Il va ainsi dénombrer toutes les appels (<em>calls</em>), leur durée d&#8217;exécution et leur fichier d&#8217;origine, entre autre. L&#8217;idée est bien entendu de voir ce qui consomme le plus d&#8217;appels et de temps pour savoir si ce comportement est normal ou pas. À ce stade là, difficile de pousser la granularité du profileur plus loins.</p>
<p>Sauf en utilisant le profileur directement dans le code comme on a déjà pu le faire pour les <em>logs</em>. <code>console.profile()</code> et <code>console.profileEnd()</code> seront vos amis. C&#8217;est vraiment l&#8217;idéal pour <strong>profiler l&#8217;exécution d&#8217;une fonction</strong>, voire même les portions de code exécutée en son sein.</p>
<h4>L&#8217;extension YSlow</h4>
<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/12/firebug-yslow.png" alt="Firebug YSlow" /></p>
<p>L&#8217;<a href="https://addons.mozilla.org/en-US/firefox/addon/5369">extension YSlow</a> est une extension pour Firefox mais elle nécessite toutefois la présence de Firebug. Elle s&#8217;articule autour de trois critères.</p>
<p>Il y&#8217; a d&#8217;une part la surveillance des performances. YSlow se base sur la <a href="http://developer.yahoo.com/performance/rules.html">liste des bonnes pratiques établies par Yahoo!</a> (14 à l&#8217;heure actuelle). YSlow passe ces critères en revue et accorde une note en conséquence. Si certaines sont difficiles à tenir, c&#8217;est un bon moyen de s&#8217;intéresser à de <strong>nouvelles pratiques d&#8217;optimisation et de performances</strong>.</p>
<p>Le second critère est affiché dans le panneau <em>stats</em>. Il s&#8217;agit de la capture d&#8217;écran ci-dessus. Certes il s&#8217;agit d&#8217;un simple tableau mais dont les chiffres sont intéressants à étudier. YSlow analyse la page pour un premier et un second chargement. La différence entre les deux ? C&#8217;est que le cache est passé par là et normalement, je dis bien normalement, <strong>le second chargement se doit d&#8217;être beaucoup plus rapide</strong>.<br />
Si ce n&#8217;est pas le cas, il y a de l&#8217;optimisation à faire et cela peut aussi signifier du côté serveur Web. Pas forcément du développement donc.</p>
<p>Enfin on termine sur une partie complémentaire aux stats : les composants (<em>components</em>). Elle distille des informations plus verbeuses que le traceur réseau de Firebug en se focalisant sur les E-Tag, la présence ou pas de compression, la date de validité du cache ainsi que la taille des objets.</p>
<h3>Conclusion</h3>
<p>J&#8217;espère avoir éclairé quelques lanternes sur l&#8217;utilisation de Firebug. Cette extension est suffisamment puissante pour gagner en confort de développement ; il serait dommage de s&#8217;en priver. <strong>On gagne du temps, du confort et surtout, de la qualité de développement</strong>.<br />
À noter qu&#8217;il existe aussi Firebug Lite. Il s&#8217;agit d&#8217;un script JavaScript compatible avec les principaux navigateurs du marché mais comme le <em>Lite</em> l&#8217;indique, les fonctionnalités sont plutôt limitées. Seule la console JavaScript persiste.</p>
]]></content:encoded>
			<wfw:commentRss>http://case.oncle-tom.net/2007/bonnes-pratiques-firebug-developpement-web/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Modifier du HTML à la volée de manière non intrusive</title>
		<link>http://case.oncle-tom.net/2007/modifier-html-non-intrusif/</link>
		<comments>http://case.oncle-tom.net/2007/modifier-html-non-intrusif/#comments</comments>
		<pubDate>Mon, 10 Sep 2007 11:00:55 +0000</pubDate>
		<dc:creator>Oncle Tom</dc:creator>
				<category><![CDATA[Accessibilité]]></category>
		<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[Standards du Web]]></category>
		<category><![CDATA[bonnes pratiques]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[xpath]]></category>
		<guid isPermaLink="false">http://case.oncle-tom.net/2007/09/10/modifier-html-non-intrusif/</guid>
		<description><![CDATA[Lors de la refonte de ce blog, j&#8217;ai concocté un petit script JavaScript (non intrusif bien entendu) affichant et modifiant le contenu d&#8217;un bandeau sous la forme d&#8217;une classe statique reponsant sur jQuery. J&#8217;explique aujourd&#8217;hui comment ces 48 petits lignes de code (en comptant commentaires, sauts de lignes et accolades) fonctionnent, comment il est aisé [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/09/javascript.png" alt="Javascript" /></p>
<p><a href="http://case.oncle-tom.net/2007/07/27/blog-nouveau-look/">Lors de la refonte de ce blog</a>, j&#8217;ai concocté un petit script JavaScript (non intrusif bien entendu) affichant et modifiant le contenu d&#8217;un bandeau sous la forme d&#8217;une classe statique reponsant sur <a href="http://jquery.com/">jQuery</a>. J&#8217;explique aujourd&#8217;hui comment ces 48 petits lignes de code (en comptant commentaires, sauts de lignes et accolades) fonctionnent, comment il est aisé de mettre en place de telles routines de manière intelligente, souple et non intrusive.</p>
<p>Et comme l&#8217;indique le slogan de <cite>jQuery</cite> : <q>Write less, do more</q>.<br />
<span id="more-769"></span></p>
<h3>Le besoin</h3>
<p>Avant de se lancer tête baissée dans le code, <strong>prenons le temps d&#8217;exprimer avec des mots ce que l&#8217;on aimerait faire</strong>.</p>
<p>On souhaite disposer d&#8217;une <strong>liste de liens</strong>. <strong>Lors d&#8217;un clic</strong> sur un lien de cette liste, l&#8217;<strong>encart correspondant doit s&#8217;afficher</strong> pour illustrer davantage son sens. Eventuellement, lorsque l&#8217;on <strong>reclique sur ce même lien</strong>, le visiteur est transporté sur la page en question.</p>
<p>J&#8217;ai grassé les mots importants de ce besoin. Vous le verrez par la suite, ils vont régir le comportement du script.</p>
<h3>La structure <acronym title="HyperText Markup Language">HTML</acronym></h3>
<p>Nous allons donc nous retrouver avec trois grosses parties dans le code :</p>
<ul>
<li><strong>la liste de liens</strong>, une balise <code>ul</code> semble toute indiquée)</li>
<li><strong>une liste de textes correspondants</strong>, il n&#8217;a pas lieu d&#8217;être visible pour l&#8217;utilisateur final concerné par le code</li>
<li>un <strong>bloc conteneur neutre</strong> destiné à recevoir les textes d&#8217;enrichissement de manière visuelle</li>
</ul>
<p>Des mots au code, voici ce que donnerait la structure balisée :</p>
<pre><code class="html">&lt;body&gt;
&lt;!-- (...) --&gt;
	&lt;div id="conteneur_cible"&gt;&lt;/div&gt;
	&lt;!-- (...) --&gt;
	&lt;ul id="liens_etendus"&gt;
		&lt;li&gt;&lt;a href="page1.html" class="page1"&gt;Page 1&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="page2.html" class="page2"&gt;Page 2&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="page3.html" class="page3"&gt;Page 3&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;!-- (...) --&gt;
	&lt;div id="conteneur_source"&gt;
		&lt;h2&gt;Titre&lt;/h2&gt;
		&lt;p&gt;Texte explicatif apportant de la cohérence aux utilisateurs dépourvus de JavaScript et d'interprétation des feuilles de style.&lt;/p&gt;
		&lt;ul&gt;
			&lt;li class="page1"&gt;Texte page 1&lt;/li&gt;
			&lt;li class="page2"&gt;Texte page 2&lt;/li&gt;
			&lt;li class="page3"&gt;Texte page 3&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/div&gt;
&lt;!-- (...) --&gt;
&lt;/body&gt;
</code></pre>
<p><strong>L&#8217;ordre de la structure importe peu</strong> mais dans tous les cas, leur position dans le flux <acronym title="HyperText Markup Language">HTML</acronym> dépend avant tout de leur importance au sein de celui-ci. De manière générale, <strong>il vaut mieux disposer le contenu principal tout en haut du flux et le faire suivre par le contenu secondaire</strong> tels que les menus de navigation et les textes supplémentaires.<br />
Je pense que le code parle de lui-même, posez vos questions en commentaires si jamais il y a besoin d&#8217;explications plus poussées.</p>
<p>Côté <acronym title="HyperText Markup Language">HTML</acronym> tout est réglé avec ceci. <strong>Il ne restera éventuellement que du travail de stylage pour lui donner une apparence plus conviviale</strong>.<br />
Vous remarquerez qu&#8217;il n&#8217;y a aucune mention à du JavaScript à l&#8217;intérieur de ce code et ce sera le cas jusqu&#8217;au bout. C&#8217;est tout l&#8217;intérêt de séparer fond et forme et donc, du <strong>JavaScript non intrusif</strong>.</p>
<h3>Le code Javascript</h3>
<p>J&#8217;ai pris la décision d&#8217;écrire ce code pour <em>jQuery</em> car cette bibliothèque (ou <em>framework</em>) est embarquée dans WordPress et réduit drastiquement la quantité de code à écrire pour produire des résultats.</p>
<p>Dans la pratique, le code va se charger dès que possible (c&#8217;est à dire dès que le <acronym title="Document Object Model"><acronym title="Document Object Model">DOM</acronym></acronym> est prêt) et exécutera une méthode en se servant des paramètres prédéfinis ou passés manuellement à la classe. Le code suivant est structuré et suffisamment commenté pour le comprendre sans trop de difficulté. J&#8217;expliquerai en-dessous sa logique :</p>
<pre><code class="javascript">/*////////////////////////////////////////
// Classe statique 'oncletom_text_grabber'
// # Permet d'afficher un slide d'informations en cliquant sur un lien
// # C'est rigolo et en plus ça sert à quelque chose
// @ parametres (objet, optionnel) : objet de clé:valeur paramétrant le comportement
////////////////////////////////////////*/
function oncletom_text_grabber()
{
	var parametres = arguments.length == 1 &amp;&amp; typeof arguments[0] == 'object' ? arguments[0] : {};
	//Paramétrage de la fonction
	//# permet un lancement de la classe avec un paramétrage par défaut
	parametres.source = typeof parametres.source == 'undefined' ? '#conteneur_source &gt; ul &gt; li' : parametres.source;
	parametres.bindto = typeof parametres.bindto == 'undefined' ? '#liens_etendus a' : parametres.bindto;
	parametres.target = typeof parametres.target == 'undefined' ? '#conteneur_cible' : parametres.target;
	/*////////////////////////////////////////
	// Méthode publique 'ot_text_caller'
	// # Récupère le contenu associé à l'attribut 'rel'
	// # Méthode à appeler sur un évènement
	////////////////////////////////////////*/
	function ot_text_caller()
	{
		//sélection de l'élément à récupérer
		var id = $(this).attr('class');
		//hop ! on vérifie c'est déjà ouvert. Auquel cas le lien redevient cliquable
		if( $( parametres.target ).attr('class') == id )
		{
			return true;
		}
		//on nettoie le contenu de la destination
		$( parametres.target ).empty();
		$( parametres.target ).attr({ 'class' : '' });
		//on remplit la destination avec le bon contenu
		//on le fait en utilisant une expression régulières pour récupérer l'élément voulu
		$( parametres.target ).fadeIn( 'slow' ).append(  $( parametres.source+"."+id ).html() ).toggleClass( id );
		//évite que le lien soit cliqué
		return false;
	}
	//On greffe les différentes méthodes
	$( parametres.bindto ).click( ot_text_caller );
}
//exécution automatique de fonctions au lancement du document
$( oncletom_text_grabber );
//FACULTATIF
//pour assigner une deuxième liste de liens, il suffirait d'écrire le code ci-contre, par exemple :
//tous les paramètres non renseignés prennent la valeur par défaut de la classe
$( function(){ oncletom_text_grabber({ 'target' : '#nouveau_conteneur_cible', 'bindto' : '#exemple_entete ol a[@rel]', 'source' : '#liste_source2' }); } );
</code></pre>
<ol>
<li>Dans un premier temps, je m&#8217;applique toujours à pouvoir <strong>proposer une utilisation de la classe sans avoir à fournir de paramètre lors de son appel</strong>. C&#8217;est un côté pratique qui permet en plus de documenter les différentes options possibles. Ces options correspondent aux différents <a href="http://docs.jquery.com/DOM/Traversing/Selectors">sélecteurs jQuery</a> dont on aura besoin par la suite ;</li>
<li>Dans un deuxième temps, je déclare une méthode interne à la classe. <em>La cascade des accolades</em> fait qu&#8217;elle n&#8217;est accessible que depuis la classe. Cette méthode sera assignée à l&#8217;évènement <code>onclick</code> de tous les éléments concernés par <code>parametre.bindto</code>. En clair, des liens hypertextes. Le <code>this</code> y fait référence.
<ol>
<li>On stocke dans la variable interne <code>id</code> le nom de la classe. En effet, la classe du lien permet de récupérer le bon texte dans el conteneur source (<code>parametre.source</code>),</li>
<li>On vérifie que le conteneur cible ne porte pas le même nom de classe : si oui, on suit le lien, si non, on affiche d&#8217;abord le texte complémentaire (la suite),</li>
<li>Le passage le plus délicat consiste à extraire ce qu&#8217;il faut et le placer où il faut. Heureusement jQuery dispose de deux fonctions magiques : <code>append()</code> et <code>html()</code>. La première rajoute du <acronym title="HyperText Markup Language">HTML</acronym> à la suite du sélecteur tandis que la deuxième extrait le <acronym title="HyperText Markup Language">HTML</acronym> par sélection. Le fonctionnement en chaîne de jQuery permet de réaliser tout ceci en une ligne,</li>
<li>Pourquoi un <code>return false;</code> pour terminer ? Tout simplement pour éviter que le lien hypertexte contenu dans l&#8217;attribut <code>href</code> du lien soit suivi.</li>
</ol>
</li>
<li>Dans un troisième temps, on assigne la méthode déclarée juste avant. A chaque clic de chaque élément, elle sera appelée et surtout, aura accès à tous les paramètres de la classe ;</li>
<li>Enfin, après avoir clôturé la classe, on l&#8217;exécute dès que le <acronym title="Document Object Model">DOM</acronym> est chargé.</li>
</ol>
<h3>Conclusion et résultat</h3>
<p>Pour que ce code soit effectif, il faut bien évidemment l&#8217;insérer à même la page ou bien en appelant un script externe (cette méthode est recommandée justement pour dissocier fond et forme). Il faut aussi penser à inclure jQuery dans votre page sans quoi le compilateur JavaScript va tirer la tête.</p>
<p>Pour résumer, je résume la pensée des <strong>bonnes pratiques du JavaScript non intrusif</strong>, prouvant si besoin en était que JavaScript est loin d&#8217;être le Diable :</p>
<ol>
<li>définir sa structure <acronym title="HyperText Markup Language">HTML</acronym></li>
<li>styler le <acronym title="HyperText Markup Language">HTML</acronym></li>
<li>ajouter le JavaScript en surcouche</li>
</ol>
<p>Ainsi, <strong>on ne pénalise personne</strong> (y compris en cas d&#8217;erreur de programmation), <strong>on conserve un code lisible</strong> tout en <strong>facilitant sa réutilisation</strong> dans un autre document.</p>
]]></content:encoded>
			<wfw:commentRss>http://case.oncle-tom.net/2007/modifier-html-non-intrusif/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rock your Firefox : mes extensions Firefox préférées</title>
		<link>http://case.oncle-tom.net/2007/facebook-rock-your-firefox/</link>
		<comments>http://case.oncle-tom.net/2007/facebook-rock-your-firefox/#comments</comments>
		<pubDate>Tue, 07 Aug 2007 11:00:26 +0000</pubDate>
		<dc:creator>Oncle Tom</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[optimisation]]></category>
		<guid isPermaLink="false">http://case.oncle-tom.net/2007/08/07/facebook-rock-your-firefox/</guid>
		<description><![CDATA[Read/WriteWeb fait partie de mes sources d&#8217;informations quotidiennes. Je suis tombé aujourd&#8217;hui sur un article concernant le lancement d&#8217;une nouvelle application Facebook permettant de recommander ses extensions favorites : Rock your Firefox. Ca tombe bien puisque je songeais depuis quelques jours à parler des extensions que j&#8217;utilise quotidiennement dans Firefox. Certaines n&#8217;intéresseront que les développeurs, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align:center"><img src='http://case.oncle-tom.net/images/2007/08/rock-your-firefox.gif' alt='Rock your Firefox logo' /></p>
<p><a href="http://www.readwriteweb.com/">Read/WriteWeb</a> fait partie de mes sources d&#8217;informations quotidiennes. Je suis tombé aujourd&#8217;hui sur un article concernant le <a href="http://www.readwriteweb.com/archives/firefox_launches_facebook_app.php">lancement d&#8217;une nouvelle application Facebook permettant de recommander ses extensions favorites</a> : <a href="http://www.facebook.com/apps/application.php?api_key=b342b55715483ad3ff6a5495b9368702">Rock your Firefox</a>.</p>
<p>Ca tombe bien puisque je songeais depuis quelques jours à parler des extensions que j&#8217;utilise quotidiennement dans Firefox. Certaines n&#8217;intéresseront que les développeurs, d&#8217;autres les amateurs de praticité.<br />
<span id="more-735"></span></p>
<h3>Extensions Firefox</h3>
<p>Avant toute chose, si jamais vous vous posiez la question <q>où trouver de nouvelles extensions pour Firefox</q> (ou <em>Thunderbird</em> ou d&#8217;autres produits <em>Mozilla</em>), rendez-vous sur <a href="https://addons.mozilla.org/fr/">Mozilla Add-ons</a>.<br />
L&#8217;application Facebook <strong>Rock your Firefox</strong> reprend la liste des extensions et des thèmes en vous proposant de choisir vos préférées et de les partager sur votre profil. C&#8217;est un bon moyen pour afficher votre qualité d&#8217;utilisation de ce navigateur libre et gratuit.</p>
<h3>Extensions &laquo;&nbsp;Pratiques&nbsp;&raquo;</h3>
<h4><a href="https://addons.mozilla.org/fr/firefox/addon/10">Adblock</a></h4>
<p>Certains sites sont envahis de publicités qui gênent affreusement la navigation. Plutôt que de se passer d&#8217;un contenu intéressant, autant supprimer les nuisances. <strong>Adblock</strong> est là pour ça. Que ça soit des images,des animations Flash ou bien encore des scripts JavaScript, <strong>Adblock liste le contenu des ressources bloquables</strong> et permet même de créer des filtres génériques à l&#8217;aide du caractère <code>*</code> (<em>wildcard</em>, remplace un à plusieurs caractères, peu importe lesquels).<br />
<strong>Attention</strong> toutefois, la <em>publicité est vitale pour de nombreux sites</em> donc bloquez avec intelligence.</p>
<h4><a href="https://www.google.com/tools/firefox/browsersync/">Google Browser Sync</a></h4>
<p>C&#8217;est certainement l&#8217;extension que j&#8217;installe en premier et pour cause : <strong>Google Browser Sync sauvegarde tous mos favoris, cookies et historique de navigation de manière sécurisée</strong>.<br />
Je l&#8217;utilise sur plusieurs ordinateurs et plusieurs installations de Firefox ce qui me permet de retrouver tous mes favoris peu importe où je me trouve, à partir du moment où il y a une connexion Internet. A utiliser pour vos sauvegardes ou vos besoins de mobilité.</p>
<h4><a href="https://addons.mozilla.org/fr/firefox/addon/636"><acronym title="Portable Document Format">PDF</acronym> Download</a></h4>
<p>Je n&#8217;aime pas que les documents <acronym title="Portable Document Format"><acronym title="Portable Document Format">PDF</acronym></acronym> s&#8217;ouvrent directement dans un onglet ou une fenêtre de mon navigateur Web. Surtout quand les plus lourds le font planter. <strong><acronym title="Portable Document Format">PDF</acronym> Download</strong> affiche systématiquement plusieurs choix tels que <q>Afficher dans la page</q>, <q>Ouvrir en tant que <acronym title="Portable Document Format">PDF</acronym></q> ou encore <q>Télécharger directement</q>.</p>
<h4><a href="https://addons.mozilla.org/fr/firefox/addon/1146">Screengrab!</a></h4>
<p><strong>Screengrab</strong> est une <strong>solution propre pour effectuer une capture d&#8217;écran</strong> de sa portion visible, d&#8217;une page Web complète ou bien d&#8217;une portion d&#8217;écran bien définie. Vous l&#8217;aurez compris, pas besoin de faire 10 000 captures pour une page étalée en hauteur et pas besoin d&#8217;avoir <em>Photoshop</em> ou <em>The Gimp</em> d&#8217;installé pour s&#8217;en sortir.</p>
<h4><a href="https://addons.mozilla.org/fr/firefox/addon/1122">Tab Mix Plus</a></h4>
<p><strong>Tab Mix Plus</strong> apporte un <strong>lot considérable d&#8217;options pour mieux régler le comportement de vos onglets</strong>. Personnellement je l&#8217;utilise pour que toute nouvelle fenêtre se charge obligatoirement dans un nouvel onglet <em>sans me déranger</em> (chargement en arrière-plan). Je profite aussi de son indicateur de chargement allant de 0 à 100%.<br />
En revanche j&#8217;évite son système de récupération en cas de plantage, il fonctionne moins bien que celui intégré à Firefox (pour les rares cas où cela s&#8217;est produit chez moi).</p>
<p style="text-align:center"><img src='http://case.oncle-tom.net/images/2007/08/firefox-extensions.gif' alt='Extensions Firefox' /></p>
<h3>Extensions &laquo;&nbsp;Développeur Web&nbsp;&raquo;</h3>
<h4><a href="https://addons.mozilla.org/fr/firefox/addon/271">ColorZilla</a></h4>
<p><strong>ColorZilla</strong> est une simple <strong>pipette colorimétrique</strong> mais ô combien efficace. Un clic sur un endroit de la page mémorise automatiquement le code couleur associé et permet de l&#8217;utiliser sous plusieurs formats dans n&#8217;importe quel autre programme dont <em>Photoshop</em> ou votre éditeur <acronym title="Cascading Style Sheets"><acronym title="Cascading Style Sheets">CSS</acronym></acronym> favori.</p>
<h4><acronym title="Document Object Model">DOM</acronym> Inspector</h4>
<p>C&#8217;est la seule extension qui ne se télécharge pas/plus (jusqu&#8217;à la version 1.5 c&#8217;était encore possible). L&#8217;inspecteur <acronym title="Document Object Model"><acronym title="Document Object Model">DOM</acronym></acronym> s&#8217;installe en même temps que Firefox (si vous cochez la case adéquate) et permet comme son nom l&#8217;indique, d&#8217;<strong>inspecter les noeuds de votre document</strong> (<acronym title="HyperText Markup Language"><acronym title="HyperText Markup Language">HTML</acronym></acronym> ou <acronym title="eXtensible Markup Language"><acronym title="eXtensible Markup Language">XML</acronym></acronym>), d&#8217;en voir leurs attributs, fonctions et ce de <em>manière récursive</em>.<br />
L&#8217;analyse en temps réel permet même de voir les modifications apportées à l&#8217;arbre <acronym title="Document Object Model">DOM</acronym> par le biais du JavaScript.</p>
<h4><a href="https://addons.mozilla.org/fr/firefox/addon/1843">Firebug</a></h4>
<p><strong>Firebug</strong> est obligatoire lorsqu&#8217;on souhaite <strong>explorer avec aisance la structure <acronym title="HyperText Markup Language">HTML</acronym></strong> d&#8217;un document, <strong>exécuter du JavaScript à même la page</strong> ou <strong>déboguer efficacement son code</strong>, ne serait-ce qu&#8217;en se rendant compte des temps de chargement des différents fichiers (<acronym title="Cascading Style Sheets">CSS</acronym>, JavaScript, Flash etc.).<br />
Ca incite notamment à taper son code directement dans sa console plutôt qu&#8217;à le modifier et recharger la page pour déceler des erreurs ou étudier le comportement de la page. On gagne du temps et votre employeur de l&#8217;argent.</p>
<h4><a href="https://addons.mozilla.org/fr/firefox/addon/5369">Firebug : YSlow</a></h4>
<p><strong>YSlow</strong> est une extension Firefox mais dédiée à Firebug. Une petite première <em>made in Yahoo!</em> très utile. Cette extension permet de calculer les <strong>performances de la page</strong>, <strong>suggère des optimisations</strong> et <strong>analyse les différents composants</strong> ainsi que leurs caractéristiques (<acronym title="Uniform Resource Locator">URL</acronym>, poids, temps de réponse et ETag).<br />
Indispensable pour les phases d&#8217;<strong>optimisation</strong> et de <em>fine tuning</em> comme dirait l&#8217;autre.</p>
<h4><a href="https://addons.mozilla.org/fr/firefox/addon/4106">Operator</a></h4>
<p>Je vous ai déjà parlé de l&#8217;<a href="http://case.oncle-tom.net/2007/07/31/semantique-microformats-internet/">intérêt des microformats</a> ? <strong>Operator</strong> est un outil notifiant des microformats actifs sur les pages que vous visitez. Outre la navigation interactive procurée, Operator signale dans la console de débogage d&#8217;éventuelles erreurs (élément absent, malformé ou invalidant un microformat).</p>
<h4><a href="https://addons.mozilla.org/fr/firefox/addon/2063">TimeStamp Converter</a></h4>
<p>Le nombre 1198533599 vous dit quelque chose ? Avec <strong>TimeStamp Converter</strong> ça sera le cas. Cette extension convertit les temps Unix en heure humainement compréhensible et vice-versa. Elle le fait également à partir de sélections de texte, évitant ainsi toute saisie pénible.</p>
<h4><a href="https://addons.mozilla.org/fr/firefox/addon/60">Web Developer</a></h4>
<p>Le Saint-Graal du développeur Web. Triturer la page, modifier ses mécanismes, débloquer des champs en lecture seule, afficher les champs masqués, topographie de la page, modifier la résolution et afficher l&#8217;arborescence en cascade de la page jusqu&#8217;à un élément pointé de la souris sont le genre d&#8217;outils fournis par <strong>Web Developer</strong>. Couplée avec Firebug, vous transformez un &laquo;&nbsp;simple&nbsp;&raquo; navigateur Web en machine de guerre du développement Web propre et efficace.</p>]]></content:encoded>
			<wfw:commentRss>http://case.oncle-tom.net/2007/facebook-rock-your-firefox/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Tableau auto-extensible en JavaScript</title>
		<link>http://case.oncle-tom.net/2007/tableau-auto-extensible-en-javascript/</link>
		<comments>http://case.oncle-tom.net/2007/tableau-auto-extensible-en-javascript/#comments</comments>
		<pubDate>Tue, 26 Jun 2007 11:59:32 +0000</pubDate>
		<dc:creator>Oncle Tom</dc:creator>
				<category><![CDATA[Accessibilité]]></category>
		<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[Standards du Web]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[bonne pratique]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[mootools]]></category>
		<guid isPermaLink="false">http://case.oncle-tom.net/2007/06/26/tableau-auto-extensible-en-javascript/</guid>
		<description><![CDATA[Bon nombre de clients utilisant les sites Internet de mon employeur passent des commandes en saisissant directement les codes articles de leur choix. Ce n&#8217;est pas anodin : pour du réassort de magasin, ils savent exactement ce qu&#8217;ils veulent. Et un beau jour on vient me voir en me disant qu&#8217;ils ne peuvent saisir qu&#8217;un [...]]]></description>
			<content:encoded><![CDATA[<p>Bon nombre de clients utilisant les sites Internet de mon employeur passent des commandes en saisissant directement les codes articles de leur choix. Ce n&#8217;est pas anodin : pour du réassort de magasin, ils savent exactement ce qu&#8217;ils veulent. Et un beau jour on vient me voir en me disant qu&#8217;<cite>ils ne peuvent saisir qu&#8217;un code et une seule quantité à la fois</cite>, qu&#8217;il faudrait changer ça.</p>
<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/06/articles-autoexpand-mini.png" alt="Ligne article" /></p>
<p>Voici donc mon constat de départ :</p>
<ul>
<li>un client doit pouvoir saisir <em>un seul article</em> s&#8217;il le veut</li>
<li>un client doit pouvoir saisir <em>10 articles</em> s&#8217;il le veut</li>
<li>un client doit pouvoir saisir <em>100 articles</em> s&#8217;il le veut</li>
<li>mais <strong>celui qui n&#8217;en saisit que 10 ne doit pas être gêné par 100 lignes de formulaire à remplir</strong></li>
<li>un <em>débutant</em> doit pouvoir saisir 100 lignes sans avoir de mode d&#8217;emploi sous la main</li>
</ul>
<p>Donc ma solution a été très simple : <strong>je ne mettrai qu&#8217;une ligne</strong>.<br />
<span id="more-680"></span></p>
<h3>L&#8217;idée</h3>
<p>Comment faire pour satisfaire tout le monde, les gros donneurs d&#8217;ordre comme les petits ?<br />
<strong>En faisant en sorte que le formulaire s&#8217;adapte à leur besoin.</strong> Je voulais donc qu&#8217;à chaque ligne complétée s&#8217;en ajoute une autre avant de passer à la validation finale. Place au combo <strong>JavaScript + <acronym title="Document Object Model">DOM</acronym> = Ajax</strong>.</p>
<h3>La version dégradée</h3>
<p>Une <em>bonne pratique de l&#8217;Ajax</em> est de partir du cas particulier : celui où les conditions ne sont pas requises. En clair, une personne qui n&#8217;a pas JavaScript d&#8217;activé ou pas de JavaScript tout court.<br />
Conclusion, j&#8217;ai décidé de générer un tableau en <acronym title="HyperText Markup Language">HTML</acronym> de 10 lignes. 10 est un choix arbitraire, modifiable à tout moment et qui ne doit donc pas gêner la version dynamique en cas de changement (ajout de colonne, ajout de lignes).</p>
<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/06/articles-autoexpand.png" alt="Tableau auto-extansible dégradé" /></p>
<h3>La version Ajax</h3>
<p>On peut manipuler le document à loisir grâce à JavaScript. <strong>Avec un code propre et ordonné c&#8217;est d&#8217;autant plus simple</strong>. Alors voici la logique à mettre en oeuvre :</p>
<ol>
<li>éliminer toutes les lignes dont on ne veut pas et n&#8217;en garder qu&#8217;une</li>
<li>assigner à chaque champ de formulaire de la ligne (<code>input</code>, <code>select</code>, <code>textarea</code>) une fonction de vérification : si tous les éléments de la ligne sont remplis / cochés et qu&#8217;il n&#8217;y a pas de ligne après, on clonera la ligne</li>
<li>cloner la ligne en la vidant de ses valeurs, en modifiant les noms de champ pour les rendre exploitable après coup</li>
</ol>
<p><strong><br />
Ce qu&#8217;on l&#8217;on veut étant relativement simple, <em>le code doit l&#8217;être également</em></strong> ! Le résultat aussi, la preuve en mouvement.</p>
<div style="text-align:center"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="372" height="188" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://case.oncle-tom.net/images/2007/06/articles-autoexpand.swf" /><embed type="application/x-shockwave-flash" width="372" height="188" src="http://case.oncle-tom.net/images/2007/06/articles-autoexpand.swf"></embed></object></div>
<p>Au final, <strong>50 lignes de JavaScript ont suffit</strong> à transformer un tableau complètement statique en tableau dynamique, s&#8217;adaptant à la demande de n&#8217;importe quel client. Client qui pourra également utiliser le clavier pour davantage d&#8217;efficacité de saisie.</p>
<p>C&#8217;est à dire <strong>exactement ce que l&#8217;on souhaitait au départ</strong>.</p>
<h3>Le code</h3>
<h4>Le tableau <acronym title="HyperText Markup Language">HTML</acronym></h4>
<pre><code class="html">&lt;table cellspacing="0" id="ajout_multi_articles"&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Code article&lt;/th&gt;
      &lt;th&gt;Quantité&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr class="article"&gt;
      &lt;th&gt;&lt;input type="text" name="article[1][ref]" maxlength="10" /&gt;&lt;/th&gt;
      &lt;td&gt;&lt;input type="text" name="article[1][qte]" maxlength="5" size="5" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="article"&gt;
      &lt;th&gt;&lt;input type="text" name="article[2][ref]" maxlength="10" /&gt;&lt;/th&gt;
      &lt;td&gt;&lt;input type="text" name="article[2][qte]" maxlength="5" size="5" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="article"&gt;
      &lt;th&gt;&lt;input type="text" name="article[3][ref]" maxlength="10" /&gt;&lt;/th&gt;
      &lt;td&gt;&lt;input type="text" name="article[3][qte]" maxlength="5" size="5" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="article"&gt;
      &lt;th&gt;&lt;input type="text" name="article[4][ref]" maxlength="10" /&gt;&lt;/th&gt;
      &lt;td&gt;&lt;input type="text" name="article[4][qte]" maxlength="5" size="5" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="article"&gt;
      &lt;th&gt;&lt;input type="text" name="article[5][ref]" maxlength="10" /&gt;&lt;/th&gt;
      &lt;td&gt;&lt;input type="text" name="article[5][qte]" maxlength="5" size="5" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="article"&gt;
      &lt;th&gt;&lt;input type="text" name="article[6][ref]" maxlength="10" /&gt;&lt;/th&gt;
      &lt;td&gt;&lt;input type="text" name="article[6][qte]" maxlength="5" size="5" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="article"&gt;
      &lt;th&gt;&lt;input type="text" name="article[7][ref]" maxlength="10" /&gt;&lt;/th&gt;
      &lt;td&gt;&lt;input type="text" name="article[7][qte]" maxlength="5" size="5" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="article"&gt;
      &lt;th&gt;&lt;input type="text" name="article[8][ref]" maxlength="10" /&gt;&lt;/th&gt;
      &lt;td&gt;&lt;input type="text" name="article[8][qte]" maxlength="5" size="5" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="article"&gt;
      &lt;th&gt;&lt;input type="text" name="article[9][ref]" maxlength="10" /&gt;&lt;/th&gt;
      &lt;td&gt;&lt;input type="text" name="article[9][qte]" maxlength="5" size="5" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="article"&gt;
      &lt;th&gt;&lt;input type="text" name="article[10][ref]" maxlength="10" /&gt;&lt;/th&gt;
      &lt;td&gt;&lt;input type="text" name="article[10][qte]" maxlength="5" size="5" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;</code></pre>
<h4>La fonction JavaScript</h4>
<pre><code class="javascript">/**
 * Transforme un tableau multi-lignes en un tableau mono-ligne mais auto-extensible
 * Renomme également les noms de champ en suivant un masque paramétrable ; par défaut article[]
 *
 * @usage articlesMultiRows([{'css_id': ?, 'css_row_class': ?, 'check_inputs': ?}])
 * @param {Object} params Objet contenant (ou pas) les paramètres de contrôle de la classe
 */
function articlesMultiRows(params)
{
  this.row_number = 0;
  /*
   * Extension des paramètres par défaut
   */
  var params = params || {};
  params.css_id = params.css_id || 'ajout_multi_articles';
  params.css_row_class = params.css_row_class || 'article';
  params.check_inputs = params.check_inputs || 'input,select,textarea';
  /**
   * Initialise le tableau de données et accroche les méthodes dynamiques
   */
  this.init = function(){
    //aucun ID détecté, pas la peine de continuer plus loin
    if (!$(params.css_id))
    {
      return false;
    }
    //on récupère les lignes, on enlève la première du tableau et on supprime les autres
    var rows = $(params.css_id).getElements('tr.'+params.css_row_class);
    var row_first = rows.shift();
    rows.removeElements();
    rows = null;
    /*
     * On assigne l'évènement aux champs paramétrés de la ligne
     * On place le focus sur le premier champ
     */
    $ES(params.check_inputs, row_first).addEvent('blur', rowCheck);
    $(row_first).getElement('input').focus();
    row_number = 1;
    /*
     * On écrit un petit message sympathique indiquant le fonctionnement du bazar
     * On le fait via JavaScript car un utilisateur sans <acronym title="JavaScript">JS</acronym> ne pourrait justement pas suivre les infos
     * Il est placé juste avant le tableau
     */
    new Element('p',{
          'class' : 'message'
          }).setHTML("Dès qu'un code article et une quantité sont saisis ci-dessous, &lt;strong&gt;une nouvelle ligne s'ajoute automatiquement&lt;/strong&gt;.&lt;br /&gt;Afin d'accélérer votre saisie, &lt;em&gt;utilisez la touche de tabulation de votre clavier&lt;/em&gt; pour passer d'un champ à l'autre. Vous verrez, c'est facile et surtout efficace !").injectBefore(params.css_id);
  };
  /**
   * Vérifie si la ligne a entièrement été complétée et le cas échéant, déclenche l'ajout de ligne
   */
  this.rowCheck = function(){
    var row = { 'inputs' : 0, 'completed' : 0, 'dom' : $(this).getParent().getParent() };
    $ES(params.check_inputs, row.dom).each(function(input){
      //Un élément de plus ...
      ++row.inputs;
      //... dont on vérifie s'il est bien complété
      switch (input.getTag())
      {
        case 'input':
        case 'textarea':
          if (input.value.clean())
          {
            ++row.completed;
          }
        break;
        case 'select':
          if (input.selectedIndex &gt;= 0 &amp;&amp; input.selectedIndex &lt; input.length)
          {
            ++row.completed;
          }
        break;
      }
    });
    /*
     * Pour insérer une nouvelle ligne, on doit avoir :
     * - autant de champs complétés que de champs existants
     * - aucun élément suivant
     */
    if (row.inputs === row.completed &amp;&amp; !row.dom.getNext())
    {
      rowInsert(row.dom);
    }
  };
  /**
   * Insère une nouvelle ligne en clonant la dernière du tableau et la purgeant de ses valeurs
   *
   * @param {Object} row Noeud <acronym title="Document Object Model">DOM</acronym> correspondant à la ligne à cloner
   */
  this.rowInsert = function( row ){
    //On incrémente le nombre de lignes dispo
    //Ce numéro sert à changer les masques de nom de champ
    ++row_number;
    var row_clone = row.clone();
    //Clonage de la ligne
    $ES('input[type=text],input[type=password],input[type=hidden],textarea', row_clone).setProperty('value', '');
    $ES(params.check_inputs, row_clone).removeEvents('blur'); /* obligé car <acronym title="Internet Explorer 5">IE5</acronym>+ clone aussi les évènements ... alors qu'il ne le devrait pas */
    $ES(params.check_inputs, row_clone).addEvent('blur', rowCheck); /* oui oui, <acronym title="Internet Explorer 5">IE5</acronym>+ ne rassignait pas cet évènement comme il fallait malgré ça */
    //On remplace les noms des champs pour que permettre une utilisation des résultats $_POST
    $ES(params.check_inputs, row_clone).each(function(input){
      input.name = input.name.replace(new RegExp('^'+params.css_row_class+'\[[0-9]+\]'), params.css_row_class+'['+row_number+']');
    });
    //Injection de la ligne, une fois tout le travail terminé
    row_clone.injectAfter(row);
    //Nettoyage, le clonage, ça salit
    row_clone = null;
    row = null;
  };
  /*
   * Initialisation de la classe
   */
  this.init();
}
/*
 * Initialisation du tableau multi-lignes avec les options par défaut
 */
window.addEvent('domready', articlesMultiRows);</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://case.oncle-tom.net/2007/tableau-auto-extensible-en-javascript/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>

