MOD on ne peut plus avec le nick par défaut : <nick>
[euphorik.git] / js / euphorik.js
index c796e41..b2024ad 100755 (executable)
@@ -1,23 +1,23 @@
-// coding: utf-8\r
-// Copyright 2008 Grégory Burri\r
-//\r
-// This file is part of Euphorik.\r
-//\r
-// Euphorik is free software: you can redistribute it and/or modify\r
-// it under the terms of the GNU General Public License as published by\r
-// the Free Software Foundation, either version 3 of the License, or\r
-// (at your option) any later version.\r
-//\r
-// Euphorik is distributed in the hope that it will be useful,\r
-// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-// GNU General Public License for more details.\r
-//\r
-// You should have received a copy of the GNU General Public License\r
-// along with Euphorik.  If not, see <http://www.gnu.org/licenses/>.\r
-\r
-/**\r
-  * Contient la base javascript pour le site euphorik.ch.\r
+// coding: utf-8
+// Copyright 2008 Grégory Burri
+//
+// This file is part of Euphorik.
+//
+// Euphorik is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Euphorik is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Euphorik.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+  * Contient la base javascript pour le site euphorik.ch.
   * Chaque page possède son propre fichier js nommé "page<nom de la page>.js".
   * Auteur : GBurri
   * Date : 6.11.2007
   * Chaque page possède son propre fichier js nommé "page<nom de la page>.js".
   * Auteur : GBurri
   * Date : 6.11.2007
   
 
 /**
   
 
 /**
-  * La configuration.\r
+  * La configuration.
   * Normalement 'const' à la place de 'var' mais non supporté par IE7.
   * Normalement 'const' à la place de 'var' mais non supporté par IE7.
-  */\r
-var conf = {\r
+  */
+var conf = {
+   nickDefaut : "<nick>",
    nbMessageAffiche : 40, // (par page)
    nbMessageAffiche : 40, // (par page)
-   pseudoDefaut : "<nick>",\r
+   pseudoDefaut : "<nick>",
    tempsAffichageMessageDialogue : 4000, // en ms
    tempsKick : 15, // en minute
    tempsAffichageMessageDialogue : 4000, // en ms
    tempsKick : 15, // en minute
-   tempsBan : 60 * 24 * 3, // en minutes (3jours)\r
-   smiles : {   \r
-      "smile" : [/:\)/g, /:-\)/g],  \r
-      "bigsmile" : [/:D/g, /:-D/g],\r
-      "clin" : [/;\)/g, /;-\)/g],\r
-      "cool" : [/8\)/g, /8-\)/g],\r
+   tempsBan : 60 * 24 * 3, // en minutes (3jours)
+   smiles : {   
+      "smile" : [/:\)/g, /:-\)/g],  
+      "bigsmile" : [/:D/g, /:-D/g],
+      "clin" : [/;\)/g, /;-\)/g],
+      "cool" : [/8\)/g, /8-\)/g],
       "eheheh" : [/:P/g, /:-P/g],
       "lol" : [/\[-lol\]/g],
       "eheheh" : [/:P/g, /:-P/g],
       "lol" : [/\[-lol\]/g],
