1

yop,

Je m'essaie à ces choses-là en ce moment, histoire de voir à quoi ça ressemble. Après avoir passé une heure à trimer pour faire fonctionner un petit test, je suis curieux de voir si quelqu'un ici n'aurait pas une solution bien plus élégante que celle que j'ai été obligé d'utiliser. Je tente une présentation différente de d'habitude, je sais pas si ça sera plus clair :

Objectif :
[ul][li]Récupérer via un XMLHttpRequest une page en XHTML (générée en PHP), et ne garder de cette page qu'un élément (avec son contenu) identifié par son attribut "id"[/li][/ul]
Problèmes :
[ul][li]Les réponses des objets XMLHttpRequest sont sous forme soit de chaine de caractères (.responseText), soit d'arbre DOM (.responseXML), mais la 2eme forme n'est disponible qu'à certaines conditions (de mémoire, le content-type de la page doit être application/xml, text/xml ou application/xhtml+xml)[/li][li]Même en obéissant à cette règle, Internet Explorer a beaucoup de mal à récupérer l'arbre, ou plus précisément le document qu'il contient, supposé être dans .responseXML.documentElement[/li][li]Forcer le content-type de la page a de toutes façons d'autres effets secondaires, parfois gênants[/li][li]Firefox est capable de forcer le type mime du résultat avec la méthode overridemimetype, ce qui fonctionne à merveille, mais Internet Explorer ne sait pas faire ça[/li][li]Une autre solution envisageable serait de parser le contenu de .responseText (la chaine de caractère) pour obtenir un arbre DOM; c'est possible, mais c'est très lent et ne fonctionne pas toujours très bien avec Internet Explorer qui a besoin d'un code différent des autres navigateurs (décidément...)[/li][/ul]
Solution retenue :
[ul][li]Elle est immonde : ça consiste à créer un élement temporaire (temp = document.createElement ('div'); par exemple), puis à mettre le contenu de .responseText dans son champ innerHTML, ce qui a pour effet de parser immédiatement la chaine, puis enfin de parcourir les fils de l'élément temporaire qui contient maintenant un arbre DOM[/li][/ul]
Inconvénient :
[ul][li]Avec cette méthode, on dispose d'un objet "element" et non pas d'un objet "document", donc la méthode ".getElementById" requise pour trouver l'élément à garder dans la page (cf "Objectif", plus haut) n'est pas disponible... Ça impose de passer par des fonctions de parcours de l'arbre "faites à la main" et donc assez lentes[/li][/ul]
Serais-je passé à coté de la solution miracle ? Sachant que l'objectif ne peut pas être changé, donc par exemple faire en sorte que le script PHP ne génère que l'élément dont j'ai besoin n'est pas une solution.

Merci hehe
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

2

Ton post est tres clair, mais qu'est ce que tu veux dire par :
Zephyr (./1) :
Même en obéissant à cette règle, Internet Explorer a beaucoup de mal à récupérer l'arbre, ou plus précisément le document qu'il contient, supposé être dans .responseXML.documentElement


avatar
納 豆パワー!
I becamed a natto!!!1!one!

3

En fait je ne sais pas trop : d'après ce que j'ai pu lire sur certains sites, quelques utilisateurs arrivent à accéder à ".responseXML.documentElement" avec Internet Explorer, mais leur code a tendance à fonctionner de façon plus ou moins aléatoire et ils n'en connaissent pas la raison. D'autres sites annoncent directement que cette méthode est trop hasardeuse sous IE pour tenter de l'utiliser. Je n'ai encore trouvé personne annonçant qu'il aurait réussi à obtenir quelque chose de fiable et en sachant pourquoi :/
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

4

hmm, au pif tu as essaye avec getElementsByTagName ?

cf. http://d.hatena.ne.jp/AjaxEroge/20050825/1124946045
avatar
納 豆パワー!
I becamed a natto!!!1!one!

5

c'est quoi ce site? heureusement que mon chef est pas passé derrière moi grin

6

ok j'ai rien dit, avec ie ca semble foirer des le .documentElement, oublie mon post grin

apres je suppose que tu es tombe sur des sites de ce genre : http://www.ajaxtutorial.net/index.php/2006/02/28/ajax-with-php-using-responsexml/
avatar
納 豆パワー!
I becamed a natto!!!1!one!

7

Oui j'ai essayé le getElementsByTagName, en fait c'est la solution que j'utilise actuellement (je commence par faire un tri par tagnames pour avoir une liste plus réduite dans laquelle chercher l'élément que je veux obtenir). Sinon ton deuxième lien a l'air de supposer que documentElement fonctionne :/
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

8

