MOD french -> english (2)
authorGreg Burri <greg.burri@gmail.com>
Tue, 27 Jan 2009 21:07:06 +0000 (21:07 +0000)
committerGreg Burri <greg.burri@gmail.com>
Tue, 27 Jan 2009 21:07:06 +0000 (21:07 +0000)
MOD merge of comet.js into communication.js #100

16 files changed:
index.yaws
js/betterjs.js
js/client.js
js/comet.js [deleted file]
js/communication.js
js/euphorik.js
js/libs/json2.js
js/pageAdmin.js
js/pageMinichat/conversations.js
js/pageMinichat/pageMinichat.js
js/pageStatic.js [new file with mode: 0644]
js/pageStatique.js [deleted file]
pages/conditions_utilisation.html [deleted file]
pages/terms_of_use.html [new file with mode: 0644]
styles/1/euphorik.css
styles/2/euphorik.css

index 87f40e2..7b391d3 100755 (executable)
@@ -10,9 +10,7 @@
       end
    }}.
 </erl>
-<html xmlns="http://www.w3.org/1999/xhtml" 
-      xmlns:svg="http://www.w3.org/2000/svg"
-      xmlns:xlink="http://www.w3.org/1999/xlink">
+<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>euphorik.ch</title>
@@ -53,7 +51,7 @@
    <script type="text/javascript" src="js/pages.js" prod="delete"></script>
    <script type="text/javascript" src="js/client.js" prod="delete"></script>
 
-   <script type="text/javascript" src="js/pageStatique.js" prod="delete"></script>
+   <script type="text/javascript" src="js/pageStatic.js" prod="delete"></script>
    <script type="text/javascript" src="js/pageMinichat/pageMinichat.js" prod="delete"></script>
    <script type="text/javascript" src="js/pageMinichat/conversation.js" prod="delete"></script>
    <script type="text/javascript" src="js/pageMinichat/conversations.js" prod="delete"></script>
                            )
                         }.
                   </erl>
-                  <!-- option value="1" selected="selected">Retro</option>
-                  <option value="2">Dark</option -->
                </select>
             </p>
          </form> 
          <div id="page"></div>
-         <div id="footer"><span class="copyright">copyright 2008 euphorik.ch</span><span class="conditions lien">conditions d'utilisation</span><a href="http://yaws.hyber.org"><img src="img/powered-by-yaws.gif" alt="powered by Yaws" /></a></div>
+         <div id="footer"><span class="copyright">copyright 2008 euphorik.ch</span><span class="termsOfUse pageLink">terms of use</span><a href="http://yaws.hyber.org"><img src="img/powered-by-yaws.gif" alt="powered by Yaws" /></a></div>
       </div>
    </body>
 </html>
index d982030..6c5b0e6 100644 (file)
@@ -1,11 +1,12 @@
 // coding: utf-8
-// tout un tas d'améliorations de JavaScript ;)
-
+// some improvements for JavaScript
 
 /**
-  * Pour chaque propriété de l'objet execute f(p, v) ou p est le nom de la propriété et v sa valeur.
-  * Ne parcours pas les propriétés des prototypes.
-  * FIXME : Normalement : Object.prototype.each = function(f) mais non supporté par jquery
+  * For each object properties execute f(p, v) where p is the propertie name and v its value.
+  * Does not traverse the protypes properties.
+  * FIXME : Should be "Object.prototype.each = function(f)" but doen't supported by jQuery.
+  * @o The object.
+  * @f The function f(p, v).
   */
 //Object.prototype.each = function(f) {
 var objectEach = function(o, f) {
@@ -16,6 +17,11 @@ var objectEach = function(o, f) {
    }
 };
 