-      "spliff" : [/\[-spliff\]/g],\r
+      "spliff" : [/\[-spliff\]/g],
       "oh" : [/:o/g, /:O/g],
       "heink" : [/\[-heink\]/g],
       "hum" : [/\[-hum\]/g],
       "boh" : [/\[-boh\]/g],
       "sniff" : [/:\(/g, /:-\(/g],
       "oh" : [/:o/g, /:O/g],
       "heink" : [/\[-heink\]/g],
       "hum" : [/\[-hum\]/g],
       "boh" : [/\[-boh\]/g],
       "sniff" : [/:\(/g, /:-\(/g],
-      "triste" : [/\[-triste\]/g],\r
-      "pascontent" : [/>\(/g, /&gt;\(/g],\r
+      "triste" : [/\[-triste\]/g],
+      "pascontent" : [/>\(/g, /&gt;\(/g],
       "argn" : [/\[-argn\]/g],
       "argn" : [/\[-argn\]/g],
-      "redface" : [/\[-redface\]/g],\r
-      "bunny" : [/\[-lapin\]/g],\r
-      "chat" : [/\[-chat\]/g],\r
-      "renne" : [/\[-renne\]/g],\r
-      "star" : [/\[-star\]/g],\r
+      "redface" : [/\[-redface\]/g],
+      "bunny" : [/\[-lapin\]/g],
+      "chat" : [/\[-chat\]/g],
+      "renne" : [/\[-renne\]/g],
+      "star" : [/\[-star\]/g],
       "kirby" : [/\[-kirby\]/g],
       "slurp" : [/\[-slurp\]/g],
       "agreed" : [/\[-agreed\]/g],
       "dodo" : [/\[-dodo\]/g],
       "kirby" : [/\[-kirby\]/g],
       "slurp" : [/\[-slurp\]/g],
       "agreed" : [/\[-agreed\]/g],
       "dodo" : [/\[-dodo\]/g],
-      "bn" : [/\[-bn\]/g]\r
-   }\r
-}\r
+      "bn" : [/\[-bn\]/g]
+   }
+}
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-\r
-String.prototype.trim = function()\r
-{\r
-       return jQuery.trim(this) // anciennement : this.replace(/^\s+|\s+$/g, "");\r
-}\r
-\r
-String.prototype.ltrim = function()\r
-{\r
-       return this.replace(/^\s+/, "");\r
-}\r
-\r
-String.prototype.rtrim = function()\r
-{\r
-       return this.replace(/\s+$/, "");\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////////////////////////////\r
-\r
-/**\r
+
+String.prototype.trim = function()
+{
+       return jQuery.trim(this) // anciennement : this.replace(/^\s+|\s+$/g, "");
+}
+
+String.prototype.ltrim = function()
+{
+       return this.replace(/^\s+/, "");
+}
+
+String.prototype.rtrim = function()
+{
+       return this.replace(/\s+$/, "");
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
   * Cette classe regroupe des fonctions utilitaires (helpers).
   * Cette classe regroupe des fonctions utilitaires (helpers).
-  * @formateur est permet de formater les messages affichés à l'aide de messageDialogue (facultatif)\r
+  * @formateur est permet de formater les messages affichés à l'aide de messageDialogue (facultatif)
   */
 function Util(formateur)
 {
   */
 function Util(formateur)
 {
@@ -102,9 +103,9 @@ var messageType = {informatif: 0, question: 1, erreur: 2}
 
 /**
   * Affiche une boite de dialogue avec un message à l'intérieur.
 
 /**
   * Affiche une boite de dialogue avec un message à l'intérieur.
-  * @param message le message (string)\r
-  * @param type voir 'messageType'. par défaut messageType.informatif\r
-  * @param les boutons sous la forme d'un objet ou les clefs sont les labels des boutons\r
+  * @param message le message (string)
+  * @param type voir 'messageType'. par défaut messageType.informatif
+  * @param les boutons sous la forme d'un objet ou les clefs sont les labels des boutons
   *        et les valeurs les fonctions executées lorsqu'un bouton est activé.
   * @param formate faut-il formaté le message ? true par défaut
   */
   *        et les valeurs les fonctions executées lorsqu'un bouton est activé.
   * @param formate faut-il formaté le message ? true par défaut
   */
@@ -137,7 +138,7 @@ Util.prototype.messageDialogue = function(message, type, boutons, formate)
    
    $("#info").slideDown(200)
    this.timeoutMessageDialogue = setTimeout(fermer, conf.tempsAffichageMessageDialogue)   
    
    $("#info").slideDown(200)
    this.timeoutMessageDialogue = setTimeout(fermer, conf.tempsAffichageMessageDialogue)   
-}\r
+}
 
 /**
   * Affiche un info bulle lorsque le curseur survole l'élément donné.
 
 /**
   * Affiche un info bulle lorsque le curseur survole l'élément donné.
@@ -158,12 +159,17 @@ Util.prototype.infoBulle = function(message, element)
       {
          if (!thisUtil.bulleActive)
             return
       {
          if (!thisUtil.bulleActive)
             return
-         
+                  
          var m = $("#messageBulle")
          var f = $("#flecheBulle")
          
          var m = $("#messageBulle")
          var f = $("#flecheBulle")
          
+         // remplie le paragraphe de la bulle avec le message
          $("p", m).html(message)
          $("p", m).html(message)
-      
+         
+         // réinitialise la position, évite le cas ou la boite est collé à droite et remplie avec un texte la faisant dépassé
+         // dans ce cas la hauteur n'est pas calculé correctement
+         m.css("top", 0).css("left", 0)
+         
          var positionFleche = {
             left : element.offset().left + element.width() / 2 - f.width() / 2,
             top : element.offset().top - f.height()
          var positionFleche = {
             left : element.offset().left + element.width() / 2 - f.width() / 2,
             top : element.offset().top - f.height()
@@ -195,79 +201,76 @@ Util.prototype.jsonVersAction = function(json)
 {
    return {action : JSON.stringify(json) }
 }
 {
    return {action : JSON.stringify(json) }
 }
-\r
-Util.prototype.md5 = function(chaine)\r
-{\r
-   return hex_md5(chaine)\r
+
+Util.prototype.md5 = function(chaine)
+{
+   return hex_md5(chaine)
 }
 }
-\r
-// pompé de http://www.faqts.com/knowledge_base/view.phtml/aid/13562/fid/130\r
+
+// pompé de http://www.faqts.com/knowledge_base/view.phtml/aid/13562/fid/130
 Util.prototype.setSelectionRange = function(input, selectionStart, selectionEnd)
 Util.prototype.setSelectionRange = function(input, selectionStart, selectionEnd)
-{\r
+{
    if (input.setSelectionRange)
    if (input.setSelectionRange)
-   {\r
-      input.focus()\r
-      input.setSelectionRange(selectionStart, selectionEnd)\r
-   }\r
+   {
+      input.focus()
+      input.setSelectionRange(selectionStart, selectionEnd)
+   }
    else if (input.createTextRange)
    else if (input.createTextRange)
-   {\r
-      var range = input.createTextRange()\r
-      range.collapse(true)\r
-      range.moveEnd('character', selectionEnd)\r
-      range.moveStart('character', selectionStart)\r
-      range.select()\r
-   }\r
-}
-\r
+   {
+      var range = input.createTextRange()
+      range.collapse(true)
+      range.moveEnd('character', selectionEnd)
+      range.moveStart('character', selectionStart)
+      range.select()
+   }
+}
+
 Util.prototype.setCaretToEnd = function(input)
 Util.prototype.setCaretToEnd = function(input)
-{\r
-   this.setSelectionRange(input, input.value.length, input.value.length)\r
-}\r
+{
+   this.setSelectionRange(input, input.value.length, input.value.length)
+}
 Util.prototype.setCaretToBegin = function(input)
 Util.prototype.setCaretToBegin = function(input)
-{\r
-   this.setSelectionRange(input, 0, 0)\r
-}\r
+{
+   this.setSelectionRange(input, 0, 0)
+}
 Util.prototype.setCaretToPos = function(input, pos)
 Util.prototype.setCaretToPos = function(input, pos)
-{\r
-   this.setSelectionRange(input, pos, pos)\r
-}\r
+{
+   this.setSelectionRange(input, pos, pos)
+}
 Util.prototype.selectString = function(input, string)
 Util.prototype.selectString = function(input, string)
-{\r
-   var match = new RegExp(string, "i").exec(input.value)\r
+{
+   var match = new RegExp(string, "i").exec(input.value)
    if (match)
    if (match)
-   {\r
-      this.setSelectionRange (input, match.index, match.index + match[0].length)\r
-   }\r
-}\r
-Util.prototype.replaceSelection = function(input, replaceString) {\r
+   {
+      this.setSelectionRange (input, match.index, match.index + match[0].length)
+   }
+}
+Util.prototype.replaceSelection = function(input, replaceString) {
    if (input.setSelectionRange)
    if (input.setSelectionRange)
-   {\r
-      var selectionStart = input.selectionStart\r
-      var selectionEnd = input.selectionEnd\r
+   {
+      var selectionStart = input.selectionStart
+      var selectionEnd = input.selectionEnd
       input.value = input.value.substring(0, selectionStart) + replaceString + input.value.substring(selectionEnd)
       input.value = input.value.substring(0, selectionStart) + replaceString + input.value.substring(selectionEnd)
-      \r
-      if (selectionStart != selectionEnd) // has there been a selection\r
-         this.setSelectionRange(input, selectionStart, selectionStart + replaceString.length)\r
-      else // set caret\r
-         this.setCaretToPos(input, selectionStart + replaceString.length)\r
-   }\r
+      
+      if (selectionStart != selectionEnd) // has there been a selection
+         this.setSelectionRange(input, selectionStart, selectionStart + replaceString.length)
+      else // set caret
+         this.setCaretToPos(input, selectionStart + replaceString.length)
+   }
    else if (document.selection)
    else if (document.selection)
-   {\r
-      var range = document.selection.createRange();\r
+   {
+      input.focus()
+      var range = document.selection.createRange()
       if (range.parentElement() == input)
       if (range.parentElement() == input)
-      {\r
-         var isCollapsed = range.text == ''\r
-         range.text = replaceString\r
+      {
+         var isCollapsed = range.text == ''
+         range.text = replaceString
          if (!isCollapsed)
          {
          if (!isCollapsed)
          {
-            // there has been a selection\r
-            // it appears range.select() should select the newly \r
-            // inserted text but that fails with IE\r
-            range.moveStart('character', -replaceString.length);\r
-            range.select();\r
-         }\r
-      }\r
-   }\r
+            range.moveStart('character', -replaceString.length);
+         }
+      }
+   }
 }
 
 Util.prototype.rot13 = function(chaine)
 }
 
 Util.prototype.rot13 = function(chaine)
@@ -301,15 +304,26 @@ function Pages()
    this.pages = {}
 }
 
    this.pages = {}
 }
 
+/**
+  * Accepte soit un objet soit un string.
+  * un string correspond au nom de la page, par exemple : "page" -> "page.html"
+  */
 Pages.prototype.ajouterPage = function(page)
 {
 Pages.prototype.ajouterPage = function(page)
 {
-   page.pages = this // la magie des langages dynamiques : le foutoire
-   this.pages[page.nom] = page
+   if (typeof page == "string")
+   {
+      this.pages[page] = page
+   }
+   else
+   {
+      page.pages = this // la magie des langages dynamiques : le foutoire
+      this.pages[page.nom] = page
+   }
 }
 
 Pages.prototype.afficherPage = function(nomPage, forcerChargement)
 }
 
 Pages.prototype.afficherPage = function(nomPage, forcerChargement)
-{\r
-   if (forcerChargement == undefined) forcerChargement = false\r
+{
+   if (forcerChargement == undefined) forcerChargement = false
 
    var page = this.pages[nomPage]
    if (page == undefined || (!forcerChargement && page == this.pageCourante)) return
 
    var page = this.pages[nomPage]
    if (page == undefined || (!forcerChargement && page == this.pageCourante)) return
@@ -321,7 +335,12 @@ Pages.prototype.afficherPage = function(nomPage, forcerChargement)
    $("#menu li." + nomPage).addClass("courante")
       
    this.pageCourante = page
    $("#menu li." + nomPage).addClass("courante")
       
    this.pageCourante = page
-   $("#page").html(this.pageCourante.contenu()).removeClass().addClass(this.pageCourante.nom)
+   var contenu = ""
+   if (typeof page == "string")
+      $.ajax({async: false, url: "pages/" + page + ".html", success : function(page) { contenu += page }})
+   else
+      contenu += this.pageCourante.contenu()
+   $("#page").html(contenu).removeClass().addClass(this.pageCourante.nom)
    
    if (this.pageCourante.charger)
       this.pageCourante.charger()
    
    if (this.pageCourante.charger)
       this.pageCourante.charger()
@@ -336,13 +355,13 @@ Pages.prototype.afficherPage = function(nomPage, forcerChargement)
   */
 function Formateur()
 {
   */
 function Formateur()
 {
-   this.smiles = conf.smiles\r
-   this.protocoles = "http|https|ed2k"\r
-   \r
-   this.regexUrl = new RegExp("(?:(?:" + this.protocoles + ")://|www\\.)[^ ]*", "gi")\r
-   this.regexImg = new RegExp("^.*?\\.(gif|jpg|png|jpeg|bmp|tiff)$", "i")\r
-   this.regexDomaine = new RegExp("^(?:(?:" + this.protocoles + ")://|www\\.).*?([^/.]+\\.[^/.]+)(?:$|/).*$", "i")\r
-   this.regexTestProtocoleExiste = new RegExp("^(?:" + this.protocoles + ")://.*$", "i")\r
+   this.smiles = conf.smiles
+   this.protocoles = "http|https|ed2k"
+   
+   this.regexUrl = new RegExp("(?:(?:" + this.protocoles + ")://|www\\.)[^ ]*", "gi")
+   this.regexImg = new RegExp("^.*?\\.(gif|jpg|png|jpeg|bmp|tiff)$", "i")
+   this.regexDomaine = new RegExp("^(?:(?:" + this.protocoles + ")://|www\\.).*?([^/.]+\\.[^/.]+)(?:$|/).*$", "i")
+   this.regexTestProtocoleExiste = new RegExp("^(?:" + this.protocoles + ")://.*$", "i")
    this.regexNomProtocole = new RegExp("^(.*?)://")
 }
 
    this.regexNomProtocole = new RegExp("^(.*?)://")
 }
 
@@ -355,16 +374,16 @@ Formateur.prototype.filtrerInputPseudo = function(pseudo)
 {
    return pseudo.replace(/{|}/g, "").trim()
 }
 {
    return pseudo.replace(/{|}/g, "").trim()
 }
-\r
-Formateur.prototype.getSmilesHTML = function()\r
-{\r
-   var XHTML = ""\r
-   for (var sNom in this.smiles)\r
-   {\r
-      XHTML += "<img class=\"" + sNom + "\" src=\"img/smileys/" + sNom + ".gif\" alt =\"" + sNom + "\" />"\r
-   }\r
-   return XHTML\r
-}\r
+
+Formateur.prototype.getSmilesHTML = function()
+{
+   var XHTML = ""
+   for (var sNom in this.smiles)
+   {
+      XHTML += "<img class=\"" + sNom + "\" src=\"img/smileys/" + sNom + ".gif\" alt =\"" + sNom + "\" />"
+   }
+   return XHTML
+}
 
 /**
   * Formatage complet d'un texte.
 
 /**
   * Formatage complet d'un texte.
@@ -392,10 +411,10 @@ Formateur.prototype.traiterLiensConv = function(M)
       }
    )
 }
       }
    )
 }
-\r
-/**\r
+
+/**
   * FIXME : Cette méthode est attrocement lourde ! A optimiser.
   * FIXME : Cette méthode est attrocement lourde ! A optimiser.
-  * moyenne sur échantillon : 234ms\r
+  * moyenne sur échantillon : 234ms
   */
 Formateur.prototype.traiterSmiles = function(M)
 {  
   */
 Formateur.prototype.traiterSmiles = function(M)
 {  
@@ -418,9 +437,9 @@ Formateur.prototype.traiterURL = function(M, pseudo)
    thisFormateur = this
          
    var traitementUrl = function(url)
    thisFormateur = this
          
    var traitementUrl = function(url)
-   {    \r
-      // si ya pas de protocole on rajoute "http://"\r
-      if (!thisFormateur.regexTestProtocoleExiste.test(url))\r
+   {    
+      // si ya pas de protocole on rajoute "http://"
+      if (!thisFormateur.regexTestProtocoleExiste.test(url))
          url = "http://" + url
       var extension = thisFormateur.getShort(url)
       return "<a " + (extension[1] ? "title=\"" + (pseudo == undefined ? "" : thisFormateur.traiterPourFenetreLightBox(pseudo, url) + ": ") +  thisFormateur.traiterPourFenetreLightBox(M, url) + "\"" + " rel=\"lightbox\"" : "") + " href=\"" + url + "\" >[" + extension[0] + "]</a>"
          url = "http://" + url
       var extension = thisFormateur.getShort(url)
       return "<a " + (extension[1] ? "title=\"" + (pseudo == undefined ? "" : thisFormateur.traiterPourFenetreLightBox(pseudo, url) + ": ") +  thisFormateur.traiterPourFenetreLightBox(M, url) + "\"" + " rel=\"lightbox\"" : "") + " href=\"" + url + "\" >[" + extension[0] + "]</a>"
@@ -448,35 +467,35 @@ Formateur.prototype.traiterWikiSyntaxe = function(M)
       }
    )
 }
       }
    )
 }
-\r
-/**\r
-  * Renvoie une version courte de l'url.\r
-  * par exemple : http://en.wikipedia.org/wiki/Yakov_Smirnoff devient wikipedia.org\r
+
+/**
+  * Renvoie une version courte de l'url.
+  * par exemple : http://en.wikipedia.org/wiki/Yakov_Smirnoff devient wikipedia.org
   */
 Formateur.prototype.getShort = function(url)
   */
 Formateur.prototype.getShort = function(url)
-{\r
+{
       var estUneImage = false
       var versionShort = null
       var rechercheImg = this.regexImg.exec(url)
       
       var estUneImage = false
       var versionShort = null
       var rechercheImg = this.regexImg.exec(url)
       
-      if (rechercheImg != null)\r
+      if (rechercheImg != null)
       {
       {
-         versionShort = rechercheImg[1].toLowerCase()\r
-         if (versionShort == "jpeg") versionShort = "jpg" // jpeg -> jpg\r
-         estUneImage = true\r
-      }\r
-      else\r
-      {\r
-         var rechercheDomaine = this.regexDomaine.exec(url)\r
-         if (rechercheDomaine != null && rechercheDomaine.length >= 2)\r
-            versionShort = rechercheDomaine[1]\r
-         else\r
-         {\r
-            var nomProtocole = this.regexNomProtocole.exec(url)\r
-            if (nomProtocole != null && nomProtocole.length >= 2)\r
-               versionShort = nomProtocole[1]\r
-         }\r
-      }\r
+         versionShort = rechercheImg[1].toLowerCase()
+         if (versionShort == "jpeg") versionShort = "jpg" // jpeg -> jpg
+         estUneImage = true
+      }
+      else
+      {
+         var rechercheDomaine = this.regexDomaine.exec(url)
+         if (rechercheDomaine != null && rechercheDomaine.length >= 2)
+            versionShort = rechercheDomaine[1]
+         else
+         {
+            var nomProtocole = this.regexNomProtocole.exec(url)
+            if (nomProtocole != null && nomProtocole.length >= 2)
+               versionShort = nomProtocole[1]
+         }
+      }
       
       return [versionShort == null ? "url" : versionShort, estUneImage]
  }
       
       return [versionShort == null ? "url" : versionShort, estUneImage]
  }
@@ -491,7 +510,7 @@ Formateur.prototype.traiterPourFenetreLightBox = function(M, urlCourante)
    {
       return "[" + thisFormateur.getShort(url)[0] + (urlCourante == url ? "*" : "") + "]"
    }
    {
       return "[" + thisFormateur.getShort(url)[0] + (urlCourante == url ? "*" : "") + "]"
    }
-   \r
+   
    return this.remplacerBalisesHTML(M).replace(this.regexUrl, traitementUrl)
 }
 
    return this.remplacerBalisesHTML(M).replace(this.regexUrl, traitementUrl)
 }
 
@@ -507,30 +526,30 @@ var statutType = {
    // mode déconnecté, ne peut pas poster de message
    deconnected : 2
 }
    // mode déconnecté, ne peut pas poster de message
    deconnected : 2
 }
-\r
-function Client(util)\r
+
+function Client(util)
 {
    this.util = util
 {
    this.util = util
-   \r
+   
    this.cookie = null
    this.regexCookie = new RegExp("^cookie=([^;]*)")
    
    this.cookie = null
    this.regexCookie = new RegExp("^cookie=([^;]*)")
    
-   // données personnels\r
+   // données personnels
    this.resetDonneesPersonnelles()
    
    this.resetDonneesPersonnelles()
    
-   this.setStatut(statutType.deconnected)\r
-   \r
-   // si true alors chaque modification du client est mémorisé sur le serveur\r
-   this.autoflush = $.browser["opera"]\r
+   this.setStatut(statutType.deconnected)
+   
+   // si true alors chaque modification du client est mémorisé sur le serveur
+   this.autoflush = $.browser["opera"]
 }
 }
-\r
-Client.prototype.resetDonneesPersonnelles = function()\r
+
+Client.prototype.resetDonneesPersonnelles = function()
 {
 {
-   this.id = 0\r
-   this.pseudo = conf.pseudoDefaut\r
-   this.login = ""\r
-   this.password = ""\r
-   this.email = ""\r
+   this.id = 0
+   this.pseudo = conf.pseudoDefaut
+   this.login = ""
+   this.password = ""
+   this.email = ""
    this.css = $("link#cssPrincipale").attr("href")
    this.nickFormat = "nick"
    this.viewTimes = true
    this.css = $("link#cssPrincipale").attr("href")
    this.nickFormat = "nick"
    this.viewTimes = true
@@ -543,7 +562,7 @@ Client.prototype.resetDonneesPersonnelles = function()
    // les conversations, une conversation est un objet possédant les attributs suivants :
    // - racine (entier)
    // - page (entier)
    // les conversations, une conversation est un objet possédant les attributs suivants :
    // - racine (entier)
    // - page (entier)
-   this.conversations = new Array()\r
+   this.conversations = new Array()
 }
 
 Client.prototype.setCss = function(css)
 }
 
 Client.prototype.setCss = function(css)
@@ -553,8 +572,6 @@ Client.prototype.setCss = function(css)
 
    this.css = css
    $("link#cssPrincipale").attr("href", this.css)
 
    this.css = css
    $("link#cssPrincipale").attr("href", this.css)
-   this.majMenu()\r
-   \r
    if (this.autoflush) this.flush(true)
 }
 
    if (this.autoflush) this.flush(true)
 }
 
