<?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/"
	>

<channel>
	<title>Pims Labs &#187; Langages</title>
	<atom:link href="http://labs.pimsworld.org/category/langages/feed/" rel="self" type="application/rss+xml" />
	<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>
			<item>
		<title>Firefox Native Content Aware Image Resizing</title>
		<link>http://labs.pimsworld.org/2009/04/firefox-native-content-aware-image-resizing/</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>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/04/firefox-native-content-aware-image-resizing/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Bug de la méthode getElementById dans IE6 : une solution !</title>
		<link>http://labs.pimsworld.org/2009/02/bug-de-la-methode-getelementbyid-dans-ie6-une-solution/</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>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/02/bug-de-la-methode-getelementbyid-dans-ie6-une-solution/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Erreur Javascript Firefox : oTidyBrowser is not defined</title>
		<link>http://labs.pimsworld.org/2009/02/erreur-javascript-firefox-otidybrowser-is-not-defined/</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>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/02/erreur-javascript-firefox-otidybrowser-is-not-defined/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Fichiers CSV</title>
		<link>http://labs.pimsworld.org/2009/02/fichiers-csv/</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>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/02/fichiers-csv/feed/</wfw:commentRss>
		</item>
		<item>
		<title>JavaScript, la bible en vidéo</title>
		<link>http://labs.pimsworld.org/2009/02/javascript-la-bible-en-video/</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>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/02/javascript-la-bible-en-video/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Petite histoire d&#8217;une formule mathématique discrète</title>
		<link>http://labs.pimsworld.org/2009/02/petite-histoire-dune-formule-mathematique-discrete/</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>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/02/petite-histoire-dune-formule-mathematique-discrete/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Xoad et le Zend Framework</title>
		<link>http://labs.pimsworld.org/2009/01/xoad-et-le-zend-framework/</link>
		<comments>http://labs.pimsworld.org/2009/01/xoad-et-le-zend-framework/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 17:53:24 +0000</pubDate>
		<dc:creator>jrm</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Tutoriels]]></category>

		<category><![CDATA[Xoad]]></category>

		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=162</guid>
		<description><![CDATA[Dans cet article vous allez découvrir comment XOAD permet d&#8217;exporter des classes PHP vers du code Javascript par l&#8217;intermédiaire du Zend Framework.

Ce qu&#8217;il faut savoir pour comprendre cet article :

Avoir de bonnes bases en javascript, PHP.
Comprendre le  design pattern MVC.
Savoir créer le bootstrap d&#8217;une application avec le Zend Framework.

Xoad
Xoad permet d&#8217;exporter des objets du [...]]]></description>
			<content:encoded><![CDATA[<p>Dans cet article vous allez découvrir comment XOAD permet d&#8217;exporter des classes PHP vers du code Javascript par l&#8217;intermédiaire du Zend Framework.</p>
<p><span id="more-162"></span></p>
<p><strong>Ce qu&#8217;il faut savoir pour comprendre cet article </strong>:</p>
<ul>
<li>Avoir de bonnes bases en javascript, PHP.</li>
<li>Comprendre le  design pattern MVC.</li>
<li>Savoir créer le bootstrap d&#8217;une application avec le Zend Framework.</li>
</ul>
<h2>Xoad</h2>
<p>Xoad permet d&#8217;exporter des objets du côté serveur vers le côté client. Xoad est un environnement basé sur un ORB. Un ORB (Object Request Broker) est un ensemble de fonctions qui implément un bus logiciel par lequel des objets envoient et reçoivent des requêtes et des réponses, de manière transparente et portable.</p>
<h2>Zend Framework</h2>
<p>Le Zend Framework est un <a title="Framework" href="http://fr.wikipedia.org/wiki/Framework">framework</a> pour <a title="PHP: Hypertext Preprocessor" href="http://fr.wikipedia.org/wiki/PHP:_Hypertext_Preprocessor">PHP 5</a> créé par <a title="Zend (informatique)" href="http://fr.wikipedia.org/wiki/Zend_%28informatique%29">Zend</a>. Il est distribué sous la <a title="Licence BSD" href="http://fr.wikipedia.org/wiki/Licence_BSD">New BSD license</a>. Le Zend Framework, aussi nommé ZF, a été développé dans le but de simplifier le développement Web tout en recommandant les bonnes pratiques et la <a title="Programmation orientée objet" href="http://fr.wikipedia.org/wiki/Programmation_orient%C3%A9e_objet">conception orientée objets</a> en offrant des outils puissants aux développeurs. ZF permet aussi d&#8217;utiliser nativement le principe de MVC (Modèle-Vue-Contrôleur) mais ne l&#8217;oblige pas.</p>
<h2>Préalable</h2>
<h3>Configuration du Zend-Framework :</h3>
<p>Si vous êtes débutant avec le ZF vous pouvez vous reporter à l&#8217;arcticle suivant :<a href="http://julien-pauli.developpez.com/tutoriels/zend-framework/presentation/"> Premier pas avec le ZF</a> .</p>
<h3>Considérons l&#8217;arborescence suivante :</h3>
<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">/</span>application<span class="sy0">/</span><br />
&nbsp; Lab<span class="sy0">/</span><br />
&nbsp; &nbsp; controllers<span class="sy0">/</span><br />
&nbsp; &nbsp; &nbsp; LabController.php<br />
&nbsp; &nbsp; views<span class="sy0">/</span><br />
&nbsp; &nbsp; &nbsp; scripts<span class="sy0">/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; lab<span class="sy0">/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;xoad.phtml<br />
&nbsp; &nbsp; Xoad.php<br />
<span class="sy0">/</span>deploy<span class="sy0">/</span><br />
&nbsp; index.php <span class="br0">&#40;</span>bootstrap<span class="br0">&#41;</span><br />
<span class="sy0">/</span>lib<span class="sy0">/</span><br />
&nbsp; Zend<span class="sy0">/</span><br />
&nbsp; xoad<span class="sy0">/</span></div></div>
<p>Vous pouvez télécharger la librairie XOAD  <a href="http://sourceforge.net/projects/xoad">ici</a>. <br />
Nous allons créer une vue qui va nous permettre d&#8217;afficher le traditionnel &#8220;Hello world&#8221; lors du clique sur un bouton.</p>
<h3>xoad.phtml</h3>
<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 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.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/title.html"><span class="kw2">title</span></a>&gt;</span>Zend <span class="sc1">&amp; XOAD tutorial&lt;/title&gt;</span><br />
<span class="sc1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;application/xhtml+xml;</span> charset=utf-8&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/base.html"><span class="kw2">base</span></a> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;http://localhost/earl/deploy/&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> <span class="kw3">src</span><span class="sy0">=</span><span class="st0">&quot;public/lab/xoad_optimized.js&quot;</span>&gt;&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; &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><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var Lab_Xoad = <span class="sc2">&lt;?php echo $this-&gt;</span>jsObject ?&gt;;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <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 />
<span class="sc2">&lt;<a href="http://december.com/html/4/element/body.html"><span class="kw2">body</span></a>&gt;</span><br />
<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;button&quot;</span> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;hello-world&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;Hello World !&quot;</span>&gt;</span><br />
<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><br />
document.getElementById('hello-world').onclick = function ()<br />
{<br />
&nbsp; &nbsp; alert(Lab_Xoad.test());<br />
};<br />
<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 />
<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 cette vue, rien d&#8217;extraordinaire :<br />
- inclusion de la librairie javascript xoad (optimisée)<br />
- affichage de l&#8217;objet javascript généré côté serveur  et passé à la vue.</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:540px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace">var Lab_Xoad = <span class="kw2">&lt;?php</span> <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">jsObject</span> <span class="sy1">?&gt;</span>;</div></div>
<p>- ajout d&#8217;un évènement sur le onclick d&#8217;un bouton qui va nous permettre d&#8217;afficher la réponse générée par xoad.</p>
<h3>LabController.php</h3>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:540px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">&lt;?php</span><br />
<span class="kw2">class</span> Lab_LabController <span class="kw2">extends</span> Zend_Controller_Action <br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; &nbsp;* Specific view<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @var Zend_view<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">private</span> <span class="re0">$_view</span> <span class="sy0">=</span> <span class="kw2">null</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; &nbsp;* Init zend view.<br />
&nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp;* @return void <br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> init<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span>_view &nbsp;<span class="sy0">=</span> <span class="kw2">new</span> Zend_View<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span>_view<span class="sy0">-&gt;</span><span class="me1">setScriptPath</span><span class="br0">&#40;</span><a href="http://www.php.net/dirname"><span class="kw3">dirname</span></a><span class="br0">&#40;</span><a href="http://www.php.net/dirname"><span class="kw3">dirname</span></a><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &nbsp;<span class="sy0">.</span> <span class="st_h">'/views/scripts/'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; &nbsp;* Xoad tutorial action.<br />
&nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp;* @return void<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> xoadAction<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Zend_Loader<span class="sy0">::</span><span class="me2">loadClass</span><span class="br0">&#40;</span><span class="st_h">'Lab_Xoad'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/define"><span class="kw3">define</span></a><span class="br0">&#40;</span><span class="st_h">'XOAD_AUTOHANDLE'</span><span class="sy0">,</span> <span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">require_once</span> <span class="st_h">'xoad/xoad.php'</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span>_view<span class="sy0">-&gt;</span><span class="me1">jsObject</span> <span class="sy0">=</span> XOAD_Client<span class="sy0">::</span><span class="me2">register</span><span class="br0">&#40;</span><span class="kw2">new</span> Lab_Xoad<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span><span class="st_h">'lab/lab/xoad'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Render content</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$this</span><span class="sy0">-&gt;</span>_view<span class="sy0">-&gt;</span><span class="me1">render</span><span class="br0">&#40;</span><span class="st_h">'lab/xoad.phtml'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></div>
<p>Ce controller va nous permettre d&#8217;effectuer le rendu de notre vue décrite plus haut.<br />
La méthode init nous permet de créer une vue personnalisée.<br />
La méthode xoadAction va permettre à Xoad d&#8217;interagir avec le Zend Framework.<br />
<strong>Particularités</strong> :<br />
- On force le chargement de la class Lab_Xoad avec le Zend_Loader.<br />
- On inclut la librairie xoad (située dans le repertoire lib)<br />
- On génère l&#8217;objet javascript à partir de la méthode statique &#8220;register&#8221; en lui passant en premier paramètre la classe et en second l&#8217;url de callback utilisée par xoad <br />
- Le fait de définir à true la constante XOAD_AUTOHANDLE permet à xoad de déterminer si l&#8217;action du controller a été appelé lors d&#8217;une requête ajax ou non, dans le cas d&#8217;une requête Ajax le script s&#8217;arrête après le require_once de la librairie xoad, le format de retour est alors du json qui servira comme outil de communication à notre objet js. </p>
<h3>Xoad.php</h3>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:540px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">&lt;?php</span><br />
<span class="kw2">class</span> Lab_Xoad<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> test<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st_h">'Hello world !'</span><span class="sy0">;</span> &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></div>
<p>C&#8217;est là que ça commence à devenir interessant !<br /> <br />
En effet, cette class va pouvoir être utilisée directement en javascript sans avoir à le modifier.<br />
Toutes ses méthodes et ses attributs sont directement disponibles en javascript.<br />
<strong>Vous n&#8217;avez plus à vous soucier d&#8217;écrire le code Javascript qui va se charger d&#8217;effectuer des requêtes Ajax et d&#8217;en traiter le retour.</strong><br />
Exemple, dans notre vue nous appelons directement la méthode suivante :</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="kw3">alert</span><span class="br0">&#40;</span>Lab_Xoad.<span class="me1">test</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></div>
<p>Cet appel Javascript va nous retourner &#8220;Hello World&#8221;, les aller-retours serveur nécessaires vont se faire en backend.</p>
<p>Alors convaincu ?</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/01/xoad-et-le-zend-framework/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Eval is evil !</title>
		<link>http://labs.pimsworld.org/2009/01/eval-is-evil/</link>
		<comments>http://labs.pimsworld.org/2009/01/eval-is-evil/#comments</comments>
		<pubDate>Fri, 23 Jan 2009 16:44:12 +0000</pubDate>
		<dc:creator>cponcin</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=215</guid>
		<description><![CDATA[Si vous utilisez le vérificateur de javascript JSLint, vous avez certainement eu le message d&#8217;erreur  eval is evil.
Pour contourner le problème utilisez plutôt le code suivant
window[function]
au lieu de
eval(function)
plus d&#8217;erreur et le code est plus sûr.
]]></description>
			<content:encoded><![CDATA[<p>Si vous utilisez le vérificateur de javascript JSLint, vous avez certainement eu le message d&#8217;erreur  <em>eval is evil</em>.</p>
<p>Pour contourner le problème utilisez plutôt le code suivant</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">window[function]</div></div>
<p>au lieu de</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">eval(function)</div></div>
<p>plus d&#8217;erreur et le code est plus sûr.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/01/eval-is-evil/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tests unitaires avec Zend Studio</title>
		<link>http://labs.pimsworld.org/2009/01/tests-unitaires-avec-zend-studio/</link>
		<comments>http://labs.pimsworld.org/2009/01/tests-unitaires-avec-zend-studio/#comments</comments>
		<pubDate>Mon, 19 Jan 2009 18:09:02 +0000</pubDate>
		<dc:creator>Kal</dc:creator>
		
		<category><![CDATA[Open Source]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Tests Unitaires]]></category>

		<category><![CDATA[Tutoriels]]></category>

		<category><![CDATA[PHPUnit]]></category>

		<category><![CDATA[tests unitaires]]></category>

		<category><![CDATA[Zend Studio]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=10</guid>
		<description><![CDATA[Si vous êtes persuadés de l'intérêt des tests unitaires pour vos développements PHP mais que vous n'avez jamais osé franchir le pas, ce tutoriel est fait pour vous. Afin de migrer en douceur vers les préceptes sacrés de l'eXtreme Programming je vous propose un exemple concret de mise en place des tests unitaires sous l'environnement Zend Studio.]]></description>
			<content:encoded><![CDATA[<p>Si vous êtes persuadés de l&#8217;intérêt des tests unitaires pour vos développements PHP mais que vous n&#8217;avez jamais osé franchir le pas, ce tutoriel est fait pour vous. Afin de migrer en douceur vers les préceptes sacrés de l&#8217;eXtreme Programming je vous propose un exemple concret de mise en place des tests unitaires sous l&#8217;environnement Zend Studio.</p>
<p><span id="more-10"></span></p>
<p>Pour ce faire, nous allons implémenter une bonne vieille <strong>pile LIFO</strong> en PHP.</p>
<p>Après avoir crée un projet avec Zend Studio et une classe <strong>Unit_Stack</strong>, on commence par écrire le squelette de cette classe :</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:540px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co4">/**<br />
* A LIFO Stack<br />
*/</span><br />
<span class="kw2">class</span> Unit_Stack<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; * Push an item.<br />
&nbsp; &nbsp; *<br />
&nbsp; &nbsp; * @param mixed $item<br />
&nbsp; &nbsp; *<br />
&nbsp; &nbsp; * @return void<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> push<span class="br0">&#40;</span><span class="re0">$item</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; * Pop an item.<br />
&nbsp; &nbsp; *<br />
&nbsp; &nbsp; * @return mixed<br />
&nbsp; &nbsp; * @throws Exception if stack is empty.<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> pop<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; * Count items of stack.<br />
&nbsp; &nbsp; *<br />
&nbsp; &nbsp; * @return int<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; * Tells if stack is empty.<br />
&nbsp; &nbsp; *<br />
&nbsp; &nbsp; * @return boolean<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> isEmpty<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; * Removes all items of stack.<br />
&nbsp; &nbsp; *<br />
&nbsp; &nbsp; * @return void<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> <a href="http://www.php.net/reset"><span class="kw3">reset</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></div>
<p>Les commentaires devraient suffire à expliquer ce qu&#8217;est sensée faire cette classe.</p>
<p>L&#8217;étape suivante consiste à créer la classe de tests unitaires ou <strong>Test Case</strong>. Dans l&#8217;arborescence <em>tests/unit/Unit/</em>, faire click droit puis <strong>new -&gt; PHPUnit Test Case</strong>.</p>
<p>Il suffit alors de choisir la classe à tester via le bouton <strong>Browse</strong> en face de<strong> &#8216;Element to Test&#8217;</strong>, puis de corriger le nom de la classe de Test générée dans le champ <strong>&#8216;Test File Name&#8217;</strong> en virant le préfixe Unit_&#8217;. Cela devrait ressembler à ça :</p>
<div id="attachment_143" class="wp-caption aligncenter" style="width: 532px"><img class="size-full wp-image-143" src="http://labs.pimsworld.org/wp-content/uploads/2009/01/unit1.png" alt="Création d'un Test Case" width="522" height="497" /><p class="wp-caption-text">Création d&#39;un Test Case</p></div>
<p>Le <strong>Test Case</strong> généré devrait comprendre :</p>
<ul>
<li>une méthode setUp : lancée avant chaque test.</li>
<li>une méthode tearDown : lancée après chaque test.</li>
<li>un constructeur : pas vraiment utile.</li>
<li>une méthode de test par méthode publique de la classe à tester.</li>
</ul>
<p>Dans le cadre de cet exemple, je vous invite à supprimer le constructeur ainsi que les méthodes setUp et tearDown.</p>
<p>Nous rentrons maintenant dans le vif du sujet, il s&#8217;agit :</p>
<ol>
<li>d&#8217;écrire un test</li>
<li>de lancer le Test Case afin de vérifier (oh surprise) qu&#8217;il échoue</li>
<li>d&#8217;implémenter la fonctionnalité</li>
<li>de relancer le test et éventuellement corriger jusqu&#8217;à ce que le test passe !</li>
</ol>
<h2>Écriture du test</h2>
<p>Nous proposons pour la méthode <strong>isEmpty</strong> l&#8217;écriture du test suivant :</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:540px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">public</span> <span class="kw2">function</span> testIsEmpty <span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$stack</span> <span class="sy0">=</span> <span class="kw2">new</span> Unit_Stack<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="co1">// a new stack is empty !</span><br />
&nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">assertTrue</span><span class="br0">&#40;</span><span class="re0">$stack</span><span class="sy0">-&gt;</span><span class="me1">isEmpty</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div></div>
<h2>Lancer le Test Case</h2>
<p>Il suffit d&#8217;un click droit sur le fichier du <strong>Test Case</strong> puis de choisir <strong>Run as -&gt; PHPUnit Test</strong></p>
<p>Si tout se passe bien, le test devrait apparaître en erreur et les autres en non implémentés.</p>
<h2>
<p><div id="attachment_146" class="wp-caption aligncenter" style="width: 458px"><img class="size-full wp-image-146" src="http://labs.pimsworld.org/wp-content/uploads/2009/01/unit11.png" alt="Résultats test case" width="448" height="173" /><p class="wp-caption-text">Résultats test case</p></div></h2>
<h2>Implémenter la fonctionnalité</h2>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:540px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">public</span> <span class="kw2">function</span> isEmpty<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <a href="http://www.php.net/empty"><span class="kw3">empty</span></a><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span>_array<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div></div>
<p>Trop facile &#8230;</p>
<h2>Relancer le test et corriger</h2>
<p>Même procédure que le lancement précédent, cette fois le test devrait apparaître comme réussi.</p>
<h2>Ensuite&#8230;.</h2>
<p>Il suffit de refaire la même procédure itérativement pour chaque fonctionnalité. A mesure que les nouvelles fonctionnalités sont implémentées, de nouveaux tests peuvent être écrits en plus de ceux générés par Zend Studio. Il suffit de créer une méthode publique dont le nom commence par <strong>test</strong>.</p>
<p>Si votre application contient plusieurs classes et donc plusieurs Test Case (ce qui est souvent le cas !), il peut être fastidieux de lancer les tests cases un par un, il est alors intéressant d&#8217;utiliser les <strong>Tests Suites</strong>. Il suffit de faire un click droit dans Zend studio sur le répertoire <em>test/unit/</em> puis <strong>New -&gt; PHPUnit Test Suite</strong>.</p>
<p>On sélectionne alors les Tests Case à lancer puis finish. Une Suite se lance alors de le même façon qu&#8217;un Test Case.</p>
<p>Liens :</p>
<ul>
<li>Les sources de <a href="http://labs.pimsworld.org/download/test.zip" target="_blank">l&#8217;exemple</a></li>
<li>Le site de <a href="http://www.phpunit.de/" target="_blank">PhpUnit </a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/01/tests-unitaires-avec-zend-studio/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Deobfuscateur JavaScript pour Firefox</title>
		<link>http://labs.pimsworld.org/2009/01/deobfuscateur-javascript-pour-firefox/</link>
		<comments>http://labs.pimsworld.org/2009/01/deobfuscateur-javascript-pour-firefox/#comments</comments>
		<pubDate>Mon, 19 Jan 2009 10:01:51 +0000</pubDate>
		<dc:creator>Stéphane Roucheray</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[extension]]></category>

		<category><![CDATA[Firefox]]></category>

		<category><![CDATA[obfuscator]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=129</guid>
		<description><![CDATA[Le développeur de l&#8217;extension Adblock Plus pour Firefox vient de créer une extension permettant d&#8217;améliorer la lisibilité des codes JavaScript obfusqués. L&#8217;obfuscation consiste à protéger du code en le rendant particulièrement illisible par un être humain. Beaucoup de sites utilisent cette technique simplement pour réduire la taille de leur code et en accélérer le téléchargement [...]]]></description>
			<content:encoded><![CDATA[<p>Le développeur de l&#8217;extension Adblock Plus pour Firefox vient de créer une extension permettant d&#8217;améliorer la lisibilité des codes JavaScript obfusqués. L&#8217;<a href="http://fr.wikipedia.org/wiki/Obfuscation">obfuscation</a> consiste à protéger du code en le rendant particulièrement illisible par un être humain. Beaucoup de sites utilisent cette technique simplement pour réduire la taille de leur code et en accélérer le téléchargement (mauvaise pratique ceci étant dit).</p>
<p>L&#8217;extension est pour l&#8217;instant disponible dans le bac à sable du dépôt des extensions Firefox, il faut s&#8217;y connecter pour la <a href="https://addons.mozilla.org/fr/firefox/addon/10345">télécharger</a>. Une fois installée et activée elle inscrit dans le log du debogueur JavaScript le code obfusqué qu&#8217;elle trouve en le deobfusquant. Le code deobfusqué n&#8217;est évidemment pas identique au code d&#8217;origine mais ceci permet au moins de l&#8217;éclaircir. </p>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/01/deobfuscateur-javascript-pour-firefox/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
