MOD Correction de petits bugs
[euphorik.git] / js / euphorik.js
index a20ee37..c37ee4c 100755 (executable)
@@ -6,13 +6,14 @@
   * 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 : 80, // (par page)
+   nbMessageAffiche : 10, // (par page)
    pseudoDefaut : "<nick>",\r
    tempsAffichageMessageDialogue : 4000, // en ms\r
    smiles : {   \r
@@ -40,7 +41,7 @@ var conf = {
 \r
 String.prototype.trim = function()\r
 {\r
-       return this.replace(/^\s+|\s+$/g, "");\r
+       return jQuery.trim(this) // anciennement : this.replace(/^\s+|\s+$/g, "");\r
 }\r
 \r
 String.prototype.ltrim = function()\r
@@ -53,26 +54,13 @@ String.prototype.rtrim = function()
        return this.replace(/\s+$/, "");\r
 }\r
 \r
-String.prototype.dump = function()\r
-{\r
-   if (typeof dump != "undefined")\r
-   {\r
-      dump("\n--- EUPHORIK.CH ---\n")\r
-      dump(this)\r
-      dump("\n------\n")\r
-   }\r
-}\r
-\r
 ///////////////////////////////////////////////////////////////////////////////////////////////////\r
 \r
 /**\r
   * Cette classe regroupe des fonctions utilitaires (helpers).\r
   */
 function Util()
-{\r
-   if(typeof XMLSerializer != "undefined")
-      this.serializer = new XMLSerializer()
-      
+{
    jQuery("#info .fermer").click(function(){
       jQuery("#info").slideUp(50) 
    })
@@ -110,44 +98,16 @@ Util.prototype.messageDialogue = function(message, type, boutons)
    jQuery("#info").slideDown(200)
    this.timeoutMessageDialogue = setTimeout(fermer, conf.tempsAffichageMessageDialogue)   
 }
-var messageType = {informatif: 0, question: 1, erreur: 2}
-\r
-/**\r
-  * Transforme un document XML en string.\r
-  */\r
-Util.prototype.serializeXML = function(documentXML)\r
-{\r
-   if (this.serializer)\r
-      return this.serializer.serializeToString(documentXML)\r
-   else\r
-      return documentXML.xml\r
-}\r
 
-Util.prototype.creerDocumentXMLAction = function()
-{\r
-   if (document.implementation && document.implementation.createDocument)\r
-   {\r
-      // var doc = document.implementation.createDocument("", "action", null)
-      var parser = new DOMParser();
-      var doc =  parser.parseFromString("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<action/>", "text/xml")
-      //alert(this.serializeXML(doc))
-      return doc\r
-   }\r
-   else if (window.ActiveXObject)\r
-   {\r
-      var doc = new ActiveXObject("MSXML2.DOMDocument") //("Microsoft.XMLDOM")\r
-      doc.appendChild(doc.createElement("action"));\r
-      //doc.loadXML("<action></action>")\r
-      //alert(doc.documentElement)\r
-      //doc.createElement("action")\r
-      return doc\r
-   }   
-}
+var messageType = {informatif: 0, question: 1, erreur: 2}\r
 
-Util.prototype.xmlVersAction = function(xml)
+/**
+  * Utilisé pour l'envoie de donnée avec la méthode ajax de jQuery.
+  */
+Util.prototype.jsonVersAction = function(json)
 {
-   //return {action: this.to_utf8(this.serializeXML(xml /*, "UTF-8"*/))}
-   return {action: this.serializeXML(xml)}
+   // FIXME : ne plus encapsuler json dans de l'xml (problème avec yaws)
+   return {action: "<json>" + JSON.stringify(json) + "</json>" }
 }
 \r
 Util.prototype.md5 = function(chaine)\r
@@ -294,11 +254,28 @@ Formateur.prototype.getSmilesHTML = function()
 
 Formateur.prototype.traitementComplet = function(M, pseudo)
 {
-   return this.traiterSmiles(this.traiterURL(this.remplacerBalisesHTML(M), pseudo))
+   return this.traiterLiensConv(this.traiterSmiles(this.traiterURL(this.remplacerBalisesHTML(M), pseudo)))
+}
+
+/**
+  * 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 !!\r
+  * FIXME : Cette méthode est attrocement lourde ! A optimiser.\r
   */
 Formateur.prototype.traiterSmiles = function(M)
 {  
@@ -383,7 +360,15 @@ Formateur.prototype.traiterPourFenetreLightBox = function(M, urlCourante)
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-var statutType = {enregistre: 0, identifie: 1, non_identifie: 2}
+// 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
 {
@@ -391,14 +376,11 @@ function Client(util)
    \r
    this.cookie = null
    this.regexCookie = new RegExp("^cookie=([^;]*)")
-   \r
-   // Obsolète
-   //this.captchaCrypt = null
    
    // données personnels\r
    this.resetDonneesPersonnelles()
    
-   this.setStatut(statutType.non_identifie)
+   this.setStatut(statutType.deconnected)
    
    // le dernier message d'erreur recut du serveur (par exemple une connexion foireuse : "login impossible")
    this.dernierMessageErreur = ""\r
@@ -428,15 +410,49 @@ Client.prototype.setCss = function(css)
    this.css = css
    jQuery("link#cssPrincipale").attr("href", this.css)
    this.majMenu()
+}
 
-   if (this.identifie())
-      this.flush()   
+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
+  * @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)
@@ -447,7 +463,6 @@ Client.prototype.ajouterConversation = function(racine)
          return false
          
    this.conversations.push({racine : racine, page : 1})
-   this.flush(false)
    return true
 }
 
@@ -459,129 +474,63 @@ Client.prototype.supprimerConversation = function(num)
    for (var i = num; i < this.conversations.length - 1; i++)
       this.conversations[i] = this.conversations[i+1]
    this.conversations.pop()
-   
-   this.flush(false)
-}\r
-
-Client.prototype.getXMLlogin = function(login, password)
-{
-   var XMLDocument = this.util.creerDocumentXMLAction()
-   XMLDocument.documentElement.setAttribute("name", "login")
-   
-   var nodeLogin = XMLDocument.createElement("login")
-   nodeLogin.appendChild(XMLDocument.createTextNode(login))
-   XMLDocument.documentElement.appendChild(nodeLogin)
-   
-   var nodePassword = XMLDocument.createElement("password")
-   nodePassword.appendChild(XMLDocument.createTextNode(password))
-   XMLDocument.documentElement.appendChild(nodePassword)
-   
-   return XMLDocument   
 }
 