@@ -608,9 +625,9 @@ Client.prototype.ajouterConversation = function(racine)
       if (this.conversations[i].root == racine)
          return false
          
       if (this.conversations[i].root == racine)
          return false
          
-   this.conversations.push({root : racine, page : 1})\r
-   \r
-   if (this.autoflush) this.flush(true)\r
+   this.conversations.push({root : racine, page : 1})
+   
+   if (this.autoflush) this.flush(true)
    
    return true
 }
    
    return true
 }
@@ -622,8 +639,8 @@ Client.prototype.supprimerConversation = function(num)
    // décalage TODO : supprimer le dernier élément 
    for (var i = num; i < this.conversations.length - 1; i++)
       this.conversations[i] = this.conversations[i+1]
    // décalage TODO : supprimer le dernier élément 
    for (var i = num; i < this.conversations.length - 1; i++)
       this.conversations[i] = this.conversations[i+1]
-   this.conversations.pop()\r
-   \r
+   this.conversations.pop()
+   
    if (this.autoflush) this.flush(true)
 }
 
    if (this.autoflush) this.flush(true)
 }
 
@@ -695,21 +712,23 @@ Client.prototype.getCookie = function()
    var cookie = this.regexCookie.exec(document.cookie)
    if (cookie == null) this.cookie = null
    else this.cookie = cookie[1]
    var cookie = this.regexCookie.exec(document.cookie)
    if (cookie == null) this.cookie = null
    else this.cookie = cookie[1]
