MOD Passage au JSON (tout cassé pour l'instant)
[euphorik.git] / js / euphorik.js
index fafa854..f78e103 100755 (executable)
@@ -12,7 +12,7 @@
   * 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
@@ -53,11 +53,12 @@ String.prototype.rtrim = function()
        return this.replace(/\s+$/, "");\r
 }\r
 \r
-String.prototype.dump = function()\r
-{\r
+String.prototype.dump = function(titre)\r
+{
+   titre = titre == undefined ? "" : titre\r
    if (typeof dump != "undefined")\r
    {\r
-      dump("\n--- EUPHORIK.CH ---\n")\r
+      dump("\n--- EUPHORIK.CH : " + titre + " ---\n")\r
       dump(this)\r
       dump("\n------\n")\r
    }\r
@@ -72,8 +73,7 @@ function Util()
 {\r
    if(typeof XMLSerializer != "undefined")
       this.serializer = new XMLSerializer()
-      \r
-   // fermeture des dialogues d
+      
    jQuery("#info .fermer").click(function(){
       jQuery("#info").slideUp(50) 
    })
@@ -124,25 +124,29 @@ Util.prototype.serializeXML = function(documentXML)
       return documentXML.xml\r
 }\r
 
+var documentXMLBase = undefined // singleton 
 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
+{
+   // FIXME : essayer de garder le doc de base en cache (singleton) et d'en retourner une copie
+   if (true)//documentXMLBase == undefined)
    {\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
-   }   
+      if (document.implementation && document.implementation.createDocument)\r
+      {\r
+         // var doc = document.implementation.createDocument("", "action", null)
+         var parser = new DOMParser();
+         documentXMLBase =  parser.parseFromString("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<action/>", "text/xml")
+         //alert(this.serializeXML(doc))\r
+      }\r
+      else if (window.ActiveXObject)\r
+      {\r
+         documentXMLBase = new ActiveXObject("MSXML2.DOMDocument") //("Microsoft.XMLDOM")\r
+         documentXMLBase.appendChild(doc.createElement("action"));\r
+         //doc.loadXML("<action></action>")\r
+         //alert(doc.documentElement)\r
+         //doc.createElement("action")\r
+      }
+   }
+   return documentXMLBase
 }
 
 Util.prototype.xmlVersAction = function(xml)
@@ -150,6 +154,15 @@ Util.prototype.xmlVersAction = function(xml)
    //return {action: this.to_utf8(this.serializeXML(xml /*, "UTF-8"*/))}
    return {action: this.serializeXML(xml)}
 }
+
+/**
+  * Utilisé pour l'envoie de donnée avec la méthode ajax de jQuery.
+  */
+Util.prototype.jsonVersAction = function(json)
+{
+   // 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
 {\r
@@ -295,11 +308,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)
 {  
@@ -392,9 +422,6 @@ function Client(util)
    \r
    this.cookie = null
    this.regexCookie = new RegExp("^cookie=([^;]*)")
-   \r
-   // Obsolète
-   //this.captchaCrypt = null
    
    // données personnels\r
    this.resetDonneesPersonnelles()
@@ -413,6 +440,8 @@ Client.prototype.resetDonneesPersonnelles = function()
    this.email = ""\r
    this.css = jQuery("link#cssPrincipale").attr("href")
    
+   this.pagePrincipale = 1
+   
    // les conversations, une conversation est un objet possédant les attributs suivants :
    // - racine (entier)
    // - page (entier)
@@ -432,15 +461,74 @@ Client.prototype.setCss = function(css)
       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
+   this.flush(false)
+}
+
+Client.prototype.pagePrecedente = function(numConv)
+{
+   if (numConv < 0)
+      this.pagePrincipale += 1
+   else 
+      this.conversations[numConv].page += 1
+   this.flush(false)
+}
+
+/**
+  * 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
+   }
+   this.flush(false)
+   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
+  * @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].racine == racine)
+         return false
+         
    this.conversations.push({racine : racine, page : 1})
-   this.flush()
+   this.flush(false)
+   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()
+   
+   this.flush(false)
 }\r
 
 Client.prototype.getXMLlogin = function(login, password)
@@ -459,6 +547,15 @@ Client.prototype.getXMLlogin = function(login, password)
    return XMLDocument   
 }
 
+Client.prototype.getJSONLogin = function(login, password)
+{
+   return {
+      "action" : "authentification",
+      "login" : login,
+      "password" : password
+   }
+}
+
 Client.prototype.getXMLloginCookie = function()
 {
    var XMLDocument = this.util.creerDocumentXMLAction()
@@ -470,32 +567,6 @@ Client.prototype.getXMLloginCookie = function()
    
    return XMLDocument
 }
-\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()
-{
-   var XMLDocument = this.util.creerDocumentXMLAction()
-   XMLDocument.documentElement.setAttribute("name", "generationCaptcha")
-   
-   return XMLDocument
-}*/
 
 Client.prototype.getXMLEnregistrement = function(login, password)
 {
@@ -513,6 +584,10 @@ Client.prototype.getXMLEnregistrement = function(login, password)
    return XMLDocument   
 }
 
+/**
+  * Sérialize le profile en XML.
+  * TODO : méthode assez lourde, 3.25ms de moyenne
+  */
 Client.prototype.getXMLProfile = function()
 {
    var XMLDocument = this.util.creerDocumentXMLAction()
@@ -542,24 +617,23 @@ Client.prototype.getXMLProfile = function()
    nodeCSS.appendChild(XMLDocument.createTextNode(this.css))
    XMLDocument.documentElement.appendChild(nodeCSS)
    
+   var nodePagePrincipale = XMLDocument.createElement("pagePrincipale")
+   nodePagePrincipale.appendChild(XMLDocument.createTextNode(this.pagePrincipale < 1 ? 1 : this.pagePrincipale))
+   XMLDocument.documentElement.appendChild(nodePagePrincipale)
+   
    // mémorise les conversations affichées
-   if (this.conversations.length > 0)
+   for (var i = 0; i < this.conversations.length; i++)
    {
-      var nodeConversations = XMLDocument.createElement("conversations")
-      XMLDocument.documentElement.appendChild(nodeConversations)
-      for (var i = 0; i < this.conversations.length; i++)
-      {
-         var nodeConv = XMLDocument.createElement("conversation")
-         nodeConversations.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)
-      }
+      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)
    }
    
    return XMLDocument    