-Client.prototype.getXMLloginCookie = function()
+Client.prototype.getJSONLogin = function(login, password)
 {
-   var XMLDocument = this.util.creerDocumentXMLAction()
-   XMLDocument.documentElement.setAttribute("name", "login")
-   
-   var nodeCookie = XMLDocument.createElement("cookie")
-   nodeCookie.appendChild(XMLDocument.createTextNode(this.cookie))
-   XMLDocument.documentElement.appendChild(nodeCookie)
-   
-   return XMLDocument
+   return {
+      "action" : "authentification",
+      "login" : login,
+      "password" : password
+   }
 }
-\r
-/* Obsolète
-Client.prototype.getXMLloginCaptcha = function(captchaCrypt, captchaInput)
-{
-   var XMLDocument = this.util.creerDocumentXMLAction()
-   XMLDocument.documentElement.setAttribute("name", "loginCaptcha")
-   
-   var nodecaptchaCrypt = XMLDocument.createElement("captchaCrypt")
-   nodecaptchaCrypt.appendChild(XMLDocument.createTextNode(captchaCrypt))
-   XMLDocument.documentElement.appendChild(nodecaptchaCrypt)
-   
-   var nodecaptchaInput = XMLDocument.createElement("captchaInput")
-   nodecaptchaInput.appendChild(XMLDocument.createTextNode(captchaInput))
-   XMLDocument.documentElement.appendChild(nodecaptchaInput)
-   
-   return XMLDocument
-}*/
-\r
-/* Obsolète
-Client.prototype.getXMLgenerationCaptcha = function()
+
+Client.prototype.getJSONLoginCookie = function()
 {
-   var XMLDocument = this.util.creerDocumentXMLAction()
-   XMLDocument.documentElement.setAttribute("name", "generationCaptcha")
-   
-   return XMLDocument
-}*/
+   return {
+      "action" : "authentification",
+      "cookie" : this.cookie
+   }
+}  
 