-}\r
-\r
-Client.prototype.delCookie = function()\r
-{\r
-   document.cookie = "cookie=; max-age=0"\r
 }
 
 }
 
-Client.prototype.setCookie = function(cookie)
+Client.prototype.delCookie = function()
 {
 {
-   if (this.cookie == null)
+   document.cookie = "cookie=; max-age=0"
+}
+
+Client.prototype.setCookie = function()
+{
+   if (this.cookie == null || this.cookie == undefined)
       return
       
       return
       
-   document.cookie =
-      "cookie="+this.cookie+
-      "; max-age="  + (60 * 60 * 24 * 365)
+   // ne fonctionne pas sous IE....
+   /*document.cookie = "cookie=" + this.cookie + "; max-age="  + (60 * 60 * 24 * 365) */
+   
+   document.cookie = 
+      "cookie="+this.cookie+"; expires=" + new Date(new Date().getTime() + 1000 * 60 * 60 * 24 * 365).toUTCString()
 }
 
 Client.prototype.authentifie = function()
 }
 
 Client.prototype.authentifie = function()
@@ -719,38 +738,38 @@ Client.prototype.authentifie = function()
 
 Client.prototype.setStatut = function(statut)
 {  
 
 Client.prototype.setStatut = function(statut)
 {  
-   // conversation en "enum" si en "string"\r
-   if (typeof(statut) == "string")\r
+   // conversation en "enum" si en "string"
+   if (typeof(statut) == "string")
    {
       statut =
          statut == "auth_registered" ?
             statutType.auth_registered :
    {
       statut =
          statut == "auth_registered" ?
             statutType.auth_registered :
-         (statut == "auth_not_registered" ? statutType.auth_not_registered : statutType.deconnected)\r
-   }   \r
-   \r
-   if (statut == this.statut) return\r
-   \r
-   this.statut = statut   \r
+         (statut == "auth_not_registered" ? statutType.auth_not_registered : statutType.deconnected)
+   }   
+   
+   if (statut == this.statut) return
+   
+   this.statut = statut   
    this.majMenu()
 }
    this.majMenu()
 }
