MOD Avancement sur le passage à JSON
[euphorik.git] / js / euphorik.js
1 // coding: utf-8
2
3 /**
4 * Contient la base javascript pour le site euphorik.ch.
5 * Chaque page possède son propre fichier js nommé "page<nom de la page>.js".
6 * Auteur : GBurri
7 * Date : 6.11.2007
8 */
9
10 /**
11 * La configuration.
12 * Normalement 'const' à la place de 'var' mais non supporté par IE7.
13 */
14 var conf = {
15 nbMessageAffiche : 10, // (par page)
16 pseudoDefaut : "<nick>",
17 tempsAffichageMessageDialogue : 4000, // en ms
18 smiles : {
19 "smile" : [/:\)/g, /:-\)/g],
20 "bigsmile" : [/:D/g, /:-D/g],
21 "clin" : [/;\)/g, /;-\)/g],
22 "cool" : [/8\)/g, /8-\)/g],
23 "eheheh" : [/:P/g, /:-P/g],
24 "oh" : [/:o/g, /:O/g],
25 "pascontent" : [/>\(/g, /&gt;\(/g],
26 "sniff" : [/:\(/g, /:-\(/g],
27 "argn" : [/\[:argn\]/g],
28 "bunny" : [/\[:lapin\]/g],
29 "chat" : [/\[:chat\]/g],
30 "renne" : [/\[:renne\]/g],
31 "lol" : [/\[:lol\]/g],
32 "spliff" : [/\[:spliff\]/g],
33 "star" : [/\[:star\]/g],
34 "triste" : [/\[:triste\]/g],
35 "kirby" : [/\[:kirby\]/g]
36 }
37 }
38
39 ///////////////////////////////////////////////////////////////////////////////////////////////////
40
41 String.prototype.trim = function()
42 {
43 return this.replace(/^\s+|\s+$/g, "");
44 }
45
46 String.prototype.ltrim = function()
47 {
48 return this.replace(/^\s+/, "");
49 }
50
51 String.prototype.rtrim = function()
52 {
53 return this.replace(/\s+$/, "");
54 }
55
56 String.prototype.dump = function(titre)
57 {
58 titre = titre == undefined ? "" : titre
59 if (typeof dump != "undefined")
60 {
61 dump("\n--- EUPHORIK.CH : " + titre + " ---\n")
62 dump(this)
63 dump("\n------\n")
64 }
65 }
66
67 ///////////////////////////////////////////////////////////////////////////////////////////////////
68
69 /**
70 * Cette classe regroupe des fonctions utilitaires (helpers).
71 */
72 function Util()
73 {
74 if(typeof XMLSerializer != "undefined")
75 this.serializer = new XMLSerializer()
76
77 jQuery("#info .fermer").click(function(){
78 jQuery("#info").slideUp(50)
79 })
80 }
81
82 /**
83 * Affiche une boite de dialogue avec un message à l'intérieur.
84 * @param message le message (string)
85 * @param type voir 'messageType'. par défaut messageType.informatif
86 * @param les boutons sous la forme d'un objet ou les clefs sont les labels des boutons
87 * et les valeurs les fonctions executées lorsqu'un bouton est activé.
88 */
89 Util.prototype.messageDialogue = function(message, type, boutons)
90 {
91 if (type == undefined)
92 type = messageType.informatif
93
94 if (this.timeoutMessageDialogue != undefined)
95 clearTimeout(this.timeoutMessageDialogue)
96
97 var fermer = function(){jQuery("#info").slideUp(100)}
98 fermer()
99
100 jQuery("#info .message").html(message)
101 switch(type)
102 {
103 case messageType.informatif : jQuery("#info #icone").attr("class", "information"); break
104 case messageType.question : jQuery("#info #icone").attr("class", "interrogation"); break
105 case messageType.erreur : jQuery("#info #icone").attr("class", "exclamation"); break
106 }
107 jQuery("#info .boutons").html("")
108 for (var b in boutons)
109 jQuery("#info .boutons").append("<div>" + b + "</div>").find("div:last").click(boutons[b]).click(fermer)
110
111 jQuery("#info").slideDown(200)
112 this.timeoutMessageDialogue = setTimeout(fermer, conf.tempsAffichageMessageDialogue)
113 }
114 var messageType = {informatif: 0, question: 1, erreur: 2}
115
116 /**
117 * Transforme un document XML en string.
118 */
119 Util.prototype.serializeXML = function(documentXML)
120 {
121 if (this.serializer)
122 return this.serializer.serializeToString(documentXML)
123 else
124 return documentXML.xml
125 }
126
127 var documentXMLBase = undefined // singleton
128 Util.prototype.creerDocumentXMLAction = function()
129 {
130 // FIXME : essayer de garder le doc de base en cache (singleton) et d'en retourner une copie
131 if (true)//documentXMLBase == undefined)
132 {
133 if (document.implementation && document.implementation.createDocument)
134 {
135 // var doc = document.implementation.createDocument("", "action", null)
136 var parser = new DOMParser();
137 documentXMLBase = parser.parseFromString("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<action/>", "text/xml")
138 //alert(this.serializeXML(doc))
139 }
140 else if (window.ActiveXObject)
141 {
142 documentXMLBase = new ActiveXObject("MSXML2.DOMDocument") //("Microsoft.XMLDOM")
143 documentXMLBase.appendChild(doc.createElement("action"));
144 //doc.loadXML("<action></action>")
145 //alert(doc.documentElement)
146 //doc.createElement("action")
147 }
148 }
149 return documentXMLBase
150 }
151
152 Util.prototype.xmlVersAction = function(xml)
153 {
154 //return {action: this.to_utf8(this.serializeXML(xml /*, "UTF-8"*/))}
155 return {action: this.serializeXML(xml)}
156 }
157
158 /**
159 * Utilisé pour l'envoie de donnée avec la méthode ajax de jQuery.
160 */
161 Util.prototype.jsonVersAction = function(json)
162 {
163 // FIXME : ne plus encapsuler json dans de l'xml (problème avec yaws)
164 return {action: "<json>" + JSON.stringify(json) + "</json>" }
165 }
166
167 Util.prototype.md5 = function(chaine)
168 {
169 return hex_md5(chaine)
170 }
171
172 // pompé de http://www.faqts.com/knowledge_base/view.phtml/aid/13562/fid/130
173 Util.prototype.setSelectionRange = function(input, selectionStart, selectionEnd)
174 {
175 if (input.setSelectionRange)
176 {
177 input.focus()
178 input.setSelectionRange(selectionStart, selectionEnd)
179 }
180 else if (input.createTextRange)
181 {
182 var range = input.createTextRange()
183 range.collapse(true)
184 range.moveEnd('character', selectionEnd)
185 range.moveStart('character', selectionStart)
186 range.select()
187 }
188 }
189
190 Util.prototype.setCaretToEnd = function(input)
191 {
192 this.setSelectionRange(input, input.value.length, input.value.length)
193 }
194 Util.prototype.setCaretToBegin = function(input)
195 {
196 this.setSelectionRange(input, 0, 0)
197 }
198 Util.prototype.setCaretToPos = function(input, pos)
199 {
200 this.setSelectionRange(input, pos, pos)
201 }
202 Util.prototype.selectString = function(input, string)
203 {
204 var match = new RegExp(string, "i").exec(input.value)
205 if (match)
206 {
207 this.setSelectionRange (input, match.index, match.index + match[0].length)
208 }
209 }
210 Util.prototype.replaceSelection = function(input, replaceString) {
211 if (input.setSelectionRange)
212 {
213 var selectionStart = input.selectionStart
214 var selectionEnd = input.selectionEnd
215 input.value = input.value.substring(0, selectionStart) + replaceString + input.value.substring(selectionEnd)
216
217 if (selectionStart != selectionEnd) // has there been a selection
218 this.setSelectionRange(input, selectionStart, selectionStart + replaceString.length)
219 else // set caret
220 this.setCaretToPos(input, selectionStart + replaceString.length)
221 }
222 else if (document.selection)
223 {
224 var range = document.selection.createRange();
225 if (range.parentElement() == input)
226 {
227 var isCollapsed = range.text == ''
228 range.text = replaceString
229 if (!isCollapsed)
230 {
231 // there has been a selection
232 // it appears range.select() should select the newly
233 // inserted text but that fails with IE
234 range.moveStart('character', -replaceString.length);
235 range.select();
236 }
237 }
238 }
239 }
240
241 ///////////////////////////////////////////////////////////////////////////////////////////////////
242
243 function Pages()
244 {
245 this.pageCourante = null
246 this.pages = {}
247 }
248
249 Pages.prototype.ajouterPage = function(page)
250 {
251 page.pages = this // la magie des langages dynamiques : le foutoire
252 this.pages[page.nom] = page
253 }
254
255 Pages.prototype.afficherPage = function(nomPage, forcerChargement)
256 {
257 if (forcerChargement == undefined) forcerChargement = false
258
259 var page = this.pages[nomPage]
260 if (page == undefined || (!forcerChargement && page == this.pageCourante)) return
261
262 if (this.pageCourante != null && this.pageCourante.decharger)
263 this.pageCourante.decharger()
264
265 jQuery("#menu div").removeClass("courante")
266 jQuery("#menu div." + nomPage).addClass("courante")
267
268 this.pageCourante = page
269 jQuery("#page").html(this.pageCourante.contenu()).removeClass().addClass(this.pageCourante.nom)
270
271 if (this.pageCourante.charger)
272 this.pageCourante.charger()
273 }
274
275 ///////////////////////////////////////////////////////////////////////////////////////////////////
276
277 function Formateur()
278 {
279 this.smiles = conf.smiles
280 this.protocoles = "http|https|ed2k"
281
282 this.regexUrl = new RegExp("(?:(?:" + this.protocoles + ")://|www\\.)[^ ]*", "gi")
283 this.regexImg = new RegExp("^.*?\\.(gif|jpg|png|jpeg|bmp|tiff)$", "i")
284 this.regexDomaine = new RegExp("^(?:(?:" + this.protocoles + ")://|www\\.).*?([^/.]+\\.[^/.]+)(?:$|/).*$", "i")
285 this.regexTestProtocoleExiste = new RegExp("^(?:" + this.protocoles + ")://.*$", "i")
286 this.regexNomProtocole = new RegExp("^(.*?)://")
287 }
288
289 /**
290 * Formate un pseudo saise par l'utilisateur.
291 * @param pseudo le pseudo brut
292 * @return le pseudo filtré
293 */
294 Formateur.prototype.filtrerInputPseudo = function(pseudo)
295 {
296 return pseudo.replace(/{|}/g, "").trim()
297 }
298
299 Formateur.prototype.getSmilesHTML = function()
300 {
301 var XHTML = ""
302 for (var sNom in this.smiles)
303 {
304 XHTML += "<img class=\"" + sNom + "\" src=\"img/smileys/" + sNom + ".gif\" />"
305 }
306 return XHTML
307 }
308
309 Formateur.prototype.traitementComplet = function(M, pseudo)
310 {
311 return this.traiterLiensConv(this.traiterSmiles(this.traiterURL(this.remplacerBalisesHTML(M), pseudo)))
312 }
313
314 /**
315 * Transforme les liens en entités clickables.
316 * Un lien vers une conversation permet d'ouvrire celle ci, elle se marque comme ceci dans un message :
317 * "{5F}" ou 5F est la racine de la conversation.
318 * Ce lien sera transformer en <span class="lienConv">{5F}</span> pouvant être clické pour créer la conv 5F.
319 */
320 Formateur.prototype.traiterLiensConv = function(M)
321 {
322 return M.replace(
323 /\{\w+\}/g,
324 function(lien)
325 {
326 return "<span class=\"lienConv\">" + lien + "</span>"
327 }
328 )
329 }
330
331 /**
332 * FIXME : Cette méthode est attrocement lourde ! A optimiser.
333 */
334 Formateur.prototype.traiterSmiles = function(M)
335 {
336 for (var sNom in this.smiles)
337 {
338 ss = this.smiles[sNom]
339 for (var i = 0; i < ss.length; i++)
340 M = M.replace(ss[i], "<img src=\"img/smileys/" + sNom + ".gif\" />")
341 }
342 return M
343 }
344
345 Formateur.prototype.remplacerBalisesHTML = function(M)
346 {
347 return M.replace(/</g, "&lt;").replace(/>/g, "&gt;")
348 }
349
350 Formateur.prototype.traiterURL = function(M, pseudo)
351 {
352 thisFormateur = this
353
354 if (pseudo == undefined)
355 pseudo = ""
356
357 var traitementUrl = function(url)
358 {
359 // si ya pas de protocole on rajoute "http://"
360 if (!thisFormateur.regexTestProtocoleExiste.test(url))
361 url = "http://" + url
362 var extension = thisFormateur.getShort(url)
363 return "<a " + (extension[1] ? "title=\"" + thisFormateur.traiterPourFenetreLightBox(pseudo, url) + ": " + thisFormateur.traiterPourFenetreLightBox(M, url) + "\"" + " rel=\"lightbox[groupe]\"" : "") + " href=\"" + url + "\" >[" + extension[0] + "]</a>"
364 }
365 return M.replace(this.regexUrl, traitementUrl)
366 }
367
368 /**
369 * Renvoie une version courte de l'url.
370 * par exemple : http://en.wikipedia.org/wiki/Yakov_Smirnoff devient wikipedia.org
371 */
372 Formateur.prototype.getShort = function(url)
373 {
374 var estUneImage = false
375 var versionShort = null
376 var rechercheImg = this.regexImg.exec(url)
377 //alert(url)
378 if (rechercheImg != null)
379 {
380 versionShort = rechercheImg[1].toLowerCase()
381 if (versionShort == "jpeg") versionShort = "jpg" // jpeg -> jpg
382 estUneImage = true
383 }
384 else
385 {
386 var rechercheDomaine = this.regexDomaine.exec(url)
387 if (rechercheDomaine != null && rechercheDomaine.length >= 2)
388 versionShort = rechercheDomaine[1]
389 else
390 {
391 var nomProtocole = this.regexNomProtocole.exec(url)
392 if (nomProtocole != null && nomProtocole.length >= 2)
393 versionShort = nomProtocole[1]
394 }
395 }
396
397 return [versionShort == null ? "url" : versionShort, estUneImage]
398 }
399
400 /**
401 * Traite les pseudo et messages à être affiché dans le titre d'une image visualisé avec lightbox.
402 */
403 Formateur.prototype.traiterPourFenetreLightBox = function(M, urlCourante)
404 {
405 thisFormateur = this
406 var traitementUrl = function(url)
407 {
408 return "[" + thisFormateur.getShort(url)[0] + (urlCourante == url ? ": image courante" : "") + "]"
409 }
410
411 return this.remplacerBalisesHTML(M).replace(this.regexUrl, traitementUrl)
412 }
413
414
415 ///////////////////////////////////////////////////////////////////////////////////////////////////
416
417 var statutType = {enregistre: 0, identifie: 1, non_identifie: 2}
418
419 function Client(util)
420 {
421 this.util = util
422
423 this.cookie = null
424 this.regexCookie = new RegExp("^cookie=([^;]*)")
425
426 // données personnels
427 this.resetDonneesPersonnelles()
428
429 this.setStatut(statutType.non_identifie)
430
431 // le dernier message d'erreur recut du serveur (par exemple une connexion foireuse : "login impossible")
432 this.dernierMessageErreur = ""
433 }
434
435 Client.prototype.resetDonneesPersonnelles = function()
436 {
437 this.pseudo = conf.pseudoDefaut
438 this.login = ""
439 this.password = ""
440 this.email = ""
441 this.css = jQuery("link#cssPrincipale").attr("href")
442
443 this.pagePrincipale = 1
444
445 // les conversations, une conversation est un objet possédant les attributs suivants :
446 // - racine (entier)
447 // - page (entier)
448 this.conversations = new Array()
449 }
450
451 Client.prototype.setCss = function(css)
452 {
453 if (this.css == css)
454 return
455
456 this.css = css
457 jQuery("link#cssPrincipale").attr("href", this.css)
458 this.majMenu()
459
460 if (this.identifie())
461 this.flush()
462 }
463
464 Client.prototype.pageSuivante = function(numConv)
465 {
466 if (numConv < 0 && this.pagePrincipale > 1)
467 this.pagePrincipale -= 1
468 else if (this.conversations[numConv].page > 1)
469 this.conversations[numConv].page -= 1
470 this.flush(false)
471 }
472
473 Client.prototype.pagePrecedente = function(numConv)
474 {
475 if (numConv < 0)
476 this.pagePrincipale += 1
477 else
478 this.conversations[numConv].page += 1
479 this.flush(false)
480 }
481
482 /**
483 * Définit la première page pour la conversation donnée.
484 * @return true si la page a changé sinon false
485 */
486 Client.prototype.goPremierePage = function(numConv)
487 {
488 if (numConv < 0)
489 {
490 if (this.pagePrincipale == 1)
491 return false
492 this.pagePrincipale = 1
493 }
494 else
495 {
496 if (this.conversations[numConv].page == 1)
497 return false
498 this.conversations[numConv].page = 1
499 }
500 this.flush(false)
501 return true
502 }
503
504 /**
505 * Ajoute une conversation à la vue de l'utilisateur.
506 * Le profile de l'utilisateur est directement sauvegardé sur le serveur.
507 * @param racines la racine de la conversation
508 * @return true si la conversation a été créée sinon false (par exemple si la conv existe déjà)
509 */
510 Client.prototype.ajouterConversation = function(racine)
511 {
512 // vérification s'il elle n'existe pas déjà
513 for (var i = 0; i < this.conversations.length; i++)
514 if (this.conversations[i].racine == racine)
515 return false
516
517 this.conversations.push({racine : racine, page : 1})
518 this.flush(false)
519 return true
520 }
521
522 Client.prototype.supprimerConversation = function(num)
523 {
524 if (num < 0 || num >= this.conversations.length) return
525
526 // décalage TODO : supprimer le dernier élément
527 for (var i = num; i < this.conversations.length - 1; i++)
528 this.conversations[i] = this.conversations[i+1]
529 this.conversations.pop()
530
531 this.flush(false)
532 }
533
534 Client.prototype.getXMLlogin = function(login, password)
535 {
536 var XMLDocument = this.util.creerDocumentXMLAction()
537 XMLDocument.documentElement.setAttribute("name", "login")
538
539 var nodeLogin = XMLDocument.createElement("login")
540 nodeLogin.appendChild(XMLDocument.createTextNode(login))
541 XMLDocument.documentElement.appendChild(nodeLogin)
542
543 var nodePassword = XMLDocument.createElement("password")
544 nodePassword.appendChild(XMLDocument.createTextNode(password))
545 XMLDocument.documentElement.appendChild(nodePassword)
546
547 return XMLDocument
548 }
549
550 Client.prototype.getJSONLogin = function(login, password)
551 {
552 return {
553 "action" : "authentification",
554 "login" : login,
555 "password" : password
556 }
557 }
558
559 Client.prototype.getXMLloginCookie = function()
560 {
561 var XMLDocument = this.util.creerDocumentXMLAction()
562 XMLDocument.documentElement.setAttribute("name", "login")
563
564 var nodeCookie = XMLDocument.createElement("cookie")
565 nodeCookie.appendChild(XMLDocument.createTextNode(this.cookie))
566 XMLDocument.documentElement.appendChild(nodeCookie)
567
568 return XMLDocument
569 }
570
571 Client.prototype.getXMLEnregistrement = function(login, password)
572 {
573 var XMLDocument = this.util.creerDocumentXMLAction()
574 XMLDocument.documentElement.setAttribute("name", "register")
575
576 var nodeLogin = XMLDocument.createElement("login")
577 nodeLogin.appendChild(XMLDocument.createTextNode(login))
578 XMLDocument.documentElement.appendChild(nodeLogin)
579
580 var nodePassword = XMLDocument.createElement("password")
581 nodePassword.appendChild(XMLDocument.createTextNode(password))
582 XMLDocument.documentElement.appendChild(nodePassword)
583
584 return XMLDocument
585 }
586
587 /**
588 * Sérialize le profile en XML.
589 * TODO : méthode assez lourde, 3.25ms de moyenne
590 */
591 Client.prototype.getXMLProfile = function()
592 {
593 var XMLDocument = this.util.creerDocumentXMLAction()
594 XMLDocument.documentElement.setAttribute("name", "profile")
595
596 var nodeCookie = XMLDocument.createElement("cookie")
597 nodeCookie.appendChild(XMLDocument.createTextNode(this.cookie))
598 XMLDocument.documentElement.appendChild(nodeCookie)
599
600 var nodeLogin = XMLDocument.createElement("login")
601 nodeLogin.appendChild(XMLDocument.createTextNode(this.login))
602 XMLDocument.documentElement.appendChild(nodeLogin)
603
604 var nodePassword = XMLDocument.createElement("password")
605 nodePassword.appendChild(XMLDocument.createTextNode(this.password))
606 XMLDocument.documentElement.appendChild(nodePassword)
607
608 var nodePseudo = XMLDocument.createElement("pseudo")
609 nodePseudo.appendChild(XMLDocument.createTextNode(this.pseudo))
610 XMLDocument.documentElement.appendChild(nodePseudo)
611
612 var nodeEmail = XMLDocument.createElement("email")
613 nodeEmail.appendChild(XMLDocument.createTextNode(this.email))
614 XMLDocument.documentElement.appendChild(nodeEmail)
615
616 var nodeCSS = XMLDocument.createElement("css")
617 nodeCSS.appendChild(XMLDocument.createTextNode(this.css))
618 XMLDocument.documentElement.appendChild(nodeCSS)
619
620 var nodePagePrincipale = XMLDocument.createElement("pagePrincipale")
621 nodePagePrincipale.appendChild(XMLDocument.createTextNode(this.pagePrincipale < 1 ? 1 : this.pagePrincipale))
622 XMLDocument.documentElement.appendChild(nodePagePrincipale)
623
624 // mémorise les conversations affichées
625 for (var i = 0; i < this.conversations.length; i++)
626 {
627 var nodeConv = XMLDocument.createElement("conversation")
628 XMLDocument.documentElement.appendChild(nodeConv)
629
630 var nodeRacine = XMLDocument.createElement("racine")
631 nodeRacine.appendChild(XMLDocument.createTextNode(this.conversations[i].racine))
632 nodeConv.appendChild(nodeRacine)
633
634 var nodePage = XMLDocument.createElement("page")
635 nodePage.appendChild(XMLDocument.createTextNode(this.conversations[i].page))
636 nodeConv.appendChild(nodePage)
637 }
638
639 return XMLDocument
640 }
641
642 /**
643 * Renvoie null si pas définit.
644 */
645 Client.prototype.getCookie = function()
646 {
647 var cookie = this.regexCookie.exec(document.cookie)
648 if (cookie == null) this.cookie = null
649 else this.cookie = cookie[1]
650 }
651
652 Client.prototype.delCookie = function()
653 {
654 document.cookie = "cookie=; max-age=0"
655 }
656
657 Client.prototype.setCookie = function(cookie)
658 {
659 if (this.cookie == null)
660 return
661
662 document.cookie =
663 "cookie="+this.cookie+
664 "; max-age=" + (60 * 60 * 24 * 365)
665 }
666
667 Client.prototype.identifie = function()
668 {
669 return this.statut == statutType.enregistre || this.statut == statutType.identifie
670 }
671
672 Client.prototype.setStatut = function(statut)
673 {
674 if(typeof(statut) == "string")
675 {
676 statut =
677 statut == "enregistre" ?
678 statutType.enregistre : (statut == "identifie" ? statutType.identifie : statutType.non_identifie)
679 }
680
681 if (statut == this.statut) return
682
683 this.statut = statut
684 this.majMenu()
685 }
686
687 /**
688 * Effectue la connexion vers le serveur.
689 * Cette fonction est bloquante tant que la connexion n'a pas été établie.
690 * S'il existe un cookie en local on s'authentifie directement avec lui.
691 * Si il n'est pas possible de s'authentifier alors on affiche un captcha anti-bot.
692 */
693 Client.prototype.connexionCookie = function()
694 {
695 this.getCookie()
696 if (this.cookie == null) return false;
697 return this.connexion(this.util.xmlVersAction(this.getXMLloginCookie()))
698 }
699
700 Client.prototype.connexionLogin = function(login, password)
701 {
702 // return this.connexion(this.util.xmlVersAction(this.getXMLlogin(login, password)))
703 return this.connexion(this.util.jsonVersAction(this.getJSONLogin(login, password)))
704 }
705
706 Client.prototype.enregistrement = function(login, password)
707 {
708 if (this.identifie())
709 {
710 this.login = login
711 this.password = password
712 if(this.flush())
713 this.setStatut(statutType.enregistre)
714 return true
715 }
716 else
717 {
718 if (login == undefined) login = ""
719 if (password == undefined) password = ""
720 return this.connexion(this.util.xmlVersAction(this.getXMLEnregistrement(login, password)))
721 }
722 }
723
724 Client.prototype.connexion = function(action)
725 {
726 action.action.dump("Connexion client")
727 thisClient = this
728 jQuery.ajax(
729 {
730 async: false,
731 type: "POST",
732 url: "request",
733 dataType: "json",
734 data: action,
735 success:
736 function(data)
737 {
738 thisClient.util.serializer.serializeToString(data).dump("Charger client")
739 thisClient.chargerDonnees(data)
740 }
741 }
742 )
743 return this.identifie()
744 }
745
746 Client.prototype.deconnexion = function()
747 {
748 this.setStatut(statutType.non_identifie) // deconnexion
749 this.resetDonneesPersonnelles()
750 this.delCookie ()
751 }
752
753 Client.prototype.chargerDonnees = function(data)
754 {
755 var thisClient = this
756
757 this.setStatut(jQuery("statut", data.documentElement).text())
758
759 if (this.identifie())
760 {
761 this.cookie = jQuery("cookie", data.documentElement).text()
762 this.setCookie()
763
764 this.login = jQuery("login", data.documentElement).text()
765 this.pseudo = jQuery("pseudo", data.documentElement).text()
766 this.email = jQuery("email", data.documentElement).text()
767 this.css = jQuery("css", data.documentElement).text()
768
769 // la page de la conversation principale
770 var tmp = jQuery("pagePrincipale", data.documentElement)
771 this.pagePrincipale = tmp.length < 1 ? 1 : parseInt(tmp.text())
772
773 // met à jour la css
774 if (this.css != "")
775 {
776 jQuery("link#cssPrincipale").attr("href", this.css)
777 this.majMenu()
778 }
779 // les conversations
780 this.conversations = new Array()
781 jQuery("conversation", data.documentElement).each(
782 function(i)
783 {
784 thisClient.conversations.push( { racine : jQuery("racine", this).text(), page : jQuery("page", this).text() } )
785 }
786 )
787 }
788 this.dernierMessageErreur = jQuery("information", data.documentElement).text()
789 }
790
791 /**
792 * Met à jour les données personne sur serveur.
793 * @param async de manière asynchrone ? défaut = true
794 */
795 Client.prototype.flush = function(async)
796 {
797 if (async == undefined)
798 async = true
799
800 thisClient = this
801 this.util.xmlVersAction(this.getXMLProfile()).action.dump("Flush client")
802 jQuery.ajax(
803 {
804 async: async,
805 type: "POST",
806 url: "request",
807 dataType: "xml",
808 data: this.util.xmlVersAction(this.getXMLProfile()),
809 success:
810 function(data)
811 {
812 //thisClient.util.log(thisClient.util.serializer.serializeToString(data))
813 }
814 }
815 )
816 // TODO : retourner false si un problème est survenu lors de l'update du profile
817 return true
818 }
819
820 Client.prototype.majMenu = function()
821 {
822 var displayType = this.css == "css/3/euphorik.css" ? "block" : "inline" //this.client
823
824 // met à jour le menu
825 if (this.statut == statutType.enregistre)
826 {
827 jQuery("#menu .profile").css("display", displayType).text("profile")
828 jQuery("#menu .logout").css("display", displayType)
829 jQuery("#menu .register").css("display", "none")
830 }
831 else if (this.statut == statutType.identifie)
832 {
833 jQuery("#menu .profile").css("display", "none")
834 jQuery("#menu .logout").css("display", displayType)
835 jQuery("#menu .register").css("display", displayType)
836 }
837 else
838 {
839 jQuery("#menu .profile").css("display", displayType).text("login")
840 jQuery("#menu .logout").css("display", "none")
841 jQuery("#menu .register").css("display", displayType)
842 }
843 }
844
845 ///////////////////////////////////////////////////////////////////////////////////////////////////
846
847 jQuery.noConflict()
848
849
850 // le main
851 jQuery(document).ready(
852 function()
853 {
854 /* FIXME : ce code pose problème sur konqueror, voir : http://www.kde-forum.org/thread.php?threadid=17993
855 var p = new DOMParser();
856 var doc = p.parseFromString("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<action/>", "text/xml")
857 var s = new XMLSerializer()
858 alert(s.serializeToString(doc)) */
859
860 var util = new Util()
861 var client = new Client(util)
862 var pages = new Pages()
863 var formateur = new Formateur()
864
865 // connexion vers le serveur (utilise un cookie qui traine)
866 client.connexionCookie()
867
868 // les styles css
869 for (var i = 1; i <= 3; i++)
870 {
871 jQuery("#css"+i).click(function(){
872 client.setCss("css/" + jQuery(this).attr("id").charAt(3) + "/euphorik.css")
873 })
874 }
875
876 jQuery("#menu .minichat").click(function(){ pages.afficherPage("minichat") })
877 jQuery("#menu .profile").click(function(){ pages.afficherPage("profile") })
878 jQuery("#menu .logout").click(function(){
879 util.messageDialogue("Êtes-vous sur de vouloir vous délogger ?", messageType.question,
880 {"Oui" : function()
881 {
882 client.deconnexion();
883 pages.afficherPage("minichat", true)
884 },
885 "Non" : function(){}
886 }
887 )
888 })
889 jQuery("#menu .register").click(function(){ pages.afficherPage("register") })
890
891 pages.ajouterPage(new PageMinichat(client, formateur, util))
892 pages.ajouterPage(new PageProfile(client, formateur, util))
893 pages.ajouterPage(new PageRegister(client, formateur, util))
894 pages.afficherPage("minichat")
895 }
896 )
897