-Client.prototype.getXMLEnregistrement = function(login, password)
+/**
+  * 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 XMLDocument = this.util.creerDocumentXMLAction()
-   XMLDocument.documentElement.setAttribute("name", "register")
+   var mess = { "action" : "register" }
    
-   var nodeLogin = XMLDocument.createElement("login")
-   nodeLogin.appendChild(XMLDocument.createTextNode(login))
-   XMLDocument.documentElement.appendChild(nodeLogin)
-   
-   var nodePassword = XMLDocument.createElement("password")
-   nodePassword.appendChild(XMLDocument.createTextNode(password))
-   XMLDocument.documentElement.appendChild(nodePassword)
+   if (login != undefined && password != undefined)
+   {
+      mess["login"] = login
+      mess["password"] = password
+   }
    
-   return XMLDocument   
+   return mess;
 }
 
-Client.prototype.getXMLProfile = function()
+Client.prototype.getJSONConversations = function()
 {
-   var XMLDocument = this.util.creerDocumentXMLAction()
-   XMLDocument.documentElement.setAttribute("name", "profile")
-   
-   var nodeCookie = XMLDocument.createElement("cookie")
-   nodeCookie.appendChild(XMLDocument.createTextNode(this.cookie))
-   XMLDocument.documentElement.appendChild(nodeCookie)
-   
-   var nodeLogin = XMLDocument.createElement("login")
-   nodeLogin.appendChild(XMLDocument.createTextNode(this.login))
-   XMLDocument.documentElement.appendChild(nodeLogin)
-   
-   var nodePassword = XMLDocument.createElement("password")
-   nodePassword.appendChild(XMLDocument.createTextNode(this.password))
-   XMLDocument.documentElement.appendChild(nodePassword)
-   
-   var nodePseudo = XMLDocument.createElement("pseudo")
-   nodePseudo.appendChild(XMLDocument.createTextNode(this.pseudo))
-   XMLDocument.documentElement.appendChild(nodePseudo)
-   
-   var nodeEmail = XMLDocument.createElement("email")
-   nodeEmail.appendChild(XMLDocument.createTextNode(this.email))
-   XMLDocument.documentElement.appendChild(nodeEmail)
-   
-   var nodeCSS = XMLDocument.createElement("css")
-   nodeCSS.appendChild(XMLDocument.createTextNode(this.css))
-   XMLDocument.documentElement.appendChild(nodeCSS)
-   
-   var nodePagePrincipale = XMLDocument.createElement("pagePrincipale")
-   nodePagePrincipale.appendChild(XMLDocument.createTextNode(this.pagePrincipale))
-   XMLDocument.documentElement.appendChild(nodePagePrincipale)
-   
-   // mémorise les conversations affichées
+   var conversations = new Array()
    for (var i = 0; i < this.conversations.length; i++)
-   {
-      var nodeConv = XMLDocument.createElement("conversation")
-      XMLDocument.documentElement.appendChild(nodeConv)
-      
-      var nodeRacine = XMLDocument.createElement("racine")
-      nodeRacine.appendChild(XMLDocument.createTextNode(this.conversations[i].racine))
-      nodeConv.appendChild(nodeRacine)
-      
-      var nodePage = XMLDocument.createElement("page")
-      nodePage.appendChild(XMLDocument.createTextNode(this.conversations[i].page))
-      nodeConv.appendChild(nodePage)
+      conversations.push({ "racine" : this.conversations[i].racine, "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,
+      "main_page" : this.pagePrincipale < 1 ? 1 : this.pagePrincipale,
+      "conversations" : this.getJSONConversations()
    }
-   
-   return XMLDocument    
 }
 
 /**
@@ -609,51 +558,27 @@ Client.prototype.setCookie = function(cookie)
       "; max-age="  + (60 * 60 * 24 * 365)
 }
 
-Client.prototype.identifie = function()
+Client.prototype.authentifie = function()
 {
-   return this.statut == statutType.enregistre || this.statut == statutType.identifie
+   return this.statut == statutType.auth_registered || this.statut == statutType.auth_not_registered
 }
 
 Client.prototype.setStatut = function(statut)
-{  \r
-   if(typeof(statut) == "string")\r
+{  
+   // conversation en "enum" si en "string"\r
+   if (typeof(statut) == "string")\r
    {
       statut =
-         statut == "enregistre" ?
-            statutType.enregistre : (statut == "identifie" ? statutType.identifie : statutType.non_identifie)   \r
+         statut == "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
-
-/**
-  * Demande la génération d'un captcha au serveur et l'affiche.
-  */\r
-  /* Obsolète
-Client.prototype.afficherCaptcha = function(query)
-{
-   var thisClient = this
-
-   $.post("request", this.util.xmlVersAction(this.getXMLgenerationCaptcha()),
-      function(data, textStatus)
-      {
-         var chemin = jQuery("chemin", data.documentElement).text()
-         thisClient.captchaCrypt = jQuery("captchaCrypt", data.documentElement).text()
-         jQuery(query).prepend(
-            "<p id=\"captcha\" >Es-tu un bot ? <img class=\"captchaImg\" src=\"" + chemin + "\" />" +
-            "<input name=\"captchaInput\" type=\"text\" size=\"5\" max_length=\"5\" ></p>"
-         )
-      }
-   )
 }
-
-Client.prototype.cacherCaptcha = function()
-{
-   jQuery("#captcha").remove()
-}*/
 \r
 /**\r
   * Effectue la connexion vers le serveur.\r
@@ -665,63 +590,55 @@ Client.prototype.connexionCookie = function()
 {\r
    this.getCookie()\r
    if (this.cookie == null) return false;
-   return this.connexion(this.util.xmlVersAction(this.getXMLloginCookie()))\r
+   return this.connexion(this.getJSONLoginCookie())\r
 }
 
 Client.prototype.connexionLogin = function(login, password)
 {
-   return this.connexion(this.util.xmlVersAction(this.getXMLlogin(login, password)))
-}
-\r
-/* Obsolète\r
-Client.prototype.connexionCaptcha = function()
-{   
-   return this.connexion(this.util.xmlVersAction(this.getXMLloginCaptcha(this.captchaCrypt, jQuery("#captcha input").val())))
-}*/
+   return this.connexion(this.getJSONLogin(login, password))
+}\r
 
 Client.prototype.enregistrement = function(login, password)
 { 
-   if (this.identifie())
+   if (this.authentifie())
    {
       this.login = login
       this.password = password
       if(this.flush())
-         this.setStatut(statutType.enregistre)
+         this.setStatut(statutType.auth_registered)
       return true
    }
    else\r
-   {\r
-      if (login == undefined) login = ""\r
-      if (password == undefined) password = ""
-      return this.connexion(this.util.xmlVersAction(this.getXMLEnregistrement(login, password)))\r
+   {
+      return this.connexion(this.getJSONEnregistrement(login, password))\r
    }
 }
 
-Client.prototype.connexion = function(action)
+Client.prototype.connexion = function(messageJson)
 {
-   //action.action.dump()
+   ;;; dumpObj(messageJson)
    thisClient = this
    jQuery.ajax(
       {
          async: false,
          type: "POST",
          url: "request",
-         dataType: "xml",
-         data: action,
+         dataType: "json",
+         data: this.util.jsonVersAction(messageJson),
          success:
             function(data)
             {
-               //thisClient.util.serializer.serializeToString(data).dump()
+               ;;; dumpObj(data)
                thisClient.chargerDonnees(data)
             }
       }
    )
-   return this.identifie()
+   return this.authentifie()
 }\r
 \r
 Client.prototype.deconnexion = function()\r
 {\r
-   this.setStatut(statutType.non_identifie) // deconnexion\r
+   this.setStatut(statutType.deconnected) // deconnexion\r
    this.resetDonneesPersonnelles()\r
    this.delCookie ()\r
 }
@@ -730,21 +647,20 @@ Client.prototype.chargerDonnees = function(data)
 {
    var thisClient = this
 
-   this.setStatut(jQuery("statut", data.documentElement).text())       
+   this.setStatut(data["status"]) 
    
-   if (this.identifie())
+   if (this.authentifie())
    {
-      this.cookie = jQuery("cookie", data.documentElement).text()
+      this.cookie = data["cookie"]
       this.setCookie()
       \r
-      this.login = jQuery("login", data.documentElement).text()
-      this.pseudo = jQuery("pseudo", data.documentElement).text()\r
-      this.email = jQuery("email", data.documentElement).text()\r
-      this.css = jQuery("css", data.documentElement).text()
+      this.login = data["login"]
+      this.pseudo = data["nick"]\r
+      this.email = data["email"]\r
+      this.css = data["css"]
       
       // la page de la conversation principale
-      var tmp = jQuery("pagePrincipale", data.documentElement)
-      this.pagePrincipale = tmp.length < 1 ? 1 : tmp.text()
+      this.pagePrincipale = data["main_page"] == undefined ? 1 : data["main_page"]
       
       // met à jour la css
       if (this.css != "")
@@ -753,35 +669,34 @@ Client.prototype.chargerDonnees = function(data)
          this.majMenu()
       }
       // les conversations
-      this.conversations = new Array()
-      jQuery("conversation", data.documentElement).each(
-         function(i)
-         {
-            thisClient.conversations.push( { racine : jQuery("racine", this).text(), page : jQuery("page", this).text() } )
-         }
-      )
+      thisClient.conversations = data["conversations"]
+      
    }
-   this.dernierMessageErreur = jQuery("information", data.documentElement).text()
+   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
-   //thisClient.util.log(this.util.xmlVersAction(this.getXMLProfile()).action)      
+   ;;; dumpObj(this.getJSONProfile())
    jQuery.ajax(
       {
          async: async,
          type: "POST",
          url: "request",
-         dataType: "xml",
-         data: this.util.xmlVersAction(this.getXMLProfile()),
+         dataType: "json",
+         data: this.util.jsonVersAction(this.getJSONProfile()),
          success:
             function(data)
             {
@@ -798,13 +713,13 @@ Client.prototype.majMenu = function()
    var displayType = this.css == "css/3/euphorik.css" ? "block" : "inline" //this.client
 
    // met à jour le menu   
-   if (this.statut == statutType.enregistre)
+   if (this.statut == statutType.auth_registered)
    {
       jQuery("#menu .profile").css("display", displayType).text("profile")\r
       jQuery("#menu .logout").css("display", displayType)
       jQuery("#menu .register").css("display", "none")
    }
-   else if (this.statut == statutType.identifie)
+   else if (this.statut == statutType.auth_not_registered)
    {
       jQuery("#menu .profile").css("display", "none")\r
       jQuery("#menu .logout").css("display", displayType)
@@ -822,6 +737,8 @@ Client.prototype.majMenu = function()
 
 jQuery.noConflict()
             
+// charge dynamiquement le script de debug
+;;; jQuery.ajax({async : false, url : "js/debug.js", dataType : "script"})
       \r
 // le main
 jQuery(document).ready(
@@ -848,6 +765,15 @@ jQuery(document).ready(
             client.setCss("css/" + jQuery(this).attr("id").charAt(3) + "/euphorik.css")
          })
       }
+
+      // TODO : pourquoi jQuery(document).unload ne fonctionne pas ?
+      jQuery(window).unload(
+         function()
+         {
+            //alert("ok")
+            client.flush(false)
+         }
+      )
       
       jQuery("#menu .minichat").click(function(){ pages.afficherPage("minichat") })
       jQuery("#menu .profile").click(function(){ pages.afficherPage("profile") })\r
@@ -869,5 +795,4 @@ jQuery(document).ready(
       pages.ajouterPage(new PageRegister(client, formateur, util))
       pages.afficherPage("minichat")
    }
-)
-
+)
\ No newline at end of file