-\r
-/**\r
-  * Effectue la connexion vers le serveur.\r
-  * Cette fonction est bloquante tant que la connexion n'a pas été établie.\r
-  * S'il existe un cookie en local on s'authentifie directement avec lui.\r
-  * Si il n'est pas possible de s'authentifier alors on affiche un captcha anti-bot.\r
-  */\r
-Client.prototype.connexionCookie = function()\r
-{\r
-   this.getCookie()\r
+
+/**
+  * Effectue la connexion vers le serveur.
+  * Cette fonction est bloquante tant que la connexion n'a pas été établie.
+  * S'il existe un cookie en local on s'authentifie directement avec lui.
+  * Si il n'est pas possible de s'authentifier alors on affiche un captcha anti-bot.
+  */
+Client.prototype.connexionCookie = function()
+{
+   this.getCookie()
    if (this.cookie == null) return false;
    if (this.cookie == null) return false;
-   return this.connexion(this.getJSONLoginCookie())\r
+   return this.connexion(this.getJSONLoginCookie())
 }
 
 Client.prototype.connexionLogin = function(login, password)
 {
    return this.connexion(this.getJSONLogin(login, password))
 }
 
 Client.prototype.connexionLogin = function(login, password)
 {
    return this.connexion(this.getJSONLogin(login, password))
-}\r
+}
 
 Client.prototype.enregistrement = function(login, password)
 { 
 
 Client.prototype.enregistrement = function(login, password)
 { 
@@ -765,9 +784,9 @@ Client.prototype.enregistrement = function(login, password)
       }
       return false
    }
       }
       return false
    }
