HTML_ENTITIES_DECODE

Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 - 20 mars 2010 à 17:44
jdmcreator Messages postés 647 Date d'inscription samedi 30 décembre 2000 Statut Membre Dernière intervention 20 juillet 2012 - 25 mars 2010 à 23:56
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/51468-html-entities-decode

jdmcreator Messages postés 647 Date d'inscription samedi 30 décembre 2000 Statut Membre Dernière intervention 20 juillet 2012 7
25 mars 2010 à 23:56
-_-

Une petite question, pourquoi n'utilise dont pas ma solution. Elle est encore plus optimisé et prend moins de place

---> 163 caractères pour moi et + de 5000 pour toi O_O

5000 caractères !!!! C'est 5, 218 KO !!!! C'est le cinquième de la taille de JQuery, qui fait des centaines de fonctionnalité de plus !!!

Désolé, mais je ne comprends pourquoi tu ne regardes pas ma solution, elle est cross-browser : testé avec Safari, IE, Firefox, Opéra et Chrome et surtout, mais SURTOUT, elle prend 33 fois moins d'espace !!! Désolé mon emportement, mais ça dépasse ma logique ^^ Quelqu'un pour me dire ce qui cloche dans la fonction ? Y a-t-il un bug (je peux essayer de régler) ? Ou alors la fonction est-elle trop simple ?

Je reposte :

