MOD avancement dans la Grande Restructuration
[euphorik.git] / js / euphorik.js
index b36fbbb..8c13841 100755 (executable)
-// coding: utf-8\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
-  * Normalement 'const' à la place de 'var' mais non supporté par IE7.
-  */\r
-var conf = {\r
-   nbMessageAffiche : 10, // (par page)
-   pseudoDefaut : "<nick>",\r
-   tempsAffichageMessageDialogue : 4000, // en ms\r
-   smiles : {   \r
-      "smile" : [/:\)/g, /:-\)/g],  \r
-      "bigsmile" : [/:D/g, /:-D/g],\r
-      "clin" : [/;\)/g, /;-\)/g],\r
-      "cool" : [/8\)/g, /8-\)/g],\r
-      "eheheh" : [/:P/g, /:-P/g],
-      "lol" : [/\[-lol\]/g],
-      "spliff" : [/\[-spliff\]/g],\r
-      "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
-      "argn" : [/\[-argn\]/g],
-      "redface" : [/\[-redface\]/g],\r
-      "bunny" : [/\[-lapin\]/g],\r
-      "chat" : [/\[-chat\]/g],\r
-      "renne" : [/\[-renne\]/g],\r
-      "star" : [/\[-star\]/g],\r
-      "kirby" : [/\[-kirby\]/g],
-      "slurp" : [/\[-slurp\]/g],
-      "agreed" : [/\[-agreed\]/g],
-      "dodo" : [/\[-dodo\]/g],
-      "bn" : [/\[-bn\]/g]\r
-   }\r
-}\r
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-\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
+// tout euphorik est contenu dans cet objet
+var euphorik = {}
+// ;; euphorik.include = 
+// ;; euphorik.include = function(f) { var s = document.createElement('script'); s.type = 'text/javascript'; s.src = "js/" + f + ".js"; document.getElementsByTagName('head')[0].appendChild(s); }
+
+
+// version jQuery : function(f) { jQuery.ajax({async : false, url : "js/" + f + ".js", dataType : "script"}) }
+// mais comme il n'est pas encore chargé...
+;; euphorik.include = function(f) {
+;;    var req, url = 'js/' + f + '.js'
+;;    if  (window.XMLHttpRequest) {
+;;       req = new XMLHttpRequest(); req.open("GET", url, false /* async */); req.send(null);
+;;    } else if (window.ActiveXObject) {    
+;;       req = new ActiveXObject((navigator.userAgent.toLowerCase().indexOf('msie 5') != -1) ? "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP");
+;;       if (req) { req.open("GET", url, false); req.send(); }
+;;    }
+;;    if (req!==false) { if (req.status==200) { window.eval(req.responseText); } else if (req.status==404) { alert("erreur de chargement (404) de : " + url) } }
+;; } 
+
+;; euphorik.include("jquery")
+;; euphorik.include("jquery.lightbox")
+;; euphorik.include("md5")
+;; euphorik.include("json2")
+
+;; euphorik.include("conf")
+;; euphorik.include("util")\r
+;; euphorik.include("formateur")\r
+;; euphorik.include("pages")
+
+;; euphorik.include("pageMinichat")
+;; euphorik.include("pageAdmin")
+;; euphorik.include("pageProfile")
+;; euphorik.include("pageRegister")
+;; euphorik.include("pageAbout")
+\r
+\r
+// tout un tas d'améliorations de JavaScript ;)\r
 /**\r
 /**\r
-  * Cette classe regroupe des fonctions utilitaires (helpers).\r
-  */
-function Util()
-{
-   $("#info .fermer").click(function(){
-      $("#info").slideUp(50) 
-   })
-}
-
-/**
-  * 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
-  *        et les valeurs les fonctions executées lorsqu'un bouton est activé.
-  */
-Util.prototype.messageDialogue = function(message, type, boutons)
-{
-   if (type == undefined)
-      type = messageType.informatif
-
-   if (this.timeoutMessageDialogue != undefined)
-      clearTimeout(this.timeoutMessageDialogue)
-      
-   var fermer = function(){$("#info").slideUp(100)}
-   fermer()   
-   
-   $("#info .message").html(message)
-   switch(type)
-   {
-      case messageType.informatif : $("#info #icone").attr("class", "information"); break
-      case messageType.question : $("#info #icone").attr("class", "interrogation"); break
-      case messageType.erreur : $("#info #icone").attr("class", "exclamation"); break
-   }   
-   $("#info .boutons").html("")
-   for (var b in boutons)
-      $("#info .boutons").append("<div>" + b + "</div>").find("div:last").click(boutons[b]).click(fermer)
-   
-   $("#info").slideDown(200)
-   this.timeoutMessageDialogue = setTimeout(fermer, conf.tempsAffichageMessageDialogue)   
-}
-
-var messageType = {informatif: 0, question: 1, erreur: 2}\r
-
-/**
-  * Utilisé pour l'envoie de donnée avec la méthode ajax de jQuery.
-  */
-Util.prototype.jsonVersAction = function(json)
-{
-   return {action : JSON.stringify(json) }
-}
-\r
-Util.prototype.md5 = function(chaine)\r
-{\r
-   return hex_md5(chaine)\r
-}
-\r
-// pompé de http://www.faqts.com/knowledge_base/view.phtml/aid/13562/fid/130\r
-Util.prototype.setSelectionRange = function(input, selectionStart, selectionEnd)
-{\r
-   if (input.setSelectionRange)
-   {\r
-      input.focus()\r
-      input.setSelectionRange(selectionStart, selectionEnd)\r
-   }\r
-   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
+  * Pour chaque propriété de l'objet execute f(p, v) ou p est le nom de la propriété et v sa valeur.\r
+  * Ne parcours pas les propriétés des prototypes.\r
+  */\r
+Object.prototype.each = function(f) {\r
+   for (var k in this) {\r
+      if (this.hasOwnProperty(k)) {\r
+         f(k, this[k]);\r
+      }\r
    }\r
    }\r
-}
+};\r
 \r
 \r