-   else\r
+   else
    {
    {
-      return this.connexion(this.getJSONEnregistrement(login, password))\r
+      return this.connexion(this.getJSONEnregistrement(login, password))
    }
 }
 
    }
 }
 
@@ -794,14 +813,14 @@ Client.prototype.connexion = function(messageJson)
       }
    )
    return this.authentifie()
       }
    )
    return this.authentifie()
-}\r
-\r
-Client.prototype.deconnexion = function()\r
+}
+
+Client.prototype.deconnexion = function()
 {
    this.flush(true)
    this.delCookie()
 {
    this.flush(true)
    this.delCookie()
-   this.resetDonneesPersonnelles()\r
-   this.setStatut(statutType.deconnected) // deconnexion\r
+   this.resetDonneesPersonnelles()
+   this.setStatut(statutType.deconnected) // deconnexion
 }
 
 Client.prototype.chargerDonnees = function(data)
 }
 
 Client.prototype.chargerDonnees = function(data)
@@ -817,10 +836,10 @@ Client.prototype.chargerDonnees = function(data)
       this.cookie = data["cookie"]
       this.setCookie()
       
       this.cookie = data["cookie"]
       this.setCookie()
       
-      this.id = data["id"]\r
+      this.id = data["id"]
       this.login = data["login"]
       this.login = data["login"]