@@ -608,33 +682,7 @@ Client.prototype.setStatut = function(statut)
    \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
@@ -651,14 +699,9 @@ Client.prototype.connexionCookie = function()
 
 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.util.xmlVersAction(this.getXMLlogin(login, password)))
+   return this.connexion(this.util.jsonVersAction(this.getJSONLogin(login, password)))
+}\r
 
 Client.prototype.enregistrement = function(login, password)
 { 
@@ -680,18 +723,21 @@ Client.prototype.enregistrement = function(login, password)
 
 Client.prototype.connexion = function(action)
 {
+   action.action.dump("Connexion client")
    thisClient = this
    jQuery.ajax(
       {
          async: false,
          type: "POST",
          url: "request",
-         dataType: "xml",
+         dataType: "json",
          data: action,
          success:
             function(data)
             {
-               thisClient.chargerDonnees(data)
+               //alert(data["error_message"])
+               //thisClient.util.serializer.serializeToString(data).dump("Charger client")
+               //thisClient.chargerDonnees(data)
             }
       }
    )
@@ -707,6 +753,8 @@ Client.prototype.deconnexion = function()
 
 Client.prototype.chargerDonnees = function(data)
 {
+   var thisClient = this
+
    this.setStatut(jQuery("statut", data.documentElement).text())       
    
    if (this.identifie())
@@ -718,26 +766,43 @@ Client.prototype.chargerDonnees = function(data)
       this.pseudo = jQuery("pseudo", data.documentElement).text()\r
       this.email = jQuery("email", data.documentElement).text()\r
       this.css = jQuery("css", data.documentElement).text()
+      
+      // la page de la conversation principale
+      var tmp = jQuery("pagePrincipale", data.documentElement)
+      this.pagePrincipale = tmp.length < 1 ? 1 : parseInt(tmp.text())
+      
       // met à jour la css
       if (this.css != "")
       {
          jQuery("link#cssPrincipale").attr("href", this.css)
          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() } )
+         }
+      )
    }
    this.dernierMessageErreur = jQuery("information", data.documentElement).text()
 }
 
 /**
   * Met à jour les données personne sur serveur.
+  * @param async de manière asynchrone ? défaut = true
   */
-Client.prototype.flush = function()
+Client.prototype.flush = function(async)
 {
+   if (async == undefined)
+      async = true
+
    thisClient = this
-   //thisClient.util.log(this.util.xmlVersAction(this.getXMLProfile()).action)      
+   this.util.xmlVersAction(this.getXMLProfile()).action.dump("Flush client")      
    jQuery.ajax(
       {
-         async: true,
+         async: async,
          type: "POST",
          url: "request",
          dataType: "xml",