+/**
+  * Return the number of properties of a given object.
+  * Does not count the prototypes properties.
+  * @o The object.
+  */
 var objectMemberCount = function(o) {
    var nb = 0;
    for (var k in o) {
@@ -26,34 +32,52 @@ var objectMemberCount = function(o) {
    return nb;
 };
 
+/**
+  * Call a function to all value of the Array.
+  * @f The function f(i, v) where i is the index and v the value.
+  */
 Array.prototype.each = function(f) {
    for (var i = 0; i < this.length; i++) {
       f(i, this[i]);
    }
 };
 
+/**
+  * Map a function to all value of the Array.
+  * @f The function f(v) -> v' where v is the old value and v' the new one.
+  */
 Array.prototype.map = function(f) {
    for (var i = 0; i < this.length; i++) {
       this[i] = f(this[i]);
    }
 };
 
+/**
+  * Remove all space character (space, tab) at the begining and the end of the String.
+  */
 String.prototype.trim = function() {
        return jQuery.trim(this); // anciennement : this.replace(/^\s+|\s+$/g, "");
 };
 
+/**
+  * Remove all space character (space, tab) at the begining of the String.
+  */
 String.prototype.ltrim = function() {
        return this.replace(/^\s+/, "");
 };
 
+/**
+  * Remove all space character (space, tab) at the end of the String.
+  */
 String.prototype.rtrim = function() {
        return this.replace(/\s+$/, "");
 };
 
 /**
-  * Voir : http://www.coolpage.com/developer/javascript/Correct%20OOP%20for%20Javascript.html
+  * (Not use for the moment)
+  * See : http://www.coolpage.com/developer/javascript/Correct%20OOP%20for%20Javascript.html
   *
-  * Exemple :  
+  * Example :  
   *
   * function Mammal(name) {
   *    this.name = name;
index 5324f96..98c0413 100644 (file)
@@ -31,7 +31,7 @@ euphorik.Client = function(util, communication) {
    // données personnels\r
    this.resetDonneesPersonnelles();\r
    \r
-   this.setStatut(euphorik.Client.statutType.deconnected);\r
+   this.setStatut(euphorik.Client.statutType.disconnected);\r
    \r
    // si true alors chaque modification du client est mémorisé sur le serveur\r
    this.autoflush = $.browser.opera;\r
@@ -44,7 +44,7 @@ euphorik.Client.statutType = {
    // mode identifié, peut poster des messages mais n'a pas accès au profile\r
    auth_not_registered : 1,\r
    // mode déconnecté, ne peut pas poster de message\r
-   deconnected : 2\r
+   disconnected : 2\r
 };\r
 \r
 euphorik.Client.prototype.resetDonneesPersonnelles = function() {\r
@@ -232,7 +232,7 @@ euphorik.Client.prototype.setStatut = function(statut)
       statut =\r
          statut === "auth_registered" ?\r
             euphorik.Client.statutType.auth_registered :\r
-         (statut === "auth_not_registered" ? euphorik.Client.statutType.auth_not_registered : euphorik.Client.statutType.deconnected);\r
+         (statut === "auth_not_registered" ? euphorik.Client.statutType.auth_not_registered : euphorik.Client.statutType.disconnected);\r
    }\r
    \r
    if (statut === this.statut) {\r
@@ -244,14 +244,12 @@ euphorik.Client.prototype.setStatut = function(statut)
    this.majMenu();\r
    this.majLogo();\r
 };\r
-\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
+
+/**
+  * Try to authentify the client with the cookie information.
+  * Do nothing if there is no cookie.
   */\r
-euphorik.Client.prototype.connexionCookie = function() {\r
+euphorik.Client.prototype.connectionCookie = function() {\r
    this.getCookie();\r
    if (!this.cookie) {\r
       return false;\r
@@ -315,11 +313,11 @@ euphorik.Client.prototype.connexion = function(action, messageJson) {
    return this.authentifie();\r
 };\r
 \r
-euphorik.Client.prototype.deconnexion = function() {\r
+euphorik.Client.prototype.disconnect = function() {\r
    this.flush(true);\r
    this.delCookie();\r
    this.resetDonneesPersonnelles();\r
-   this.setStatut(euphorik.Client.statutType.deconnected); // deconnexion\r
+   this.setStatut(euphorik.Client.statutType.disconnected);\r
 };\r
 \r
 euphorik.Client.prototype.chargerDonnees = function(data) {\r
diff --git a/js/comet.js b/js/comet.js
deleted file mode 100644 (file)
index 8c427c9..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-// coding: utf-8\r
-// Copyright 2008 Grégory Burri\r
-//\r
-// This file is part of Euphorik.\r
-//\r
-// Euphorik is free software: you can redistribute it and/or modify\r
-// it under the terms of the GNU General Public License as published by\r
-// the Free Software Foundation, either version 3 of the License, or\r
-// (at your option) any later version.\r
-//\r
-// Euphorik is distributed in the hope that it will be useful,\r
-// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-// GNU General Public License for more details.\r
-//\r
-// You should have received a copy of the GNU General Public License\r
-// along with Euphorik.  If not, see <http://www.gnu.org/licenses/>.\r
-\r
-/*jslint laxbreak:true */\r
-\r
-/**\r
-  * Permet de gérer les événements (push serveur).\r
-  * Principe de fonctionnement :\r
-  *  - La page courante créer un objet euphorik.Comet en indiquant le nom de la page et la version du protocole.\r
-  *  - La page courante attend un événement en appelant 'waitEvent' (non-bloquant) et en donnant deux fonctions :\r
-  *    - 'funSend' une fonction qui renvoie l'objet à envoyer avant l'attente, par exemple {"dernierMess" : 23}\r
-  *       ("header" et "page" sont automatiquement ajoutés à l'objet)\r
-  *    - 'funsReceive' un ensemble de fonctions à appeler en fonction du "reply" du serveur, par exemple {"set_nom" : function(data) { print("ok : " + data.nom); } }\r
-  *\r
-  * l'information envoyée est sous la forme :\r
-  *  {\r
-  *     "header" : {"action" : "wait_event", "version" : <v> },\r
-  *     "page" : <page>\r
-  *     [..]\r
-  *  }\r
-  * l'information reçue est sous la forme :\r
-  *  {\r
-  *     "reply" : <reply>\r
-  *     [..]\r
-  *  }\r
-  * <reply> et <page> sont de type chaine\r
-  *\r
-  * @page [string] la page courante pour laquelle on écoute des événements (un string)\r
-  * @util [int] la version\r
-  */\r
-Comet = function(page, version) {\r
-   this.page = page;\r
-   this.version = version;\r
-   \r
-   // l'objet JSONHttpRequest représentant la connexion d'attente\r
-   this.attenteCourante = undefined;\r
-   \r
-   // le multhreading du pauvre, merci javascript de m'offrire autant de primitives pour la gestion de la concurrence...\r
-   this.stop = false;\r
-};\r
-\r
-/**\r
-  * Arrête l'attente courante s'il y en a une.\r
-  */\r
-Comet.prototype.stopAttenteCourante = function() {\r
-   this.stop = true;\r
-         \r
-   if (this.attenteCourante) {\r
-      this.attenteCourante.abort();\r
-   }\r
-};\r
-\r
-/**\r
-  * Attend un événement lié à la page. Non-bloquant. \r
-  * @funSend une fonction renvoyant les données json à envoyer\r
-  * @funsReceive est un objet comprenant les fonctions à appeler en fonction du "reply"\r
-  * les fonctions acceptent un paramètre correspondant au données reçues.\r
-  * exemple : {"new_message" : function(data){ ... }}\r
-  */\r
-Comet.prototype.waitEvent = function(funSend, funsReceive) {\r
-   this.stopAttenteCourante();\r
-   \r
-   this.stop = false;\r
-   \r
-   var thisComet = this;\r
-      \r
-   // on doit conserver l'ordre des valeurs de l'objet JSON (le serveur les veut dans l'ordre définit dans le protocole)\r
-   // TODO : ya pas mieux ?\r
-   var dataToSend = {\r
-      "header" : { "action" : "wait_event", "version" : this.version },\r
-      "page" : this.page\r
-   };\r
-   var poulpe = funSend();\r
-   objectEach(poulpe, function(k, v) {\r
-      dataToSend[k] = v;\r
-   });\r
-   \r
-   this.attenteCourante = jQuery.ajax({\r
-      type: "POST",\r
-      url: "request",\r
-      dataType: "json",\r
-      // TODO : doit disparaitre\r
-      timeout: 180000, // timeout de 3min. Gros HACK pas beau. FIXME problème décrit ici : http://groups.google.com/group/jquery-en/browse_thread/thread/8724e64af3333a76\r
-      data: { action : JSON.stringify(dataToSend) },\r
-      success:\r
-         function(data) {\r
-            funsReceive[data.reply](data);\r
-         \r
-            // rappel de la fonction dans 100 ms\r
-            setTimeout(function(){ thisComet.waitEvent2(funSend, funsReceive); }, 100);\r
-         },\r
-      error:\r
-         function(XMLHttpRequest, textStatus, errorThrown) {\r
-            ;; console.log("Connexion perdue dans Comet.prototype.waitEvent() : \n" + textStatus);\r
-            setTimeout(function(){ thisComet.waitEvent2(funSend, funsReceive); }, 1000);\r
-         }\r
-   });\r
-};\r
-\r
-/**\r
-  * Si un stopAttenteCourante survient un peu n'importe quand il faut imédiatement arreter de boucler.\r
-  */\r
-Comet.prototype.waitEvent2 = function(funSend, funsReceive) {\r
-   if (this.stop) {\r
-      return;\r
-   }\r
-   this.waitEvent(funSend, funsReceive);\r
-};
\ No newline at end of file
index 985aeed..7288810 100644 (file)
@@ -108,9 +108,114 @@ euphorik.Communication.prototype.requete = function(action, json, funOk, funErro
    \r
    jQuery.ajax(paramsAjax);\r
 };\r
+
+euphorik.Communication.prototype.createCometConnection = function(name) {
+   return new Comet(name, this.getBase);
+};
 \r
 euphorik.Communication.prototype.getBase = function(action) {\r
    return {\r
       "header" : { "action" : action, "version" : euphorik.conf.versionProtocole }\r
    };\r
+};
+
+/**
+  * Permet de gérer les événements (push serveur).
+  * Principe de fonctionnement :
+  *  - La page courante créer un objet euphorik.Comet en indiquant le nom de la page et la version du protocole.
+  *  - La page courante attend un événement en appelant 'waitEvent' (non-bloquant) et en donnant deux fonctions :
+  *    - 'funSend' une fonction qui renvoie l'objet à envoyer avant l'attente, par exemple {"dernierMess" : 23}
+  *       ("header" et "page" sont automatiquement ajoutés à l'objet)
+  *    - 'funsReceive' un ensemble de fonctions à appeler en fonction du "reply" du serveur, par exemple {"set_nom" : function(data) { print("ok : " + data.nom); } }
+  *
+  * l'information envoyée est sous la forme :
+  *  {
+  *     "header" : {"action" : "wait_event", "version" : <v> },
+  *     "page" : <page>
+  *     [..]
+  *  }
+  * l'information reçue est sous la forme :
+  *  {
+  *     "reply" : <reply>
+  *     [..]
+  *  }
+  * <reply> et <page> sont de type chaine
+  *
+  * @page [string] la page courante pour laquelle on écoute des événements (un string)
+  * @util [int] la version
+  */
+Comet = function(page, getBase) {
+   this.page = page;
+   this.getBase = getBase;
+   
+   // l'objet JSONHttpRequest représentant la connexion d'attente
+   this.attenteCourante = undefined;
+   
+   // le multhreading du pauvre, merci javascript de m'offrire autant de primitives pour la gestion de la concurrence...
+   this.stop = false;
+};
+
+/**
+  * Arrête l'attente courante s'il y en a une.
+  */
+Comet.prototype.stopAttenteCourante = function() {
+   this.stop = true;
+         
+   if (this.attenteCourante) {
+      this.attenteCourante.abort();
+   }
+};
+
+/**
+  * Attend un événement lié à la page. Non-bloquant. 
+  * @funSend une fonction renvoyant les données json à envoyer
+  * @funsReceive est un objet comprenant les fonctions à appeler en fonction du "reply"
+  * les fonctions acceptent un paramètre correspondant au données reçues.
+  * exemple : {"new_message" : function(data){ ... }}
+  */
+Comet.prototype.waitEvent = function(funSend, funsReceive) {
+   this.stopAttenteCourante();   
+   this.stop = false;   
+   var thisComet = this;
+      
+   // on doit conserver l'ordre des valeurs de l'objet JSON (le serveur les veut dans l'ordre définit dans le protocole)
+   // TODO : ya pas mieux ?
+   var dataToSend = this.getBase("wait_event")
+   dataToSend["page"] = this.page;
+   
+   var poulpe = funSend();
+   objectEach(poulpe, function(k, v) {
+      dataToSend[k] = v;
+   });
+   
+   this.attenteCourante = jQuery.ajax({
+      type: "POST",
+      url: "request",
+      dataType: "json",
+      // TODO : doit disparaitre
+      timeout: 180000, // timeout de 3min. Gros HACK pas beau. FIXME problème décrit ici : http://groups.google.com/group/jquery-en/browse_thread/thread/8724e64af3333a76
+      data: { action : JSON.stringify(dataToSend) },
+      success:
+         function(data) {
+            funsReceive[data.reply](data);
+         
+            // rappel de la fonction dans 100 ms
+            setTimeout(function(){ thisComet.waitEvent2(funSend, funsReceive); }, 100);
+         },
+      error:
+         function(XMLHttpRequest, textStatus, errorThrown) {
+            ;; console.log("Connexion perdue dans Comet.prototype.waitEvent() : \n" + textStatus);
+            setTimeout(function(){ thisComet.waitEvent2(funSend, funsReceive); }, 1000);
+         }
+   });
+};
+
+/**
+  * Si un stopAttenteCourante survient un peu n'importe quand il faut imédiatement arreter de boucler.
+  */
+Comet.prototype.waitEvent2 = function(funSend, funsReceive) {
+   if (this.stop) {
+      return;
+   }
+   this.waitEvent(funSend, funsReceive);
 };
\ No newline at end of file
index 107a5c0..e3bd720 100755 (executable)
@@ -34,14 +34,14 @@ $(document).ready(
       );
       var client = new euphorik.Client(util, communication);
       var pages = new euphorik.Pages(fragment, communication);
-      
-      // connexion vers le serveur (utilise un cookie qui traine)
-      client.connexionCookie();
+           
+      // Client authentification with the cookie information (if  it exists).
+      client.connectionCookie();
       
       $("#menuCss").change(function() { client.setCss("styles/" + $("option:selected", this).attr("value") + "/euphorik.css"); });
 
       // FIXME : doesn't work under Opera
-      // voir : http://dev.jquery.com/ticket/2892#preview
+      // see : http://dev.jquery.com/ticket/2892#preview
       $(window).unload(function() { client.flush(); });
       
       $("#menu .minichat").click(function() { pages.displayPage("minichat"); });
@@ -51,7 +51,7 @@ $(document).ready(
          util.messageDialog("Are you sure you want to log out?", euphorik.Util.messageType.question,
             {
                "Yes" : function() {
-                  client.deconnexion();
+                  client.disconnect();
                   pages.displayPage("minichat", true);
                },
                "No" : function() {}
@@ -63,15 +63,15 @@ $(document).ready(
       
       // TODO : simplification : such link[1] should be created and automatically open the right page without\r
       //  explicitly add a page.\r
-      // [1] : <a class="lien" href="conditions">Conditions d'utilisation</a>
-      $("#footer .conditions").click(function(){ pages.displayPage("conditions_utilisation"); });
+      // [1] : <a class="pageLink" href="termes_of_use">Terms of use</a>
+      $("#footer .termsOfUse").click(function(){ pages.displayPage("terms_of_use"); });
       
       pages.addPage(new euphorik.PageMinichat(client, formater, util, communication), true);
       pages.addPage(new euphorik.PageAdmin(client, formater, util, communication));
       pages.addPage(new euphorik.PageProfile(client, formater, util));
       pages.addPage(new euphorik.PageRegister(client, formater, util));
       pages.addPage(new euphorik.PageAbout(client, formater, util, communication));
-      pages.addPage("conditions_utilisation");
+      pages.addPage("terms_of_use");
       
       pages.displayPage(); // display the default page
    }
index 25ff1ec..241a271 100644 (file)
@@ -1,6 +1,6 @@
 /*
     http://www.JSON.org/json2.js
-    2008-03-24
+    2008-11-19
 
     Public Domain.
 
@@ -8,23 +8,22 @@
 
     See http://www.JSON.org/js.html
 
-    This file creates a global JSON object containing three methods: stringify,
-    parse, and quote.
-
+    This file creates a global JSON object containing two methods: stringify
+    and parse.
 
         JSON.stringify(value, replacer, space)
             value       any JavaScript value, usually an object or array.
 
             replacer    an optional parameter that determines how object
-                        values are stringified for objects without a toJSON
-                        method. It can be a function or an array.
+                        values are stringified for objects. It can be a
+                        function or an array of strings.
 
             space       an optional parameter that specifies the indentation
                         of nested structures. If it is omitted, the text will
                         be packed without extra whitespace. If it is a number,
                         it will specify the number of spaces to indent at each
-                        level. If it is a string (such as '\t'), it contains the
-                        characters used to indent at each level.
+                        level. If it is a string (such as '\t' or '&nbsp;'),
+                        it contains the characters used to indent at each level.
 
             This method produces a JSON text from a JavaScript value.
 
             method, its toJSON method will be called and the result will be
             stringified. A toJSON method does not serialize: it returns the
             value represented by the name/value pair that should be serialized,
-            or undefined if nothing should be serialized. The toJSON method will
-            be passed the key associated with the value, and this will be bound
-            to the object holding the key.
+            or undefined if nothing should be serialized. The toJSON method
+            will be passed the key associated with the value, and this will be
+            bound to the object holding the key.
+
+            For example, this would serialize Dates as ISO strings.
 
-            This is the toJSON method added to Dates:
+                Date.prototype.toJSON = function (key) {
+                    function f(n) {
+                        // Format integers to have at least two digits.
+                        return n < 10 ? '0' + n : n;
+                    }
 
-                function toJSON(key) {
                     return this.getUTCFullYear()   + '-' +
                          f(this.getUTCMonth() + 1) + '-' +
                          f(this.getUTCDate())      + 'T' +
                          f(this.getUTCHours())     + ':' +
                          f(this.getUTCMinutes())   + ':' +
                          f(this.getUTCSeconds())   + 'Z';
-                }
+                };
 
             You can provide an optional replacer method. It will be passed the
             key and value of each member, with this bound to the containing
             serialized. If your method returns undefined, then the member will
             be excluded from the serialization.
 
-            If no replacer parameter is provided, then a default replacer
-            will be used:
-
-                function replacer(key, value) {
-                    return Object.hasOwnProperty.call(this, key) ?
-                        value : undefined;
-                }
-
-            The default replacer is passed the key and value for each item in
-            the structure. It excludes inherited members.
-
-            If the replacer parameter is an array, then it will be used to
-            select the members to be serialized. It filters the results such
-            that only members with keys listed in the replacer array are
+            If the replacer parameter is an array of strings, then it will be
+            used to select the members to be serialized. It filters the results
+            such that only members with keys listed in the replacer array are
             stringified.
 
-            Values that do not have JSON representaions, such as undefined or
+            Values that do not have JSON representations, such as undefined or
             functions, will not be serialized. Such values in objects will be
             dropped; in arrays they will be replaced with null. You can use
             a replacer function to replace those with JSON values.
             JSON.stringify(undefined) returns undefined.
 
-            The optional space parameter produces a stringification of the value
-            that is filled with line breaks and indentation to make it easier to
-            read.
+            The optional space parameter produces a stringification of the
+            value that is filled with line breaks and indentation to make it
+            easier to read.
 
             If the space parameter is a non-empty string, then that string will
             be used for indentation. If the space parameter is a number, then
-            then indentation will be that many spaces.
+            the indentation will be that many spaces.
 
             Example:
 
             text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
             // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
 
+            text = JSON.stringify([new Date()], function (key, value) {
+                return this[key] instanceof Date ?
+                    'Date(' + this[key] + ')' : value;
+            });
+            // text is '["Date(---current time---)"]'
+
 
         JSON.parse(text, reviver)
             This method parses a JSON text to produce an object or array.
                 return value;
             });
 
-
-        JSON.quote(text)
-            This method wraps a string in quotes, escaping some characters
-            as needed.
+            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+                var d;
+                if (typeof value === 'string' &&
+                        value.slice(0, 5) === 'Date(' &&
+                        value.slice(-1) === ')') {
+                    d = new Date(value.slice(5, -1));
+                    if (d) {
+                        return d;
+                    }
+                }
+                return value;
+            });
 
 
     This is a reference implementation. You are free to copy, modify, or
     redistribute.
 
-    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD THIRD PARTY
-    CODE INTO YOUR PAGES.
+    This code should be minified before deployment.
+    See http://javascript.crockford.com/jsmin.html
+
+    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+    NOT CONTROL.
 */
 
-/*jslint regexp: true, forin: true, evil: true */
+/*jslint evil: true */
 
 /*global JSON */
 
 /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
-    call, charCodeAt, floor, getUTCDate, getUTCFullYear, getUTCHours,
-    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, length,
-    parse, propertyIsEnumerable, prototype, push, quote, replace, stringify,
-    test, toJSON, toString
+    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
 */
 
-if (!this.JSON) {
-
 // Create a JSON object only if one does not already exist. We create the
-// object in a closure to avoid global variables.
+// methods in a closure to avoid creating global variables.
 
-    JSON = function () {
+if (!this.JSON) {
+    JSON = {};
+}
+(function () {
 
-        function f(n) {    // Format integers to have at least two digits.
-            return n < 10 ? '0' + n : n;
-        }
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10 ? '0' + n : n;
+    }
 
-        Date.prototype.toJSON = function () {
+    if (typeof Date.prototype.toJSON !== 'function') {
 
-// Eventually, this method will be based on the date.toISOString method.
+        Date.prototype.toJSON = function (key) {
 
             return this.getUTCFullYear()   + '-' +
                  f(this.getUTCMonth() + 1) + '-' +
@@ -168,173 +180,177 @@ if (!this.JSON) {
                  f(this.getUTCSeconds())   + 'Z';
         };
 
-
-        var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g,
-            gap,
-            indent,
-            meta = {    // table of character substitutions
-                '\b': '\\b',
-                '\t': '\\t',
-                '\n': '\\n',
-                '\f': '\\f',
-                '\r': '\\r',
-                '"' : '\\"',
-                '\\': '\\\\'
-            },
-            rep;
-
-
-        function quote(string) {
+        String.prototype.toJSON =
+        Number.prototype.toJSON =
+        Boolean.prototype.toJSON = function (key) {
+            return this.valueOf();
+        };
+    }
+
+    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        gap,
+        indent,
+        meta = {    // table of character substitutions
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '\\': '\\\\'
+        },
+        rep;
+
+
+    function quote(string) {
 
 // If the string contains no control characters, no quote characters, and no
 // backslash characters, then we can safely slap some quotes around it.
 // Otherwise we must also replace the offending characters with safe escape
 // sequences.
 
-            return escapeable.test(string) ?
-                '"' + string.replace(escapeable, function (a) {
-                    var c = meta[a];
-                    if (typeof c === 'string') {
-                        return c;
-                    }
-                    c = a.charCodeAt();
-                    return '\\u00' + Math.floor(c / 16).toString(16) +
-                                               (c % 16).toString(16);
-                }) + '"' :
-                '"' + string + '"';
-        }
+        escapable.lastIndex = 0;
+        return escapable.test(string) ?
+            '"' + string.replace(escapable, function (a) {
+                var c = meta[a];
+                return typeof c === 'string' ? c :
+                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+            }) + '"' :
+            '"' + string + '"';
+    }
 
 
-        function str(key, holder) {
+    function str(key, holder) {
 
 // Produce a string from holder[key].
 
-            var i,          // The loop counter.
-                k,          // The member key.
-                v,          // The member value.
-                length,
-                mind = gap,
-                partial,
-                value = holder[key];
+        var i,          // The loop counter.
+            k,          // The member key.
+            v,          // The member value.
+            length,
+            mind = gap,
+            partial,
+            value = holder[key];
 
 // If the value has a toJSON method, call it to obtain a replacement value.
 
-            if (value && typeof value === 'object' &&
-                    typeof value.toJSON === 'function') {
-                value = value.toJSON(key);
-            }
+        if (value && typeof value === 'object' &&
+                typeof value.toJSON === 'function') {
+            value = value.toJSON(key);
+        }
 
 // If we were called with a replacer function, then call the replacer to
 // obtain a replacement value.
 
-            if (typeof rep === 'function') {
-                value = rep.call(holder, key, value);
-            }
+        if (typeof rep === 'function') {
+            value = rep.call(holder, key, value);
+        }
 
 // What happens next depends on the value's type.
 
-            switch (typeof value) {
-            case 'string':
-                return quote(value);
+        switch (typeof value) {
+        case 'string':
+            return quote(value);
 
-            case 'number':
+        case 'number':
 
 // JSON numbers must be finite. Encode non-finite numbers as null.
 
-                return isFinite(value) ? String(value) : 'null';
+            return isFinite(value) ? String(value) : 'null';
 
-            case 'boolean':
-            case 'null':
+        case 'boolean':
+        case 'null':
 
 // If the value is a boolean or null, convert it to a string. Note:
 // typeof null does not produce 'null'. The case is included here in
 // the remote chance that this gets fixed someday.
 
-                return String(value);
+            return String(value);
 
 // If the type is 'object', we might be dealing with an object or an array or
 // null.
 
-            case 'object':
+        case 'object':
 
 // Due to a specification blunder in ECMAScript, typeof null is 'object',
 // so watch out for that case.
 
-                if (!value) {
-                    return 'null';
-                }
+            if (!value) {
+                return 'null';
+            }
 
 // Make an array to hold the partial results of stringifying this object value.
 
-                gap += indent;
-                partial = [];
+            gap += indent;
+            partial = [];
 
-// If the object has a dontEnum length property, we'll treat it as an array.
+// Is the value an array?
 
-                if (typeof value.length === 'number' &&
-                        !(value.propertyIsEnumerable('length'))) {
+            if (Object.prototype.toString.apply(value) === '[object Array]') {
 
-// The object is an array. Stringify every element. Use null as a placeholder
+// The value is an array. Stringify every element. Use null as a placeholder
 // for non-JSON values.
 
-                    length = value.length;
-                    for (i = 0; i < length; i += 1) {
-                        partial[i] = str(i, value) || 'null';
-                    }
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
 
 // Join all of the elements together, separated with commas, and wrap them in
 // brackets.
 
-                    v = partial.length === 0 ? '[]' :
-                        gap ? '[\n' + gap + partial.join(',\n' + gap) +
-                                  '\n' + mind + ']' :
-                              '[' + partial.join(',') + ']';
-                    gap = mind;
-                    return v;
-                }
+                v = partial.length === 0 ? '[]' :
+                    gap ? '[\n' + gap +
+                            partial.join(',\n' + gap) + '\n' +
+                                mind + ']' :
+                          '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
 
 // If the replacer is an array, use it to select the members to be stringified.
 
-                if (typeof rep === 'object') {
-                    length = rep.length;
-                    for (i = 0; i < length; i += 1) {
-                        k = rep[i];
-                        if (typeof k === 'string') {
-                            v = str(k, value, rep);
-                            if (v) {
-                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
-                            }
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    k = rep[i];
+                    if (typeof k === 'string') {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                         }
                     }
-                } else {
+                }
+            } else {
 
 // Otherwise, iterate through all of the keys in the object.
 
-                    for (k in value) {
-                        v = str(k, value, rep);
+                for (k in value) {
+                    if (Object.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
                         if (v) {
                             partial.push(quote(k) + (gap ? ': ' : ':') + v);
                         }
                     }
                 }
+            }
 
 // Join all of the member texts together, separated with commas,
 // and wrap them in braces.
 
-                v = partial.length === 0 ? '{}' :
-                    gap ? '{\n' + gap + partial.join(',\n' + gap) +
-                              '\n' + mind + '}' :
-                          '{' + partial.join(',') + '}';
-                gap = mind;
-                return v;
-            }
+            v = partial.length === 0 ? '{}' :
+                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+                        mind + '}' : '{' + partial.join(',') + '}';
+            gap = mind;
+            return v;
         }
+    }
 
+// If the JSON object does not yet have a stringify method, give it one.
 
-// Return the JSON object containing the stringify, parse, and quote methods.
-
-        return {
-            stringify: function (value, replacer, space) {
+    if (typeof JSON.stringify !== 'function') {
+        JSON.stringify = function (value, replacer, space) {
 
 // The stringify method takes a value and an optional replacer, and an optional
 // space parameter, and returns a JSON text. The replacer can be a function
@@ -342,120 +358,121 @@ if (!this.JSON) {
 // A default replacer method can be provided. Use of the space parameter can
 // produce text that is more easily readable.
 
-                var i;
-                gap = '';
-                indent = '';
-                if (space) {
+            var i;
+            gap = '';
+            indent = '';
 
 // If the space parameter is a number, make an indent string containing that
 // many spaces.
 
-                    if (typeof space === 'number') {
-                        for (i = 0; i < space; i += 1) {
-                            indent += ' ';
-                        }
-
-// If the space parameter is a string, it will be used as the indent string.
-
-                    } else if (typeof space === 'string') {
-                        indent = space;
-                    }
+            if (typeof space === 'number') {
+                for (i = 0; i < space; i += 1) {
+                    indent += ' ';
                 }
 
-// If there is no replacer parameter, use the default replacer.
+// If the space parameter is a string, it will be used as the indent string.
 
-                if (!replacer) {
-                    rep = function (key, value) {
-                        if (!Object.hasOwnProperty.call(this, key)) {
-                            return undefined;
-                        }
-                        return value;
-                    };
+            } else if (typeof space === 'string') {
+                indent = space;
+            }
 
-// The replacer can be a function or an array. Otherwise, throw an error.
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
 
-                } else if (typeof replacer === 'function' ||
-                        (typeof replacer === 'object' &&
-                         typeof replacer.length === 'number')) {
-                    rep = replacer;
-                } else {
-                    throw new Error('JSON.stringify');
-                }
+            rep = replacer;
+            if (replacer && typeof replacer !== 'function' &&
+                    (typeof replacer !== 'object' ||
+                     typeof replacer.length !== 'number')) {
+                throw new Error('JSON.stringify');
+            }
 
 // Make a fake root object containing our value under the key of ''.
 // Return the result of stringifying the value.
 
-                return str('', {'': value});
-            },
+            return str('', {'': value});
+        };
+    }
+
 
+// If the JSON object does not yet have a parse method, give it one.
 
-            parse: function (text, reviver) {
+    if (typeof JSON.parse !== 'function') {
+        JSON.parse = function (text, reviver) {
 
 // The parse method takes a text and an optional reviver function, and returns
 // a JavaScript value if the text is a valid JSON text.
 
-                var j;
+            var j;
 
-                function walk(holder, key) {
+            function walk(holder, key) {
 
 // The walk method is used to recursively walk the resulting structure so
 // that modifications can be made.
 
-                    var k, v, value = holder[key];
-                    if (value && typeof value === 'object') {
-                        for (k in value) {
-                            if (Object.hasOwnProperty.call(value, k)) {
-                                v = walk(value, k);
-                                if (v !== undefined) {
-                                    value[k] = v;
-                                } else {
-                                    delete value[k];
-                                }
+                var k, v, value = holder[key];
+                if (value && typeof value === 'object') {
+                    for (k in value) {
+                        if (Object.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
                             }
                         }
                     }
-                    return reviver.call(holder, key, value);
                 }
+                return reviver.call(holder, key, value);
+            }
+
 
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            cx.lastIndex = 0;
+            if (cx.test(text)) {
+                text = text.replace(cx, function (a) {
+                    return '\\u' +
+                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
 
-// Parsing happens in three stages. In the first stage, we run the text against
-// regular expressions that look for non-JSON patterns. We are especially
-// concerned with '()' and 'new' because they can cause invocation, and '='
-// because it can cause mutation. But just to be safe, we want to reject all
-// unexpected forms.
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
 
-// We split the first stage into 4 regexp operations in order to work around
+// We split the second stage into 4 regexp operations in order to work around
 // crippling inefficiencies in IE's and Safari's regexp engines. First we
-// replace all backslash pairs with '@' (a non-JSON character). Second, we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
 // replace all simple value tokens with ']' characters. Third, we delete all
 // open brackets that follow a colon or comma or that begin the text. Finally,
 // we look to see that the remaining characters are only whitespace or ']' or
 // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
 
-                if (/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/bfnrtu]/g, '@').
+            if (/^[\],:{}\s]*$/.
+test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
 replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
 replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
 
-// In the second stage we use the eval function to compile the text into a
+// In the third stage we use the eval function to compile the text into a
 // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
 // in JavaScript: it can begin a block or an object literal. We wrap the text
 // in parens to eliminate the ambiguity.
 
-                    j = eval('(' + text + ')');
+                j = eval('(' + text + ')');
 
-// In the optional third stage, we recursively walk the new structure, passing
+// In the optional fourth stage, we recursively walk the new structure, passing
 // each name/value pair to a reviver function for possible transformation.
 
-                    return typeof reviver === 'function' ?
-                        walk({'': j}, '') : j;
-                }
+                return typeof reviver === 'function' ?
+                    walk({'': j}, '') : j;
+            }
 
 // If the text is not JSON parseable, then a SyntaxError is thrown.
 
-                throw new SyntaxError('JSON.parse');
-            },
-
-            quote: quote
+            throw new SyntaxError('JSON.parse');
         };
-    }();
-}
+    }
+})();
index 87c2ee9..d5d4679 100644 (file)
@@ -29,9 +29,9 @@ euphorik.PageAdmin = function(client, formater, util, communication) {
    this.util = util;
    this.communication = communication;
    
-   this.comet = new Comet("admin", euphorik.conf.versionProtocole);
+   this.comet = this.communication.createCometConnection("admin");
    
-   // le timer qui rappelle periodiquement le rafraichissement des IP bannies
+   // a timer which will periodically refresh the banned IP list
    this.timeoutIDmajIPs = null;
 };
 
index 03a93a9..063220c 100644 (file)
@@ -21,7 +21,7 @@
 /**\r
   * Représente l'ensemble des conversations affichés.\r
   */\r
-euphorik.Conversations = function(client, formater, util, fragment) {\r
+euphorik.Conversations = function(client, formater, util, communication, fragment) {\r
    this.client = client;\r
    this.formater = formater;\r
    this.util = util;\r
@@ -36,7 +36,7 @@ euphorik.Conversations = function(client, formater, util, fragment) {
    \r
    this.trollIdCourant = 0;\r
    \r
-   this.comet = new Comet("chat", euphorik.conf.versionProtocole);\r
+   this.comet = communication.createCometConnection("chat");\r
 };\r
 \r
 // les messages auquels l'utilisateur répond et qui sont insérés dans le document XHTML\r
index fd7e3bc..0b9c5b3 100755 (executable)
@@ -60,18 +60,18 @@ euphorik.PageMinichat.prototype.classes = function() {
    return this.client.chatOrder === "reverse" ? "orderReverse" : "orderChrono";
 };
 
-euphorik.PageMinichat.prototype.charger = function() {   
+euphorik.PageMinichat.prototype.charger = function() {
    thisPage = this;
    
    $("#posterMessage input.pseudo").val(this.client.pseudo);
    
    // cet appel ne doit pas être fait avant l'appel à 'charger'
-   this.conversations = new euphorik.Conversations(this.client, this.formater, this.util, this.fragment);   
+   this.conversations = new euphorik.Conversations(this.client, this.formater, this.util, this.communication, this.fragment);   
    
    this.chargerConversationsFragment();
    
    this.conversations.rafraichirMessages(true);   
-    
+
    this.util.setCaretToEnd($("form#posterMessage input.message")[0]);
 
    // les outils de bannissement (uniquement pour les ekMaster)
@@ -82,7 +82,7 @@ euphorik.PageMinichat.prototype.charger = function() {
          ' <span class="spacer"></span>' +
          ' <form action=""><p><input id="raison" name="raison" type="text" size="10" maxlength="200"></input></p></form>' +
          ' <img id="ban" src="img/ban.gif" alt="Ban de 3 jours" />' +
-         ' <img id="kick" src="img/kick.gif" alt="Ban de 15min" />' +
+         ' <img id="kick" src="img/kick.gif" alt="Ban de 15 min" />' +
          ' <img id="slap" src="img/slap.gif" alt="Avertissement" />' +
          '</span>'
       );
diff --git a/js/pageStatic.js b/js/pageStatic.js
new file mode 100644 (file)
index 0000000..4580bf3
--- /dev/null
@@ -0,0 +1,32 @@
+// 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/>.
+
+/**
+  * Correspond à une page html statique se nommant "<nom>.html" et se trouvant dans "/pages/".
+  */
+euphorik.PageStatique = function(nom, communication) {
+   this.nom = nom;
+   this.communication = communication;
+};
+
+euphorik.PageStatique.prototype.contenu = function() {
+   return this.communication.load("pages/" + this.nom + ".html");
+};
+
+euphorik.PageStatique.prototype.charger = function() {
+};
diff --git a/js/pageStatique.js b/js/pageStatique.js
deleted file mode 100644 (file)
index 4580bf3..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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/>.
-
-/**
-  * Correspond à une page html statique se nommant "<nom>.html" et se trouvant dans "/pages/".
-  */
-euphorik.PageStatique = function(nom, communication) {
-   this.nom = nom;
-   this.communication = communication;
-};
-
-euphorik.PageStatique.prototype.contenu = function() {
-   return this.communication.load("pages/" + this.nom + ".html");
-};
-
-euphorik.PageStatique.prototype.charger = function() {
-};
diff --git a/pages/conditions_utilisation.html b/pages/conditions_utilisation.html
deleted file mode 100644 (file)
index e714d0a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<!-- encoding: utf-8 -->\r
-\r
-<h1>Conditions d'utilisation</h1>\r
-<ul>\r
-   <li>L'utilisateur d'euphorik.ch s'engage à prendre connaissance et à respecter ces conditions d'utilisation.</li>\r
-   <li>L'utilisateur est propriétaire de ses dires. Euphorik.ch n'est en aucun cas responsable des messages postés par l' utilisateur.</li>\r
-   <li>L'utilisateur s'engage à se conformer au droit suisse.</li>\r
-</ul>
\ No newline at end of file
diff --git a/pages/terms_of_use.html b/pages/terms_of_use.html
new file mode 100644 (file)
index 0000000..e714d0a
--- /dev/null
@@ -0,0 +1,8 @@
+<!-- encoding: utf-8 -->\r
+\r
+<h1>Conditions d'utilisation</h1>\r
+<ul>\r
+   <li>L'utilisateur d'euphorik.ch s'engage à prendre connaissance et à respecter ces conditions d'utilisation.</li>\r
+   <li>L'utilisateur est propriétaire de ses dires. Euphorik.ch n'est en aucun cas responsable des messages postés par l' utilisateur.</li>\r
+   <li>L'utilisateur s'engage à se conformer au droit suisse.</li>\r
+</ul>
\ No newline at end of file
index 59e8ab0..6859cd8 100755 (executable)
@@ -279,16 +279,16 @@ form input[readonly] {
 }
 
 /***** Les liens *****/
-.lien, a {
+.pageLink, a {
        text-decoration: underline;
        color: #c62929;
 }
-.lien {
+.pageLink {
        cursor: pointer
 }
 a:link, a:visited {
        color: #c62929;
 }
-.lien:hover, .lien:active, a:hover, a:active {
+.pageLink:hover, .pageLink:active, a:hover, a:active {
        color: #e84747;
 }
index 261d8b3..f2a6781 100755 (executable)
@@ -243,17 +243,17 @@ form input[readonly] {
 }
 
 /***** Les liens *****/
-.lien, a {
+.pageLink, a {
        text-decoration: none;
        color: #7664ff;
 }
-.lien {
+.pageLink {
        cursor: pointer;
 }
 a:link, a:visited {
        color: #7664ff;
 }
-.lien:hover, .lien:active, a:hover, a:active {
+.pageLink:hover, .pageLink:active, a:hover, a:active {
    color: #ffad0f;
 }