-      this.pseudo = data["nick"]\r
-      this.email = data["email"]\r
+      this.pseudo = data["nick"]
+      this.email = data["email"]
       this.setCss(data["css"])
       this.nickFormat = data["nick_format"]
       this.viewTimes = data["view_times"]
       this.setCss(data["css"])
       this.nickFormat = data["nick_format"]
       this.viewTimes = data["view_times"]
@@ -833,6 +852,7 @@ Client.prototype.chargerDonnees = function(data)
       this.conversations = data["conversations"]
       
       this.majBulle()
       this.conversations = data["conversations"]
       
       this.majBulle()
+      this.majCssSelectionee()
    }
 }
 
    }
 }
 
@@ -882,8 +902,6 @@ Client.prototype.flush = function(async)
 
 Client.prototype.majMenu = function()
 {
 
 Client.prototype.majMenu = function()
 {
-   // TODO : à virer : ne plus changer de style de display ... spa beau .. ou trouver une autre méthode
-   // var displayType = this.css == "css/3/euphorik.css" ? "block" : "inline" //this.client
    displayType = "block"
 
    $("#menu .admin").css("display", this.ekMaster ? displayType : "none")
    displayType = "block"
 
    $("#menu .admin").css("display", this.ekMaster ? displayType : "none")
@@ -891,19 +909,19 @@ Client.prototype.majMenu = function()
    // met à jour le menu   
    if (this.statut == statutType.auth_registered)
    {
    // met à jour le menu   
    if (this.statut == statutType.auth_registered)
    {
-      $("#menu .profile").css("display", displayType).text("profile")\r
+      $("#menu .profile").css("display", displayType).text("profile")
       $("#menu .logout").css("display", displayType)
       $("#menu .register").css("display", "none")
    }
    else if (this.statut == statutType.auth_not_registered)
    {
       $("#menu .logout").css("display", displayType)
       $("#menu .register").css("display", "none")
    }
    else if (this.statut == statutType.auth_not_registered)
    {
-      $("#menu .profile").css("display", "none")\r
+      $("#menu .profile").css("display", "none")
       $("#menu .logout").css("display", displayType)
       $("#menu .register").css("display", displayType)
    }
    else
    {
       $("#menu .logout").css("display", displayType)
       $("#menu .register").css("display", displayType)
    }
    else
    {
-      $("#menu .profile").css("display", displayType).text("login")\r
+      $("#menu .profile").css("display", displayType).text("login")
       $("#menu .logout").css("display", "none")
       $("#menu .register").css("display", displayType)
    }
       $("#menu .logout").css("display", "none")
       $("#menu .register").css("display", displayType)
    }
@@ -917,6 +935,20 @@ Client.prototype.majBulle = function()
    this.util.bulleActive = this.viewTooltips
 }
 
    this.util.bulleActive = this.viewTooltips
 }
 
