<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Pims Labs</title>
	
	<link>http://labs.pimsworld.org</link>
	<description>Les labs de Pims World</description>
	<pubDate>Thu, 28 May 2009 08:15:39 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PimsLabs" /><feedburner:info uri="pimslabs" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>HTML5 : le futur de la vidéo et du son sur internet</title>
		<link>http://feedproxy.google.com/~r/PimsLabs/~3/4EJKUsqw2K8/</link>
		<comments>http://labs.pimsworld.org/2009/05/html5-futur-de-la-video-et-du-son-sur-internet/#comments</comments>
		<pubDate>Thu, 28 May 2009 08:15:39 +0000</pubDate>
		<dc:creator>Stéphane Roucheray</dc:creator>
		
		<category><![CDATA[Open Source]]></category>

		<category><![CDATA[audio]]></category>

		<category><![CDATA[HTML5]]></category>

		<category><![CDATA[ogg]]></category>

		<category><![CDATA[son]]></category>

		<category><![CDATA[theora]]></category>

		<category><![CDATA[Vidéo]]></category>

		<category><![CDATA[vorbis]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=609</guid>
		<description><![CDATA[Le futur de la vidéo et du son sur Internet passerait-il par les standards ouverts ? 
C&#8217;est ce que semble indiquer l&#8217;annonce  faite par Dailymotion et rapporté par Christophe Blizzard, un des responsables de la fondation Mozilla. 
Il s&#8217;agit pour Dailymotion de remplacer, sur cette partie de son site pour l&#8217;instant, le lecteur Flash [...]]]></description>
			<content:encoded><![CDATA[<p>Le futur de la vidéo et du son sur Internet passerait-il par les standards ouverts ? </p>
<p>C&#8217;est ce que semble indiquer l&#8217;annonce  faite par <a href="http://blog.dailymotion.com/2009/05/27/watch-videowithout-flash/">Dailymotion</a> et <a href="http://www.0xdeadbeef.com/weblog/?p=1312">rapporté par Christophe Blizzard</a>, un des responsables de la fondation Mozilla. </p>
<p>Il s&#8217;agit pour Dailymotion de remplacer, <strong><a href="http://www.dailymotion.com/openvideodemo">sur cette partie de son site pour l&#8217;instant</a></strong>, le lecteur Flash par un lecteur en pur HTML. En effet, la norme HTML5 introduit les nouvelles balises <a href="https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox">&lt;video&gt; et &lt;audio&gt;</a> qui permettent d&#8217;insérer ces médias directement dans une page HTML comme on insère une image avec la balise &lt;img&gt;.<br />
On parle de standards ouverts, car les formats utilisés pour encapsuler (Ogg) et pour encoder la vidéo (Theora) et le son (Vorbis) sont libres de droits.  La fondation Mozilla et Dailymotion ont travaillé de concert pour aider ce projet à voir le jour.</p>
<p>Ces nouvelles fonctionnalités seront disponibles notamment dans Firefox 3.5 dont la sortie définitive est prévue courant juin. Vous pouvez dors et déjà les tester en <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">téléchargeant une pré-version de Firefox 3.5</a>. Tous les autres navigateurs, dignes d&#8217;intérêt, les implémentent ou les implémenteront dans leur prochaine version de cette année.</p>
<img src="http://feeds.feedburner.com/~r/PimsLabs/~4/4EJKUsqw2K8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/05/html5-futur-de-la-video-et-du-son-sur-internet/feed/</wfw:commentRss>
		<feedburner:origLink>http://labs.pimsworld.org/2009/05/html5-futur-de-la-video-et-du-son-sur-internet/</feedburner:origLink></item>
		<item>
		<title>Découper un fichier avec split</title>
		<link>http://feedproxy.google.com/~r/PimsLabs/~3/oxlyllFKr-k/</link>
		<comments>http://labs.pimsworld.org/2009/05/decouper-fichier-split/#comments</comments>
		<pubDate>Wed, 13 May 2009 14:28:56 +0000</pubDate>
		<dc:creator>Yann</dc:creator>
		
		<category><![CDATA[Tips]]></category>

		<category><![CDATA[couper]]></category>

		<category><![CDATA[fichier]]></category>

		<category><![CDATA[file]]></category>

		<category><![CDATA[script]]></category>

		<category><![CDATA[slipt]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=585</guid>
		<description><![CDATA[Il arrive parfois que nous ayons besoin de scinder un fichier en deux fichiers de tailles égales (ou plus). Voici quelques lignes de commandes qui vous permettront de réaliser cette manipulation rapidement en utilisant la commande split.
La commande split
split découpe par défaut un fichier en plusieurs fichiers de 1000 lignes chacun nommés xaa, xab…
Les options [...]]]></description>
			<content:encoded><![CDATA[<p>Il arrive parfois que nous ayons besoin de scinder un fichier en deux fichiers de tailles égales (ou plus). Voici quelques lignes de commandes qui vous permettront de réaliser cette manipulation rapidement en utilisant la commande <strong>split</strong>.<span id="more-585"></span></p>
<h4>La commande split</h4>
<p><strong>split</strong> découpe par défaut un fichier en plusieurs fichiers de 1000 lignes chacun nommés xaa, xab…<br />
Les options intéressantes sont :</p>
<ul>
<li><strong>-l <em>number</em></strong> qui permet de définir le nombre de lignes par fichier</li>
<li><strong>-a <em>number</em></strong> qui permet de définir la longueur du suffixe</li>
<li><strong>-d</strong> qui permet d&#8217;utiliser des suffixes numériques (00, 01…) plutôt qu&#8217;alphabétique</li>
</ul>
<p>Par exemple, si on dispose d&#8217;un fichier de 42 lignes, on peut utiliser la commande ci-dessous :</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:540px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">split</span> <span class="re5">-l</span> <span class="nu0">10</span> <span class="re5">-a</span> <span class="nu0">1</span> <span class="re5">-d</span> complete.txt split.txt.</div></div>
<p>pour créer des fichiers de 10 lignes portant les noms : split.txt.0, split.txt.1, split.txt.2, split.txt.3 et split.txt.4 (ce dernier ne contenant que 2 lignes).</p>
<h4>Couper un fichier en deux</h4>
<p>Pour couper un fichier en deux fichiers contenant le même nombre de lignes, nous pouvons utiliser les commandes suivantes :</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:540px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">$<span class="sy0">&gt;</span> <span class="re2">FILE</span>=complete.txt<br />
$<span class="sy0">&gt;</span> <span class="re2">LINE</span>=<span class="sy0">`</span><span class="kw2">wc</span> <span class="re5">-l</span> <span class="re1">$FILE</span> <span class="sy0">|</span><span class="kw2">cut</span> <span class="re5">-d</span><span class="st0">&quot; &quot;</span> -f1<span class="sy0">`</span><br />
$<span class="sy0">&gt;</span> <span class="kw2">split</span> <span class="re5">-l</span> <span class="sy0">`</span><span class="kw3">echo</span> <span class="re1">$LINE</span> <span class="sy0">/</span> <span class="nu0">2</span> + <span class="nu0">1</span><span class="sy0">|</span> <span class="kw2">bc</span><span class="sy0">`</span> <span class="re5">-d</span> <span class="re5">-a</span> <span class="nu0">1</span> <span class="re1">$FILE</span> <span class="re1">$FILE</span>.</div></div>
<p>La première ligne permet de stocker le nom du fichier dans la variable <em>FILE</em>.<br />
La seconde calcule le nombre de ligne du fichier et le stocke dans la variable <em>LINE</em>.<br />
La troisième coupe le fichier en 2 en ajoutant un suffixe numérique à la fin du nom du fichier original (toto devient toto.0).</p>
<h4>Script générique</h4>
<p>Il est bien évidemment possible d&#8217;adapter ces commandes à ses besoins. Voici par exemple un script bash (<a class="downloadlink" href="http://labs.pimsworld.org/download/splitsh.txt" title=" downloaded 124 times" >Script de découpe de fichiers (124)</a>) permettant de découper un fichier en N fichiers de taille identique :</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:540px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co0">#!/bin/sh</span><br />
<br />
<span class="re2">USAGE</span>=<span class="st_h">'Usage split.sh [options] filename\nOptions :\n<br />
&nbsp;-c N\tsplit filename in N files (default 2)\n<br />
&nbsp;-o O\tprefixe output files with O (default filename plus dot)\n<br />
&nbsp;-s N\tuse N-length suffixes (default 1)<br />
'</span><br />
<br />
<span class="co0"># Need at least the filename</span><br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re4">$#</span> <span class="re5">-lt</span> <span class="nu0">1</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="re5">-e</span> <span class="re1">$USAGE</span>;<br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">1</span><br />
<span class="kw1">fi</span><br />
<br />
<span class="co0"># Fetch options</span><br />
<span class="kw1">while</span> <span class="kw3">getopts</span> <span class="st0">&quot;:c:o:s::&quot;</span> optname<br />
<span class="kw1">do</span><br />
&nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&quot;<span class="es2">$optname</span>&quot;</span> <span class="kw1">in</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;c&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">COUNT</span>=<span class="re1">$OPTARG</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;o&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">PREFIXE</span>=<span class="re1">$OPTARG</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;s&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">SUF_LENGTH</span>=<span class="re1">$OPTARG</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;?&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="re5">-e</span> <span class="st0">&quot;Unknown option <span class="es2">$OPTARG</span><span class="es1">\n</span>&quot;</span><span class="re1">$USAGE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">2</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;:&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="re5">-e</span> <span class="st0">&quot;No argument value for option <span class="es2">$OPTARG</span><span class="es1">\n</span>&quot;</span><span class="re1">$USAGE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">*</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Unknown error while processing options&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">127</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
&nbsp; &nbsp; <span class="kw1">esac</span><br />
<span class="kw1">done</span><br />
<br />
<span class="co0"># Check that filename is present</span><br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re1">$OPTIND</span> <span class="re5">-gt</span> <span class="re4">$#</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="re5">-e</span> <span class="st0">&quot;filename missing<span class="es1">\n</span>&quot;</span><span class="re1">$USAGE</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">5</span><br />
<span class="kw1">fi</span><br />
<br />
<span class="co0"># and alone</span><br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re4">$#</span> <span class="re5">-gt</span> <span class="re1">$OPTIND</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="re5">-e</span> <span class="st0">&quot;too much arguments<span class="es1">\n</span>&quot;</span><span class="re1">$USAGE</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">6</span><br />
<span class="kw1">fi</span><br />
<br />
<span class="re2">FILE</span>=<span class="co1">${!OPTIND}</span><br />
<br />
<span class="co0"># Filename is there but does it exist?</span><br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="sy0">!</span> <span class="re5">-r</span> <span class="st0">&quot;<span class="es2">$FILE</span>&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="re5">-e</span> <span class="st0">&quot;file <span class="es2">$FILE</span> does not exists or is not readable&quot;</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">7</span><br />
<span class="kw1">fi</span><br />
<br />
<span class="co0"># Set default values for unset options</span><br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="st0">&quot;<span class="es2">$COUNT</span>&quot;</span> = <span class="st0">&quot;&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="re2">COUNT</span>=<span class="nu0">2</span><br />
<span class="kw1">fi</span><br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="st0">&quot;<span class="es2">$PREFIXE</span>&quot;</span> = <span class="st0">&quot;&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="re2">PREFIXE</span>=<span class="st0">&quot;<span class="es2">$FILE</span>.&quot;</span><br />
<span class="kw1">fi</span><br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="st0">&quot;<span class="es2">$SUF_LENGTH</span>&quot;</span> = <span class="st0">&quot;&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="re2">SUF_LENGTH</span>=<span class="nu0">1</span><br />
<span class="kw1">fi</span><br />
<br />
<span class="re2">TOTAL_LINES</span>=<span class="sy0">`</span><span class="kw2">wc</span> <span class="re5">-l</span> <span class="re1">$FILE</span> <span class="sy0">|</span><span class="kw2">cut</span> <span class="re5">-d</span><span class="st0">&quot; &quot;</span> -f1<span class="sy0">`</span><br />
<span class="re2">LINES</span>=<span class="sy0">`</span><span class="kw3">echo</span> <span class="re1">$TOTAL_LINES</span> <span class="sy0">/</span> <span class="re1">$COUNT</span> + <span class="nu0">1</span><span class="sy0">|</span> <span class="kw2">bc</span><span class="sy0">`</span><br />
<br />
<span class="kw2">split</span> <span class="re5">-l</span> <span class="re1">$LINES</span> <span class="re5">-d</span> <span class="re5">-a</span> <span class="re1">$SUF_LENGTH</span> <span class="re1">$FILE</span> <span class="re1">$PREFIXE</span></div></div>
<p>Le script est loin d&#8217;être parfait (pas de vérification des valeurs passées en paramètre par exemple), mais il est suffisant dans la plupart des cas.</p>
<img src="http://feeds.feedburner.com/~r/PimsLabs/~4/oxlyllFKr-k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/05/decouper-fichier-split/feed/</wfw:commentRss>
		<feedburner:origLink>http://labs.pimsworld.org/2009/05/decouper-fichier-split/</feedburner:origLink></item>
		<item>
		<title>A JavaScript implementation of the Content Aware Image Resizing algorithm</title>
		<link>http://feedproxy.google.com/~r/PimsLabs/~3/ZX2YsAykouQ/</link>
		<comments>http://labs.pimsworld.org/2009/05/a-javascript-implementation-of-the-content-aware-image-resizing-algorithm/#comments</comments>
		<pubDate>Mon, 04 May 2009 16:33:12 +0000</pubDate>
		<dc:creator>Stéphane Roucheray</dc:creator>
		
		<category><![CDATA[News]]></category>

		<category><![CDATA[2D]]></category>

		<category><![CDATA[browser]]></category>

		<category><![CDATA[canvas]]></category>

		<category><![CDATA[content aware image resizing]]></category>

		<category><![CDATA[image processing]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[liquid rescale]]></category>

		<category><![CDATA[seam carving]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=477</guid>
		<description><![CDATA[In my previous post, Firefox Native Content Aware Image Resizing, I introduced  a pure JavaScript implementation of the famous Content Aware Image Resizing algorithm also known as Liquid Rescale. I explained the idea and the possible future of this implementation.
Since then, I have had some precious feedbacks from Paul Rouget and Tristan Nitot. They [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous post, <a href="http://labs.pimsworld.org/2009/04/firefox-native-content-aware-image-resizing/">Firefox Native Content Aware Image Resizing</a>, I introduced  a pure JavaScript implementation of the famous <strong>Content Aware Image Resizing</strong> algorithm also known as <strong>Liquid Rescale</strong>. I explained the idea and the possible future of this implementation.</p>
<p>Since then, I have had some precious feedbacks from <a href="http://blog.mozbox.org/">Paul Rouget</a> and <a href="http://standblog.org/blog/">Tristan Nitot</a>. They suggested to make the demo a little bit more interactive. Paul gave me some guidelines to improve the overall performance and I tried to follow his advices. <strong><a href="http://labs.pimsworld.org/wp-content/uploads/2009/04/demo-content-aware-image-resizing-2/">You can play with this demo here</a></strong> (Firefox 3.5b4+ required).</p>
<p>It also required a little bit more informations&#8230;</p>
<h3>How does it work ?</h3>
<p>Obviously, the only way to manipulate bitmap data in a browser is to use the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html">Canvas API</a>. In this demo, when the page is loaded, the process is launched with an image URL and some parameters. A little form enables the visitor to play with them.</p>
<p>The process involves 4 iterative steps, starting with a source image.</p>
<div style="margin: 0pt auto; width: 300px;">
<img src="http://labs.pimsworld.org/wp-content/uploads/2009/05/leslumieres_affiche.jpg" alt="leslumieres_affiche" title="leslumieres_affiche" width="300" height="251" class="aligncenter size-full wp-image-549" />
</div>
<h4>1 - It Generates a grayscale image from the source</h4>
<div style="margin: 0pt auto; width: 300px;">
<img src="http://labs.pimsworld.org/wp-content/uploads/2009/05/leslumieres_affiche_grey.jpg" alt="leslumieres_affiche_grey" title="leslumieres_affiche_grey" width="300" height="251" class="aligncenter size-full wp-image-525" />
</div>
<p>Canvas only provides a low level API for pixel manipulation. Developers only have access to a 1 dimension array containing the 4 components (RGBA) in a row along with a width and a height properties. The ImageData object appears as follow :</p>
<div class="codecolorer-container javascript " style="overflow:auto;white-space:nowrap;width:540px"><div class="javascript codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="coMULTI">/* Array of pixel components : [R, G, B, A, R, G, B, A...] */</span><br />
imageDataObject.<span class="me1">data</span> <br />
<span class="co2">/* Array length &nbsp;*/</span><br />
imageDataObject.<span class="me1">data</span>.<span class="me1">length</span><br />
<br />
<span class="co2">/* Image width */</span><br />
imageDataObject.<span class="me1">width</span><br />
<span class="co2">/* Image height */</span> <br />
imageDataObject.<span class="me1">height</span></div></div>
<p>The following luminance (Y) formula is used to obtain a grayscale :</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:540px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">Y = 0.299 * R + 0.587 * G + 0.114 * B</div></div>
<p>Canvas only manipulates 4 components (RGBA) images. Thus, luminance must be applied to RGB components to display the grayscale version of the image.</p>
<h4>2 - It generates an edge detection and an energy map from the grayscale image</h4>
<div style="margin: 0pt auto; width: 300px;">
<img src="http://labs.pimsworld.org/wp-content/uploads/2009/05/leslumieres_affiche_sobel.jpg" alt="leslumieres_affiche_sobel" title="leslumieres_affiche_sobel" width="300" height="251" class="aligncenter size-full wp-image-526" />
</div>
<p>The edge detection image is generated using a <a href="http://en.wikipedia.org/wiki/Sobel_operator">Sobel convolution</a>. Since canvas does not provide a direct way to apply a convolution filter to an image, the Sobel matrix is applied to each pixel in a loop.<br />
To increase performance, the Sobel and the energy are computed together in the same loop. </p>
<div style="margin: 0pt auto; width: 300px;">
<img src="http://labs.pimsworld.org/wp-content/uploads/2009/05/energy.png" alt="energy" title="energy" width="300" height="251" class="aligncenter size-full wp-image-529" />
</div>
<p>Energy is obtained with the following formula : <em>&#8220;the energy of a pixel is computed from its own value plus the value of the lowest energy pixel from the three above it&#8221;</em>. To obtain the energy map, the image is crawled from top left to bottom right.</p>
<h4>3 - It generates a seam of the lowest energy</h4>
<div style="margin: 0pt auto; width: 300px;">
<img src="http://labs.pimsworld.org/wp-content/uploads/2009/05/seam.png" alt="seam" title="seam" width="300" height="251" class="aligncenter size-full wp-image-533" />
</div>
<p>A seam is a 1 pixel wide vertical line.<br />
The seam is generated from the bottom to the top row of the image :</p>
<ol>
<li>It takes the lowest energy pixel of the bottom row of the energy map</li>
<li>It takes the lowest energy pixel from the three above it</li>
<li>It repeats 1 and 2 until it reaches the top row of the image</li>
</ol>
<h4>4 - It slices the seam from the source</h4>
<p>The process computes an output image from the original picture by slicing the seam. The new generated picture is re-injected as a parameter for the next iteration. </p>
<h3>Performances</h3>
<p>The process has to be repeated for each seam. Reducing the image width of 50 pixels implies 50 vertical seams. Such algorithm is a good place for improvement because it involves a lot of repetitive tasks. A little improvement can result in seconds.<br />
I tweaked many aspects of the algorithm to increase performances. For example, I reduced the crawl in the scope chain by using local variables. I avoided function calls in loops. I tried to use one loop instead of two inner loops when computing pixels (using the length property of canvas <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata">ImageData</a> data object instead of its width and height properties).</p>
<p>I also tried a more radical way to improve performance by reducing the size of the image before entering the process and retrieving the original size after its completion. Such task has side effects. Indeed, when a 2 factor is used (reducing the image by half and then re-increasing it by 2), calculating the seam provides a 2 pixels wide seam instead of 1 pixel wide seam. Thus, the process is almost twice faster but only half of the intermediate results is obtained. For a 50 seams reduction, only 25 intermediates images are calculated in this way.</p>
<p>Finally, let&#8217;s mention memory usage. I had to store the artefacts generated along the process (grayscale image, energy map and seam map). Instead of creating a new ImageData object for each artefact, I stored all of them in a single ImageData object. For that purpose, I used the R component for grayscale values, the G component for energy map and the B component for seam map. In the demo, the pseudo image is displayed, on the fly, by regenerating a real ImageData object from a single component.</p>
<h3>What&#8217;s next ?</h3>
<p>The algorithm is not perfect and fits to some images better than to others.<br />
Many improvements are possible :</p>
<ul>
<li>Adding expansion capability</li>
<li>Adding vertical resizing</li>
<li>Adding the feature of image removal portion</li>
<li>Adding support for threading</li>
</ul>
<p>In a future post I&#8217;ll surely try to go a little bit further and see what I can do with <a href="https://developer.mozilla.org/en/Using_DOM_workers">Workers</a>, and maybe add some new features to this implementation : first on my roadmap is expansion capability.</p>
<h3>How to use the demo ?</h3>
<p>In this demo, you can compare both the liquid resized and the CSS resized image. Give a closer look at Wolverine head !</p>
<div style="margin: 0pt auto; width: 284px;">
<img class="aligncenter size-full wp-image-481" title="Compare Liquid and CSS resize" src="http://labs.pimsworld.org/wp-content/uploads/2009/04/compare-xmen.png" alt="Compare Liquid and CSS resize" width="284" height="540" />
</div>
<p>You can also change the bottom reference picture to compare liquid resize with the artefacts generated during the process (use the drop down list in the title of the picture) :</p>
<div style="margin: 0pt auto; width: 300px;">
<img class="aligncenter size-full wp-image-486" title="Pseudo images" src="http://labs.pimsworld.org/wp-content/uploads/2009/04/pseudo-compare-xmen.png" alt="Pseudo images" width="300" height="132" />
</div>
<p>I must admit the process is very fast, but <em>still</em> not realtime. However, after a short process time, it&#8217;s possible to resize manually the images, by dragging the right border of the top image or even by using left and right arrows.</p>
<div style="margin: 0pt auto; width: 264px;">
<img class="aligncenter size-full wp-image-483" title="Resize image by mouse" src="http://labs.pimsworld.org/wp-content/uploads/2009/04/resize-by-hand.png" alt="Resize image by mouse" width="264" height="312" />
</div>
<p>Finally, a little form will give you the chance to change some settings :</p>
<div style="margin: 0pt auto; width: 400px;">
<img class="size-full wp-image-484" title="cair-form" src="http://labs.pimsworld.org/wp-content/uploads/2009/04/cair-form.jpg" alt="Litlle form" width="400" height="250" /></div>
<p>Any comments, any ideas, any suggestions are welcome !</p>
<img src="http://feeds.feedburner.com/~r/PimsLabs/~4/ZX2YsAykouQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/05/a-javascript-implementation-of-the-content-aware-image-resizing-algorithm/feed/</wfw:commentRss>
		<feedburner:origLink>http://labs.pimsworld.org/2009/05/a-javascript-implementation-of-the-content-aware-image-resizing-algorithm/</feedburner:origLink></item>
		<item>
		<title>Firefox Native Content Aware Image Resizing</title>
		<link>http://feedproxy.google.com/~r/PimsLabs/~3/E6SkfCsQeuA/</link>
		<comments>http://labs.pimsworld.org/2009/04/firefox-native-content-aware-image-resizing/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 16:40:52 +0000</pubDate>
		<dc:creator>Stéphane Roucheray</dc:creator>
		
		<category><![CDATA[Ergonomie]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Tutoriels]]></category>

		<category><![CDATA[canvas]]></category>

		<category><![CDATA[convolution]]></category>

		<category><![CDATA[filter]]></category>

		<category><![CDATA[Firefox]]></category>

		<category><![CDATA[HTML5]]></category>

		<category><![CDATA[image processing]]></category>

		<category><![CDATA[liquid rescale]]></category>

		<category><![CDATA[seam carving]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=442</guid>
		<description><![CDATA[This article is about a pure JavaScript implementation of the famous image resizing algorithm known under the names of Content Aware Image Resizing, Seam Carving or Liquid Rescale. A live demo is available here (Fireox 3.1/3.5 required : download it here).
Update : since this post the demo has been improved and a new post has [...]]]></description>
			<content:encoded><![CDATA[<p>This article is about a <strong>pure JavaScript</strong> implementation of the famous image resizing algorithm known under the names of <strong>Content Aware Image Resizing</strong>, <strong>Seam Carving</strong> or <strong>Liquid Rescale</strong>.<span id="more-442"></span> <a href="http://labs.pimsworld.org/wp-content/uploads/2009/04/demo-content-aware-image-resizing/index.html"><strong>A live demo is available here</strong></a> (Fireox 3.1/3.5 required : <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">download it here</a>).<br />
<strong style="background: #555; color: white; padding: 2px 10px">Update : since this post the demo has been improved and a new post has been written : <a href="http://labs.pimsworld.org/2009/05/a-javascript-implementation-of-the-content-aware-image-resizing-algorithm/">A JavaScript implementation of the content aware image resizing algorithm</a></strong></p>
<h3>Short story</h3>
<p>Last year an incredible buzz around the new image resizing algorithm exposed by <a href="http://www.shaiavidan.org/">Shai Avidan</a> and <a href="http://www.faculty.idc.ac.il/arik/site/index.asp">Ariel Shamir</a> happened.</p>
<p>For those on vacation in 2008 I suggest to give a look at this demo : <a href="http://www.seamcarving.com/">http://www.seamcarving.com/</a>.</p>
<p>As I saw it I started to think about implementations. There are already some <a href="http://liquidrescale.wikidot.com/">here</a> and <a href="http://rsizr.com/">there</a>. Some are fairly fast, some are plugins, some are web based. None of them (from what I saw) are browser native.</p>
<h3>Next gen browsers and HTML5</h3>
<p>I started some work with Flash and ActionsScript 3 and then&#8230; several demos of the new HTML5 native features of next Firefox release (<a href="http://fr.www.mozilla.com/fr/firefox/all-beta.html">3.5 formerly 3.1</a>) by Paul Rouget (<a href="http://blog.mozbox.org/post/2009/02/25/video-canvas%3A-special-effects">video canvas special effects</a> and <a href="http://blog.mozbox.org/post/2009/03/10/video-tag-and-subtitles">video tag and subtitles</a>) and some great articles by <a href="http://blog.vlad1.com/">Vladimir Vukićević</a> arose.</p>
<p>I decided to try to implement the algorithm in pure JavaScript, and this article presents the early results.  The <em>C</em> based <a href="http://brain.recall.googlepages.com/cair">CAIR</a> implementation, and associated article, was really helpful to fully understand the algorithm thus I used the same photo from the NASA, downscaled though, for performance reason.</p>
<h3>JavaScript - Content Aware Image Resizing Algorithm</h3>
<p>Below you can see three pictures :</p>
<ol>
<li>First is the original, its size is 256px / 170px</li>
<li>Second is resized using Content Aware Image Resizing algorithm, its size is 206px / 170px</li>
<li>Third is resized with CSS, I put it here as a reference and its size is also 206px / 170px</li>
</ol>
<div style="margin: 0pt auto; width: 256px;">
<div id="attachment_447" class="wp-caption aligncenter" style="width: 266px"><img class="size-full wp-image-447" title="Original picture" src="http://labs.pimsworld.org/wp-content/uploads/2009/04/original.jpg" alt="Original picture without resize" width="256" height="170" /><p class="wp-caption-text">Original picture</p></div>
<div id="attachment_445" class="wp-caption aligncenter" style="width: 215px"><img class="size-full wp-image-445" title="cair-resized" src="http://labs.pimsworld.org/wp-content/uploads/2009/04/cair-resized.png" alt="Content Aware 50px Resized" width="205" height="170" /><p class="wp-caption-text">50px resized - Content Aware Image Resizing algorithm </p></div>
<div id="attachment_448" class="wp-caption aligncenter" style="width: 216px"><img class="size-full wp-image-448" title="css-resized" src="http://labs.pimsworld.org/wp-content/uploads/2009/04/css-resized.jpg" alt="50px CSS resized " width="206" height="170" /><p class="wp-caption-text">50px resized - CSS Resizing reference</p></div>
</div>
<p>Compare how the angles and the cosmonauts are reproduced on both resized images. Content Aware Image Resizing algorithm manage to get rid of parts of the image with less energy (short for : less important parts of the image) and leave intact the most important parts.</p>
<h3>A JavaScript implementation</h3>
<p>The current implementation I made is really a first shout. It only makes use of JavaScript and the HTML5 &lt;canvas /&gt; tag. It uses the <a href="http://fr.wikipedia.org/wiki/Algorithme_de_Sobel">Sobel convolution filter</a> for edge detection. You&#8217;ll need Firefox 3.1/3.5 to run it (merely tested). The code is still a bit awful and I may refactor and optimize it when I have time.</p>
<p>Next steps could be :</p>
<ul>
<li> Add expansion capabilities</li>
<li> Add vertical reduction and expansion</li>
<li> Test some other edge detection filters</li>
<li> Add some features as image portion removing</li>
<li> Improve performances in order to make it real time on page resizing (is it useful ?)</li>
<li> Improve performances just for the beauty of art</li>
<li> Include it in a JavaScript image manipulation widget from any toolkit like <a href="http://www.pixastic.com/">Pixstatic</a>.</li>
</ul>
<p>Any comments are welcome !</p>
<img src="http://feeds.feedburner.com/~r/PimsLabs/~4/E6SkfCsQeuA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/04/firefox-native-content-aware-image-resizing/feed/</wfw:commentRss>
		<feedburner:origLink>http://labs.pimsworld.org/2009/04/firefox-native-content-aware-image-resizing/</feedburner:origLink></item>
		<item>
		<title>Générer une version statique d’un site</title>
		<link>http://feedproxy.google.com/~r/PimsLabs/~3/Eoveb0u4UA0/</link>
		<comments>http://labs.pimsworld.org/2009/03/generer-une-version-statique-dun-site/#comments</comments>
		<pubDate>Fri, 20 Mar 2009 11:20:56 +0000</pubDate>
		<dc:creator>Kal</dc:creator>
		
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=431</guid>
		<description><![CDATA[Votre site web est dynamique et vous avez besoin de le mettre sur une clée usb, un CD ou encore de le déployer sur un serveur mou-du-genou ?
Je vous propose une solution universelle ou presque pour générer une version statique de votre site avec la commande wget.

wget -k -X admin -B http://monsiteweb.com/ -r -l inf [...]]]></description>
			<content:encoded><![CDATA[<p>Votre site web est dynamique et vous avez besoin de le mettre sur une clée usb, un CD ou encore de le déployer sur un serveur mou-du-genou ?</p>
<p>Je vous propose une solution universelle ou presque pour générer une version statique de votre site avec la commande wget.</p>
<p><span id="more-431"></span></p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:540px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">wget -k -X admin -B http://monsiteweb.com/ -r -l inf -np -nv http://monsiteweb.com</div></div>
<p>Explication des paramètres :<br />
-X  : liste des dossiers à exclure. (ici admin)<br />
-B : la racine du site à aspirer (base).<br />
-r : récursif.<br />
-l inf : un niveau infini de récursions.<br />
-np : ne pas remonter dans le répertoire parent.<br />
-nv : non verbeux.<br />
-k : les liens des pages sont récrits en relatif.</p>
<p>La principale limitation de cette solution (en dehors du fait qu&#8217;il faut que wget soit disponible sur votre système) est qu&#8217;il n&#8217;aspire pas les ressources chargées en js.</p>
<p>A part cela, le résultat est souvent parfait ! <img src='http://labs.pimsworld.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/PimsLabs/~4/Eoveb0u4UA0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/03/generer-une-version-statique-dun-site/feed/</wfw:commentRss>
		<feedburner:origLink>http://labs.pimsworld.org/2009/03/generer-une-version-statique-dun-site/</feedburner:origLink></item>
		<item>
		<title>Bug de la méthode getElementById dans IE6 : une solution !</title>
		<link>http://feedproxy.google.com/~r/PimsLabs/~3/HP_lzCBDvkw/</link>
		<comments>http://labs.pimsworld.org/2009/02/bug-de-la-methode-getelementbyid-dans-ie6-une-solution/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 15:47:03 +0000</pubDate>
		<dc:creator>Yann</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Tips]]></category>

		<category><![CDATA[bug]]></category>

		<category><![CDATA[getElementById]]></category>

		<category><![CDATA[ie6]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=412</guid>
		<description><![CDATA[La méthode getElementById(string) permet en Javascript d&#8217;obtenir l&#8217;élément avec l&#8217;id string si il est présent dans la page.
Malheureusement, dans certains cas cette fonction ne remplit pas son rôle sur IE6 et retourne des résultats non cohérents.
Heureusement il existe des solutions pour corriger ce bug !

Prenons l&#8217;exemple suivant, qui est une version simplifiée de ce que [...]]]></description>
			<content:encoded><![CDATA[<p>La méthode <strong>getElementById(<em>string</em>)</strong> permet en Javascript d&#8217;obtenir l&#8217;élément avec l&#8217;id <em>string</em> si il est présent dans la page.<br />
Malheureusement, dans certains cas cette fonction ne remplit pas son rôle sur IE6 et retourne des résultats non cohérents.<br />
Heureusement il existe des solutions pour corriger ce bug !<br />
<!-- more --></p>
<p>Prenons l&#8217;exemple suivant, qui est une version simplifiée de ce que peut produire <a href="http://framework.zend.com/manual/fr/zend.form.html" title="Documentation de Zend_Form sur le site de Zend">Zend_Form</a> :</p>
<div class="codecolorer-container html4strict " style="overflow:auto;white-space:nowrap;width:540px"><div class="html4strict codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc0">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;</span><br />
<span class="sc2">&lt;<a href="http://december.com/html/4/element/html.html"><span class="kw2">html</span></a> xmlns<span class="sy0">=</span><span class="st0">&quot;http://www.w3.org/1999/xhtml&quot;</span> xml:<span class="kw3">lang</span><span class="sy0">=</span><span class="st0">&quot;fr&quot;</span> <span class="kw3">lang</span><span class="sy0">=</span><span class="st0">&quot;fr&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/head.html"><span class="kw2">head</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/meta.html"><span class="kw2">meta</span></a> <span class="kw3">http-equiv</span><span class="sy0">=</span><span class="st0">&quot;Content-Type&quot;</span> <span class="kw3">content</span><span class="sy0">=</span><span class="st0">&quot;application/xhtml+xml; charset=utf-8&quot;</span> <span class="sy0">/</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/head.html"><span class="kw2">head</span></a>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/body.html"><span class="kw2">body</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/form.html"><span class="kw2">form</span></a> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;frm&quot;</span> <span class="kw3">method</span><span class="sy0">=</span><span class="st0">&quot;&quot;</span> <span class="kw3">action</span><span class="sy0">=</span><span class="st0">&quot;&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/label.html"><span class="kw2">label</span></a> <span class="kw3">for</span><span class="sy0">=</span><span class="st0">&quot;my_input&quot;</span>&gt;</span>Label<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/label.html"><span class="kw2">label</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;hidden&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;0&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;my_input&quot;</span><span class="sy0">/</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;checkbox&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;1&quot;</span> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;my_input&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;my_input&quot;</span><span class="sy0">/</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/form.html"><span class="kw2">form</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/javascript&quot;</span>&gt;</span><span class="sc-1">&lt;!--</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;alert(document.getElementById('my_input').type);</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp;//--&gt;</span><span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/body.html"><span class="kw2">body</span></a>&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/html.html"><span class="kw2">html</span></a>&gt;</span></div></div>
<p>Dans Firefox, Safari et les autres navigateurs évolués, aucun soucis, nous avons bien une alerte qui nous affiche <em>checkbox</em>. Par contre sous IE6, nous nous retrouvons avec un insolent <em>hidden</em> !</p>
<p>En effet, l&#8217;implémentation de getElementById dans IE6 comporte un bug qui fait qu&#8217;il ne fait pas uniquement la recherche sur l&#8217;attribut <em>id</em> mais également sur <em>name</em> et qu&#8217;il retourne donc le premier élément, ici le champ caché.</p>
<p>Dans notre cas, on pourrait simplement inverser l&#8217;ordre des champs et comme la case à cocher serait placée avant elle serait retournée. Mais nous pouvons également proposer une solution plus élégante et surtout plus générique pour contourner le problème : <strong>redéfinir la méthode</strong>.</p>
<p>Voici la nouvelle méthode :</p>
<div class="codecolorer-container javascript " style="overflow:auto;white-space:nowrap;width:540px"><div class="javascript codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">if</span> <span class="br0">&#40;</span><span class="co2">/msie/i</span>.<span class="me1">test</span> <span class="br0">&#40;</span>navigator.<span class="me1">userAgent</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; document.<span class="me1">nativeGetElementById</span> <span class="sy0">=</span> document.<span class="me1">getElementById</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; document.<span class="me1">getElementById</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span>id<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Get element using native method</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> elem <span class="sy0">=</span> document.<span class="me1">nativeGetElementById</span><span class="br0">&#40;</span>id<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>elem<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// If id match, return element</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>elem.<span class="me1">attributes</span><span class="br0">&#91;</span><span class="st0">'id'</span><span class="br0">&#93;</span>.<span class="me1">value</span> <span class="sy0">==</span> id<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> elem<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Otherwise look for the right one</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i <span class="sy0">=</span> <span class="nu0">1</span><span class="sy0">;</span> i <span class="sy0">&lt;</span> document.<span class="me1">all</span><span class="br0">&#91;</span>id<span class="br0">&#93;</span>.<span class="me1">length</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>document.<span class="me1">all</span><span class="br0">&#91;</span>id<span class="br0">&#93;</span><span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">attributes</span><span class="br0">&#91;</span><span class="st0">'id'</span><span class="br0">&#93;</span>.<span class="me1">value</span> <span class="sy0">==</span> id<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> document.<span class="me1">all</span><span class="br0">&#91;</span>id<span class="br0">&#93;</span><span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">null</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></div></div>
<p>Explication du code :<br />
 - on ne redéfinit la fonction que pour Internet Explorer (on peut utiliser d&#8217;autre méthode de détection dans le premier if)<br />
 - on garde une copie de la fonction native de manière à pouvoir l&#8217;utiliser plus loin<br />
 - dans notre nouvelle méthode, on récupère l&#8217;élément avec l&#8217;ancienne méthode, puis on vérifie que son id correspond bien à ce que nous recherchons, si ce n&#8217;est pas le cas, on fait une recherche manuelle.</p>
<p>Exemple complet :</p>
<div class="codecolorer-container html4strict " style="overflow:auto;white-space:nowrap;width:540px"><div class="html4strict codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc0">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;</span><br />
<span class="sc2">&lt;<a href="http://december.com/html/4/element/html.html"><span class="kw2">html</span></a> xmlns<span class="sy0">=</span><span class="st0">&quot;http://www.w3.org/1999/xhtml&quot;</span> xml:<span class="kw3">lang</span><span class="sy0">=</span><span class="st0">&quot;fr&quot;</span> <span class="kw3">lang</span><span class="sy0">=</span><span class="st0">&quot;fr&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/head.html"><span class="kw2">head</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/meta.html"><span class="kw2">meta</span></a> <span class="kw3">http-equiv</span><span class="sy0">=</span><span class="st0">&quot;Content-Type&quot;</span> <span class="kw3">content</span><span class="sy0">=</span><span class="st0">&quot;application/xhtml+xml; charset=utf-8&quot;</span> <span class="sy0">/</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/javascript&quot;</span>&gt;</span><span class="sc-1">&lt;!--</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (/msie/i.test (navigator.userAgent))</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;document.nativeGetElementById = document.getElementById; </span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;document.getElementById = function(id)</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Get element using native method</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var elem = document.nativeGetElementById(id);</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (elem)</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// If id match, return element</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (elem.attributes['id'].value == id)</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return elem;</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Otherwise look for the right one</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for (var i = 1; i &lt; document.all[id].length; i++)</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (document.all[id][i].attributes['id'].value == id)</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return document.all[id][i];</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return null;</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp;//--&gt;</span><span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/head.html"><span class="kw2">head</span></a>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/body.html"><span class="kw2">body</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/form.html"><span class="kw2">form</span></a> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;frm&quot;</span> <span class="kw3">method</span><span class="sy0">=</span><span class="st0">&quot;&quot;</span> <span class="kw3">action</span><span class="sy0">=</span><span class="st0">&quot;&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/label.html"><span class="kw2">label</span></a> <span class="kw3">for</span><span class="sy0">=</span><span class="st0">&quot;my_input&quot;</span>&gt;</span>Label<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/label.html"><span class="kw2">label</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;hidden&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;0&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;my_input&quot;</span><span class="sy0">/</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;checkbox&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;1&quot;</span> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;my_input&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;my_input&quot;</span><span class="sy0">/</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/form.html"><span class="kw2">form</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/javascript&quot;</span>&gt;</span><span class="sc-1">&lt;!--</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;alert(document.getElementById('my_input').type);</span><br />
<span class="sc-1"> &nbsp; &nbsp; &nbsp; &nbsp;//--&gt;</span><span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/body.html"><span class="kw2">body</span></a>&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/html.html"><span class="kw2">html</span></a>&gt;</span></div></div>
<p><em>Référence : <a href="http://www.sixteensmallstones.org/ie-javascript-bugs-overriding-internet-explorers-documentgetelementbyid-to-be-w3c-compliant-exposes-an-additional-bug-in-getattributes">Sixteen Small Stones</a></em></p>
<img src="http://feeds.feedburner.com/~r/PimsLabs/~4/HP_lzCBDvkw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/02/bug-de-la-methode-getelementbyid-dans-ie6-une-solution/feed/</wfw:commentRss>
		<feedburner:origLink>http://labs.pimsworld.org/2009/02/bug-de-la-methode-getelementbyid-dans-ie6-une-solution/</feedburner:origLink></item>
		<item>
		<title>Erreur Javascript Firefox : oTidyBrowser is not defined</title>
		<link>http://feedproxy.google.com/~r/PimsLabs/~3/Fp2xqrmHyCw/</link>
		<comments>http://labs.pimsworld.org/2009/02/erreur-javascript-firefox-otidybrowser-is-not-defined/#comments</comments>
		<pubDate>Fri, 13 Feb 2009 10:07:19 +0000</pubDate>
		<dc:creator>Adrien</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Non classé]]></category>

		<category><![CDATA[Tips]]></category>

		<category><![CDATA[Erreur Javascript Firefox]]></category>

		<category><![CDATA[HTML Validator Firebug]]></category>

		<category><![CDATA[oTidyBrowser is not defined]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=404</guid>
		<description><![CDATA[Si vous travaillez avec Firefox et les extensions HTML Validator et Firebug, vous avez peut-être déjà eu une erreur Javascript récurrente dans la console d&#8217;erreur :

Error: oTidyBrowser is not defined
 Source File: chrome://tidy/content/tidyBrowser.js
 Line: 220

Ceci est dû à un bogue venant de l&#8217;utilisation conjointe de Firebug et HTML Validator. voici la procédure pour le corriger [...]]]></description>
			<content:encoded><![CDATA[<p>Si vous travaillez avec Firefox et les extensions HTML Validator et Firebug, vous avez peut-être déjà eu une erreur Javascript récurrente dans la console d&#8217;erreur :</p>
<blockquote>
<pre>Error: oTidyBrowser is not defined
 Source File: chrome://tidy/content/tidyBrowser.js
 Line: 220</pre>
</blockquote>
<p>Ceci est dû à un bogue venant de l&#8217;utilisation conjointe de Firebug et HTML Validator. voici la procédure pour le corriger :</p>
<ol>
<li>Ouvrir le dossier Firefox de votre profil<br />
(Windows) C:\Users\Dan\AppData\Roaming\Mozilla\Firefox\Profiles\vqy7rs08.default\extensions\{3b56bcc7-54e5-44a2-9b44-66c3ef58c13e}\chrome<br />
(Unix) /home/dan/.mozilla/firefox/8wazcbtr.default/extensions/{3b56bcc7-54e5-44a2-9b44-66c3ef58c13e}/chrome</li>
<li>Copier le fichier tidy.jar et renommer la copie en tidy.zip</li>
<li>Décompressez ce dernier fichier</li>
<li>Ouvrez le fichier content/tidyBrowser.js</li>
<li>Allez à la ligne 220, la section de code recherchée est :<br />
<blockquote>
<pre> 220. if( oTidyBrowser.bTopLoadBusy==false )</pre>
<pre> 221. {</pre>
<pre> 222.  oTidyUtil.tidy.log( ‘&lt;javascript&gt;tidyEndDocumentLoadObserver' );</pre>
<pre> 223.  oTidyBrowser.bTopLoadBusy = true;</pre>
<pre> 224.  try</pre>
<pre> 225.  {</pre>
<pre> 226.   // Validate the 1rst request</pre>
<pre> 227.   oTidyBrowser.bIgnorePageShow = true;</pre>
<pre> 228.   oTidyBrowser.validateFrame( window.content );</pre>
<pre> 229.   // oTidyBrowser.validateCache( subject.document, true );</pre>
<pre> 230.</pre>
<pre> 231.   // Process the events that fired during the 1rst one</pre>
<pre> 232.   // ex: page with frames.</pre>
<pre> 233.   var doc = oTidyBrowser.oEventQueue.pop();</pre>
<pre> 234.   while( doc )</pre>
<pre> 235.   {</pre>
<pre> 236.    oTidyBrowser.validateCache( doc, true );</pre>
<pre> 237.    doc = oTidyBrowser.oEventQueue.pop();</pre>
<pre> 238.   }</pre>
<pre> 239.  }</pre>
<pre> 240.  catch(ex)</pre>
<pre> 241.  {</pre>
<pre> 242.   tidyShowExceptionInConsole( ex );</pre>
<pre> 243.  }</pre>
<pre> 244.  oTidyBrowser.bTopLoadBusy = false;</pre>
<pre> 245. }</pre>
<pre> 246. else</pre>
<pre> 247. {</pre>
<pre> 248.  // Parallel events are placed in a event queue.</pre>
<pre> 249.  oTidyBrowser.oEventQueue.push( event.originalTarget );</pre>
<pre> 250. }</pre>
</blockquote>
</li>
<li>Rajouter cette section de code :<br />
<blockquote>
<pre>if( !oTidyBrowser )</pre>
<pre>{</pre>
<pre>  // Do nothing</pre>
<pre>}</pre>
<pre>else if( oTidyBrowser.bTopLoadBusy==false )</pre>
<pre>{</pre>
<pre>  oTidyUtil.tidy.log( ‘&lt;javascript&gt;tidyEndDocumentLoadObserver' );</pre>
<pre>  oTidyBrowser.bTopLoadBusy = true;</pre>
<pre>    .....</pre>
</blockquote>
</li>
<li>Recompressez les trois dossiers (content, locale et skin) en une archive tidy.zip</li>
<li>Faites une sauvegarde de tidy.jar et renommez tidy.zip en tidy.jar</li>
<li>Redémarrez Firefox</li>
<li>Oh bonheur ! L&#8217;erreur a disparu.</li>
</ol>
<img src="http://feeds.feedburner.com/~r/PimsLabs/~4/Fp2xqrmHyCw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/02/erreur-javascript-firefox-otidybrowser-is-not-defined/feed/</wfw:commentRss>
		<feedburner:origLink>http://labs.pimsworld.org/2009/02/erreur-javascript-firefox-otidybrowser-is-not-defined/</feedburner:origLink></item>
		<item>
		<title>Fichiers CSV</title>
		<link>http://feedproxy.google.com/~r/PimsLabs/~3/cm-tJzo-VFQ/</link>
		<comments>http://labs.pimsworld.org/2009/02/fichiers-csv/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 15:06:08 +0000</pubDate>
		<dc:creator>Adrien</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Tips]]></category>

		<category><![CDATA[csv virgule point-virgule compatibilité]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=397</guid>
		<description><![CDATA[Déjà eu des problèmes à lire un fichier d&#8217;export au format CSV ?
Voici le formattage assurant un maximum de compatibilité :

utiliser l&#8217;extension &#8220;.csv&#8221;
utiliser des délimiteurs de champs pour toutes les lignes du fichiers, généralement ce sont les doubles guillements (&#8221;) qui sont utilisés
si une valeur de champ contient le délimiteur de champ, le doubler, exemple: [...]]]></description>
			<content:encoded><![CDATA[<p>Déjà eu des problèmes à lire un fichier d&#8217;export au format CSV ?<br />
Voici le formattage assurant un maximum de compatibilité :</p>
<ul>
<li>utiliser l&#8217;extension &#8220;.csv&#8221;</li>
<li>utiliser des délimiteurs de champs pour toutes les lignes du fichiers, généralement ce sont les doubles guillements (&#8221;) qui sont utilisés</li>
<li>si une valeur de champ contient le délimiteur de champ, le doubler, exemple: &#8220;Voici un caractère &#8220;&#8221; dans un champ du fichier&#8221;</li>
<li>utiliser le point-virgule &#8220;;&#8221; comme séparateur de champ</li>
<li>terminer les lignes par le caractère &#8220;\n&#8221;</li>
<li>supprimer toute occurrence du caractère &#8220;\r&#8221; dans le fichier (mal supporté par Windows)</li>
</ul>
<p>J&#8217;ai également rencontré des problèmes avec l&#8217;encodage unicode UTF-8  et Microsoft Office Excel (il n&#8217;a pas l&#8217;air de vouloir le lire et force l&#8217;encodage ISO) mais je n&#8217;ai pas trouvé de solution.</p>
<p><span style="text-decoration: underline;">Post scriptum:</span> n&#8217;essayez même pas d&#8217;assurer une compatibilité avec les versions antérieures à Micorsoft Office Excel 98</p>
<img src="http://feeds.feedburner.com/~r/PimsLabs/~4/cm-tJzo-VFQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/02/fichiers-csv/feed/</wfw:commentRss>
		<feedburner:origLink>http://labs.pimsworld.org/2009/02/fichiers-csv/</feedburner:origLink></item>
		<item>
		<title>JavaScript, la bible en vidéo</title>
		<link>http://feedproxy.google.com/~r/PimsLabs/~3/zUO2n3Po1Yk/</link>
		<comments>http://labs.pimsworld.org/2009/02/javascript-la-bible-en-video/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 11:59:24 +0000</pubDate>
		<dc:creator>Stéphane Roucheray</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[DOM]]></category>

		<category><![CDATA[Douglas Crockford]]></category>

		<category><![CDATA[Présentation]]></category>

		<category><![CDATA[Vidéo]]></category>

		<category><![CDATA[Yahoo]]></category>

		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=358</guid>
		<description><![CDATA[Le domaine des développeurs de Yahoo est une mine d&#8217;informations sur JavaScript. De nombreuses conférences données par des experts de Yahoo! ou des intervenants extérieurs de grande qualité sont en streaming et en téléchargement dans la zone vidéo du site. Souvent leurs présentations PowerPoint sont également disponibles.
Si vous êtes intéressés par JavaScript, quelque soit votre [...]]]></description>
			<content:encoded><![CDATA[<p>Le domaine des développeurs de <a href="http://developer.yahoo.com">Yahoo</a> est une mine d&#8217;informations sur <a href="http://labs.pimsworld.org/tag/javascript/">JavaScript</a>. De nombreuses conférences données par des experts de Yahoo! ou des intervenants extérieurs de grande qualité sont en streaming et en téléchargement dans la <a href="http://developer.yahoo.com/yui/theater/">zone vidéo du site</a>. Souvent leurs présentations PowerPoint sont également disponibles.</p>
<p>Si vous êtes intéressés par JavaScript, quelque soit votre niveau - débutant, intermédiaire ou expert - je ne saurais trop vous conseiller ces 4 vidéos de l&#8217;excellent <a href="http://www.crockford.com/">Douglas Crockford</a> dont le modeste titre est &#8220;<em>The JavaScript Programming Language</em>&#8221; et dont la présentation PowerPoint est téléchargeable <a href="http://yuiblog.com/assets/crockford/javascript.zip">ici</a>.<br />
</p>
<div style="margin: 0pt auto; width: 490px;"><object width="490" height="370" data="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.34" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="AllowScriptAccess" value="always" /><param name="bgcolor" value="#000000" /><param name="flashVars" value="id=1710507&amp;vid=111593&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//us.i1.yimg.com/us.yimg.com/i/us/sch/cn/v/v0/w327/111593_320_240.jpeg&amp;embed=1" /><param name="src" value="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.34" /><param name="flashvars" value="id=1710507&amp;vid=111593&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//us.i1.yimg.com/us.yimg.com/i/us/sch/cn/v/v0/w327/111593_320_240.jpeg&amp;embed=1" /><param name="allowfullscreen" value="true" /></object><br />
<a href="http://video.yahoo.com/watch/111593/1710507">&#8220;The JavaScript Programming Language&#8221; 1 / 4</a> @ <a href="http://video.yahoo.com">Yahoo! Video</a></div>
<div style="margin: 0pt auto; width: 490px;"></div>
<p></p>
<div style="margin: 0pt auto; width: 490px;"><object width="490" height="370" data="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.34" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="AllowScriptAccess" value="always" /><param name="bgcolor" value="#000000" /><param name="flashVars" value="id=1710553&amp;vid=111594&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//us.i1.yimg.com/us.yimg.com/i/us/sch/cn/v/v0/w326/111594_320_240.jpeg&amp;embed=1" /><param name="src" value="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.34" /><param name="flashvars" value="id=1710553&amp;vid=111594&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//us.i1.yimg.com/us.yimg.com/i/us/sch/cn/v/v0/w326/111594_320_240.jpeg&amp;embed=1" /><param name="allowfullscreen" value="true" /></object><br />
<a href="http://video.yahoo.com/watch/111594/1710553">&#8220;The JavaScript Programming Language&#8221; 2 / 4</a> @ <a href="http://video.yahoo.com">Yahoo! Video</a></div>
<div style="margin: 0pt auto; width: 490px;"></div>
<p></p>
<div style="margin: 0pt auto; width: 490px;"><object width="490" height="370" data="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.34" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="AllowScriptAccess" value="always" /><param name="bgcolor" value="#000000" /><param name="flashVars" value="id=1710607&amp;vid=111595&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//us.i1.yimg.com/us.yimg.com/i/us/sch/cn/v/v0/w326/111595_320_240.jpeg&amp;embed=1" /><param name="src" value="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.34" /><param name="flashvars" value="id=1710607&amp;vid=111595&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//us.i1.yimg.com/us.yimg.com/i/us/sch/cn/v/v0/w326/111595_320_240.jpeg&amp;embed=1" /><param name="allowfullscreen" value="true" /></object><br />
<a href="http://video.yahoo.com/watch/111595/1710607">&#8220;The JavaScript Programming Language&#8221; 3 / 4</a> @ <a href="http://video.yahoo.com">Yahoo! Video</a></div>
<div style="margin: 0pt auto; width: 490px;"></div>
<p></p>
<div style="margin: 0pt auto; width: 490px;"><object width="490" height="370" data="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.34" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="AllowScriptAccess" value="always" /><param name="bgcolor" value="#000000" /><param name="flashVars" value="id=1710658&amp;vid=111596&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//us.i1.yimg.com/us.yimg.com/i/us/sch/cn/v/v0/w326/111596_320_240.jpeg&amp;embed=1" /><param name="src" value="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.34" /><param name="flashvars" value="id=1710658&amp;vid=111596&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//us.i1.yimg.com/us.yimg.com/i/us/sch/cn/v/v0/w326/111596_320_240.jpeg&amp;embed=1" /><param name="allowfullscreen" value="true" /></object><br />
<a href="http://video.yahoo.com/watch/111596/1710658">&#8220;The JavaScript Programming Language&#8221; 4 / 4</a> @ <a href="http://video.yahoo.com">Yahoo! Video</a></div>
<img src="http://feeds.feedburner.com/~r/PimsLabs/~4/zUO2n3Po1Yk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/02/javascript-la-bible-en-video/feed/</wfw:commentRss>
		<feedburner:origLink>http://labs.pimsworld.org/2009/02/javascript-la-bible-en-video/</feedburner:origLink></item>
		<item>
		<title>Petite histoire d’une formule mathématique discrète</title>
		<link>http://feedproxy.google.com/~r/PimsLabs/~3/5fnkhK3jt_c/</link>
		<comments>http://labs.pimsworld.org/2009/02/petite-histoire-dune-formule-mathematique-discrete/#comments</comments>
		<pubDate>Mon, 02 Feb 2009 15:40:58 +0000</pubDate>
		<dc:creator>Stéphane Roucheray</dc:creator>
		
		<category><![CDATA[ActionScript]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Open Source]]></category>

		<category><![CDATA[AS3]]></category>

		<category><![CDATA[Maths]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=273</guid>
		<description><![CDATA[Lors de deux projets récents, j&#8217;ai été confronté à des problématiques similaires. J&#8217;ai d&#8217;abord eu à construire une réglette en ActionScript 3, puis un navigateur de produits, semblable à celui du site de Apple, en JavaScript.
Dans les deux cas, il fallait pouvoir récupérer, depuis la position du curseur sur sa réglette, des valeurs par paliers. [...]]]></description>
			<content:encoded><![CDATA[<p>Lors de deux projets récents, j&#8217;ai été confronté à des problématiques similaires. J&#8217;ai d&#8217;abord eu à construire une réglette en ActionScript 3, puis un navigateur de produits, semblable à celui du site de <a href="http://www.apple.com/fr/mac/">Apple</a>, en <a href="http://labs.pimsworld.org/tag/javascript/">JavaScript</a>.</p>
<p>Dans les deux cas, il fallait pouvoir récupérer, depuis la position du curseur sur sa réglette, des valeurs par paliers. La question était donc celle-ci : <strong>Comment récupérer une valeur discrète sur une échelle continue ?</strong> </p>
<h2>Valeurs continues</h2>
<p>Tout d&#8217;abord pour récupérer une valeur continue sur une réglette, une simple règle de trois suffit : </p>
<p><strong>AS3 : récupération d&#8217;une valeur continue sur une réglette arbitraire</strong></p>
<div class="codecolorer-container actionscript3 " style="overflow:auto;white-space:nowrap;width:540px"><div class="actionscript3 codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="coMULTI">/**<br />
&nbsp;* min :&nbsp; &nbsp; &nbsp; &nbsp; valeur minimum de la réglette<br />
&nbsp;* max :&nbsp; &nbsp; &nbsp; &nbsp; valeur maximum de la réglette<br />
&nbsp;* width :&nbsp; &nbsp; &nbsp; largeur de la réglette<br />
&nbsp;* position : &nbsp; position du curseur sur la réglette<br />
&nbsp;*/</span><br />
<span class="kw2">var</span> continuous = <span class="kw7">min</span> <span class="sy0">+</span> <span class="br0">&#40;</span><span class="kw7">max</span> <span class="sy0">-</span> <span class="kw7">min</span><span class="br0">&#41;</span> <span class="sy0">*</span> <span class="kw7">position</span> <span class="sy0">/</span> <span class="kw7">width</span></div></div>
<h2>Arrondi au multiple le plus proche</h2>
<p>Supposons maintenant que je décide d&#8217;ajouter la notion de <strong>pas</strong> sur ma réglette. Je ne souhaite alors récupérer que les valeurs multiples de ce pas. Par exemple, si mon pas est de 3 j&#8217;obtiendrais la série suivante :</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:540px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">0, 3, 6, 9, 12...</div></div>
<p>Voici la formule qui me permet d&#8217;obtenir ce résultat.</p>
<p><strong>AS3 : formule retournant une valeur discrète à partir d&#8217;une échelle continue</strong></p>
<div class="codecolorer-container actionscript3 " style="overflow:auto;white-space:nowrap;width:540px"><div class="actionscript3 codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="coMULTI">/**<br />
&nbsp;* step : &nbsp; &nbsp; &nbsp; pas de mon échelle<br />
&nbsp;* continuous : valeur continue sur mon échelle<br />
&nbsp;*/</span><br />
<span class="kw2">var</span> discrete = step <span class="sy0">*</span> <a href="http://www.google.com/search?q=math%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:math.html&amp;filter=0&amp;num=100&amp;btnI=lucky"><span class="kw5">Math</span></a>.<span class="kw7">floor</span><span class="br0">&#40;</span><span class="br0">&#40;</span>continuous <span class="sy0">+</span> step <span class="sy0">/</span> <span class="nu0">2</span><span class="br0">&#41;</span> <span class="sy0">/</span> step <span class="br0">&#41;</span>;</div></div>
<p>Cette formule, renvoie donc une valeur discrète (arrondie) quand on lui fournit le <strong>pas</strong> à respecter (<em>step</em>) et une <strong>valeur continue</strong> (<em>value</em>).</p>
<p>Il subsiste encore un problème, la formule précédente ne prend pas en compte la valeur minimum de ma réglette. En reprenant l&#8217;exemple précédent, lorsque je récupère des valeurs avec un <strong>pas</strong> de 3 mais ne commençant pas à 0&#8230; disons à 2,  je souhaiterais obtenir la série suivante  :</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:540px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">2, 5, 8, 11, 14...</div></div>
<p>Or avec la formule précédente, je n&#8217;obtiens que des arrondis de multiples du pas mais 2, 5, 8, 11, 14 ne sont pas des multiples de 3.</p>
<h2>Valeurs discrètes et minimum d&#8217;échelle</h2>
<p>Pour résoudre le problème, il faut donc modifier les 2 formules précédentes en décalant l&#8217;échelle de la valeur minimum avant d&#8217;utiliser la fonction d&#8217;arrondi  puis en la corrigeant à nouveau après.<br />
En plus clair : </p>
<ol>
<li>Retrancher la valeur minimum à la valeur continue (pour que l&#8217;échelle de la réglette parte de 0 et pas de la valeur minimum)</li>
<li>Puis ajouter cette même valeur minimum à la valeur arrondie pour corriger le décalage introduit précédemment</li>
</ol>
<p><strong>AS3 : Comparaison des formules</strong></p>
<div class="codecolorer-container actionscript3 " style="overflow:auto;white-space:nowrap;width:540px"><div class="actionscript3 codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1">// Formules précédentes</span><br />
<span class="kw2">var</span> continuous = &nbsp;<span class="kw7">min</span> <span class="sy0">+</span> <span class="br0">&#40;</span><span class="kw7">max</span> <span class="sy0">-</span> <span class="kw7">min</span><span class="br0">&#41;</span> <span class="sy0">*</span> <span class="kw7">position</span> <span class="sy0">/</span> <span class="kw7">width</span>;<br />
<span class="kw2">var</span> discrete = step <span class="sy0">*</span> <a href="http://www.google.com/search?q=math%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:math.html&amp;filter=0&amp;num=100&amp;btnI=lucky"><span class="kw5">Math</span></a>.<span class="kw7">floor</span><span class="br0">&#40;</span><span class="br0">&#40;</span>continuous <span class="sy0">+</span> step <span class="sy0">/</span> <span class="nu0">2</span><span class="br0">&#41;</span> <span class="sy0">/</span> step<span class="br0">&#41;</span>;<br />
<br />
<span class="co1">// Formules corrigées</span><br />
<span class="kw2">var</span> continuous = &nbsp;<span class="br0">&#40;</span><span class="kw7">max</span> <span class="sy0">-</span> <span class="kw7">min</span><span class="br0">&#41;</span> <span class="sy0">*</span> <span class="kw7">position</span> <span class="sy0">/</span> <span class="kw7">width</span>;<br />
<span class="kw2">var</span> discrete = <br />
&nbsp; &nbsp; step <span class="sy0">*</span> <a href="http://www.google.com/search?q=math%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:math.html&amp;filter=0&amp;num=100&amp;btnI=lucky"><span class="kw5">Math</span></a>.<span class="kw7">floor</span><span class="br0">&#40;</span><span class="br0">&#40;</span>continuous <span class="sy0">+</span> step <span class="sy0">/</span> <span class="nu0">2</span><span class="br0">&#41;</span> <span class="sy0">/</span> step<span class="br0">&#41;</span> <span class="sy0">+</span> mini;</div></div>
<p>Pour tester la formule, voici un exemple des réglettes faites en AS3. L&#8217;une retourne des valeurs continues l&#8217;autre des valeurs par paliers. Les valeurs minimum et maximum ainsi que le pas de la deuxième réglette sont paramétrables.</p>
<div style="width:230px; margin: 0 auto;">

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_0" width="230" height="250">
      <param name="movie" value="http://labs.pimsworld.org/wp-content/uploads/2009/02/curseur.swf" />
      <param name="wmode" value="transparent" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://labs.pimsworld.org/wp-content/uploads/2009/02/curseur.swf" width="230" height="250" wmode="transparent">
      <!--<![endif]-->
        <p>Le plugin Flash est requis pour visualiser cet objet.</p>
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

</div>
<img src="http://feeds.feedburner.com/~r/PimsLabs/~4/5fnkhK3jt_c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/02/petite-histoire-dune-formule-mathematique-discrete/feed/</wfw:commentRss>
		<feedburner:origLink>http://labs.pimsworld.org/2009/02/petite-histoire-dune-formule-mathematique-discrete/</feedburner:origLink></item>
	</channel>
</rss>