il a surtout l'air de dire qu'avec IE la requette HTTP se fait via activeX. Si c'est deja ce que tu fais, ben je sais pas. Apres tout j'ai jamais programme avec ajax grin
avatar
納 豆パワー!
I becamed a natto!!!1!one!

9

Oui oui, pour ça y'a pas le choix : ça ne fonctionne de toutes façons pas autrement; mais le problème vient après :/
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

10

Idée à la con : tu peux peut-être faire une iframe "invisible" dans laquelle tu mets le contenu de la requête et utiliser son objet document pour faire le getElementById.
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

11

tu as des liens qui parlent de ce probleme ? (desole, je vois pas vraiment la source du probleme)
avatar
納 豆パワー!
I becamed a natto!!!1!one!

12

moi je ferais comme toi, puisque cette bidouille permet d'utiliser au max les fonctions built-in du browser et est donc la solution la plus rapide à l'execution.

Edit: je dis ca en supposant que documentElement ne marche pas. Sinon ca serait le plus propre en effet.
Tout ce qui passe pas par le port 80, c'est de la triche.

13

BookeldOr > c'est pas forcément con, c'est une évolution de la solution que j'utilise en ce moment et si ça fonctionne ça présente un bon avantage; par contre ça reste aussi crade que la solution actuelle, je trouve :/

liquid > désolé je n'ai pas gardé les liens, en gros en cherchant "ajax documentelement null internet explorer" sur google tu devrais retomber dessus, mais je n'ai rien vu d'officiel sur le sujet :/ (visiblement, les sites qui utilisent de l'ajax aujourd'hui se limitent à des choses relativement basiques, et .responseXML n'est pas aussi utilisé que .responseText, donc le nombre de topics qui en parlent est assez réduit)

onur > dans tous les cas les fonctions utilisées seront built-in : c'est le navigateur qui va parser le document dans tous les cas, et je doute que le code nécessaire ait été dupliqué donc quelle que soit la méthode, je pense que ce qui se passe derrière ne diffère pas beaucoup; c'est aussi pour ça que j'aimerais bien utiliser une méthode "propre" tant qu'à faire
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

14

j'ai pas compris l'interet de recuperer tout le contenu XHTML par un httprequest pour ne récuperer qu'une valeur d'un champ...

pourquoi tu ne retourne pas seulement la valeur dont tu a besoin ?!

sinon, tu peux aussi très bien generer du javascript via PHP, et faire un eval sur ta réponse, et ainsi attribuer directement des valeurs à des variables préalablements définit dans ton script.
Ancien pseudo : lolo

15

Spipu (./14) :
j'ai pas compris l'interet de recuperer tout le contenu XHTML par un httprequest pour ne récuperer qu'une valeur d'un champ...
pourquoi tu ne retourne pas seulement la valeur dont tu a besoin ?!

Décidément : bang

Dernier paragraphe de mon post, juste avant le "merci" tongue (c'est juste un exercice perso et je veux faire comme ça, je sais bien que ça pourrait fonctionner autrement, mais c'est pas ce que je cherche à faire ^^)
sinon, tu peux aussi très bien generer du javascript via PHP, et faire un eval sur ta réponse, et ainsi attribuer directement des valeurs à des variables préalablements définit dans ton script.

Pas compris ?
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

16

ben dans ton script, en global, tu déclares une variable :
var tableau_valeur = new Array();

ton fichier PHP de requete génère un struc du style
tableau_valeur['toto']=1;
tableau_valeur['tata']=2;

ben ton httprequest recupere le resultat, et tu fais un eval du resultat, et ca remplie automatiquement ton tableau smile
Ancien pseudo : lolo

17

Zephyr (./13) :
BookeldOr > c'est pas forcément con, c'est une évolution de la solution que j'utilise en ce moment et si ça fonctionne ça présente un bon avantage; par contre ça reste aussi crade que la solution actuelle, je trouve :/


Mais impossible de savoir à l'avance ce qui va fonctionner ou non sur IE... Je veux bien des nouvelles si tu testes smile
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

18

Bookeldor > oki happy

Spipu > heu oui mais je comprends absolument pas en quoi ça m'aide pour le problème du 1er post ?
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

19

en rien, c'était une alternative smile

sinon, si vraiment t'as pas le choix, je ferais dans une iframe avec un getelementbyid, mais le pb c'est que si il y a des images, elles seront chargées inutilement...
Ancien pseudo : lolo

20

Oui mais je vois *vraiment* pas le rapport entre ce que j'ai exposé comme problème, et ta solution grin