-Util.prototype.setCaretToEnd = function(input)
-{\r
-   this.setSelectionRange(input, input.value.length, input.value.length)\r
-}\r
-Util.prototype.setCaretToBegin = function(input)
-{\r
-   this.setSelectionRange(input, 0, 0)\r
-}\r
-Util.prototype.setCaretToPos = function(input, pos)
-{\r
-   this.setSelectionRange(input, pos, pos)\r
-}\r
-Util.prototype.selectString = function(input, string)
-{\r
-   var match = new RegExp(string, "i").exec(input.value)\r
-   if (match)
-   {\r
-      this.setSelectionRange (input, match.index, match.index + match[0].length)\r
-   }\r
-}\r
-Util.prototype.replaceSelection = function(input, replaceString) {\r
-   if (input.setSelectionRange)
-   {\r
-      var selectionStart = input.selectionStart\r
-      var selectionEnd = input.selectionEnd\r
-      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
-   else if (document.selection)
-   {\r
-      var range = document.selection.createRange();\r
-      if (range.parentElement() == input)
-      {\r
-         var isCollapsed = range.text == ''\r
-         range.text = replaceString\r
-         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
+Array.prototype.each = function(f) {\r
+   for (var i = 0; i < this.length; i++) {\r
+      f(i, this[i]);\r
    }\r
    }\r
-}
-
-Util.prototype.rot13 = function(chaine)
-{
-   var ACode = 'A'.charCodeAt(0)
-   var aCode = 'a'.charCodeAt(0)
-   var MCode = 'M'.charCodeAt(0)
-   var mCode = 'm'.charCodeAt(0)
-   var ZCode = 'Z'.charCodeAt(0)
-   var zCode = 'z'.charCodeAt(0)
-
-   var f = function(ch, pos) {
-      if (pos == ch.length)
-         return ""
-      
-      var c = ch.charCodeAt(pos);
-      return String.fromCharCode(
-         c +
-         (c >= ACode && c <= MCode || c >= aCode && c <= mCode ? 13 :
-         (c > MCode && c <= ZCode || c > mCode && c <= zCode ? -13 : 0))
-      ) + f(ch, pos + 1)
-   }
-   return f(chaine, 0)
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-function Pages()
-{
-   this.pageCourante = null
-   this.pages = {}
-}
-
-Pages.prototype.ajouterPage = function(page)
-{
-   page.pages = this // la magie des langages dynamiques : le foutoire
-   this.pages[page.nom] = page
-}
-
-Pages.prototype.afficherPage = function(nomPage, forcerChargement)
-{\r
-   if (forcerChargement == undefined) forcerChargement = false\r
-
-   var page = this.pages[nomPage]
-   if (page == undefined || (!forcerChargement && page == this.pageCourante)) return
-   
-   if (this.pageCourante != null && this.pageCourante.decharger)
-      this.pageCourante.decharger()
-  
-   $("#menu div").removeClass("courante")
-   $("#menu div." + nomPage).addClass("courante")
-      
-   this.pageCourante = page
-   $("#page").html(this.pageCourante.contenu()).removeClass().addClass(this.pageCourante.nom)
-   
-   if (this.pageCourante.charger)
-      this.pageCourante.charger()
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-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.regexNomProtocole = new RegExp("^(.*?)://")
-}
-
-/**
-  * Formate un pseudo saise par l'utilisateur.
-  * @param pseudo le pseudo brut
-  * @return le pseudo filtré
-  */
-Formateur.prototype.filtrerInputPseudo = function(pseudo)
-{
-   return pseudo.replace(/{|}/g, "").trim()
-}
+};\r
 \r
 \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\" />"\r
+Array.prototype.map = function(f) {\r
+   for (var i = 0; i < this.length; i++) {\r
+      this[i] = f(this[i])\r
    }\r
    }\r
-   return XHTML\r
-}\r
+};\r
 
 
-Formateur.prototype.traitementComplet = function(M, pseudo)
-{
-   return this.traiterLiensConv(this.traiterSmiles(this.traiterURL(this.remplacerBalisesHTML(M), pseudo)))
+String.prototype.trim = function() {
+       return jQuery.trim(this) // anciennement : this.replace(/^\s+|\s+$/g, "");
 }
 
 }
 
-/**
-  * Transforme les liens en entités clickables.
-  * Un lien vers une conversation permet d'ouvrire celle ci, elle se marque comme ceci dans un message :
-  * "{5F}" ou 5F est la racine de la conversation.
-  * Ce lien sera transformer en <span class="lienConv">{5F}</span> pouvant être clické pour créer la conv 5F.
-  */
-Formateur.prototype.traiterLiensConv = function(M)
-{
-   return M.replace(
-      /\{\w+\}/g,
-      function(lien)
-      {
-         return "<span class=\"lienConv\">" + lien + "</span>"
-      }
-   )
-}
-\r
-/**\r
-  * FIXME : Cette méthode est attrocement lourde ! A optimiser.
-  * moyenne su échantillon : 234ms\r
-  */
-Formateur.prototype.traiterSmiles = function(M)
-{  
-   for (var sNom in this.smiles)
-   {
-      ss = this.smiles[sNom]
-      for (var i = 0; i < ss.length; i++)       
-         M = M.replace(ss[i], "<img src=\"img/smileys/" + sNom + ".gif\" />")
-   }
-   return M
+String.prototype.ltrim = function() {
+       return this.replace(/^\s+/, "");
 }
 
 }
 
-Formateur.prototype.remplacerBalisesHTML = function(M)
-{
-   return M.replace(/</g, "&lt;").replace(/>/g, "&gt;")
-}
-
-Formateur.prototype.traiterURL = function(M, pseudo)
-{
-   thisFormateur = this
-   
-   if (pseudo == undefined)
-      pseudo = ""
-         
-   var traitementUrl = function(url)
-   {    \r
-      // si ya pas de protocole on rajoute "http://"\r
-      if (!thisFormateur.regexTestProtocoleExiste.test(url))\r
-         url = "http://" + url
-      var extension = thisFormateur.getShort(url)
-      return "<a " + (extension[1] ? "title=\"" + thisFormateur.traiterPourFenetreLightBox(pseudo, url) + ": " +  thisFormateur.traiterPourFenetreLightBox(M, url) + "\"" + " rel=\"lightbox\"" : "") + " href=\"" + url + "\" >[" + extension[0] + "]</a>"
-   }
-   return M.replace(this.regexUrl, traitementUrl)
-}
-\r
-/**\r
-  * Renvoie une version courte de l'url.\r
-  * par exemple : http://en.wikipedia.org/wiki/Yakov_Smirnoff devient wikipedia.org\r
-  */
-Formateur.prototype.getShort = function(url)
-{\r
-      var estUneImage = false
-      var versionShort = null
-      var rechercheImg = this.regexImg.exec(url)\r
-      //alert(url)
-      if (rechercheImg != null)\r
-      {
-         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
-      
-      return [versionShort == null ? "url" : versionShort, estUneImage]
- }
-/**
-  * Traite les pseudo et messages à être affiché dans le titre d'une image visualisé avec lightbox.
-  */
-Formateur.prototype.traiterPourFenetreLightBox = function(M, urlCourante)
-{
-   thisFormateur = this
-   var traitementUrl = function(url)
-   {
-      return "[" + thisFormateur.getShort(url)[0] + (urlCourante == url ? ": image courante" : "") + "]"
-   }
-   \r
-   return this.remplacerBalisesHTML(M).replace(this.regexUrl, traitementUrl)
+String.prototype.rtrim = function() {
+       return this.replace(/\s+$/, "");
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-// les statuts possibes du client
-var statutType = {
-   // mode enregistré, peut poster des messages et modifier son profile
-   auth_registered : 0,
-   // mode identifié, peut poster des messages mais n'a pas accès au profile
-   auth_not_registered : 1,
-   // mode déconnecté, ne peut pas poster de message
-   deconnected : 2
-}
-\r
-function Client(util)\r
-{
-   this.util = util
-   \r
-   this.cookie = null
-   this.regexCookie = new RegExp("^cookie=([^;]*)")
-   
-   // données personnels\r
-   this.resetDonneesPersonnelles()
-   
-   this.setStatut(statutType.deconnected)
-   
-   // le dernier message d'erreur recut du serveur (par exemple une connexion foireuse : "login impossible")
-   this.dernierMessageErreur = ""\r
-}
-\r
-Client.prototype.resetDonneesPersonnelles = function()\r
-{\r
-   this.pseudo = conf.pseudoDefaut\r
-   this.login = ""\r
-   this.password = ""\r
-   this.email = ""\r
-   this.css = $("link#cssPrincipale").attr("href")
-   this.nickFormat = "nick"
-   
-   this.pagePrincipale = 1
-   this.ekMaster = false
-   
-   // les conversations, une conversation est un objet possédant les attributs suivants :
-   // - racine (entier)
-   // - page (entier)
-   this.conversations = new Array()\r
-}
-
-Client.prototype.setCss = function(css)
-{
-   if (this.css == css)
-      return
-
-   this.css = css
-   $("link#cssPrincipale").attr("href", this.css)
-   this.majMenu()
-}
-
-Client.prototype.pageSuivante = function(numConv)
-{
-   if (numConv < 0 && this.pagePrincipale > 1)
-      this.pagePrincipale -= 1
-   else if (this.conversations[numConv].page > 1)
-      this.conversations[numConv].page -= 1
-}
-
-Client.prototype.pagePrecedente = function(numConv)
-{
-   if (numConv < 0)
-      this.pagePrincipale += 1
-   else 
-      this.conversations[numConv].page += 1
-}
-
-/**
-  * Définit la première page pour la conversation donnée.
-  * @return true si la page a changé sinon false
-  */
-Client.prototype.goPremierePage = function(numConv)
-{
-   if (numConv < 0)
-   {
-      if (this.pagePrincipale == 1)
-         return false
-      this.pagePrincipale = 1
-   }
-   else
-   {
-      if (this.conversations[numConv].page == 1)
-         return false
-      this.conversations[numConv].page = 1
-   }
-   return true
-}
-
-/**
-  * Ajoute une conversation à la vue de l'utilisateur.
-  * Le profile de l'utilisateur est directement sauvegardé sur le serveur.
-  * @param racines la racine de la conversation (integer)
-  * @return true si la conversation a été créée sinon false (par exemple si la conv existe déjà)
-  */
-Client.prototype.ajouterConversation = function(racine)
-{
-   // vérification s'il elle n'existe pas déjà
-   for (var i = 0; i < this.conversations.length; i++)
-      if (this.conversations[i].root == racine)
-         return false
-         
-   this.conversations.push({root : racine, page : 1})
-   return true
-}
-
-Client.prototype.supprimerConversation = function(num)
-{
-   if (num < 0 || num >= this.conversations.length) return
-   
-   // 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()
-}
-
-Client.prototype.getJSONLogin = function(login, password)
-{
-   return {
-      "action" : "authentification",
-      "login" : login,
-      "password" : password
-   }
-}
-
-Client.prototype.getJSONLoginCookie = function()
-{
-   return {
-      "action" : "authentification",
-      "cookie" : this.cookie
-   }
-}  
-
-/**
-  * le couple (login, password) est facultatif. S'il n'est pas fournit alors il ne sera pas possible
-  * de s'autentifier avec (login, password).
-  */
-Client.prototype.getJSONEnregistrement = function(login, password)
-{
-   var mess = { "action" : "register" }
-   
-   if (login != undefined && password != undefined)
-   {
-      mess["login"] = login
-      mess["password"] = password
-   }
-   
-   return mess;
-}
-
-Client.prototype.getJSONConversations = function()
-{
-   var conversations = new Array()
-   for (var i = 0; i < this.conversations.length; i++)
-      conversations.push({ "root" : this.conversations[i].root, "page" : this.conversations[i].page})
-   return conversations
-}
-
-Client.prototype.getJSONProfile = function()
-{
-   return {
-      "action" : "set_profile",
-      "cookie" : this.cookie,
-      "login" : this.login,
-      "password" : this.password,
-      "nick" : this.pseudo,
-      "email" : this.email,
-      "css" : this.css,
-      "nick_format" : this.nickFormat,
-      "main_page" : this.pagePrincipale < 1 ? 1 : this.pagePrincipale,
-      "conversations" : this.getJSONConversations()
-   }
-}
-
-/**
-  * Renvoie null si pas définit.
-  */
-Client.prototype.getCookie = function()
-{
-   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)
-{
-   if (this.cookie == null)
-      return
-      
-   document.cookie =
-      "cookie="+this.cookie+
-      "; max-age="  + (60 * 60 * 24 * 365)
-}
-
-Client.prototype.authentifie = function()
-{
-   return this.statut == statutType.auth_registered || this.statut == statutType.auth_not_registered
-}
-
-Client.prototype.setStatut = function(statut)
-{  
-   //alert(statut)
-   // conversation en "enum" si en "string"\r
-   if (typeof(statut) == "string")\r
-   {
-      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
-   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
-   if (this.cookie == null) return false;
-   return this.connexion(this.getJSONLoginCookie())\r
-}
-
-Client.prototype.connexionLogin = function(login, password)
-{
-   return this.connexion(this.getJSONLogin(login, password))
-}\r
-
-Client.prototype.enregistrement = function(login, password)
-{ 
-   if (this.authentifie())
-   {
-      this.login = login
-      this.password = password
-      if(this.flush())
-         this.setStatut(statutType.auth_registered)
-      return true
-   }
-   else\r
-   {
-      return this.connexion(this.getJSONEnregistrement(login, password))\r
-   }
-}
-
-Client.prototype.connexion = function(messageJson)
-{
-   ;;; dumpObj(messageJson)
-   thisClient = this
-   jQuery.ajax(
-      {
-         async: false,
-         type: "POST",
-         url: "request",
-         dataType: "json",
-         data: this.util.jsonVersAction(messageJson),
-         success:
-            function(data)
-            {
-               ;;; dumpObj(data)
-               thisClient.chargerDonnees(data)
-            }
-      }
-   )
-   return this.authentifie()
-}\r
-\r
-Client.prototype.deconnexion = function()\r
-{
-   this.flush()
-   this.delCookie()\r
-   this.setStatut(statutType.deconnected) // deconnexion\r
-   this.resetDonneesPersonnelles()\r
-}
 
 
-Client.prototype.chargerDonnees = function(data)
-{
-   var thisClient = this
-
-   this.setStatut(data["status"]) 
-   
-   if (this.authentifie())
-   {
-      this.cookie = data["cookie"]
-      this.setCookie()
-      \r
-      this.login = data["login"]
-      this.pseudo = data["nick"]\r
-      this.email = data["email"]\r
-      this.css = data["css"]
-      this.nickFormat = data["nick_format"]
-      
-      // la page de la conversation principale
-      this.pagePrincipale = data["main_page"] == undefined ? 1 : data["main_page"]
-      
-      // met à jour la css
-      if (this.css != "")
-      {
-         $("link#cssPrincipale").attr("href", this.css)
-         this.majMenu()
-      }
-      // les conversations
-      thisClient.conversations = data["conversations"]
-      
-      thisClient.ekMaster = data["ek_master"]
-   }
-   this.dernierMessageErreur = data["error_message"]
-}
-
-/**
-  * Met à jour les données personne sur serveur.
-  * @param async de manière asynchrone ? défaut = true
-  * @return false si le flush n'a pas pû se faire sinon true
-  */
-Client.prototype.flush = function(async)
-{
-   if (async == undefined)
-      async = true
-      
-   if (!this.authentifie())
-      return false
-
-   thisClient = this
-   ;;; dumpObj(this.getJSONProfile())
-   jQuery.ajax(
-      {
-         async: async,
-         type: "POST",
-         url: "request",
-         dataType: "json",
-         data: this.util.jsonVersAction(this.getJSONProfile()),
-         success:
-            function(data)
-            {
-               //thisClient.util.log(thisClient.util.serializer.serializeToString(data))   
-            }
-      }
-   )
-   // TODO : retourner false si un problème est survenu lors de l'update du profile
-   return true
-}
-
-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
-
-   $("#menu .admin").css("display", this.ekMaster ? "none" : "inline")
-
-   // met à jour le menu   
-   if (this.statut == statutType.auth_registered)
-   {
-      $("#menu .profile").css("display", displayType).text("profile")\r
-      $("#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 .logout").css("display", displayType)
-      $("#menu .register").css("display", displayType)
-   }
-   else
-   {
-      $("#menu .profile").css("display", displayType).text("login")\r
-      $("#menu .logout").css("display", "none")
-      $("#menu .register").css("display", displayType)
-   }
-}
-
-
-Client.prototype.slap = function(userId, raison)
-{
-   var thisClient = this
-   
-   jQuery.ajax({
-      type: "POST",
-      url: "request",
-      dataType: "json",
-      data: this.util.jsonVersAction(
-         {
-            "action" : "slap",
-            "cookie" : thisClient.cookie,
-            "user_id" : userId,
-            "reason" : raison
-         }),
-      success: 
-         function(data)
-         {
-            if (data["reply"] == "error")
-               thisClient.util.messageDialogue(data["error_message"])
-         }
-   })
-}
-
-
-Client.prototype.ban = function(userId, raison, minutes)
-{
-   var thisClient = this
-
-   // par défaut un ban correspond à 3 jours
-   if (typeof(minutes) == "undefined")
-      minutes = 60 * 24 * 3
-      
-   jQuery.ajax({
-      type: "POST",
-      url: "request",
-      dataType: "json",
-      data: this.util.jsonVersAction(
-         {
-            "action" : "ban",
-            "cookie" : thisClient.cookie,
-            "duration" : minutes,
-            "user_id" : userId,
-            "reason" : raison
-         }),
-      success: 
-         function(data)
-         {
-            if (data["reply"] == "error")
-               thisClient.util.messageDialogue(data["error_message"])
-         }
-   })
-}
-
-Client.prototype.kick = function(userId, raison)
-{
-   this.ban(userId, raison, 15)
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-function initialiserListeStyles(client)
-{
-   $("#menuCss").change(
-      function()
-      {
-         client.setCss("css/" + $("option:selected", this).attr("value") + "/euphorik.css")
-      }
-   )
-}
-            
-// 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()
-   {  
-      var util = new Util()
+   {
+      var formateur = new euphorik.Formateur()
+      var util = new euphorik.Util(formateur)
       var client = new Client(util)
       var client = new Client(util)
-      var pages = new Pages()
-      var formateur = new Formateur()\r
-      \r
-      // connexion vers le serveur (utilise un cookie qui traine)\r
+      var pages = new euphorik.Pages()
+      
+      // connexion vers le serveur (utilise un cookie qui traine)
       client.connexionCookie()
       
       client.connexionCookie()
       
-      initialiserListeStyles(client)
+      $("#menuCss").change(function(){ client.setCss("styles/" + $("option:selected", this).attr("value") + "/euphorik.css")})
 
 
-      // TODO : pourquoi $(document).unload ne fonctionne pas ?
-      $(window).unload(function(){client.flush(false)})
+      // FIXME : ne fonctionne pas sous opera
+      // voir : http://dev.jquery.com/ticket/2892#preview
+      $(window).unload(function(){client.flush()})
       
       $("#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(){
       $("#menu .logout").click(function(){
-         util.messageDialogue("Êtes-vous sur de vouloir vous délogger ?", messageType.question,
+         util.messageDialogue("Êtes-vous sur de vouloir vous délogger ?", euphorik.Util.messageType.question,
             {"Oui" : function()
                {
                   client.deconnexion();
             {"Oui" : function()
                {
                   client.deconnexion();
@@ -882,12 +134,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")
    }
-)
\ No newline at end of file
+)