-----------
function convertToHex(ty){

tn=document.createElement("div");
tn.innerHTML=ty;
yn= tn.innerText || tn.textContent || tn.style.content;
return escape(yn);

}
/*Utilisation*/
alert(unescape(convertToHex("" + é")));
zen69 Messages postés 584 Date d'inscription jeudi 28 décembre 2006 Statut Membre Dernière intervention 29 avril 2010 1
25 mars 2010 à 18:11
Bon finalement voici la fonction complète et révisé.

Quelques modifications depuis mon dernier commentaire....

J'ai enlever la clause insensitive de l'exp reg afin de ne pas mélanger par example É et é
J'ai complèté la liste des caractères.
J'ai ajouté un condition undefined aux entités qui commence avec un # puisqu'elles sont extraites de la variable entities.
J'ai aussi modifié la longueur des entitiés nommées comme À pour prendre l'entitée complète 4 étant trop court.

Encore une fois merci à Arto_8000 pour sa grande aide!!
zen69 Messages postés 584 Date d'inscription jeudi 28 décembre 2006 Statut Membre Dernière intervention 29 avril 2010 1
25 mars 2010 à 16:48
Correction voici la fonction que j'utilise maintenant,

function html_decode(html) {
var matches = html.match(/&(#[0-9]{1,3}|[a-z]{2,6});/gi);
var nameEntities = {
quot : "%22",
apos : "%27",
amp : "%26",
lt : "%3C",
gt : "%3E",
nbsp : "%A0",
agrave : "%E0",
224 : "%E0",
32 : "%A0"
}

if (matches != null) {
for (i=0; i<matches.length; i++) {
var code = matches[i].substring(1,matches[i].length-1);
if (code.charAt(0) == "#") {
html = html.replace(matches[i], nameEntities[code.substr(1)]);
} else {
if (typeof nameEntities[code] != "undefined") {
html = html.replace(matches[i], nameEntities[code]);
}
}
}
}

return html;
}

je n'ai pas mis toutes les entités pour faire plus court...

Merci bcp Arto_8000
zen69 Messages postés 584 Date d'inscription jeudi 28 décembre 2006 Statut Membre Dernière intervention 29 avril 2010 1
25 mars 2010 à 16:41
Arto_8000: Merci beaucoup pour ces précision sur le replace avec et sans regexp, je n'étais pas au fait du fonctionnement et des différences entre les deux, mis-à-part du fait qu'un s'applique sur une exp reg et l'autre sur un string...

Ouin escape je connais mais finalement je dois le combiné avec fromCharCode...

Voici donc ce que j'utilise maintenant

function html_decode(html) {
var matches = html.match(/&(#[0-9]{1,3}|[a-z]{2,6});/gi);
var nameEntities = {
quot : "%22",
apos : "%27",
amp : "%26",
lt : "%3C",
gt : "%3E",
nbsp : "%A0",
agrave : "%E0",
224 : "%E0",
}

if (matches != null) {
for (i=0; i<matches.length; i++) {
var code = matches[i].substring(1,matches[i].length-1);
if (code.charAt(0) == "#") {
html = html.replace(matches[i], escape(String.fromCharCode(code.substr(1))));
} else {
if (typeof nameEntities[code] != "undefined") {
html = html.replace(matches[i], nameEntities[code]);
}
}
}
}

return html;
}
jdmcreator Messages postés 647 Date d'inscription samedi 30 décembre 2000 Statut Membre Dernière intervention 20 juillet 2012 7
25 mars 2010 à 00:05
Ben voyons... Ceci devrait fonctionner

<script type="text/javascript">
function convertToHex(ty){

tn=document.createElement("div");
tn.innerHTML=ty;
yn= tn.innerText || tn.textContent || tn.style.content;
return escape(yn);

}
alert(unescape(convertToHex("" + é")));
</script>

Petite précision : on devrait plutôt indiquer <script type="application/javascript"> selon les dernières nouvelles mais je n'ai pas encore eu la confirmation que tous les navigateurs le comprendront
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
24 mars 2010 à 15:32
Il faut que tu comprennes d'abord qu'il y a une grosse différence entre un replace avec regexp et sans regexp. Un replace simple prend beaucoup moins de temps à s'exécuter qu'un regexp avec une expression régulière. Une expression régulière doit être compilé et après être exécuté. En plus, un replace avec une expression régulière ne s'arrête pas après la première occurrence. Un replace simple est beaucoup plus ciblé contrairement à un replace avec un regexp.

"Je ne sais pas s'il y a un équivalent à String.fromCharCode pour transformer en hex, mais d'ici à ce que je trouve, je ne changerai pas ma fonction."

Cette fonction s'appelle escape.

https://developer.mozilla.org/fr/Guide_JavaScript_1.5/Fonctions_pr%C3%A9d%C3%A9finies/Les_fonctions_escape_et_unescape
zen69 Messages postés 584 Date d'inscription jeudi 28 décembre 2006 Statut Membre Dernière intervention 29 avril 2010 1
24 mars 2010 à 14:59
Arto_8000: mais disons que j'ai 250 accents aiguë dans mon string. Il va faire le replace 250 fois non?

Si tel est le case, c'est plus optimisé selon l'utilisation qu'on en fait...?

De plus ma fonction retournais un chaîne hex... contrairement à ta fonction qui retourne les caractères décodés.

Je ne sais pas s'il y a un équivalent à String.fromCharCode pour transformer en hex, mais d'ici à ce que je trouve, je ne changerai pas ma fonction.
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
23 mars 2010 à 22:19
"ta fonction est très loin d'être complète"

La seule chose qui manque c'est de compléter la liste des entités avec des noms et la seule raison pour laquelle je l'ai pas fait au complète c'est que de 1 ça prend énormément de place dans les commentaires et de deux n'importe qui peut compléter la liste à partir de liste facilement trouvable sur le web. Ce que j'ai voulu montré c'est l'algorithme le plus intéressant pour faire ce genre d'opération.

"cependant ta fonction elle effectue plusieurs opérations pour chaque match"

C'est très floue comme affirmation et pas tout à fait vrai. Comme tel il y a un seul replace (sans regexp) qui est fait par match.
BaFM Messages postés 64 Date d'inscription mercredi 24 juillet 2002 Statut Membre Dernière intervention 26 novembre 2009
23 mars 2010 à 20:06
Entre une solution lente et qui ne fait pas tous les cas et une solution qui nécessite quelques minutes de recherche pour être compatible tout navigateur. Je préfère la dernière.

Et il y a d'autres manières de faire passer sans problème d'encodage ces éléments.
zen69 Messages postés 584 Date d'inscription jeudi 28 décembre 2006 Statut Membre Dernière intervention 29 avril 2010 1
23 mars 2010 à 19:22
BaFM : une autre technique est de lire de descriptif avant de posté.

J'utilise la fonction pour mes alert() et mes confirm(...), et le n'avigateur ne fait justement pas la conversion tout seul. Et dans ta pseudo solution tu évoques toi même qu'elle ne fonctionne pas partout!
zen69 Messages postés 584 Date d'inscription jeudi 28 décembre 2006 Statut Membre Dernière intervention 29 avril 2010 1
23 mars 2010 à 18:50
Arto_8000: ta fonction est très loin d'être complète. Cependant je comprend bien que dans ton exemple il va faire le replace seulement à la mesure des matchs trouvé ce qui est bien, cependant ta fonction elle effectue plusieurs opérations pour chaque match.

Merci tout de même pour ta précision, je tenterai d'optimisé à l'aide de ce que tu as dis, quand j'aurai du temps, si le coeur m'en dit.
jdmcreator Messages postés 647 Date d'inscription samedi 30 décembre 2000 Statut Membre Dernière intervention 20 juillet 2012 7
23 mars 2010 à 00:52
BaFM : Il peut y avoir des problèmes de compatibilité.

En effet, sous Firefox il faut utiliser element.contentText. J'ai aussi déjà entendu parler vaguement d'un element.style.content mais je n'en ai jamais vu d'utilisation
BaFM Messages postés 64 Date d'inscription mercredi 24 juillet 2002 Statut Membre Dernière intervention 26 novembre 2009
22 mars 2010 à 09:29
Une autre technique consite à utiliser le fait que le navigateur sait faire cette conversion tout seul. Créer un élément, définir son texte HTML (innerHTML), récupérer sont texte décoder (innerText).
Il peut y avoir des problèmes de compatibilité.
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
20 mars 2010 à 17:44
Je doute très fortement que faire 340 replace avec des expressions régulières en javascript soit la meilleur solution pour faire cette tâche qui n'est pas si complexe. Surtout que le seul truc qui est à hardcoder c'est les équivalences pour les entités avec les noms. Oublie pas que les replaces avec les regexp parcourent toute la chaîne, donc ton script parcoure à tout coup 340 fois la même chaîne ce qui est évidemment lourd.

Un algorythme plus optimisé (et plus simple) devrait ressembler à quelque chose comme ceci :

function html_decode(html) {
var matches = html.match(/&(#[0-9]{1,3}|[a-z]{2,4});/gi);
var nameEntities = {
quot : """,
apos : "'",
amp : "&",
lt : "<",
gt : ">",
nbsp : " "
}

if (matches != null) {
for (i=0; i<matches.length; i++) {
var code = matches[i].substring(1,matches[i].length-1);

if (code.charAt(0) == "#") {
html = html.replace(matches[i], String.fromCharCode(code.substr(1)));
} else {
if (typeof nameEntities[code] != "undefined") {
html = html.replace(matches[i], nameEntities[code]);
}
}
}
}

return html;
}
Rejoignez-nous