Ce n'est pas une question de ne "pas avoir le choix", mais si j'arrive à faire ce que je veux, ça présente pour moi certains avantages : pas besoin de faire 36 petits fichiers PHP capables chacun de générer un bout de la page (je trouve ça bordélique au possible), il suffit de demander la page et de ne sélectionner que la partie qu'on veut mettre à jour, le reste sera inchangé et conservera les éventuelles modifications de l'utilisateur (champs de formulaire remplis, éléments dynamiques manipulés, images chargées, etc). Bref je ne cherche pas d'alernative, je voudrais vraiment trouver une solution au problème du 1er post et rien d'autre ^^

Bookeldor > bon, manque de bol ça ne marche pas (même pas sous FF) : quand on crée une iframe, son attribut "contentDocument" est à null par défaut; il a l'air d'être défini à partir du moment où on relie l'iframe au document "maître" avec un addChild, ce que je ne veux pas faire (ça modifie la structure de la page) :/
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

21

Tu as pas moyen de faire un truc (bourrin j'avoue) en passant par un second serveur que la tu maitrise qui va répondre a tes XmlhttpRequest, et parser la page que tu veux a la base ? grin (oui c'est vraiment bourrin, mais ça a le merite d'etre plsu simple que de te battre avec le javascript grin)
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

22

ouch ouais mais bon c'est pareil, c'est vraiment super crade comme solution; quitte à partir dans ce genre de trucs j'en ai au moins une qui a l'avantage de marcher plus ou moins sans avoir besoin de 2eme serveur, là ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

23

Zephyr (./20) :
il suffit de demander la page et de ne sélectionner que la partie qu'on veut mettre à jour, le reste sera inchangé et conservera les éventuelles modifications de l'utilisateur (champs de formulaire remplis, éléments dynamiques manipulés, images chargées, etc). Bref je ne cherche pas d'alernative, je voudrais vraiment trouver une solution au problème du 1er post et rien d'autre ^^


rah, pas propre, ca veut dire qu'en fait l'utilisateur recharge malgres tout l'integralité de la page. le but d'ajax c'est de ne recharger que le necessaire. et normalement quand tu conçois une application, chaque bloque d'une page est généré par des fonctions/modules/classes bien définis, et il est donc facile de ne charger qu'un bloc précis happy

mais pour revenir à ton pb initial : si c'est du XHTML bien respecté qui est généré, normalement tu peux parcourir sans pb le DOM que tu sois sous IE ou FF, non ?
Ancien pseudo : lolo

24

bon, je ne sais pas si ca va t'aider, mais j'avais ecrit ce bout de code il y a 2-3 ans... on ne sait jamais happy

/////////////////////////////////// // Fonctions de gestion de l'XML // /////////////////////////////////// /* Fonction pour FF pour créer le XML à partir d'un texte */ // txt      : texte à analyser // result   : nom de la variable de sauvegarde du XML chargé (Exemple : "xmlDoc") // fnc_load : nom de la fonction à appeler automatiquement lorsque le chargement est fini (Exemple : "Init") function xmlMake(txt, result, fnc_load) {      var parser = new DOMParser();                                   // création du Parser         zz_xmlDoc = parser.parseFromString(txt,"text/xml");          // indication du texte à parser      if (result)      eval(result+" = zz_xmlDoc");               // sauvegarde du résultat      if (fnc_load)     eval(fnc_load+"()");                         // lancement de la fonction d'initialisation perso } /* Fonction d'appel d'un XML */ // url      : url du fichier XML à charger. (Exemple : "toto.xml.php") // param    : paramètres éventuels (méthode GET, sans le ? au début. (Exemple : "f=9&g=20") // result   : nom de la variable de sauvegarde du XML chargé (Exemple : "xmlDoc") // fnc_load : nom de la fonction à appeler automatiquement lorsque le chargement est fini (Exemple : "Init") function xmlLoad(url, param, result, fnc_load) {      var zz_xhr_object = null;                                                   // Objet contenant le XML      if(window.XMLHttpRequest)                                                  // Si Firefox       {           zz_xhr_object = new XMLHttpRequest();                               // création de l'outil permetant de récuper le contenu text du XML           zz_xhr_object.open("GET", url+"?"+param, true);                // indication de la méthode et du fichier XML           // création de la fonction traitant le texte une fois chargé et créant le XML -> xmlMake           eval("zz_xhr_object.onreadystatechange = function() { if(zz_xhr_object.readyState == 4) xmlMake(zz_xhr_object.responseText, '"+result+"', '"+fnc_load+"'); } ");           // préparation de la requete            zz_xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");            zz_xhr_object.send("");                                              // envoie de la requete          return true;                                                       // fin -> xmlMake      }      else if(window.ActiveXObject)                                             // Si Internet Explorer       {            var zz_xmlDoc     = new ActiveXObject("Microsoft.XMLDOM");     // création de l'outil premetant de récupérer le DOM du XML          zz_xmlDoc.async = false;                                               // necessaire pour IE           if (typeof zz_xmlDoc!="undefined")                                   // si l'objet est bien défini                zz_xmlDoc.load(url+"?"+param)                                   // => changement du XML               while(zz_xmlDoc.readyState != 4) {};                              // attente du chargement           if (result)      eval(result+" = zz_xmlDoc");                     // sauvegarde du résultat           if (fnc_load)     eval(fnc_load+"()");                              // lancement de la fonction d'initialisation perso          return true;                                                            // fin      }      else                                                                           // sinon      {            if (result)      eval(result+" = null");                          // impossible...              return false;                                                            // fin      } } /* Fonction permetant de renvoyer dans un tableau la structure entière d'un XML */ // xmlNode   : Résultat obtenu grâce à xmlLoad dans result // root_node : noeud principal de départ (obligatoire, exemple : "ROOT", mais surtout pas "xml") // exemple : //<root> // <message> //  <title>titre1</titre> //  <msg>message1</msg> // </message> // <message> //  <title>titre2</titre> //  <msg>message2</msg> // </message> //</root> // // va donner, avec root comme noeud principal : // // liste['message']['length'] = 2 // liste['message'][0]['value'] = null // liste['message'][0]['node']['title']['length']   = 1 // liste['message'][0]['node']['title'][0]['value'] = "titre1" // liste['message'][0]['node']['title'][0]['node']  = null // liste['message'][0]['node']['msg']['length']   = 1 // liste['message'][0]['node']['msg'][0]['value'] = "message1" // liste['message'][0]['node']['msg'][0]['node']  = null // liste['message'][1]['value'] = null // liste['message'][1]['node']['title']['length']   = 1 // liste['message'][1]['node']['title'][0]['value'] = "titre2" // liste['message'][1]['node']['title'][0]['node']  = null // liste['message'][1]['node']['msg']['length']   = 1 // liste['message'][1]['node']['msg'][0]['value'] = "message2" // liste['message'][1]['node']['msg'][0]['node']  = null function xmlReadAll(xmlNode, root_node) {      if (root_node)                xmlNode = xmlNode.getElementsByTagName(root_node)[0];            var notWhitespace = /\S/;      var nbNo2, nom, val, i, n            for (i=0;i<xmlNode.childNodes.length;i++)      {           if ((xmlNode.childNodes[i].nodeType == 3)&&(!notWhitespace.test(xmlNode.childNodes[i].nodeValue)))           {                xmlNode.removeChild(xmlNode.childNodes[i]);                i--;           }      }            var liste = new Array();      var nbNo1 = xmlNode.childNodes.length;            if (xmlNode.firstChild.nodeValue!=null) nbNo1--;      for (i=0;i<nbNo1;i++)      {           nom = xmlNode.childNodes[i].nodeName;           val = xmlNode.childNodes[i].firstChild.nodeValue;           if (!liste[nom])           {                liste[nom] = new Array();                liste[nom]['length'] = 0;           }           n = liste[nom]['length'];           liste[nom][n] = new Array();           liste[nom][n]['value'] = val;                      nbNo2 = xmlNode.childNodes[i].childNodes.length;                 if (val!=null) nbNo2--;           if (nbNo2>0)                liste[nom][n]['node'] = xmlReadAll(xmlNode.childNodes[i], null);           else                liste[nom][n]['node'] = null;                      liste[nom]['length'] = n+1;      }            return liste; }
Ancien pseudo : lolo

25

Spipu (./23) :
rah, pas propre, ca veut dire qu'en fait l'utilisateur recharge dont malgres tout l'integralité de la page. le but d'ajax c'est de ne recharger que le necessaire.

Je ne considère pas que ce soit le "but" d'ajax, en fait, surtout quand le temps de génération d'une page n'est que de quelques millisecondes : quel intérêt à le réduire encore ?
et normalement quand tu conçois une application, chaque bloque d'une page est généré par des fonctions/modules/classes bien définit, et il est donc facile de ne charger qu'un bloc précis happy

Ah, attention avec les "normalement" : on va pas être d'accord grin

Pour moi, c'est typiquement le genre de conception qui résulte d'ajax : ok pour avoir un module "menu", un module "contenu principal" & co, mais en revanche un petit bout de PHP qui n'est là que pour modifier le contenu d'un <select>, pour moi c'est une horreur. Pour rappel, l'un des objectifs d'une conception c'est de s'abstraire tant que possible de l'implémentation; donc faire le choix d'Ajax ou non ne devrait pas modifier la structure du code.

Sans compter qu'avec des solutions comme ça, faire un site qui supporte Ajax et qui fonctionne avec des templates risque d'être assez fun... Donc c'est justement cette tendance à articuler sa conception autour d'Ajax que je trouve très sale moi, et que je voudrais à tout prix éviter.
mais pour revenir à ton pb initial : si c'est du XHTML bien respecté qui est généré, normalement tu peux parcourir sans pb le DOM que tu sois sous IE ou FF, non ?

Désolé mais lis le post ./1 en entier, j'ai expliqué le problème en détail...

[edit] cross, ton bout de code utilise l'une des méthodes dont j'ai déjà parlé dans le premier post...
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

26

Ce n'est pas une question de ne "pas avoir le choix", mais si j'arrive à faire ce que je veux, ça présente pour moi certains avantages : pas besoin de faire 36 petits fichiers PHP capables chacun de générer un bout de la page (je trouve ça bordélique au possible), il suffit de demander la page et de ne sélectionner que la partie qu'on veut mettre à jour, le reste sera inchangé et conservera les éventuelles modifications de l'utilisateur (champs de formulaire remplis, éléments dynamiques manipulés, images chargées, etc). Bref je ne cherche pas d'alernative, je voudrais vraiment trouver une solution au problème du 1er post et rien d'autre ^^


Pourquoi tu appelerais pas une page avec un paramètre alors? Parce que récupérer un gros truc pour filtrer coté client, déjà à la base, c'est pas très "propre".
Tout ce qui passe pas par le port 80, c'est de la triche.

27

Ça par contre c'est effectivement une idée qui m'a semblé bonne, mais je me suis retrouvé encore une fois devant le même problème : mettre ça en place, c'est plier la conception pour un besoin très particulier; je n'ai pas trouvé une méthode "propre" pour déterminer de façon générique quel impact aurait ce paramètre sur toutes les pages.

Au final, ça reviendrait à filtrer du coté serveur plutôt que du coté client, et dans tous les cas la partie la plus couteuse (l'exécution du code) se ferait à chaque fois. Je ne suis pas sûr que ce soit spécialement sale de filtrer coté client : ça allège le serveur, et dans tous les cas c'est ce qui se serait passé sans Ajax, qui ne devient donc qu'une surcouche modifiant un peu la façon dont les données sont affichées (actualisation du nécessaire plutôt que reload de toute la page).
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

28

Zephyr (./25) :
surtout quand le temps de génération d'une page n'est que de quelques millisecondes : quel intérêt à le réduire encore ?


C'est pas forcement la génération, mais le téléchargement...
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

29

Zephyr (./25) :
une page n'est que de quelques millisecondes


certaines applications métiers mettent plus d'un 1/10 de seconde à être généré... exemple : le CMS typo3... 500ms par page, à 1000 utilisateurs... il vaut mieux ne regenerer que ce dont tu as besoin !
Zephyr (./25) :
Pour rappel, l'un des objectifs d'une conception c'est de s'abstraire tant que possible de l'implémentation


je voulais dire "dévellopper" et non "concevoir", désolé... je suis tout à fait d'accord avec ton rapel happy
Zephyr (./25) :
Un petit bout de PHP qui n'est là que pour modifier le contenu d'un select, pour moi c'est une horreur


ben par forcement, quand ce selec est utilisé des centaires de fois dans l'application, c'est bien pratique d'avoir un truc qui te les génère automatiquement...
Zephyr (./25) :
Sans compter qu'avec des solutions comme ça, faire un site qui supporte Ajax et qui fonctionne avec des templates risque d'être assez fun..


d'experience, ca se fait très bien wink
Zephyr (./25) :
cross, ton bout de code est l'une des méthodes dont j'ai déjà parlé dans le premier post...


vi en effet, j'avais pas bien relu mon bout de code... il ne fait pas avancé le chmill blick (ca s'ecrit comment cette connerie ?!)
Ancien pseudo : lolo

30

Demander plus d'info qu'il n'en faut à chaque fois au serveur, ca allégerait le serveur? Pas sur.

Voici comment fait un pote:

Moi dans mon js, j'appelle toujours interface.php?action=machin
lui dans interface.php il fait if (_GET("action")=="machin"){ requiere_once("fichierDesPetitsAppels"); echo functionMachin(); }
if (_GET("action")=="truc"){ requiere_once("fichierDesPetitsAppels"); echo functionTruc(); }

(schématiquement, car je sais pas faire du php
Tout ce qui passe pas par le port 80, c'est de la triche.