+/**
+  * Met à jour la css sélectionnée, lors du chargement des données.
+  */
+Client.prototype.majCssSelectionee = function()
+{
+   // extraction du numéro de la css courante
+   var numCssCourante = this.css.match(/^.*?\/(\d)\/.*$/)
+   if (numCssCourante[1] != undefined)
+   {
+      $("#menuCss option").removeAttr("selected")
+      $("#menuCss option[value=" + numCssCourante[1]+ "]").attr("selected", "selected")
+   }
+}
+
 Client.prototype.slap = function(userId, raison)
 {
    var thisClient = this
 Client.prototype.slap = function(userId, raison)
 {
    var thisClient = this
@@ -979,6 +1011,16 @@ Client.prototype.kick = function(userId, raison)
 
 /**
    * classe permettant de gérer les événements (push serveur).
 
 /**
    * classe permettant de gérer les événements (push serveur).
+   * l'information envoyé est sous la forme :
+   *  {
+   *     "action" : "wait_event"
+   *     "page" : <page>
+   *     [..]
+   *  }
+   * l'information reçu est sous la forme :
+   *  {
+   *     "reply" : <reply>
+   *  }
    * @page la page
    */
 function PageEvent(page, util)
    * @page la page
    */
 function PageEvent(page, util)
@@ -1009,9 +1051,11 @@ PageEvent.prototype.stopAttenteCourante = function()
 /**
   * Attend un événement lié à la page. 
   * @funSend une fonction renvoyant les données json à envoyer
 /**
   * Attend un événement lié à la page. 
   * @funSend une fonction renvoyant les données json à envoyer
-  * @funReceive une fonction qui accepte un paramètre correspondant au données reçues
+  * @funsReceive est un objet comprenant les fonctions à appeler en fonction du "reply"
+  * les fonctions acceptent un paramètre correspondant au données reçues.
+  * exemple : {"new_message" : function(data){ ... }}
   */
   */
-PageEvent.prototype.waitEvent = function(funSend, funReceive)
+PageEvent.prototype.waitEvent = function(funSend, funsReceive)
 {
    this.stopAttenteCourante()
    
 {
    this.stopAttenteCourante()
    
@@ -1035,22 +1079,26 @@ PageEvent.prototype.waitEvent = function(funSend, funReceive)
    this.attenteCourante = jQuery.ajax({
       type: "POST",
       url: "request",
    this.attenteCourante = jQuery.ajax({
       type: "POST",
       url: "request",
-      dataType: "json",
+      dataType: "json",\r
+      timeout: 300000, // timeout de 5min. Gros HACK pas beau. FIXME problème décrit ici : http://groups.google.com/group/jquery-en/browse_thread/thread/8724e64af3333a76
+      // Obsolète (voir TODO)
+      //timeout: 300000, // timeout de 5min. Gros HACK pas beau. FIXME problème décrit ici : http://groups.google.com/group/jquery-en/browse_thread/thread/8724e64af3333a76
       data: this.util.jsonVersAction(dataToSend),
       success:
          function(data)
          {            
             ;; dumpObj(data)
             
       data: this.util.jsonVersAction(dataToSend),
       success:
          function(data)
          {            
             ;; dumpObj(data)
             
-            funReceive(data)
+            funsReceive[data["reply"]](data)
             
             // rappel de la fonction dans 100 ms
             
             // rappel de la fonction dans 100 ms
-            setTimeout(function(){ thisPageEvent.waitEvent2(funSend, funReceive) }, 100)
+            setTimeout(function(){ thisPageEvent.waitEvent2(funSend, funsReceive) }, 100)
          },
       error:
          function(XMLHttpRequest, textStatus, errorThrown)
          {
          },
       error:
          function(XMLHttpRequest, textStatus, errorThrown)
          {
-            setTimeout(function(){ thisPageEvent.waitEvent2(funSend, funReceive) }, 1000)
+            ;; console.log("Connexion perdue dans waitEvent")
+            setTimeout(function(){ thisPageEvent.waitEvent2(funSend, funsReceive) }, 1000)
          }
    })
 }
          }
    })
 }
@@ -1058,11 +1106,11 @@ PageEvent.prototype.waitEvent = function(funSend, funReceive)
 /**
   * Si un stopAttenteCourante survient un peu n'importe quand il faut imédiatement arreter de boucler.
   */
 /**
   * Si un stopAttenteCourante survient un peu n'importe quand il faut imédiatement arreter de boucler.
   */
-PageEvent.prototype.waitEvent2 = function(funSend, funReceive)
+PageEvent.prototype.waitEvent2 = function(funSend, funsReceive)
 {
    if (this.stop)
       return
 {
    if (this.stop)
       return
-   this.waitEvent(funSend, funReceive)
+   this.waitEvent(funSend, funsReceive)
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1079,7 +1127,7 @@ function initialiserListeStyles(client)
             
 // charge dynamiquement le script de debug
 ;; jQuery.ajax({async : false, url : "js/debug.js", dataType : "script"})
             
 // charge dynamiquement le script de debug
 ;; jQuery.ajax({async : false, url : "js/debug.js", dataType : "script"})
-      \r
+      
 // le main
 $(document).ready(
    function()
 // le main
 $(document).ready(
    function()
@@ -1087,9 +1135,9 @@ $(document).ready(
       var formateur = new Formateur()
       var util = new Util(formateur)
       var client = new Client(util)
       var formateur = new Formateur()
       var util = new Util(formateur)
       var client = new Client(util)
-      var pages = new Pages()\r
-      \r
-      // connexion vers le serveur (utilise un cookie qui traine)\r
+      var pages = new Pages()
+      
+      // connexion vers le serveur (utilise un cookie qui traine)
       client.connexionCookie()
       
       initialiserListeStyles(client)
       client.connexionCookie()
       
       initialiserListeStyles(client)
@@ -1100,7 +1148,7 @@ $(document).ready(
       
       $("#menu .minichat").click(function(){ pages.afficherPage("minichat") })
       $("#menu .admin").click(function(){ pages.afficherPage("admin") })
       
       $("#menu .minichat").click(function(){ pages.afficherPage("minichat") })
       $("#menu .admin").click(function(){ pages.afficherPage("admin") })
-      $("#menu .profile").click(function(){ pages.afficherPage("profile") })\r
+      $("#menu .profile").click(function(){ pages.afficherPage("profile") })
       $("#menu .logout").click(function(){
          util.messageDialogue("Êtes-vous sur de vouloir vous délogger ?", messageType.question,
             {"Oui" : function()
       $("#menu .logout").click(function(){
          util.messageDialogue("Êtes-vous sur de vouloir vous délogger ?", messageType.question,
             {"Oui" : function()
@@ -1114,12 +1162,17 @@ $(document).ready(
       })
       $("#menu .register").click(function(){ pages.afficherPage("register") })
       $("#menu .about").click(function(){ pages.afficherPage("about") })
       })
       $("#menu .register").click(function(){ pages.afficherPage("register") })
       $("#menu .about").click(function(){ pages.afficherPage("about") })
+      
+      // TODO : simplifier et pouvoir créer des liens par exemple : <span class="lien" href="conditions">Conditions d'utilisation</span>
+      $("#footer .conditions").click(function(){ pages.afficherPage("conditions_utilisation") })
 
       pages.ajouterPage(new PageMinichat(client, formateur, util))
       pages.ajouterPage(new PageAdmin(client, formateur, util))
       pages.ajouterPage(new PageProfile(client, formateur, util))
       pages.ajouterPage(new PageRegister(client, formateur, util))
       pages.ajouterPage(new PageAbout(client, formateur, util))
 
       pages.ajouterPage(new PageMinichat(client, formateur, util))
       pages.ajouterPage(new PageAdmin(client, formateur, util))
       pages.ajouterPage(new PageProfile(client, formateur, util))
       pages.ajouterPage(new PageRegister(client, formateur, util))
       pages.ajouterPage(new PageAbout(client, formateur, util))
+      pages.ajouterPage("conditions_utilisation")
+      
       pages.afficherPage("minichat")
    }
 )
       pages.afficherPage("minichat")
    }
 )