<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>exGobz &#187; Développement Web</title>
	<atom:link href="http://exgobz.com/article-category/Programmation/Developpement-Web/feed" rel="self" type="application/rss+xml" />
	<link>http://exgobz.com</link>
	<description>Anciens de Gobelins</description>
	<lastBuildDate>Mon, 21 Sep 2009 19:41:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Remplacer des adresses web dans un texte par des liens HTML</title>
		<link>http://exgobz.com/article-195</link>
		<comments>http://exgobz.com/article-195#comments</comments>
		<pubDate>Wed, 23 May 2007 13:02:15 +0000</pubDate>
		<dc:creator>Nicolas MASSART</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Plus pratique, plus rapide et bien plus simple que les éventuelles solutions classiques de test et de remplacement, les expressions régulières, popularisées par le langage Perl, sont la solution idéale pour vos manipulations de texte.  Voici un exemple d&#8217;utilisation d&#8217;expression régulière pour remplacer toutes les URL dans un texte par un lien correctement formé.

]]></description>
			<content:encoded><![CDATA[<p>Plus pratique, plus rapide et bien plus simple que les éventuelles solutions classiques de test et de remplacement, les expressions régulières, popularisées par le langage Perl, sont la solution idéale pour vos manipulations de texte.  Voici un exemple d&#8217;utilisation d&#8217;<a href="http://exgobz.com/article-178">expression régulière</a> pour remplacer toutes les URL dans un texte par un lien correctement formé.</p>
<p><span id="more-195"></span></p>
<p><code><?php<br />
/* la chaine de caractère dans laquelle on doit<br />
* faire le remplacement.<br />
*/<br />
$stringToReplaceIn = "
<p>Bonjour ceci est un test<br />
	avec une url http://www.exgobz.com et encore deux<br />
	autres séparées par un retour ligne<br />
	http://www.exgobz.com/article-178nhttp://www.exgobz.com/article-195</p>
<p>";</p>
<p>/* le motif à rechercher. Ici une URL.<br />
* l'expression est simplifiée pour pour considérer que l'URL<br />
* est tout ce qui est après http:// et qui se termine par un<br />
* espace ou autre caractère "blanc" tel qu'un retour ligne.<br />
* Elle est donc plus simple que l'expression que nous avons<br />
* déjà présenté pour valider une URL.<br />
*/<br />
$searchPattern = '/(http://[^s<>]+)/i';</p>
<p>/* le motif à utiliser en remplacement de<br />
* ceux trouvés grace au motif précédent.<br />
* Notez l'utilisation de "références arrières"<br />
* (back-references) avec le $1.<br />
*/<br />
$replacemenPattern = '<a href="$1">$1</a>';<br />
/* affichage du résultat.*/<br />
echo preg_replace ( $searchPattern, $replacemenPattern, $stringToReplaceIn );<br />
?></code></p>
<p>le resultat final sera le code HTML suivant :<br />
<code></p>
<p>Bonjour ceci est un test<br />
	avec une url <a href="http://www.exgobz.com">http://www.exgobz.com</a> et encore deux<br />
	autres séparées par un retour ligne<br />
	<a href="http://www.exgobz.com/article-178">http://www.exgobz.com/article-178</a><br />
<a href="http://www.exgobz.com/article-195">http://www.exgobz.com/article-195</a></p>
<p></code></p>
<p>Mon exemple est ici fait avec une seule chaine de caractère pour plus de simplicité. Mais en lisant la doc PHP vous constaterez que cette fonction accepte aussi des tableaux de valeurs en entrée, et sors des tableaux en retour. Cela vous permettra de faire des remplacement dans plusieurs chaines d&#8217;un seul coup.</p>
<p>La fonction PHP preg_replace : http://fr.php.net/manual/en/function.preg-replace.php</p>
<p>Syntaxe des motifs en PHP : http://fr.php.net/manual/en/reference.pcre.pattern.syntax.php</p>
]]></content:encoded>
			<wfw:commentRss>http://exgobz.com/article-195/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Les adresses mail avec un plus</title>
		<link>http://exgobz.com/article-193</link>
		<comments>http://exgobz.com/article-193#comments</comments>
		<pubDate>Wed, 04 Apr 2007 11:27:58 +0000</pubDate>
		<dc:creator>Nicolas MASSART</dc:creator>
				<category><![CDATA[Développement Web]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Description d&#8217;une technique anti-spam, le &#171;&#160;plus-addressing&#160;&#187;, qui a malheureusement ses limites car la plupart des sites Web ne respectent pas complètement les normes.
Vous connaissez probablement la fonctionnalité appelée &#171;&#160;[plus-addressing->http://en.wikipedia.org/wiki/E-mail_address#Plus_.28or_Minus.29_addressing]&#171;&#160;[[Il existe aussi le minus-addressing, qui utilise le signe moins, principalement utilisé avec le serveur mail Qmail]] qui consiste à ajouter un signe plus &#171;&#160;+&#160;&#187; à la [...]]]></description>
			<content:encoded><![CDATA[<p>Description d&#8217;une technique anti-spam, le &laquo;&nbsp;plus-addressing&nbsp;&raquo;, qui a malheureusement ses limites car la plupart des sites Web ne respectent pas complètement les normes.<br />
Vous connaissez probablement la fonctionnalité appelée &laquo;&nbsp;[plus-addressing->http://en.wikipedia.org/wiki/E-mail_address#Plus_.28or_Minus.29_addressing]&laquo;&nbsp;[[Il existe aussi le minus-addressing, qui utilise le signe moins, principalement utilisé avec le serveur mail Qmail]] qui consiste à ajouter un signe plus &laquo;&nbsp;+&nbsp;&raquo; à la suite de votre identifiant, juste avant l&#8217;arrobas, dans votre adresse email. Elle a été popularisé par [Google->http://www.google.com/] avec ses comptes [gmail->http://mail.google.com/].<br />
Par exemple, si vous avez une adresse toto@gmail.com, vous pouvez aussi utiliser toutes les variantes du type toto+[un truc]@gmail.com car les messages arriveront dans votre boite toto@gmail.com.</p>
<p><span id="more-193"></span></p>
<h3>Pour quoi faire ?</h3>
<p>Quel intérêt me direz vous ?<br />
Tout simple, cela permet de filtrer vos messages très facilement sans avoir à créer une nouvelle adresse dès que vous désirez vous inscrire sur un site.</p>
<p>Par exemple, pour vous inscrire sur eXgobz, entrez simplement votre adresse toto+exgobz@gmail.com. Ainsi il vous sera facile de créer un filtre sur tous les messages provenant d&#8217;exgobz. Cerise sur le gâteau, si exgobz revend illégalement votre adresse à trucmuche, et que vous recevez un spam de trucmuch chez qui vous ne vous êtes jamais volontairement inscrit, le coupable de la fraude sera vite découvert puisque l&#8217;adresse à laquelle vous aurez reçu le mail de trucmuche sera toto+exgobz@gmail.com.</p>
<h3>Quand plus rien ne marche et que ça fait ch***</h3>
<p>Bref, que du bonheur, sauf que, bien que le caractère plus soit autorisé dans les adresses email par la [RFC 2822->http://tools.ietf.org/html/rfc2822][[Chapitre 3.4 : [Address Specification->http://tools.ietf.org/html/rfc2822#section-3.4] ]] qui spécifie l&#8217;utilisation des mails, il arrive fréquemment que vous ne puissiez pas utiliser cette syntaxe.</p>
<p>Si vous l&#8217;utilisez, vous avez en effet probablement constaté que de nombreux sites ont du mal avec ce signe plus.</p>
<p>Il y a ceux qui vérifient la validité des adresses email entrées dans leurs formulaires et qui interdisent le signe plus. On n&#8217;y peut pas grand chose, à part faire un message au webmestre pour lui indiquer l&#8217;URL de la RFC et lui dire que, du coup, on ne s&#8217;inscrira pas sur son site pourri.</p>
<p>Mais il y a aussi ceux qui l&#8217;acceptent et vous plantent plus loin.</p>
<p>Prenez par exemple une inscription à des alertes de cours de bourse sur un site[[pas de noms, désolé, je ne peux pas me le permettre, c'est un client]], vous devez saisir votre email pour être prévenu de l&#8217;évolution des cours de certaines valeurs et vous saisissez votre adresse avec la syntaxe plus.<br />
Ensuite, le site vous envoie un message de confirmation par mail avec une URL à cliquer pour valider votre inscription. Et là l&#8217;url est par exemple<br />
http://www.monsite-de-bourse-en-ligne.com/confirmation.php?email=toto+bourse@gmail.com</p>
<p>Jamais vous ne pourrez confirmer. En effet, le signe plus de votre email sera considéré comme un espace dans ce contexte d&#8217;url.</p>
<p>Pour contourner ce problème, remplacez manuellement le + par son équivalent échappé &laquo;&nbsp;%2B&nbsp;&raquo;, ce qui vous donnera http://www.monsite-de-bourse-en-ligne.com/confirmation.php?email=toto%2Bbourse@gmail.com</p>
<p>{{{Comment résoudre le problème ?}}}<br />
Si vous êtes webmestre et que vous gérez un site qui pose ce genre de problème, vous voudrez probablement le résoudre, enfin j&#8217;espère.</p>
<p>Pour cela, rien de plus simple. Tout est dans le mécanisme de vérification de votre mail.</p>
<p>Si vous utilisez un CMS[[Content management system, système de gestion de contenu]] ou d&#8217;une utilisation de librairies qui ne vérifient pas correctement les emails, il est probable que celle-ci ait une librairie spécifique à la vérification que vous pouvez modifier dans le cas d&#8217;un open-source.</p>
<p>Dans le cas d&#8217;un CMS propriétaire à code source fermé, ou que vous ne désirez pas modifier, remontez ce bug &#8211; car c&#8217;en est bien un &#8211; à son éditeur ou à la communauté.</p>
<p>Dans le cas d&#8217;un site développé intégralement par vous même, je vous conseille de faire vos vérifications en utilisant des [expressions régulières->178] plutôt que des structures IF&#8230;ELSE&#8230; imbriquées.<br />
Vous pourrez modifier les règles de vérifications sans avoir à modifier la logique de votre code.<br />
Une modification de la chaine de l&#8217;expression régulière suffit.<br />
De plus vous trouverez sur le Web, des expressions régulières déjà faites[[Par exemple [http://regexlib.com/default.aspx] mais cherchez &laquo;&nbsp;regular expression&nbsp;&raquo; sur [un moteur de recherche->http://www.google.com/search?q=regular+expression] ou dans [wikipedia->http://en.wikipedia.org/wiki/Regular_expression] et vous trouverez probablement votre bonheur.]] pour de nombreux types de données, ce qui vous facilitera la vie.</p>
<p>Enfin, pour notre problème d&#8217;URL invalide dans le mail de confirmation, il y a une solution toute simple : systématiquement encoder les paramètres de l&#8217;URL avec une fonction telle que [urlencode()->http://fr2.php.net/manual/en/function.urlencode.php] en [php->http://php.net/] qui vous donnera alors une URL de la former suivante : http://www.monsite-de-bourse-en-ligne.com/confirmation.php%3Femail%3Dtoto%2Bbourse%40gmail.com<br />
Certes, c&#8217;est moins joli côté paramètres, mais au moins vous avez l&#8217;assurance que votre URL fonctionnera.</p>
<p>Notez que je propose l&#8217;encodage des paramètres uniquement et non de l&#8217;URL entière pour des raisons de lisibilité pour le destinataire du mail. Si on encode la partie &laquo;&nbsp;domaine&nbsp;&raquo; de l&#8217;URL comme cela : http%3A%2F%2Fwww.monsite-de-bourse-en-ligne.com%2Fconfirmation.php%3Femail%3Dtoto%2Bbourse%40gmail.com , l&#8217;utilisateur risque de ne pas reconnaitre le site ni le protocole et d&#8217;avoir peur que ce soit une sorte de [hammeçonnage->http://fr.wikipedia.org/wiki/Hame%C3%A7onnage][[Fishing]] (je pars du principe utopique que les utilisateurs sont de plus en plus sensibles à ces sujets, mais c&#8217;est une autre discussion). De plus, la partie &laquo;&nbsp;domaine&nbsp;&raquo; est une partie prévisible, c&#8217;est vous qui la définissez contrairement aux paramètres saisis par l&#8217;internaute. Il est donc peu probable qu&#8217;elle contienne des caractères problématiques. C&#8217;est en tout cas à vous d&#8217;y faire attention.</p>
]]></content:encoded>
			<wfw:commentRss>http://exgobz.com/article-193/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Codes de réponse HTTP</title>
		<link>http://exgobz.com/article-16</link>
		<comments>http://exgobz.com/article-16#comments</comments>
		<pubDate>Wed, 09 Nov 2005 08:46:00 +0000</pubDate>
		<dc:creator>Fred Bird</dc:creator>
				<category><![CDATA[Développement Web]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[  &#124; {{code}} &#124; {{signification}} &#124;
&#124; 100 &#124; Continue &#124;
&#124; 101 &#124; Switching Protocols &#124;
&#124; 200 &#124; OK &#124;
&#124; 201 &#124; Created &#124;
&#124; 202 &#124; Accepted &#124;
&#124; 203 &#124; Non-Authoritative Information &#124;
&#124; 204 &#124; No Content &#124;
&#124; 205 &#124; Reset Content &#124;
&#124; 206 &#124; Partial Content &#124;
&#124; 300 &#124; Multiple Choices &#124;
&#124; 301 &#124; [...]]]></description>
			<content:encoded><![CDATA[<p> <!-- more --> | {{code}} | {{signification}} |<br />
| 100 | Continue |<br />
| 101 | Switching Protocols |<br />
| 200 | OK |<br />
| 201 | Created |<br />
| 202 | Accepted |<br />
| 203 | Non-Authoritative Information |<br />
| 204 | No Content |<br />
| 205 | Reset Content |<br />
| 206 | Partial Content |<br />
| 300 | Multiple Choices |<br />
| 301 | Moved Permanently |<br />
| 302 | Found |<br />
| 303 | See Other |<br />
| 304 | Not Modified |<br />
| 305 | Use Proxy |<br />
| 307 | Temporary Redirect |<br />
| 400 | Bad Request |<br />
| 401 | Unauthorized |<br />
| 402 | Payment Required |<br />
| 403 | Forbidden |<br />
| 404 | Not Found |<br />
| 405 | Method Not Allowed |<br />
| 406 | Not Acceptable |<br />
| 407 | Proxy Authentication Required |<br />
| 408 | Request Time-out |<br />
| 409 | Conflict |<br />
| 410 | Gone |<br />
| 411 | Length Required |<br />
| 412 | Precondition Failed |<br />
| 413 | Request Entity Too Large |<br />
| 414 | Request-URI Too Large |<br />
| 415 | Unsupported Media Type |<br />
| 416 | Requested range not satisfiable |<br />
| 417 | Expectation Failed |<br />
| 500 | Internal Server Error |<br />
| 501 | Not Implemented |<br />
| 502 | Bad Gateway |<br />
| 503 | Service Unavailable |<br />
| 504 | Gateway Time-out |<br />
| 505 | HTTP Version not supported |</p>
]]></content:encoded>
			<wfw:commentRss>http://exgobz.com/article-16/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Boutons pour textarea</title>
		<link>http://exgobz.com/article-3</link>
		<comments>http://exgobz.com/article-3#comments</comments>
		<pubDate>Fri, 30 Sep 2005 13:57:20 +0000</pubDate>
		<dc:creator>Fred Bird</dc:creator>
				<category><![CDATA[Développement Web]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[- extensible : ajouter une fonctionnalité supplémentaire se fait par l&#8217;ajout de méthode à un objet.
- configurable : la définition de boutons et de sets de boutons se fait via une variable globale.
- non intrusif : un simple appel du script suffit à appliquer les améliorations sur les textareas de la page en fonction de [...]]]></description>
			<content:encoded><![CDATA[<p>- extensible : ajouter une fonctionnalité supplémentaire se fait par l&#8217;ajout de méthode à un objet.<br />
- configurable : la définition de boutons et de sets de boutons se fait via une variable globale.<br />
- non intrusif : un simple appel du script suffit à appliquer les améliorations sur les textareas de la page en fonction de leur class. <!-- more --> {{{usage}}}<br />
- appeler le script via &lt;script&gt;, dans &lt;head&gt; ou &lt;body&gt;.<br />
- configurer le script via la variable <var>ENHANCETEXTAREAS_CLASSES_ENHANCERS</var>, un tableau de la forme &#8216;className&#8217; => liste de definitions de boutons associés. Les boutons se definissent par une chaine &#8216;label|methode|arg1|arg2|etc&#8217;.</p>
<p>Tout textarea ayant pour classe l&#8217;une des clefs du tableau <var>ENHANCETEXTAREAS_CLASSES_ENHANCERS</var> se verra pourvu des boutons qu&#8217;elle définit. Seule la première classe trouvée sera prise en compte.<br />
{{{principe}}}<br />
Ce script est orienté objet. Pour chaque textarea à améliorer est créé un objet {{textareaEnhancer}} disposant d&#8217;une référence interne à l&#8217;objet DOM pour sa manipulation. Ces objets sont référencés par l&#8217;{{id}} du textarea dans le tableau global <var>textareaEnhancers</var> Des objets buttonSet et buttonSetItem sont également créés, ainsi qu&#8217;un
<div> contenant les boutons juste avant le &lt;textarea&gt;.<br />
Les boutons se voient associés un evenement au clic, qui n&#8217;est autre que l&#8217;appel d&#8217;une methode de l&#8217;objet textareaEnhancer via le tableau <var>textareaEnhancers</var>.<br />
Ce script nécessite la création d&#8217;attributs id automatiques aux textareas qui n&#8217;en seraient pas pourvus.<br />
{{{méthodes disponibles}}}<br />
- {{tagSelection}}(string <var>before</var>, string <var>after</var>): ajoute les arguments autour du texte selectionné.<br />
- {{htmlTag}}(string <var>tagName</var>, [string <var>attributeName</var>, string <var>attributeValue</var>, string <var>askMessage</var>]&#8230;) : ajoute une balise html autour du texte selectionné. Au dela du premier, des triplets d&#8217;arguments sont attendus<br />
- {{undoContentChange}}(void) : annule le dernier changement de contenu via newcontent<br />
- {{newContent}}(string <var>content</var>): modifie le contenu du textarea<br />
- {{swapView}}(void) : masque/affiche le textarea<br />
{{{extensions potentielles}}}<br />
- nettoyage du contenu via des expressions régulieres (suppression des balises)<br />
- previsualisation du contenu en mode html (ce qui nécessite de construire un sous-arbre DOM a partir d&#8217;un noeud texte)<br />
- verification orthographique<br />
- etc<br />
{{{code source}}}<br />
<code>/*<br />
enhances textareas with buttons to tag their contents<br />
creates 1 js textareaEnhancer object per textarea<br />
*/</p>
<p>/* objects and methods<br />
*/</p>
<p>// button constructor<br />
function buttonSetItem(buttonSet,buttonDef) {<br />
	// referencing parent objects<br />
	this.buttonSet=buttonSet;<br />
	this.textareaEnhancer=this.buttonSet.textareaEnhancer;<br />
	// methods<br />
	this.setLabel=buttonSetItem_setLabel;<br />
	this.setBehavior=buttonSetItem_setBehavior;<br />
	// creating HTML DOM button<br />
	this.dom=document.createElement('input');<br />
	this.dom.setAttribute('type','button');<br />
	// referencing self in DOM object<br />
	this.dom.enhancer=this;<br />
	// parsing def<br />
	var def=buttonDef.split('|');<br />
	var label=def.shift();<br />
	var textareaEnhancerMethod=def.shift();<br />
	var args=def;<br />
	// autosetting<br />
	this.setLabel(label);<br />
	this.setBehavior(textareaEnhancerMethod,args);</p>
<p>}</p>
<p>function buttonSetItem_setLabel(label) {<br />
	return this.dom.setAttribute('value',label);<br />
}</p>
<p>function buttonSetItem_setBehavior(textareaEnhancerMethod,args) {<br />
	var id=this.buttonSet.textareaEnhancer.id;<br />
	eval("var behavior=function() { return textareaEnhancers['"+id+"']."+textareaEnhancerMethod+"('"+args.join("','")+"');}");</p>
<p>	this.dom.onclick=behavior;<br />
	return true;<br />
}</p>
<p>// buttonSet constructor<br />
function buttonSet(textareaEnhancer,bSetDef) {<br />
	// referencing parent object<br />
	this.textareaEnhancer=textareaEnhancer;<br />
	containerElement='div';<br />
	// creating HTML DOM button set<br />
	this.dom=document.createElement(containerElement);<br />
	this.dom.setAttribute('class','button-set');<br />
	// creating and appending buttons<br />
	this.buttons=new Array();<br />
	for (var i=0; i<bSetDef.length; i++) {<br />
		bDef=bSetDef[i];<br />
		// alert(bDef['label']);<br />
		// button=textareaCreateButton(textarea,bDef);<br />
		var bt=new buttonSetItem(this,bDef);<br />
		this.buttons[i]=bt;<br />
		// appending button dom to self dom<br />
		this.dom.appendChild(bt.dom);<br />
	}<br />
	// alert('created buttonSet for textarea '+this.textareaEnhancer.id);<br />
}</p>
<p>// textareaEnhancer constructor<br />
function textareaEnhancer(textarea_ref, buttonSetDef) {<br />
	// properties<br />
	this.dom=textarea_ref;<br />
	this.id=textarea_ref.id;<br />
	// previous content array for undos<br />
	this.previousContents=new Array;<br />
	// show|preview|hide<br />
	this.view='show';<br />
	// methods<br />
	this.newContent=textareaEnhancer_newContent;<br />
	// action methods<br />
	this.tagSelection=textareaEnhancer_tagSelection;<br />
	this.undoContentChange=textareaEnhancer_undoContentChange;<br />
	this.swapView=textareaEnhancer_swapView;<br />
	this.htmlTag=textareaEnhancer_htmlTag;<br />
	this.insererLien=textareaEnhancer_insererLien;<br />
	// creating button set<br />
	this.buttonSet=new buttonSet(this,buttonSetDef);<br />
	// this.buttonSet.textareaEnhancer=this;<br />
	// appending button set dom to self dom<br />
	this.dom.parentNode.insertBefore(this.buttonSet.dom,this.dom);<br />
}</p>
<p>function textareaEnhancer_newContent(content) {<br />
	this.previousContents.push(this.dom.value);<br />
	this.dom.value=content;<br />
}</p>
<p>/* methodes "actions" des boutons<br />
*/</p>
<p>function textareaEnhancer_tagSelection(before,after) {<br />
	//var before=args[0];<br />
	//var after=args[1];<br />
	var txtarea=this.dom;<br />
	var selLength = txtarea.textLength;<br />
	var selStart = txtarea.selectionStart;<br />
	var selEnd = txtarea.selectionEnd;<br />
	if (selEnd == 1 || selEnd == 2)<br />
		selEnd = selLength;</p>
<p>	var s1 = (txtarea.value).substring(0,selStart);<br />
	var s2 = (txtarea.value).substring(selStart, selEnd)<br />
	var s3 = (txtarea.value).substring(selEnd, selLength);<br />
	//txtarea.value = s1 + before + s2 + after + s3;<br />
	this.newContent(s1 + before + s2 + after + s3);<br />
	return true;<br />
}<br />
// args : tagName [, attributeName, attributeValue, attributeAskMessage]*<br />
function textareaEnhancer_htmlTag(tagName) {<br />
	var attributes='';<br />
	for (var i=1; i<arguments.length; i++) {<br />
		// attributeName<br />
		attributeName=arguments[i]; i++;<br />
		attributeValue=arguments[i]?arguments[i]:''; i++;<br />
		askMessage=arguments[i]?arguments[i]:'';// i++;<br />
		if (askMessage)<br />
			attributeValue=window.prompt(askMessage,attributeValue);<br />
		if (attributeValue)<br />
			attributes=attributes+' '+attributeName+'="'+attributeValue+'"';<br />
	}<br />
	//alert(args);<br />
	var before='<'+tagName+attributes+'>';<br />
	var after='</'+tagName+'>';<br />
	return this.tagSelection(before,after);<br />
}</p>
<p>function textareaEnhancer_insererLien() {<br />
	var url=window.prompt('url ?','http://');<br />
	if (!url) return false;<br />
	var ext=window.confirm('Ouvrir dans une nouvelle fenetre ?');<br />
	var targ=ext?' target="_blank"':'';<br />
	var before='<a href="'+url+'"'+targ+'>';<br />
	var after='</a>';<br />
	return this.tagSelection(before,after);<br />
}</p>
<p>function textareaEnhancer_undoContentChange() {<br />
	if (this.previousContents.length>0) {<br />
		this.dom.value=this.previousContents.pop();<br />
		return true;<br />
	} else {<br />
		alert("dernier niveau d'annulation");<br />
		return false;<br />
	}<br />
}</p>
<p>function textareaEnhancer_swapView() {<br />
	switch(this.view) {<br />
		case 'show':<br />
			this.dom.setAttribute('style','display: none;');<br />
			this.view='hide';<br />
			break;<br />
		case 'hide':<br />
		default:<br />
			this.dom.setAttribute('style','display: block;');<br />
			this.view='show';<br />
			break;<br />
	}<br />
}</p>
<p>/*function textareaEnhancer_showPreview() {<br />
	if (!this.previewDiv) {<br />
		this.previewDiv=document.createElement('div');<br />
	}<br />
	this.previewValue=document.createTextNode(this.dom.value);<br />
	this.previewDiv.appendChild(this.previewValue);<br />
	this.dom.append<br />
}*/</p>
<p>/*function tagTextareaSelection(textareaId,textBefore,textAfter) {<br />
	alert(textareaId);<br />
	txtarea=document.getElementById(textareaId);<br />
	var selLength = txtarea.textLength;<br />
	var selStart = txtarea.selectionStart;<br />
	var selEnd = txtarea.selectionEnd;<br />
	if (selEnd == 1 || selEnd == 2)<br />
		selEnd = selLength;</p>
<p>	var s1 = (txtarea.value).substring(0,selStart);<br />
	var s2 = (txtarea.value).substring(selStart, selEnd)<br />
	var s3 = (txtarea.value).substring(selEnd, selLength);<br />
	txtarea.value = s1 + open + s2 + close + s3;<br />
	return true;<br />
}*/</p>
<p>/* generic functions required<br />
*/<br />
if (!window.autoIds) {<br />
	// auto id applying<br />
	function autoIds(tagName) {<br />
		tags=document.getElementsByTagName(tagName);<br />
		for (f=0; f<tags.length; f++) {<br />
			tag=tags[f];<br />
			if (!tag.id) {<br />
				newId=tagName+'_'+f;<br />
				//alert(newId);<br />
				tag.id=newId;<br />
			}<br />
		}<br />
	}<br />
}<br />
if (!window.hasClass) {<br />
	function hasClass(obj,cName) {<br />
		return new RegExp('\\b'+cName+'\\b').test(obj.className);<br />
	}<br />
}</p>
<p>// addEvent<br />
if (!window.addEvent) {<br />
	function addEvent(obj, evType, fn){<br />
		if (obj.addEventListener){<br />
			obj.addEventListener(evType, fn, false);<br />
			return true;<br />
		} else if (obj.attachEvent){<br />
			var r = obj.attachEvent("on"+evType, fn);<br />
			return r;<br />
		} else {<br />
			return false;<br />
		}<br />
	}<br />
}</p>
<p>/* applying script<br />
*/<br />
var textareaEnhancers=new Array();<br />
function summonTextareaEnhancers() {<br />
	// setting auto ids if necessary<br />
	autoIds('textarea');<br />
	// detecting all textareas<br />
	var textareas=document.getElementsByTagName('textarea');<br />
	//alert('detected '+forms.length+' forms');<br />
	for (f=0; f<textareas.length; f++) {<br />
		var textarea=textareas[f];<br />
		var id=textarea.id;<br />
		classes=textarea.getAttribute('class');// alert(classes);<br />
		classes=classes.split(' ');<br />
		// searching for first class triggering an enhancer<br />
		var enhancerDef;<br />
		for (var g=0; g<classes.length; g++) {<br />
			className=classes[g];<br />
			if (ENHANCETEXTAREAS_CLASSES_ENHANCERS[className]) {<br />
				// found<br />
				var tEnhancer=new textareaEnhancer(textarea,ENHANCETEXTAREAS_CLASSES_ENHANCERS[className]);<br />
				// adding object to global array<br />
				textareaEnhancers[id]=tEnhancer;<br />
				break;<br />
			}<br />
		}<br />
	}<br />
}</p>
<p>addEvent(window,'load',summonTextareaEnhancers);</code></p>
]]></content:encoded>
			<wfw:commentRss>http://exgobz.com/article-3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Listes de selection pour champ texte</title>
		<link>http://exgobz.com/article-2</link>
		<comments>http://exgobz.com/article-2#comments</comments>
		<pubDate>Sun, 25 Sep 2005 21:07:20 +0000</pubDate>
		<dc:creator>Fred Bird</dc:creator>
				<category><![CDATA[Développement Web]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Ce script permet d&#8217;utiliser des listes de selection pour définir la valeur de champs texte. C&#8217;est utile lorsque vous voulez suggérer des valeurs tout en laissant libre choix à l&#8217;utilisateur.  {{{Usage}}}
Appeler simplement le script dans la page. Tout élément {{select}} ayant une {{id}} de la forme {machinchose_selector} se comportera comme le selecteur de l&#8217;élément [...]]]></description>
			<content:encoded><![CDATA[<p>Ce script permet d&#8217;utiliser des listes de selection pour définir la valeur de champs texte. C&#8217;est utile lorsque vous voulez suggérer des valeurs tout en laissant libre choix à l&#8217;utilisateur. <!-- more --> {{{Usage}}}<br />
Appeler simplement le script dans la page. Tout élément {{select}} ayant une {{id}} de la forme {machinchose_selector} se comportera comme le selecteur de l&#8217;élément input ayant l&#8217;id {machinchose}.<br />
{{{Dépendance}}}<br />
Nécessite également l&#8217;appel de [cssFunctions->1]<br />
{{{code source}}}<br />
<code>/*<br />
this script auto-detect all select fields with class 'selector' and id like something_selector,<br />
associates it with the text field with id 'something' so that onchange value of the select is applied to the text field<br />
http://fredbird.org<br />
License : public domain<br />
*/</p>
<p>// copy value of objectFrom to objectTo<br />
function copyValue(objectFrom,idObjectTo) {<br />
	objectTo=document.getElementById(idObjectTo);<br />
	if (!objectTo) return false;<br />
	objectTo.value=objectFrom.value;<br />
	return true;<br />
}<br />
function selectorValueToTarget(selector) {<br />
	var reg=new RegExp("(_selector)");<br />
	target_id=selector.id.replace(reg,'');<br />
	if (targetElement=document.getElementById(target_id)) {<br />
		targetElement.value=selector.value;<br />
	}<br />
}</p>
<p>function selectorLabelToTarget(selector) {<br />
	var reg=new RegExp("(_selector)");<br />
	target_id=selector.id.replace(reg,'');<br />
	if (targetElement=document.getElementById(target_id)) {<br />
		// getting selected option label<br />
		// alert(selector.selectedIndex);<br />
		option=selector.options[selector.selectedIndex];<br />
		// alert (option.text);<br />
		targetElement.value=option.text;<br />
	}<br />
}</p>
<p>// detects pairs selector // target within a form<br />
function setSelectors(form) {<br />
	// value selectors<br />
	selects=getElementsByClassName('selector',document,'select');<br />
	for (var f=0; f<br />
<selects.length; f++) {<br />
		selector=selects[f];<br />
		selector.onchange=function() {selectorValueToTarget(this); return false;}<br />
	}<br />
	// label selectors<br />
	selects=getElementsByClassName('label-selector',document,'select');<br />
	for (var f=0; f<selects.length; f++) {<br />
		selector=selects[f];<br />
		selector.onchange=function() {selectorLabelToTarget(this); return false;}<br />
	}<br />
}</p>
<p>/* detects all selectors and set their behavior<br />
*/<br />
/*function setSelectors() {<br />
	//alert('setSelectors !');<br />
	forms=document.getElementsByTagName('form');<br />
	for (var f=0; f<forms.length; f++) {<br />
		pairs=detectFormSelectors(forms[f]);<br />
	}<br />
}*/</p>
<p>// applying to page<br />
if (!window.addEvent) {<br />
	function addEvent(obj, evType, fn){<br />
		if (obj.addEventListener){<br />
			obj.addEventListener(evType, fn, false);<br />
			return true;<br />
		} else if (obj.attachEvent){<br />
			var r = obj.attachEvent("on"+evType, fn);<br />
			return r;<br />
		} else {<br />
			return false;<br />
		}<br />
	}<br />
}<br />
addEvent(window,'load',setSelectors);</code></p>
]]></content:encoded>
			<wfw:commentRss>http://exgobz.com/article-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fonctions CSS javascript</title>
		<link>http://exgobz.com/article-1</link>
		<comments>http://exgobz.com/article-1#comments</comments>
		<pubDate>Sun, 25 Sep 2005 20:28:15 +0000</pubDate>
		<dc:creator>Fred Bird</dc:creator>
				<category><![CDATA[Culture]]></category>
		<category><![CDATA[Développement Web]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici quelques fonctions javascript pour manipuler les propriétés CSS. C&#8217;est à dire, les attributs class et id des objets du DOM.  &#8211; bool hasClass(DOM obj, string className)
- bool hasClasses(DOM obj, array classes)
- bool addClass(DOM obj, string className)
- bool removeClass(DOM obj, string className)
- bool swapClasses(DOM obj, string class1, string class2)
- bool switchClass(DOM obj, string to, [...]]]></description>
			<content:encoded><![CDATA[<p>Voici quelques fonctions javascript pour manipuler les propriétés CSS. C&#8217;est à dire, les attributs class et id des objets du DOM. <!-- more --> &#8211; bool hasClass(DOM obj, string className)<br />
- bool hasClasses(DOM obj, array classes)<br />
- bool addClass(DOM obj, string className)<br />
- bool removeClass(DOM obj, string className)<br />
- bool swapClasses(DOM obj, string class1, string class2)<br />
- bool switchClass(DOM obj, string to, string from)<br />
- array getElementsByClassName(string className, [DOM container],[string tag])</p>
<p><code>/* CSS-related javascript functions<br />
by Fred Bird http://fredbird.org<br />
License : Public Domain</p>
<p>file version 16/09/2005 09:30:45<br />
*/</p>
<p>/* has the DOM object a certain class ?<br />
	obj = DOM object, cName = a class name<br />
*/<br />
function hasClass(obj,cName) {<br />
	return new RegExp('\\b'+cName+'\\b').test(obj.className);<br />
}<br />
/* has the DOM object a set of classes ?<br />
	obj = DOM object, classes=array of class names<br />
*/<br />
function hasClasses(obj,classes) {<br />
	for (f=0; f&lt;classes.length; f++) {<br />
		if (!hasClass(obj,classes[i])) return false;<br />
	}<br />
	return true;<br />
}<br />
/* add a class to a DOM object if necessary<br />
	obj = DOM object, cName = a class name<br />
*/<br />
function addClass(obj,cName) {<br />
	if (!hasClass(obj,cName)) {<br />
		obj.className+=obj.className?' '+cName:cName;<br />
	}<br />
	return true;<br />
}<br />
/* removes a class from a DOM object<br />
	obj = DOM object, cName = a class name<br />
*/<br />
function removeClass(obj,cName) {<br />
	if (!hasClass(obj,cName)) return false;<br />
	var rep=obj.className.match(' '+cName)?' '+cName:cName;<br />
	obj.className=obj.className.replace(rep,'');<br />
	return true;<br />
}<br />
/* swap two classes for a DOM object, whatever provided order<br />
*/<br />
function swapClasses(obj,class1,class2) {<br />
	if (hasClass(obj,class1)) {<br />
		removeClass(obj,class1);<br />
		addClass(obj,class2);<br />
		return true;<br />
	}<br />
	if (hasClass(obj,class2)) {<br />
		removeClass(obj,class2);<br />
		addClass(obj,class1);<br />
		return true;<br />
	}<br />
	return false;<br />
}<br />
/* sets class 'to' to the DOM object obj, removes class 'from' if necessary<br />
*/<br />
function switchClass(obj,to,from) {<br />
	if (hasClass(obj,from)) removeClass(obj,from);<br />
	addClass(obj,to);<br />
	return true;<br />
}</p>
<p>/* returns an array of DOM objects having the provided class name<br />
within object 'container' and with tag name 'tag'<br />
some code from http://www.webmasterworld.com/forum91/1757.htm (unbugged)<br />
*/<br />
function getElementsByClassName(className,container,tag) {<br />
	// default container to document<br />
	container=container||document;<br />
	// default tag to *<br />
	tag=tag||'*';<br />
	// listing container descendants<br />
	var all = container.all||container.getElementsByTagName(tag);<br />
	var found=new Array();<br />
	// searching for targets<br />
	for (f=0; f&lt;all.length; f++) {<br />
		var el=all[f];<br />
		if (hasClass(all[f],className)) {<br />
			found.push(all[f]);<br />
		}<br />
	}<br />
	return found;<br />
}</code></p>
]]></content:encoded>
			<wfw:commentRss>http://exgobz.com/article-1/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
