Browse Source

Dactylotest

pull/1/head
tazzon 10 years ago
parent
commit
c545df9f09
37 changed files with 4795 additions and 0 deletions
  1. +30
    -0
      dactylotest/encode_prefs.php
  2. +39
    -0
      dactylotest/fireworks.css
  3. BIN
      dactylotest/image/blank.gif
  4. BIN
      dactylotest/image/particles.gif
  5. BIN
      dactylotest/img/argent.png
  6. BIN
      dactylotest/img/bronze.png
  7. BIN
      dactylotest/img/choco.png
  8. +87
    -0
      dactylotest/img/index.html
  9. BIN
      dactylotest/img/indicator.gif
  10. BIN
      dactylotest/img/lecturel.png
  11. BIN
      dactylotest/img/none.png
  12. BIN
      dactylotest/img/or.png
  13. +121
    -0
      dactylotest/index.html
  14. BIN
      dactylotest/indicator.gif
  15. +183
    -0
      dactylotest/js/err_test.js
  16. +561
    -0
      dactylotest/js/fireworks.js
  17. +497
    -0
      dactylotest/js/fonctions_page_2.js
  18. +152
    -0
      dactylotest/js/fonctions_texte.js
  19. +194
    -0
      dactylotest/js/fonctions_texte_2.js
  20. +152
    -0
      dactylotest/js/fonctions_texte_test.js
  21. +453
    -0
      dactylotest/js/functions_page.js
  22. +459
    -0
      dactylotest/js/functions_page_test.js
  23. +329
    -0
      dactylotest/js/ghost.js
  24. BIN
      dactylotest/js/jscolor/arrow.gif
  25. BIN
      dactylotest/js/jscolor/cross.gif
  26. BIN
      dactylotest/js/jscolor/hs.png
  27. BIN
      dactylotest/js/jscolor/hv.png
  28. +995
    -0
      dactylotest/js/jscolor/jscolor.js
  29. +56
    -0
      dactylotest/js/replay.js
  30. +34
    -0
      dactylotest/js/req.js
  31. +44
    -0
      dactylotest/js/start.js
  32. +32
    -0
      dactylotest/list_ghost.php
  33. +10
    -0
      dactylotest/load_ghost.php
  34. +36
    -0
      dactylotest/new_text.php
  35. +128
    -0
      dactylotest/save_ghost.php
  36. +41
    -0
      dactylotest/save_pref.php
  37. +162
    -0
      dactylotest/style.css

+ 30
- 0
dactylotest/encode_prefs.php View File

@@ -0,0 +1,30 @@
<?php
// donne l'état des préférences pour l'inclure dans les top_ghost
// tableau des différents cookies à tester
$cookie_tab = array("apo_typ","maj_acc","ligat","pds","no_brk_spc","no_brk_spc_display","quote_fr","cadratin");
$opt = "";
foreach ($cookie_tab as $cookie)
{
if ($_COOKIE[$cookie] == "true")
{
echo $cookie." : true";
$opt.="1";
}
else
{
echo $cookie." : false";
$opt.="0";
}
echo "<br/>";
}
echo "<br/>";
echo $opt;
echo "<br/>";
?>

+ 39
- 0
dactylotest/fireworks.css View File

@@ -0,0 +1,39 @@
/* fireworks styles */
#fireworks-template {
display:none;
}
#fireContainer {
position:absolute;
left:0px;
top:0px;
z-index:706;
}
.firework {
/* containing box which flies out first */
position:absolute;
left:0px;
top:0px;
font-size:1px;
width:4px;
height:4px;
border:1px solid #333;
background:#666;
}
.fireworkParticle {
/* elements that explode from the container */
position:absolute;
font-size:1px;
width:10px;
height:10px;
overflow:hidden;
}
.fireworkParticle img {
display:block;
width:100px;
}

BIN
dactylotest/image/blank.gif View File

Before After
Width: 1  |  Height: 1  |  Size: 43 B

BIN
dactylotest/image/particles.gif View File

Before After
Width: 100  |  Height: 70  |  Size: 2.4 KiB

BIN
dactylotest/img/argent.png View File

Before After
Width: 16  |  Height: 16  |  Size: 657 B

BIN
dactylotest/img/bronze.png View File

Before After
Width: 16  |  Height: 16  |  Size: 657 B

BIN
dactylotest/img/choco.png View File

Before After
Width: 16  |  Height: 16  |  Size: 677 B

+ 87
- 0
dactylotest/img/index.html View File

@@ -0,0 +1,87 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dactylotest : mesurez votre vitesse de frappe au clavier</title>
<script type="text/javascript" src="js/fonctions_texte.js"></script>
<script type="text/javascript" src="js/functions_page.js"></script>
<script type="text/javascript" src="js/replay.js"></script>
<script type="text/javascript" src="js/req.js"></script>
<script type="text/javascript" src="js/ghost.js"></script>
<link rel="stylesheet" type="text/css" href="style.css" />

</head>

<body>

<h1>— Dactylotest —</h1>

<div class="main">

<p class="text_nmbr" id="text_nmbr" type="text" value=""/></p>
<div class="ici">
<div id="err" class="err">— ERREUR —</div>
<p class="rd_txt" id="rd_txt"><span style="color:red"><strong>Javascript doit être activé ! Vous pouvez le faire en modifiant les préférences de votre navigateur. Si vous ne savez pas comment faire, consultez l'aide de celui-ci.</strong></span></p>
<p><textarea onkeydown="t_car[this.value.length]=new Date().getTime();list_frappes(event,this.value)" onkeyup="test(event)" id="txt" class="txt"></textarea></p>
</div>
<div>
<div class="new_text">
<input type="button" id="new_txt" onclick="new_text('new');this.blur()" value="Nouveau texte"/> <input type="button" id="same_txt" onclick="new_text('');this.blur()" value="Recommencer ce texte"/>
<p style="float:right">
<span id="d_replay">
Lecteur <input type="button" style="width:60px" id="replay" onclick="replay()" value="Play"/>
<input type="button" style="width:60px" onclick="replay('stop')" value="Stop"/>
<select id="speed_replay" onChange="vitesse=this.value;this.blur()" style="width:inherit">
<option value="1">×1 </option>
<option value="2">×2 </option>
<option value="3">×3 </option>
<option value="4">×4 </option>
</select></span><br/><br/>
⇒ <input type="button" onclick="load_ghost('list')" value="Liste des fantômes pour ce texte…"/>
</p>
<br/>
 Méthode : <select id="methode" onChange="this.blur()">
<option value="rand">aléatoire </option>
<option value="number">sélection </option>
</select>
<br/>
 Langue  : <select id="lang" onChange="this.blur()">
<option value="fr">français </option>
<option value="en">anglais </option>
</select>
<br/>
<hr/>
</div>
<div class="options">
<input type="button" onclick="this.value=view_options()" value="Afficher les options">
<div class="view_options" id="view_options">
<p id="options">
<input type="checkbox" onclick="options()" id="apo_typ" /> apostrophe typographique<br/>
<input type="checkbox" onclick="options()" id="maj_acc" /> majuscules accentuées<br/>
<input type="checkbox" onclick="options()" id="ligat" /> ligatures (æ, œ)<br/>
<input type="checkbox" onclick="options()" id="pds" /> points de suspension « … »<br/>
<input type="checkbox" onclick="options()" id="no_brk_spc" /> espaces insécables<br/>   <input type="checkbox" onclick="options()" id="no_brk_spc_display"/> les rendre visibles <br/>
<input type="checkbox" onclick="options()" id="quote_fr" /> guillemets français « »<br/>
</p><br/>
<input type="button" value="Enregister les options" onclick="save_opt();this.blur()"/>
</div>
<hr/>
<input type="checkbox" id="ghost_actif" /> activer le fantôme <span id="demo_ghost"> </span><br/>
<input type="checkbox" id="curseur_actif" checked="checked" /> activer le curseur <span id="demo_curseur"> </span><br/>
</div>
<div id="resultats" class="result"></div>
</div>
</div>

<div class="main">
<a href="http://www.lecturel.com/clavier/mots-par-minute.php"><img src="img/lecturel.png" alt="lecturel.com" title="Ce test est inspriré de celui du site www.lecturel.com" /></a>
<a href="http://bepo.fr"><img src="http://bepo.fr/wiki/skins/bepo/bepo-powered.png" alt="bepo.fr" title="Ce test à été intégralement écrit en BÉPO !" /></a>
</div>

<div style="display:none"><img src="img/indicator.gif" alt="c'est juste histoire qu'il soit chargé" /></div>

<script type="text/javascript" src="js/start.js"></script>

</body>
</html>

BIN
dactylotest/img/indicator.gif View File

Before After
Width: 16  |  Height: 16  |  Size: 729 B

BIN
dactylotest/img/lecturel.png View File

Before After
Width: 80  |  Height: 15  |  Size: 269 B

BIN
dactylotest/img/none.png View File

Before After
Width: 16  |  Height: 16  |  Size: 1.2 KiB

BIN
dactylotest/img/or.png View File

Before After
Width: 16  |  Height: 16  |  Size: 653 B

+ 121
- 0
dactylotest/index.html View File

@@ -0,0 +1,121 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dactylotest : mesurez votre vitesse de frappe au clavier</title>
<script type="text/javascript" src="js/fonctions_texte_2.js"></script>
<script type="text/javascript" src="js/err_test.js"></script>
<script type="text/javascript" src="js/fonctions_page_2.js"></script>
<script type="text/javascript" src="js/replay.js"></script>
<script type="text/javascript" src="js/req.js"></script>
<script type="text/javascript" src="js/ghost.js"></script>
<script type="text/javascript" src="js/fireworks.js"></script>
<script type="text/javascript" src="js/jscolor/jscolor.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css" />
<link rel="stylesheet" type="text/css" href="fireworks.css" />
</head>
<body onkeyup="vidactyl(event)">
<div class="bar" id="bar">
<a href="http://tazzon.free.fr/dactylotest/"><img src="../home.png" alt="home" style="padding-bottom:2px"/></a>
<a href="../dactylotest/" title="Testez votre vitesse de frappe">Dactylotest</a>
<a href="../tridactyl/" title="Perfectionnez votre frappe grâce aux trigrammes">Tridactyl</a>
<a href="../bepodactyl/" title="Bien débutez avec la disposition de clavier BÉPO">Bépodactyl</a>
<span style="color:#fafafa;float:right;padding-right:10px" id="welcome"></span>
</div>
<h1>— Dactylotest —</h1>
<div class="main">
<p class="text_nmbr" id="text_nmbr"></p>
<div class="ici">
<div id="err" class="err">— ERREUR —</div>
<p class="rd_txt" id="rd_txt"><span style="color:red"><strong>Javascript doit être activé ! Vous pouvez le faire en modifiant les préférences de votre navigateur. Si vous ne savez pas comment faire, consultez l'aide de celui-ci.</strong></span></p>
<p><textarea onkeydown="t_car[this.value.length]=new Date().getTime();list_frappes(event,this.value)" onkeyup="test(event)" id="txt" class="txt" cols="93" rows="7"></textarea></p>
</div>
<div>
<div class="new_text">
<input type="button" id="new_txt" onclick="new_text('new');this.blur()" value="Nouveau texte"/> <input type="button" id="same_txt" onclick="new_text('');this.blur()" value="Recommencer ce texte"/>
<p style="float:right">
<span id="d_replay">
Lecteur <input type="button" style="width:60px" id="replay" onclick="replay()" value="Play"/>
<input type="button" style="width:60px" onclick="replay('stop')" value="Stop"/>
<select id="speed_replay" onChange="vitesse=this.value;this.blur()" style="width:inherit">
<!--select id="speed_replay" style="width:inherit"-->
<option value="1">×1 </option>
<option value="2">×2 </option>
<option value="3">×3 </option>
<option value="4">×4 </option>
</select></span><br/><br/>
<input type="button" onclick="load_ghost('list')" value="Liste des fantômes pour ce texte"/>
</p>
<br/>
Méthode&nbsp;: <select id="methode" onChange="this.blur()">
<option value="rand">aléatoire </option>
<option value="number">sélection </option>
</select>
<br/>
Langue&nbsp;&nbsp;: <select id="lang" onChange="this.blur()">
<option value="fr">français </option>
<option value="en">anglais </option>
</select>
<br/>
<hr/>
</div>
<div class="options">
<input type="button" onclick="this.value=view_options()" value="Afficher les options"/>
<div class="view_options" id="view_options">
<p id="options">
<input type="checkbox" onclick="options()" id="apo_typ" /> apostrophe typographique<br/>
<input type="checkbox" onclick="options()" id="maj_acc" /> majuscules accentuées<br/>
<input type="checkbox" onclick="options()" id="ligat" /> ligatures (æ, œ)<br/>
<input type="checkbox" onclick="options()" id="pds" /> points de suspension « … »<br/>
<input type="checkbox" onclick="options()" id="cadratin" /> tiret cadratin<br/>
<input type="checkbox" onclick="options()" id="no_brk_spc" /> espaces insécables<br/>
&nbsp;&nbsp;&nbsp;<input type="checkbox" onclick="options()" id="no_brk_spc_display"/> les rendre visibles <br/>
<input type="checkbox" onclick="options()" id="quote_fr" /> guillemets français « »<br/>
</p>
<br/>
<input type="button" value="Enregister les options" onclick="save_opt();this.blur()"/>
<!--p>
<input type="checkbox" id="short_aff" /> Afficher les résultats en ligne
</p-->
</div>
<hr/>
<!--
<input type="checkbox" id="ghost_actif" /> activer le fantôme <span id="demo_ghost" onclick="var c=prompt('nouvelle couleur du curseur (hexa)',cur_col_ghost);cur_col_ghost=c;this.style.backgroundColor=c;curseur()">&nbsp;</span><br/>
<input type="checkbox" id="curseur_actif" checked="checked" /> activer le curseur <span id="demo_curseur" onclick="var c=prompt('nouvelle couleur du curseur (hexa)',cur_col);cur_col=c;this.style.backgroundColor=c;curseur()">&nbsp;</span><br/>
-->
<input type="checkbox" id="ghost_actif" /> activer le fantôme <input id="demo_ghost" style="width:8px;border:none" class="color {valueElement:'gh_cur_col',hash:true,caps:false,slider:true,pickerFaceColor:'transparent',pickerFace:3,pickerBorder:0,pickerInsetColor:'black'}" /><input style="display:none" type="text" id="gh_cur_col" value="#ffd7ff" onchange="cur_col_ghost=this.value;cur_mix=mix_colors(cur_col,cur_col_ghost);curseur()"/><br/>
<input type="checkbox" id="curseur_actif" checked="checked" /> activer le curseur <input id="demo_curseur" style="width:8px;border:none" class="color {valueElement:'cur_col',hash:true,caps:false,slider:true,pickerFaceColor:'transparent',pickerFace:3,pickerBorder:0,pickerInsetColor:'black'}" /><input style="display:none" type="text" id="cur_col" value="#ffd700" onchange="cur_col=this.value;cur_mix=mix_colors(cur_col,cur_col_ghost);curseur()" /><br/>
<p style="margin-top:30px">
<a href="http://bepo.fr"><img src="http://bepo.fr/wiki/skins/bepo/bepo-powered.png" alt="bepo.fr" title="Ce test a été intégralement écrit en BÉPO !" /></a>
<a href="http://www.lecturel.com/clavier/mots-par-minute.php"><img src="img/lecturel.png" alt="lecturel.com" title="Ce test est inspriré de celui du site www.lecturel.com" /></a>
</p>
</div>
<div id="resultats" class="result"></div>
</div>
</div>
<div style="display:none"><img src="img/indicator.gif" alt="c'est juste histoire qu'il soit chargé" /></div>
<div id="fireworks-template">
<div id="fw" class="firework"></div>
<div id="fp" class="fireworkParticle"><img src="image/particles.gif" alt="" /></div>
</div>
<div id="fireContainer"></div>
<script type="text/javascript" src="js/start.js"></script>
</body>
</html>

BIN
dactylotest/indicator.gif View File

Before After
Width: 16  |  Height: 16  |  Size: 729 B

+ 183
- 0
dactylotest/js/err_test.js View File

@@ -0,0 +1,183 @@
var visu_err = "";
function err_test()
{
var a="";
var b="";
var err_progress = false;
var err = false;
var dist_temp = 0;
var dist_tot = 0;
var i = 0;
//document.getElementById("resultats").innerHTML = list_f.length+"<br/><br/>";
for (i=0;i<list_f.length;i++)
{
a=list_f[i].val; // le texte frappé à la ième frappe
b=le_texte.substring(0,list_f[i].val.length); // le texte qu'on devrait avoir
if (a!=b)
{
document.getElementById("car"+a.length).style.color = "#8f4546";
document.getElementById("car"+a.length).style.backgroundColor = "#eabbbc";
if (list_f[i].val.length > list_f[i-1].val.length)
{
err_progress = true;
//a='<span style="color:red">'+a+'</span>';
//document.getElementById("resultats").innerHTML+= i+" "+b+'<br/>'+i+" "+a+'<br/><br/>';
if (le_texte.substring(0,list_f[i+1].val.length) == list_f[i+1].val)
{
dist_tot++;
visu_err += b.substring(b.length-5) + "<br/>" + a.substring(a.length-5) + "</br>";
//document.getElementById("resultats").innerHTML += "une erreur simple en plus<br/>";
}
}
else
{
if (err_progress == true)
{
err = true;
err_progress = false;
}
//a='<span style="color:orange">'+a+'</span>';
//document.getElementById("resultats").innerHTML+=i+" "+b+'<br/>'+i+" "+a+'<br/><br/>';
}
if (err == true) // dans le cas d'une erreur avec plusieurs caractères dans le rouge
{
//document.getElementById("resultats").innerHTML += "=> "+le_texte.substring(0,list_f[i-1].val.length) + "<br/>";
//document.getElementById("resultats").innerHTML += "-> "+list_f[i-1].val + "<br/>";
dist_temp = levenshtein(le_texte.substring(0,list_f[i-1].val.length),list_f[i-1].val);
dist_tot += dist_temp;
visu_err += b.substring(b.length-5) + "<br/>" + a.substring(a.length-5) + "<br/>";
//document.getElementById("resultats").innerHTML += dist_temp+"<br/><br/>";
err = false;
}
}
else
{
//a='<span style="color:green">'+a+'</span>';
//document.getElementById("resultats").innerHTML+=i+" "+b+'<br/>'+i+" "+a+'<br/><br/>';
err = false;
}
}
//document.getElementById("resultats").innerHTML += "total erreurs : "+dist_tot+"<br/>Précision : "+(1-dist_tot/nb_car);
//document.getElementById("resultats").innerHTML = txt_ok + "<br/>" + txt_err;
return dist_tot;
}
function err_test_txt()
{
var a="";
var b="";
var err_progress = false;
var err = false;
var dist_temp = 0;
var dist_tot = 0;
var i = 0;
document.getElementById("resultats").innerHTML = list_f.length+"<br/><br/>";
for (i=0;i<list_f.length;i++)
{
a=list_f[i].val; // le texte frapp� � la i�me frappe
b=le_texte.substring(0,list_f[i].val.length); // le texte qu'on devrait avoir
if (a!=b)
{
if (list_f[i].val.length > list_f[i-1].val.length)
{
err_progress = true;
a='<span style="color:red">'+a+'</span>';
document.getElementById("resultats").innerHTML+= i+" "+b+'<br/>'+i+" "+a+'<br/><br/>';
if (le_texte.substring(0,list_f[i+1].val.length) == list_f[i+1].val)
{
dist_tot++;
document.getElementById("resultats").innerHTML += "une erreur simple en plus<br/>";
}
}
else
{
if (err_progress == true)
{
err = true;
err_progress = false;
}
a='<span style="color:orange">'+a+'</span>';
document.getElementById("resultats").innerHTML+=i+" "+b+'<br/>'+i+" "+a+'<br/><br/>';
}
if (err == true) // dans le cas d'une erreur avec plusieurs caract�res dans le rouge
{
document.getElementById("resultats").innerHTML += "=> "+le_texte.substring(0,list_f[i-1].val.length) + "<br/>";
document.getElementById("resultats").innerHTML += "-> "+list_f[i-1].val + "<br/>";
dist_temp = levenshtein(le_texte.substring(0,list_f[i-1].val.length),list_f[i-1].val);
dist_tot += dist_temp;
document.getElementById("resultats").innerHTML += dist_temp+"<br/><br/>";
err = false;
}
}
else
{
a='<span style="color:green">'+a+'</span>';
document.getElementById("resultats").innerHTML+=i+" "+b+'<br/>'+i+" "+a+'<br/><br/>';
err = false;
}
}
//document.getElementById("resultats").innerHTML += "total erreurs : "+dist_tot+"<br/>Pr�cision : "+(1-dist_tot/nb_car);
//document.getElementById("resultats").innerHTML = txt_ok + "<br/>" + txt_err;
//return dist_tot;
}
function levenshtein( a, b )
{
var i;
var j;
var cost;
var d = new Array();
if ( a.length == 0 )
return b.length;
if ( b.length == 0 )
return a.length;
for ( i=0 ; i<=a.length ; i++)
{
d[i] = new Array();
d[i][0] = i;
}
for (j=0 ; j<=b.length ; j++)
{
d[0][j] = j;
}
for (i=1 ; i<=a.length ; i++)
{
for (j=1 ; j<=b.length ; j++)
{
if (a.charAt(i-1) == b.charAt(j-1))
{
cost=0;
}
else
{
cost=1;
}
d[i][j] = Math.min(d[i-1][j]+1,d[i][j-1]+1,d[i-1][j-1]+cost);
if(i>1 && j>1 && a.charAt(i-1) == b.charAt(j-2) && a.charAt(i-2) == b.charAt(j-1))
d[i][j] = Math.min(d[i][j],d[i-2][j-2]+cost);
}
}
return d[a.length][b.length];
}

+ 561
- 0
dactylotest/js/fireworks.js View File

@@ -0,0 +1,561 @@
function fireworks_dactylotest()
{
var r=12;
for(var i=r; i--;)
{
setTimeout('createFirework(20,30,2,null,50,90,30+parseInt(Math.random()*40),20+parseInt(Math.random()*20),Math.random()>0.5,true)',i*(100+parseInt(Math.random()*400)));
}
return false
}
//#############################################
// les fonctionst originales
//#############################################
function FireworksController() {
var self = this;
this.intervalRate = 20; // rate (ms) to run animation at, general best default = 20
this.DEBUG = true; // debug mode disabled by default
this.oFW = null;
this.isIE = (navigator.appVersion.indexOf('MSIE')+1);
this.isOpera = (navigator.userAgent.toLowerCase().indexOf('opera')+1);
if (this.isOpera) this.isIE = false; // no impersonation allowed here!
this.fireworks = [];
this.animator = null;
this.gOID = 0; // global object ID counter (for animation queue)
this.particleTypes = 6;
this.particleXY = 10;
this.tweenFade = [100,90,80,70,60,50,40,30,20,10,0];
this.isSafari = (navigator.appVersion.toLowerCase().indexOf('safari')+1?1:0);
this.canvasX = null;
this.canvasY = null;
this.screenY = null; // screen area (not entire page)
self.scrollY = null;
self.getWindowCoords = function() {
self.canvasX = (document.documentElement.clientWidth||document.body.clientWidth||document.body.scrollWidth);
self.canvasY = (document.documentElement.clientHeight||document.body.clientHeight||document.body.scrollHeight);
self.screenY = self.canvasY;
self.scrollY = parseInt(window.scrollY||document.documentElement.scrollTop||document.body.scrollTop);
self.canvasY += self.scrollY;
}
this.getWindowCoordsAlt = function() {
self.canvasX = window.innerWidth;
self.canvasY = window.innerHeight;
self.screenY = self.canvasY;
self.scrollY = parseInt(window.scrollY||document.documentElement.scrollTop||document.body.scrollTop);
self.canvasY += self.scrollY;
}
this.getPanX = function(x) {
x = parseInt(x);
var pos = x/self.canvasX;
if (pos<0.4) {
pos *= -1;
} else if (pos >= 0.4 && pos <= 0.6) {
pos = 0.5;
}
pos = parseInt(pos*100);
// writeDebug('getPanX('+x+'): '+pos+'%');
return pos;
}
this.isEmpty = function(o) {
// needs further hacking
return (typeof(o)=='undefined'||(o==null&&o!=0)||(o==''&&o!=0)||o=='null');
}
this.init = function() {
self.oFW = document.getElementById('fw');
self.oFP = document.getElementById('fp');
if (typeof(enableDebugMode)!='undefined' && (self.DEBUG||window.location.toString().toLowerCase().indexOf('debug')>=0)) enableDebugMode();
self.getWindowCoords();
self.animator = new Animator();
}
this.destructor = function() {
for (var i=self.fireworks.length; i--;) {
self.fireworks[i] = null;
}
self.fireworks = null;
if (soundManager) {
soundManager.destructor();
soundManager = null;
}
}
if (this.isSafari || this.isOpera) this.getWindowCoords = this.getWindowCoordsAlt;
}
function Firework(oC,startX,startY,burstX,burstY,burstType,nRadius,nParticles,nCircles,allowRandom,obeyBoundaries) {
var self = this;
this.oID = 'fp'+(fc.gOID++); // may be unneeded
var p = '';
for (var i=0; i<arguments.length-1; i++) {
p += arguments[i]+',';
}
p += arguments[i];
writeDebug('firework('+p+')');
this.oC = oC;
this.o = fc.oFW.cloneNode(!fc.isIE?true:false);
this.particles = [];
this.vX = -1;
this.vY = -4;
this.x = startX;
this.y = startY;
this.allowRandom = allowRandom;
this.obeyBoundaries = obeyBoundaries;
this.frame = 0;
this.tween = [];
this.active = false;
this.moveTo = function(x,y) {
self.o.style.left = x+'px';
self.o.style.top = y+'px';
self.x = x;
self.y = y;
}
this.slideTo = function(x,y) {
self.tween = [fc.animator.createTween(self.x,x,'blast'),fc.animator.createTween(self.y,y,'blast')];
fc.animator.enqueue(self,self.animate,self.aniExplode);
}
self.aniExplode = function() {
// called from animation finish
self.o.style.background = 'none';
self.o.style.border = 'none';
for (var i=self.particles.length; --i;) {
self.particles[i].o.style.display = 'block';
fc.animator.enqueue(self.particles[i],self.particles[i].animate);
}
// attach oncomplete event handler to last particle
self.particles[i].o.style.display = 'block';
fc.animator.enqueue(self.particles[i],self.particles[i].animate,self.beginFade);
var sID = 'boom'+parseInt(Math.random()*8);
soundManager.setPan(sID,fc.getPanX(self.x));
soundManager.play(sID);
}
self.beginFade = function() {
// writeDebug('beginFade');
self.tween = fc.animator.createTween(1,0,'fade');
fc.animator.enqueue(self,self.aniFade,self.destructor);
}
this.aniFade = function() {
// writeDebug('firework.aniFade('+self.tween[self.frame].data+')');
for (var i=self.particles.length; i--;) {
self.particles[i].moveRel();
self.particles[i].nextState();
self.particles[i].setOpacity(fc.tweenFade[self.frame]);
}
if (self.frame++>=self.tween.length) {
self.active = false;
self.frame = 0;
if (self._oncomplete) self._oncomplete();
self._oncomplete = null;
return false;
}
return true;
}
this.destructor = function() {
writeDebug('firework.destructor()');
// for (var i=0; i<self.particles.length; i++) {
for (var i=self.particles.length; i--;) {
self.particles[i].destructor();
self.particles[i] = null;
}
self.particles = null;
self.oC.removeChild(self.o);
self.o = null;
self.oC = null;
}
this.animate = function() {
// generic animation method
self.moveTo(self.tween[0][self.frame].data,self.tween[1][self.frame].data,'burst');
if (self.frame++>=self.tween[0].length-1) {
self.active = false;
self.frame = 0;
if (self._oncomplete) self._oncomplete();
self._oncomplete = null;
return false;
}
return true;
}
this.createBurst = function(circles,nMax,rMax,type) {
// c: # of circles, n: # of particles per circle, r: max radius
writeDebug('firework.createBurst('+circles+','+nMax+','+rMax+','+type+')');
var i=0, j=0;
var tmp = 0;
var radiusInc = rMax/circles;
var radius = radiusInc;
var angle = 0;
var angleInc = 0; // per-loop increment
var radiusOffset = (self.allowRandom?(0.33+Math.random()):1);
var particlesPerCircle = [];
var isRandom = Math.random()>0.5;
var circleTypes = [type,circles>1?parseInt(Math.random()*fc.particleTypes):type];
var thisType = null;
for (i=0; i<circles; i++) {
particlesPerCircle[i] = parseInt(nMax*(i+1)/circles*1/circles)||1; // hack - nMax*(i+1)/circles;
angle = angleInc; // could be offset as well
angleInc = 360/particlesPerCircle[i];
thisType = circleTypes[i%2];
for (j=0; j<particlesPerCircle[i]; j++) {
self.particles[tmp] = new FireworkParticle(self.o,self.allowRandom,thisType,burstX,burstY,self.obeyBoundaries);
self.particles[tmp].slideTo(radius*Math.cos(angle*Math.PI/180),radius*radiusOffset*Math.sin(angle*Math.PI/180));
angle += angleInc;
tmp++;
}
radius += radiusInc; // increase blast radius
}
}
// startX,startY,burstX,burstY,burstType,nRadius,nParticles,nCircles
self.oC.appendChild(self.o);
self.moveTo(self.x,self.y);
self.createBurst(nCircles,nParticles,nRadius,burstType); // create an explosion
self.slideTo(burstX,burstY);
var sID = 'fire'+parseInt(Math.random()*2);
soundManager.setPan(sID,fc.getPanX(self.x));
soundManager.play(sID);
fc.animator.start();
}
function FireworkParticle(oC,isRandom,type,baseX,baseY,obeyBoundaries) {
var self = this;
this.oC = oC;
this.oID = 'fp'+(fc.gOID++); // may be unneeded
this.o = fc.oFP.cloneNode(true);
this.obeyBoundaries = obeyBoundaries;
// set type: index becomes Y offset (for background image)
this.type = null;
this.oImg = this.o.getElementsByTagName('img')[0];
this.oImg._src = this.oImg.src;
this.o.style.display = 'none';
this.baseX = baseX;
this.baseY = baseY;
this.x = 0;
this.y = 0;
this.vx = 0;
this.vy = 0;
this.frame = 0;
this.tween = [];
this.active = null;
this.tweenType = 'blast';
this.states = [];
this.state = parseInt(Math.random()*3);
this.isRandom = isRandom;
this._mt = 5;
this.moveTo = function(x,y) {
self.o.style.left = x+'px';
self.o.style.top = y+'px';
self.vx = x-self.x;
self.vy = y-self.y;
self.x = x;
self.y = y;
}
this.moveRel = function() {
// continue last moveTo() pattern, bouncing off walls if applicable
var toX = self.x+self.vx;
var toY = self.y+self.vy;
if (self.obeyBoundaries) {
var xMax = fc.canvasX-self.baseX-fc.particleXY;
var yMax = fc.canvasY-self.baseY-fc.particleXY;
var yMin = fc.scrollY;
if (self.vx>=0) {
if (toX>=xMax) self.vx *= -1;
} else if (self.vx<0 && toX+self.baseX<=0) self.vx *= -1;
if (self.vy>=0) {
if (toY>=yMax) self.vy *= -1;
} else if (self.vy<0) {
if (toY+self.baseY-yMin<=0) self.vy *= -1;
}
}
self.moveTo(self.x+self.vx,self.y+self.vy);
}
this.setOpacity = function(n) { // where n = 0..100
self.oImg.style.marginLeft = -100+(n*fc.particleXY/10)+'px';
}
this.nextState = function() {
var vis = self.o.style.visibility;
if (self.state == 2 && vis != 'hidden') {
self.o.style.visibility = 'hidden';
} else if (self.state != 2 && vis == 'hidden') {
self.o.style.visibility = 'visible';
}
self.state = parseInt(Math.random()*3);
}
this.slideTo = function(x1,y1) {
// writeDebug('slideTo (x/y): '+x1+','+y1);
if (self.isRandom) {
// randomize a bit
x1 += (x1*0.2*(Math.random()>0.5?1:-1));
y1 += (y1*0.2*(Math.random()>0.5?1:-1));
}
self.tween = [fc.animator.createTween(self.x,x1,self.tweenType),fc.animator.createTween(self.y,y1,self.tweenType)];
// prevent X overflow (scrolling)
var xMax = fc.canvasX-fc.particleXY;
var yMax = fc.canvasY-fc.particleXY;
var xMin = fc.particleXY-self.baseX;
var yMin = fc.scrollY;
var toX = null;
var toY = null;
if (self.obeyBoundaries) {
for (var i=self.tween[0].length; i--;) {
// bounce off walls where applicable
toX = self.tween[0][i].data+self.baseX;
toY = self.tween[1][i].data+self.baseY;
if (toX>=xMax) {
self.tween[0][i].data -= (toX-xMax)*2;
// self.tween[0][i].event = 'bounce';
} else if (toX<0) {
self.tween[0][i].data -= (toX*2);
// self.tween[0][i].event = 'bounce';
}
if (toY>=yMax) {
self.tween[1][i].data -= (toY-yMax)*2;
// self.tween[1][i].event = 'bounce';
} else if (toY-yMin<=0) {
self.tween[1][i].data -= (toY-yMin)*2;
// self.tween[1][i].event = 'bounce';
}
}
}
}
this.animate = function() {
var f0 = self.tween[0][self.frame].data;
var f1 = self.tween[1][self.frame].data;
self.moveTo(f0,f1);
// possible bounce event/sound hooks
// if (self.tween[0][self.frame].event) soundManager.play(self.tween[0][self.frame].event);
// if (self.tween[1][self.frame].event) soundManager.play(self.tween[1][self.frame].event);
if (self.frame++>=self.tween[0].length-1) {
if (self._oncomplete) self._oncomplete();
self._oncomplete = null;
self.active = false;
self.frame = 0;
return false;
} else if (self.frame>10) {
self.nextState();
}
return true;
}
this.destructor = function() {
self.oImg = null;
self.oC.removeChild(self.o);
self.oC = null;
self.o = null;
}
this.setType = function(t) {
self.type = t;
self.oImg.style.marginTop = -(fc.particleXY*t)+'px';
}
self.setType(type);
self.oC.appendChild(self.o);
}
function Animator() {
var self = this;
writeDebug('Animator()');
this.tweens = [];
this.tweens['default'] = [1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2,1];
this.tweens['blast'] = [12,12,11,10,10,9,8,7,6,5,4,3,2,1];
this.tweens['fade'] = [10,10,10,10,10,10,10,10,10,10];
this.queue = [];
this.queue.IDs = [];
this.active = false;
this.timer = null;
this.createTween = function(start,end,type) {
// return array of tween coordinate data (start->end)
type = type||'default';
var tween = [start];
var tmp = start;
var diff = end-start;
var x = self.tweens[type].length;
for (var i=0; i<x; i++) {
tmp += diff*self.tweens[type][i]*0.01;
tween[i] = new Object();
tween[i].data = tmp;
tween[i].event = null;
}
return tween;
}
this.enqueue = function(o,fMethod,fOnComplete) {
// add object and associated methods to animation queue
// writeDebug('animator.enqueue()');
if (!fMethod) {
writeDebug('animator.enqueue(): missing fMethod');
}
if (typeof(self.queue.IDs[o.oID])=='undefined') {
// writeDebug('animator.enqueue(): added '+o.oID);
var i = self.queue.length;
self.queue.IDs[o.oID] = i;
self.queue[i] = o;
} else {
// writeDebug('animator.enqueue(): '+o.oID+' already queued');
var i = self.queue.IDs[o.oID]; // retrieve queue index
self.queue[i].active = true;
self.queue[i].frame = 0;
}
o.active = true; // flag for animation
self.queue[i]._method = fMethod;
self.queue[i]._oncomplete = fOnComplete?fOnComplete:null;
}
this.animate = function() {
var active = 0;
for (var i=self.queue.length; i--;) {
if (self.queue[i].active) {
self.queue[i]._method();
active++;
}
}
if (active==0 && self.timer) {
// all animations finished
self.stop();
} else {
// writeDebug(active+' active');
}
}
this.start = function() {
if (self.timer || self.active) {
// writeDebug('animator.start(): already active');
return false;
}
// writeDebug('animator.start()'); // report only if started
self.active = true;
self.timer = setInterval(self.animate,fc.intervalRate);
}
this.stop = function() {
// writeDebug('animator.stop()',true);
clearInterval(self.timer);
self.timer = null;
self.active = false;
self.queue = [];
self.queue.IDs = [];
}
}
function createFirework(nRadius,nParticles,nCircles,nBurstType,startX,startY,burstX,burstY,allowRandom,obeyBoundaries) {
// check all arguments, supply random defaults if needed
var tmp = '';
for (var i in arguments) {
tmp += i+',';
}
writeDebug('createFirework('+tmp+')');
if (fc.isEmpty(startX)) {
startX = parseInt(Math.random()*fc.canvasX);
} else {
startX = parseInt(fc.canvasX*startX/100);
}
if (fc.isEmpty(startY)) {
startY = fc.canvasY-fc.particleXY;
} else {
startY = fc.canvasY-fc.screenY+parseInt(fc.screenY*startY/100);
}
if (fc.isEmpty(burstX)) {
burstX = parseInt(fc.canvasX*0.1+(Math.random()*fc.canvasX*0.8));
} else {
burstX = parseInt(fc.canvasX*burstX/100);
}
if (fc.isEmpty(burstY)) {
burstY = fc.canvasY-parseInt(Math.random()*fc.screenY);
} else {
burstY = fc.canvasY-parseInt(fc.screenY*(100-burstY)/100);
}
if (fc.isEmpty(nBurstType)) {
nBurstType = parseInt(Math.random()*fc.particleTypes);
}
if (fc.isEmpty(nRadius)) {
nRadius = 64+parseInt(Math.random()*fc.screenY*0.75);
} else if (nRadius.toString().indexOf('%')>=0) {
nRadius = parseInt(parseInt(nRadius)/100*fc.screenY);
} else if (nRadius.toString().indexOf('.')>=0) {
nRadius = parseInt(nRadius*fc.screenY);
} else {
nRadius = parseInt(nRadius*fc.screenY/100);
}
if (fc.isEmpty(nParticles)) {
nParticles = 4+parseInt(Math.random()*64);
}
if (fc.isEmpty(nCircles)) {
nCircles = Math.random()>0.5?2:1;
}
if (fc.isEmpty(allowRandom)) {
allowRandom = Math.random()>0.5;
}
if (fc.isEmpty(obeyBoundaries)) {
obeyBoundaries = Math.random()>0.5;
}
// update screen coordinates
fc.getWindowCoords();
fc.fireworks[fc.fireworks.length] = new Firework(document.getElementById('fireContainer'),startX,startY,burstX,burstY,nBurstType,nRadius,nParticles,nCircles,allowRandom,obeyBoundaries);
}
function smNull() {
// Null object for unsupported case
this.movies = []; // movie references
this.container = null;
this.unsupported = 1;
this.FlashObject = function(url) {}
this.addMovie = function(name,url) {}
this.setPan = function() {}
this.destructor = function() {}
this.play = function(movieName,soundID) {return false;}
this.defaultName = 'default';
}
var fc = new FireworksController();
// create null objects if APIs not present
if (typeof(SoundManager)=='undefined') var soundManager = new smNull();
if (typeof(writeDebug)=='undefined') var writeDebug = function(){return false;}
function addEventHandler(o,evtName,evtHandler) {
typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);
}
function removeEventHandler(o,evtName,evtHandler) {
typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);
}
addEventHandler(window,'resize',fc.getWindowCoords);
addEventHandler(window,'scroll',fc.getWindowCoords);
addEventHandler(window,'load',fc.init);
addEventHandler(window,'unload',fc.destructor);

+ 497
- 0
dactylotest/js/fonctions_page_2.js View File

@@ -0,0 +1,497 @@
/*******************************************************************************
Toutes les fonctions liées à la page pour le gestion des cadres des options,
demande d'un nouveau texte…
*******************************************************************************/
//cette fonction permet d'avoir un nouveau texte
var texte_en_cours = ""; //c'est le texte original comme il est obtenu
var le_texte = ""; //c'est le texte avec les corrections typo validées dans les options
var le_texte_macosmod = ""; //c'est le texte avec les diacritiques pour la compatibilité MacOS
var text_nb;
var text_source;
function new_text(a)
{
//on réinitialise les variables
lost_time = 0;
nb_err = 0;
nb_fois_err = 0;
t_car = new Array;
list_f = new Array;
j = 0;
g=0;
posghost=0;
stop_ghost = true;
ghost_is_start = false;
curseur_err_bol = false;
val_result("reset");
if(a=="new")
{
// requète javascript pour récupérer numéro###credit###texte
var req = "new_text.php?t="+text_nb+"&l="+document.getElementById("lang").value;
if (document.getElementById("methode").value == "number")
{
var prompt_result = prompt("Indiquer ici le numéro du texte que vous souhaitez charger.",text_nb);
if (prompt_result == null)
return;
req += "&force="+prompt_result;
}
var req_text = request(req,"text_nmbr");
var reg = new RegExp("###","g");
var t_get = req_text.split(reg);
texte_en_cours = t_get[2];
text_source = t_get[1];
text_nb = t_get[0];
clean_ghost();
}
document.getElementById("txt").value = ""; //on efface le texte précédement tapé
val=document.getElementById("txt").value;
options(); //on passe par les options pour le mise en forme typographique et l'affichage du texte
document.getElementById("err").style.visibility = "hidden"; //on cache le champ d'erreur (pas vraiment utile car on ne peut pas finir sur une erreur)
document.getElementById("txt").style.backgroundColor = "#f0fff0"; //on met le fond de la zone de frappe en vert
document.getElementById("d_replay").style.visibility = "hidden"; //on cache le bouton de replay
document.getElementById("txt").readOnly = false; //et en écriture
document.getElementById("resultats").innerHTML = ""; //on efface les résultats de la session précédente
document.getElementById("resultats").style.backgroundColor = "inherit"; //on met le fond en blanc
document.getElementById("resultats").style.border = "none"; //et sans bordure pour rendre le tout invisible
if (text_source.length > 45)
var txt_link = text_source.substr(0,42)+"…";
else
var txt_link = text_source;
document.getElementById("text_nmbr").innerHTML = "Texte nº"+text_nb+' — source : <a title="'+text_source+'" href="'+text_source+'">'+txt_link+"</a>";
}
// retourne le texte à taper avec les diacritiques à la place des lettres pour
// le mode compatibilité avec MacOs qui lors de la frappe d'une touche morte
// affiche d'abord la diacritique puis la lettre à combiner lors de la frappe
// suivante
function MacOsMod(t)
{
var reg=new RegExp("[àèùÀÈÙ]", "g");
t = t.replace(reg,"`");
var reg=new RegExp("[âêîôûÂÊÎÔÛ]", "g");
t = t.replace(reg,"^");
var reg=new RegExp("[äëïöüÄËÏÖÜ]", "g");
t = t.replace(reg,"¨");
var reg=new RegExp("[éÉ]", "g");
t = t.replace(reg,"´");
return t;
}
//cette fonction permet de faire la mise en forme typographique et d'afficher le texte modifié
function options()
{
le_texte = texte_en_cours; //on passe par une autre variable pour conserver le texte original
//apostrophes
if (document.getElementById("apo_typ").checked == false)
{
le_texte = le_texte.replace(/’/g,"'");
}
//majuscules accentuées
if (document.getElementById("maj_acc").checked == false)
{
le_texte = le_texte.replace(/[ÉÈÊË]/g,"E");
le_texte = le_texte.replace(/À/g,"A");
//on peut bien entendu en ajouter d'autres
}
//ligatures æ, Æ, œ et Œ
if (document.getElementById("ligat").checked == false)
{
le_texte = le_texte.replace(/œ/g,"oe");
le_texte = le_texte.replace(/Œ/g,"Oe");
le_texte = le_texte.replace(/æ/g,"ae");
le_texte = le_texte.replace(/Æ/g,"Ae");
}
//guillemets français « »
if (document.getElementById("quote_fr").checked == false)
{
le_texte = le_texte.replace(/« /g,'"');
le_texte = le_texte.replace(/ »/g,'"');
}
//espaces insécables
if (document.getElementById("no_brk_spc").checked == false)
{
le_texte = le_texte.replace(/ /g," ");
}
//points de suspension
if (document.getElementById("pds").checked == false)
le_texte = le_texte.replace(/…/g,'...');
//tiret cadratin
if (document.getElementById("cadratin").checked == false)
{
le_texte = le_texte.replace(/–/g,'-');
le_texte = le_texte.replace(/—/g,'-');
}
// maintenant que toutes les options sont appliquées, on cré le texte compatible MacOs
le_texte_macosmod = MacOsMod(le_texte);
var tt = new Array;
tt = le_texte.split(""); //on split le texte pour récupérer tous les caractères indépendament
// on ajoute les espaces incécables en même temps qu'on englobe chaque caractères dans un span pour le curseur
for (var i=0 ; i<le_texte.length ; i++)
{
if (document.getElementById("no_brk_spc_display").checked == true && tt[i] == " ")
tt[i] = '<span style="background-color:#cccccc"><span id="car'+(i+1)+'">'+tt[i]+'</span></span>';
else
tt[i] = '<span id="car'+(i+1)+'">'+tt[i]+'</span>';
}
// et on met tout le texte dans la zone de lecture en recolant le tout
document.getElementById("rd_txt").innerHTML = '<span id="car-3"></span><span id="car-2"></span><span id="car-1"></span><span id="car0"></span>'+tt.join("");
if (document.getElementById("curseur_actif").checked) //si l'utilisateur en veut
document.getElementById("car1").style.backgroundColor = cur_col; //on affiche le curseur jaune
document.getElementById("txt").focus(); //on donne le focus à la zone de frappe
}
//cette fonction permet de faire une mise en forme des temps pour les résultats, utile dans la fonction calcul()
function form_time(time)
{
var min = time.getMinutes();
var sec = time.getSeconds();
var mil = time.getMilliseconds();
mil = Math.round(mil/100);
return min +" min. "+ sec +","+ mil +" s";
}
//cette fonction permet de faire les calculs de la session
var mpm_session=0; //c'est la vitesse en mpm (pour l'enregistrer avec le fantôme)
var debug=false;
function calcul()
{
var dt = new Array; //tableau des Δt(i)
for (var i=0;i<nb_car-1;i++)
{
if (!isNaN(t_car[i+1]) && !isNaN(t_car[i]))
dt[i] = t_car[i+1]-t_car[i]; // on récupère les interval de temps entre chaque frappe
else
{
if (isNaN(t_car[i]))
{
dt[i] = t_car[i+1]-((t_car[i-1]+t_car[i+1])/2); // on récupère les interval de temps entre chaque frappe
}
else if (isNaN(t_car[i+1]))
{
dt[i] = ((t_car[i]+t_car[i+2])/2)-t_car[i]; // on récupère les interval de temps entre chaque frappe
}
}
}
// on calcul le temps entre le 1er et le dernier caractère tapé
// la particularité c'est que quand on revient au premier pendant la frappe, le temps du caractère 0 (le premier en fait) est réinitialisé, on peut donc recommencé dans recharger de texte par exemple si on le souhaite
var total_time = t_car[nb_car-1] - t_car[0];
//on calcul les différentes statistiques de la session
var cps = Math.round(100000 * nb_car / total_time)/100; //coups par seconde
var mpm = Math.round(cps * 600 / lettre_par_mot)/10; //mots par minute
mpm_session = mpm; //on sauvegarde temporairement pour la donner au fantôme si on enregistre la session
nb_err = err_test();
var precision = Math.round(1000*(nb_car-nb_err)/nb_car)/10; //précision
//moyenne de la somme des fréquence de frappe
//----------------------------------------------
var msf = 0;
for (var i=0 ; i<nb_car-1 ; i++)
{
msf = msf + 1 / (dt[i]/1000);
}
msf = msf/(nb_car-1);
var fl = Math.round(cps/msf*10000)/100; // et la fluidité « fl » qui en découle
//------------------------------------------------
// la vitesse (en mots par minute) qui aurait pu être atteinte sans les erreurs et le pourcentage de temps perdu
var mpm_top = Math.round((1000 * nb_car / (total_time-lost_time))* 600 / lettre_par_mot)/10;
var lost_time_percent = Math.round(1000*lost_time/total_time)/10;
if (debug)
{
alert("lost_time"+lost_time);
alert("lost_time_percent"+lost_time_percent);
}
// le temps perdu et le temps total au format texte
lost_time = form_time(new Date(lost_time));
total_time = form_time(new Date(total_time));
// on lance l'affichage des statistiques de la session
aff_session(cps,mpm,precision,fl,mpm_top,lost_time_percent,lost_time,total_time);
}
//cette fonction affiche des résultats de la session
function aff_session(cps,mpm,precision,fl,mpm_top,lost_time_percent,lost_time,total_time)
{
var result = "";
var nl = "<br/>";
// juste pour l'orthographe
//------------------------------------
if (nb_fois_err >= 2)
var txt1 = nb_fois_err+" erreurs";
else
var txt1 = nb_fois_err+" erreur";
if (nb_err >= 2)
var txt2 = nb_err+" fautes";
else
var txt2 = nb_err+" faute";
//------------------------------------
//😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😒😓😔😖😘😚😜😝😞😠😡😢😣😥😨😩😪😫😭😰😱😲😳😵😶😷😸😹😺😻😼😽😾😿🙀
//on complète la variable de résultats
result += "Temps : "+ total_time +nl
//+"Vous avez fait "+txt1+" ("+txt2+" de frappe)."+nl
+"Vous avez fait "+txt2+" de frappe ("+txt1+")."+nl
+'Précision : <span id="precision_col" style="color:red"><strong>'+precision+' %</strong></span> :('+nl
+"Coups par seconde : "+cps+" ("+Math.round(cps*60)+" coups/min.)"+nl
//+'Mots par minute : <span title="Ce chiffre n’est coloré que pour représenter une vitesse à laquelle la frappe devient agréable — 50 mots par minute. Dès que vous atteindrez — ou dépasserez — cette vitesse régulièrement, vous aurez une grande aisance avec le clavier." id="mpm_col" style="color:orange"><strong>'+mpm+"</strong></span>"+nl;
+'Mots par minute : <span id="mpm_col" style="color:orange"><strong>'+mpm+"</strong></span>"+nl
+'Fluidité : <span id="fl_col" style="color:red"><strong>'+fl+' %</strong></span>'+nl;
// +nl+'<input style="border:none;background-color:none;width:100%" type="text" onclick="this.select()" value="texte nº '+text_nb+' ; '+mpm+'mpm ; Fluid '+fl+'% ; '+txt1+'"/>'+nl;
//si il y a des erreurs
if (nb_err != 0)
{
result += nl+"Sans erreurs, vous auriez pu atteindre <strong>"+mpm_top+"</strong> mots par minute."+nl //on donne la vitesse
+ "Temps perdu en erreurs : "+ lost_time //le temps perdu
+ " soit " + lost_time_percent + "%" +nl; //et le pourcentage de temps perdu
}
//résultats sur la précision
//😎
if (precision >= 99)
{
if (precision == 100)
{
result = result.replace(":(",":D");
fireworks_dactylotest();
}
else
result = result.replace(":(",":)");
result += nl+"Félicitations ! Votre précision est excellente."; //petite phrase d'encouragement
result = result.replace('id="precision_col" style="color:red"','id="precision_col" style="color:green"'); //et on passe la précision en vert
}
else if (precision > 96)
{
result = result.replace(":(",":|");
result += nl+"Votre précision est correcte. En étant plus précis, vous gagnerez encore un peu de vitesse.";//petite phrase pour dire que c'est bon (mais sans plus)
result = result.replace('id="precision_col" style="color:red"','id="precision_col" style="color:orange"');//et on passe la précision en orange
}
else
result += nl+"Essayez de gagner en précision et la vitesse augmentera."; //petite phrase pour dire que ça sert à rien de taper comme un dinque
//résultats sur la vitesse
if (mpm >= 50)
{
if (mpm > 90)
result += nl+"Vous vous entrainez pour un concours !?";
else
result += nl+"Félicitations ! Votre vitesse de frappe est excellente."; //petite phrase d'encouragement
result = result.replace('id="mpm_col" style="color:orange"','id="mpm_col" style="color:green"'); //et on passe la vitesse en vert
}
//résultats sur la fluidité
if (fl >= 65)
{
if (fl > 90)
result+= nl+"Vous tapez avec beaucoup de régularité ! On pourrait croire que vous êtes un robot !";
result = result.replace('id="fl_col" style="color:red"','id="fl_col" style="color:green"'); //mise en vert parce que c'est bien
}
else
{
result += nl+"Vous n'êtes pas très régulier dans votre frappe."; //sinon petite phrase parce que c'est pas trop bon
}
result += '<hr><input type="button" class="full_width" onclick="make_ghost_from_session()" value="Créer un fantôme local temporaire"/><br/><input type="button" class="full_width" onclick="this.onclick=make_ghost_from_session_and_save_it()" value="Créer un fantôme et l\'enregistrer sur le serveur"/><div id="result_ghost"></div>'
//affichage des stats de la session
document.getElementById("resultats").innerHTML = result; //on affiche
document.getElementById("resultats").style.backgroundColor = "#f0fff0"; //on colorise
document.getElementById("resultats").style.border = "1px solid black"; //on met une bordure
}
//cette fonction permet de sauvegarder la totalité de la zone de résultats et de la restaurer ensuite si besoin
var old_result = new Array; //le tableau ou est enregistré la zone de résultats
var val_result_bol = false; //true si on a déjà fait un sauvegarde
function val_result(a)
{
if (a == "save" && val_result_bol == false) //on sauvegarde
{
old_result[0] = document.getElementById("resultats").innerHTML;
old_result[1] = document.getElementById("resultats").style.backgroundColor;
old_result[2] = document.getElementById("resultats").style.border;
val_result_bol = true;
}
if (a == "resto" && val_result_bol == true) //on restaure
{
document.getElementById("resultats").innerHTML = old_result[0];
document.getElementById("resultats").style.backgroundColor = old_result[1];
document.getElementById("resultats").style.border = old_result[2];
val_result_bol = false;
}
if (a == "reset") // permet de supprimer la sauvegarde de la zone de résultats
{
old_result[0] = "";
old_result[1] = "inherit";
old_result[2] = "inherit";
}
}
// cette fonction permet de sauver les préférences des options en enregistrant des cookies
function save_opt()
{
var id_ = ""; // le nom temporaire de l'ID de l'input
var check_ = ""; // l'état temporaire du checkbox de l'input
// url pour la requete
var url = "save_pref.php?";
// un tableau de tous les inputs qui se trouvent dans les options
var list = document.getElementById("options").getElementsByTagName("input");
for (var i=0 ; i<list.length ; i++)
{
id_ = document.getElementById("options").getElementsByTagName("input")[i].id;
check_ = document.getElementById(id_).checked;
url += "&"+id_+"="+check_;
}
val_result("save"); // sauvegarde du champ de résultats
var req_rep = request(url,"resultats");
// affichage du retour de la requête
document.getElementById("resultats").innerHTML="<strong>"+req_rep+"</strong>";
document.getElementById("resultats").style.border = "none";
document.getElementById("resultats").style.backgroundColor = "inherit";
setTimeout('val_result("resto")',1500); // restauration du champ de résultats dans 1s
}
// pour afficher ou cacher le cadre des options
function view_options()
{
if (document.getElementById("view_options").style.display == "none")
{
document.getElementById("view_options").style.display = "block";
return "Cacher les options";
}
else
{
document.getElementById("view_options").style.display = "none";
return "Afficher les options";
}
}
// cette fonction permet d'avoir des raccourcis clavier
esc_key = false;
function vidactyl(e)
{
var touche = window.event ? e.keyCode : e.which; //on regarde quelle touche est frappée
if (touche == 27) // c'est la touche échap
{
if (esc_key == true)
{
esc_key = false;
val_result("resto");
if (document.getElementById("txt").readOnly == false)
document.getElementById("txt").focus();
}
else
{
esc_key = true;
document.getElementById("txt").blur();
val_result("save");
document.getElementById("resultats").innerHTML='<p><strong>Mode commande :</strong></p>[n] : nouveau texte<br/>[r] : recommencer le texte';
document.getElementById("resultats").style.border = "none";
document.getElementById("resultats").style.backgroundColor = "inherit";
}
}
else
{
if (esc_key == true)
{
esc_key = false; // dans tous les cas ça évite d'avoir des action alors qu'on est en train de taper du texte
switch(touche) // le caractère est celui entre []
{
case 48: // [*]
esc_key = false;
val_result("resto");
/*document.getElementById("fw").style.width="100%";
document.getElementById("fw").style.height="100%";
document.getElementById("fw").style.backgroundImage = "linear-gradient(top, rgba(255,255,255,0.7) 0%, rgba(0,0,0,0) 100%)";*/
fireworks_dactylotest();
break;
case 78: // [N]
new_text("new");
break;
case 82: // [R]
new_text();
break;
case 68: // [D]
err_test_txt();
break;
case 67: // [C]
alert(GetCookie(prompt("nom du cookie ?")));
break;
case 86: // [V]
var v=prompt("Variable");
document.getElementById("resultats").innerHTML = "Variable : "+ v + "<br/>Valeur : " + eval(v);
break;
default:
esc_key = false;
val_result("resto");
if (document.getElementById("txt").readOnly == false)
document.getElementById("txt").focus();
break;
}
}
else
{
esc_key = false;
val_result("resto");
if (document.getElementById("txt").readOnly == false)
document.getElementById("txt").focus();
}
}
}

+ 152
- 0
dactylotest/js/fonctions_texte.js View File

@@ -0,0 +1,152 @@
/*******************************************************************************
Toutes les fonctions liées à la frappe, erreurs, curseurs…
*******************************************************************************/

var nb_err = 0; //nombre de fautes de frappe
var nb_fois_err = 0; //nombre de fois ou le texte est passé en rouge
var nb_car = 500; //nombre de caractères à frapper
var lettre_par_mot = 5; //pour le calcul
var lost_time = 0; //le temps ou le texte est dans le rouge
var lost_time_tmp = 0; //une valeur temporaire pour le temps perdu
var t_car = new Array; //c'est un tableau ou on note les temps de chaque frappe juste, l'index du tableau est la position du caractère
var j = 0; //c'est une variable qui s'incrémente pour lister tout les caractères pour le replay
var list_f = new Array; //c'est le tableau qu'on utilise pour créer les objets (time et val) pour le replay
var val=""; //c'est le contenu du champ texte
var car_col; //c'est la couleur à afficher du curseur
var ghost_is_start = false; //contre le démarrage intenpestif du fantôme
var curseur_err_pos = 0; //position du curseur d'erreur
var curseur_err_bol = false; //true si il y a une erreur pour afficher le curseur d'erreur
var cur_col = "#ffd700"; //couleur du curseur par défaut
var cur_col_err = "#ff7777"; //couleur du curseur en cas d'erreur

//cette fonction compare le texte tapé à « le_texte »
function test(e)
{
var temp_time = new Date().getTime(); //valeur temporaire du temps à la frappe
val = document.getElementById("txt").value; //le texte qu'on tape

if (document.getElementById("ghost_actif").checked && val.length == 1) //lancement à la première frappe du fantôme si il est activé
{
stop_ghost = false;
if(!ghost_is_start) play_ghost(); // évite les double démarrages intenpestifs
ghost_is_start = true;
}

var touche = window.event ? e.keyCode : e.which; //on regarde quelle touche est frappée
//if (touche == 27)
//{
// new_text();
// return;
//}

if (val != le_texte.substr(0,val.length)) //si c'est différent
{
// curseur d'erreur et sa position
if (curseur_err_bol == false)
{
curseur_err_pos = val.length;
curseur_err_bol = true;
}
if (document.getElementById("err").style.visibility == "hidden") //on regarde si à la frappe d'avant on était bon
{ // si c'est la cas
lost_time_tmp = temp_time; //on garde la valeur temporaire
nb_fois_err++; //et on incrémente le nombre de passage dans le rouge
}

document.getElementById("err").style.visibility = "visible"; //on affiche le message d'erreur
document.getElementById("txt").style.backgroundColor = "#ffbbbb"; //on met la zone da frappe en rouge


if (touche != 8) // et si ce n'est pas un « backspace » on incrémente de nombre de faute de frappe
nb_err++;

}
else //sinon si le texte est équivalent
{
if (document.getElementById("err").style.visibility == "visible") //si on sort d'une zone rouge
lost_time = lost_time + temp_time - lost_time_tmp; //on ajoute au temps perdu total le temps perdu temporaire mesuré
document.getElementById("err").style.visibility = "hidden"; //on cache le message d'erreur
document.getElementById("txt").style.backgroundColor = "#f0fff0"; //et on met la zone de frappe en vert

// pas de curseur d'erreur
curseur_err_bol = false;
if (val.length >= nb_car) //si on a atteint le nombre de caractères à frapper
{
stop_ghost = true; //on arrête le fantôme
document.getElementById("txt").readOnly = true; //on met la zone de frappe en lecture seule
document.getElementById("txt").blur(); //on dégage le focus (pas très utile mais c'est plus beau)
document.getElementById("txt").style.backgroundColor = "#eeeeee"; //on grise la zone de frappe
document.getElementById("d_replay").style.visibility = "visible"; //on affiche le bouton de replay
list_frappes(e,val); //on ajoute les objets de la dernière frappe dans la liste de replay car elle ne l'aurait été qu'a la prochaine frappe mais vu que c'est la fin on a pas pu l'obtenir
j=0; //on réinitialise pour le replay
calcul(); //on va faire les calculs de la session
}
}
curseur();
}

// cette fonction permet la création de la list de frappe
function list(v)
{
this.time = new Date().getTime(); //avec le temps
this.val = v; //et la valeur du champ du frappe
}
function list_frappes(e,val)
{
e = window.event ? e.keyCode : e.which; //« e » est le keycode
if (e != 16) //si c'est un shift, il ne faut pas en tenir compte
{
list_f[j] = new list(val); //on créé un objet dans le tableau de la liste de frappes
j++;
}

}

// cette fonction permet l'affichage des curseurs
function curseur()
{

//on passe tout en blanc pour le curseur
document.getElementById("car"+(val.length-2)).style.backgroundColor = "inherit";
document.getElementById("car"+(val.length-1)).style.backgroundColor = "inherit";
document.getElementById("car"+(val.length)).style.backgroundColor = "inherit";
document.getElementById("car"+(val.length+1)).style.backgroundColor = "inherit";
document.getElementById("car"+(val.length+2)).style.backgroundColor = "inherit";
//et pour le fantôme
document.getElementById("car"+(posghost-2)).style.backgroundColor = "inherit";
document.getElementById("car"+(posghost-1)).style.backgroundColor = "inherit";
document.getElementById("car"+(posghost+1)).style.backgroundColor = "inherit";

if ((val.length+1) == posghost && document.getElementById("curseur_actif").checked) // si les deux curseurs sont sur la même position
{
//on affiche la couleurs mixée des 2 curseurs
document.getElementById("car"+(val.length+1)).style.backgroundColor = cur_mix;
}
else // sinon on les affiche tous les deux
{
document.getElementById("car"+posghost).style.backgroundColor = cur_col_ghost;
if (document.getElementById("curseur_actif").checked)
document.getElementById("car"+(val.length+1)).style.backgroundColor = cur_col;
}
// affichage de la position de l'erreur si le curseur est actif
if (curseur_err_bol && document.getElementById("curseur_actif").checked)
document.getElementById("car"+curseur_err_pos).style.backgroundColor = cur_col_err;
}


// fonction pour mélanger 2 couleurs
function mix_colors(a,b)
{
a = a.substring(1); // on enlève les #
b = b.substring(1);
return "#"+d2h((h2d(a)+h2d(b))/2).substring(0,6); // on ajoute le # et seulement des 6 premier caractères (il peut y avoir des décimales)
}
// trouvé ici : http://javascript.about.com/library/blh2d.htm
function d2h(d) {return d.toString(16);} // pour convertir décimal —> hexa
function h2d(h) {return parseInt(h,16);} // pour convertir hexa —> décimal

+ 194
- 0
dactylotest/js/fonctions_texte_2.js View File

@@ -0,0 +1,194 @@
/*******************************************************************************
Toutes les fonctions liées à la frappe, erreurs, curseurs…
*******************************************************************************/
var nb_err = 0; //nombre de fautes de frappe
var nb_fois_err = 0; //nombre de fois ou le texte est passé en rouge
var nb_car = 500; //nombre de caractères à frapper
var lettre_par_mot = 5; //pour le calcul
var lost_time = 0; //le temps ou le texte est dans le rouge
var lost_time_tmp = 0; //une valeur temporaire pour le temps perdu
var t_car = new Array; //c'est un tableau ou on note les temps de chaque frappe juste, l'index du tableau est la position du caractère
var j = 0; //c'est une variable qui s'incrémente pour lister tout les caractères pour le replay
var list_f = new Array; //c'est le tableau qu'on utilise pour créer les objets (time et val) pour le replay
var val=""; //c'est le contenu du champ texte
var car_col; //c'est la couleur à afficher du curseur
var ghost_is_start = false; //contre le démarrage intenpestif du fantôme
var curseur_err_pos = 0; //position du curseur d'erreur
var curseur_err_bol = false; //true si il y a une erreur pour afficher le curseur d'erreur
var cur_col = "#ffd700"; //couleur du curseur par défaut
var cur_col_err = "#ff7777"; //couleur du curseur en cas d'erreur
//var txt4dl = new Array("|","|");
var tExec = 0 // le temps d'exécution de la fonction test()
//cette fonction compare le texte tapé à « le_texte »
function test(e)
{
var temp_time = new Date().getTime(); //valeur temporaire du temps à la frappe
val = document.getElementById("txt").value; //le texte qu'on tape
if (document.getElementById("ghost_actif").checked && val.length == 1) //lancement à la première frappe du fantôme si il est activé
{
stop_ghost = false;
if(!ghost_is_start) play_ghost(); // évite les double démarrages intenpestifs
ghost_is_start = true;
}
var touche = window.event ? e.keyCode : e.which; //on regarde quelle touche est frappée
//if (touche == 27)
//{
// new_text();
// return;
//}
// --- toute cette partie est ajouté pour être compatible avec le système des accents morts sur MacOs
var TextErr = false;
var CompText = (val != le_texte.substr(0,val.length));
if (OSName == "MacOs")
{
var MacOsTest = (val.substr(0,val.length).substr(-1,1) != le_texte_macosmod.substr(0,val.length).substr(-1,1));
var CompLettreText = (val.substr(0,val.length).substr(-1,1) == le_texte.substr(0,val.length).substr(-1,1));
if (CompText == false)
TextErr = false;
else
{
if (MacOsTest == CompLettreText)
TextErr = false;
else
TextErr = true;
}
}
else
{
TextErr = CompText;
}
if (TextErr == true) // --- fin de la partie MacOs
//if (val != le_texte.substr(0,val.length)) // ligne commentée pour la version MacOs
{
// curseur d'erreur et sa position
if (curseur_err_bol == false)
{
var i=0;
while( le_texte.substr(0,val.length-i) != val.substr(0,val.length-i) ) // résoud le problème de curseur d'erreur pas au bon endroit
i++;
curseur_err_pos = val.length-i+1; // version modifiée pour tenir compte de i
//curseur_err_pos = val.length; // version d'origine
curseur_err_bol = true;
}
if (document.getElementById("err").style.visibility == "hidden") //on regarde si à la frappe d'avant on était bon
{ // si c'est la cas
lost_time_tmp = temp_time; //on garde la valeur temporaire
nb_fois_err++; //et on incrémente le nombre de passage dans le rouge
}
document.getElementById("err").style.visibility = "visible"; //on affiche le message d'erreur
document.getElementById("txt").style.backgroundColor = "#ffbbbb"; //on met la zone da frappe en rouge
if (touche != 8)
{ // et si ce n'est pas un « backspace » on incrémente de nombre de faute de frappe
nb_err++;
//txt4dl[0] = txt4dl[0] + le_texte.charAt(val.length-1);
//txt4dl[1] = txt4dl[1] + val.charAt(val.length-1);
}
}
else //sinon si le texte est équivalent
{
if (document.getElementById("err").style.visibility == "visible") //si on sort d'une zone rouge
{
lost_time = lost_time + temp_time - lost_time_tmp; //on ajoute au temps perdu total le temps perdu temporaire mesuré
//txt4dl[0] = txt4dl[0] + "|";
//txt4dl[1] = txt4dl[1] + "|";
//alert(txt4dl[0] + " - " + txt4dl[1]);
}
document.getElementById("err").style.visibility = "hidden"; //on cache le message d'erreur
document.getElementById("txt").style.backgroundColor = "#f0fff0"; //et on met la zone de frappe en vert
// pas de curseur d'erreur
curseur_err_bol = false;
if (val.length >= nb_car) //si on a atteint le nombre de caractères à frapper
{
stop_ghost = true; //on arrête le fantôme
document.getElementById("txt").readOnly = true; //on met la zone de frappe en lecture seule
document.getElementById("txt").blur(); //on dégage le focus (pas très utile mais c'est plus beau)
document.getElementById("txt").style.backgroundColor = "#eeeeee"; //on grise la zone de frappe
document.getElementById("d_replay").style.visibility = "visible"; //on affiche le bouton de replay
list_frappes(e,val); //on ajoute les objets de la dernière frappe dans la liste de replay car elle ne l'aurait été qu'a la prochaine frappe mais vu que c'est la fin on a pas pu l'obtenir
j=0;
//alert(txt4dl[0] + " - " + txt4dl[1]); //on réinitialise pour le replay
calcul(); //on va faire les calculs de la session
}
}
curseur();
tExec = new Date().getTime() - temp_time;
}
// cette fonction permet la création de la list de frappe
function list(v)
{
this.time = new Date().getTime(); //avec le temps
this.val = v; //et la valeur du champ du frappe
}
function list_frappes(e,val)
{
e = window.event ? e.keyCode : e.which; //« e » est le keycode
if (e != 16) //si c'est un shift, il ne faut pas en tenir compte
{
list_f[j] = new list(val); //on créé un objet dans le tableau de la liste de frappes
j++;
}
}
// cette fonction permet l'affichage des curseurs
function curseur()
{
//on passe tout en blanc pour le curseur
document.getElementById("car"+(val.length-2)).style.backgroundColor = "inherit";
document.getElementById("car"+(val.length-1)).style.backgroundColor = "inherit";
document.getElementById("car"+(val.length)).style.backgroundColor = "inherit";
document.getElementById("car"+(val.length+1)).style.backgroundColor = "inherit";
document.getElementById("car"+(val.length+2)).style.backgroundColor = "inherit";
//et pour le fantôme
document.getElementById("car"+(posghost-2)).style.backgroundColor = "inherit";
document.getElementById("car"+(posghost-1)).style.backgroundColor = "inherit";
document.getElementById("car"+(posghost+1)).style.backgroundColor = "inherit";
if ((val.length+1) == posghost && document.getElementById("curseur_actif").checked) // si les deux curseurs sont sur la même position
{
//on affiche la couleurs mixée des 2 curseurs
document.getElementById("car"+(val.length+1)).style.backgroundColor = cur_mix;
}
else // sinon on les affiche tous les deux
{
document.getElementById("car"+posghost).style.backgroundColor = cur_col_ghost;
if (document.getElementById("curseur_actif").checked)
document.getElementById("car"+(val.length+1)).style.backgroundColor = cur_col;
}
// affichage de la position de l'erreur si le curseur est actif
if (curseur_err_bol && document.getElementById("curseur_actif").checked)
document.getElementById("car"+curseur_err_pos).style.backgroundColor = cur_col_err;
}
// fonction pour mélanger 2 couleurs
function mix_colors(a,b)
{
a = a.substring(1); // on enlève les #
b = b.substring(1);
return "#"+d2h((h2d(a)+h2d(b))/2).substring(0,6); // on ajoute le # et seulement des 6 premier caractères (il peut y avoir des décimales)
}
// trouvé ici : http://javascript.about.com/library/blh2d.htm
function d2h(d) {return d.toString(16);} // pour convertir décimal —> hexa
function h2d(h) {return parseInt(h,16);} // pour convertir hexa —> décimal

+ 152
- 0
dactylotest/js/fonctions_texte_test.js View File

@@ -0,0 +1,152 @@
/*******************************************************************************
Toutes les fonctions liées à la frappe, erreurs, curseurs…
*******************************************************************************/

var nb_err = 0; //nombre de fautes de frappe
var nb_fois_err = 0; //nombre de fois ou le texte est passé en rouge
var nb_car = 20; //nombre de caractères à frapper
var lettre_par_mot = 5; //pour le calcul
var lost_time = 0; //le temps ou le texte est dans le rouge
var lost_time_tmp = 0; //une valeur temporaire pour le temps perdu
var t_car = new Array; //c'est un tableau ou on note les temps de chaque frappe juste, l'index du tableau est la position du caractère
var j = 0; //c'est une variable qui s'incrémente pour lister tout les caractères pour le replay
var list_f = new Array; //c'est le tableau qu'on utilise pour créer les objets (time et val) pour le replay
var val=""; //c'est le contenu du champ texte
var car_col; //c'est la couleur à afficher du curseur
var ghost_is_start = false; //contre le démarrage intenpestif du fantôme
var curseur_err_pos = 0; //position du curseur d'erreur
var curseur_err_bol = false; //true si il y a une erreur pour afficher le curseur d'erreur
var cur_col = "#ffd700"; //couleur du curseur par défaut
var cur_col_err = "#ff7777"; //couleur du curseur en cas d'erreur

//cette fonction compare le texte tapé à « le_texte »
function test(e)
{
var temp_time = new Date().getTime(); //valeur temporaire du temps à la frappe
val = document.getElementById("txt").value; //le texte qu'on tape

if (document.getElementById("ghost_actif").checked && val.length == 1) //lancement à la première frappe du fantôme si il est activé
{
stop_ghost = false;
if(!ghost_is_start) play_ghost(); // évite les double démarrages intenpestifs
ghost_is_start = true;
}

var touche = window.event ? e.keyCode : e.which; //on regarde quelle touche est frappée
//if (touche == 27)
//{
// new_text();
// return;
//}

if (val != le_texte.substr(0,val.length)) //si c'est différent
{
// curseur d'erreur et sa position
if (curseur_err_bol == false)
{
curseur_err_pos = val.length;
curseur_err_bol = true;
}
if (document.getElementById("err").style.visibility == "hidden") //on regarde si à la frappe d'avant on était bon
{ // si c'est la cas
lost_time_tmp = temp_time; //on garde la valeur temporaire
nb_fois_err++; //et on incrémente le nombre de passage dans le rouge
}

document.getElementById("err").style.visibility = "visible"; //on affiche le message d'erreur
document.getElementById("txt").style.backgroundColor = "#ffbbbb"; //on met la zone da frappe en rouge


if (touche != 8) // et si ce n'est pas un « backspace » on incrémente de nombre de faute de frappe
nb_err++;

}
else //sinon si le texte est équivalent
{
if (document.getElementById("err").style.visibility == "visible") //si on sort d'une zone rouge
lost_time = lost_time + temp_time - lost_time_tmp; //on ajoute au temps perdu total le temps perdu temporaire mesuré
document.getElementById("err").style.visibility = "hidden"; //on cache le message d'erreur
document.getElementById("txt").style.backgroundColor = "#f0fff0"; //et on met la zone de frappe en vert

// pas de curseur d'erreur
curseur_err_bol = false;
if (val.length >= nb_car) //si on a atteint le nombre de caractères à frapper
{
stop_ghost = true; //on arrête le fantôme
document.getElementById("txt").readOnly = true; //on met la zone de frappe en lecture seule
document.getElementById("txt").blur(); //on dégage le focus (pas très utile mais c'est plus beau)
document.getElementById("txt").style.backgroundColor = "#eeeeee"; //on grise la zone de frappe
document.getElementById("d_replay").style.visibility = "visible"; //on affiche le bouton de replay
list_frappes(e,val); //on ajoute les objets de la dernière frappe dans la liste de replay car elle ne l'aurait été qu'a la prochaine frappe mais vu que c'est la fin on a pas pu l'obtenir
j=0; //on réinitialise pour le replay
calcul(); //on va faire les calculs de la session
}
}
curseur();
}

// cette fonction permet la création de la list de frappe
function list(v)
{
this.time = new Date().getTime(); //avec le temps
this.val = v; //et la valeur du champ du frappe
}
function list_frappes(e,val)
{
e = window.event ? e.keyCode : e.which; //« e » est le keycode
if (e != 16) //si c'est un shift, il ne faut pas en tenir compte
{
list_f[j] = new list(val); //on créé un objet dans le tableau de la liste de frappes
j++;
}

}

// cette fonction permet l'affichage des curseurs
function curseur()
{

//on passe tout en blanc pour le curseur
document.getElementById("car"+(val.length-2)).style.backgroundColor = "inherit";
document.getElementById("car"+(val.length-1)).style.backgroundColor = "inherit";
document.getElementById("car"+(val.length)).style.backgroundColor = "inherit";
document.getElementById("car"+(val.length+1)).style.backgroundColor = "inherit";
document.getElementById("car"+(val.length+2)).style.backgroundColor = "inherit";
//et pour le fantôme
document.getElementById("car"+(posghost-2)).style.backgroundColor = "inherit";
document.getElementById("car"+(posghost-1)).style.backgroundColor = "inherit";
document.getElementById("car"+(posghost+1)).style.backgroundColor = "inherit";

if ((val.length+1) == posghost && document.getElementById("curseur_actif").checked) // si les deux curseurs sont sur la même position
{
//on affiche la couleurs mixée des 2 curseurs
document.getElementById("car"+(val.length+1)).style.backgroundColor = cur_mix;
}
else // sinon on les affiche tous les deux
{
document.getElementById("car"+posghost).style.backgroundColor = cur_col_ghost;
if (document.getElementById("curseur_actif").checked)
document.getElementById("car"+(val.length+1)).style.backgroundColor = cur_col;
}
// affichage de la position de l'erreur si le curseur est actif
if (curseur_err_bol && document.getElementById("curseur_actif").checked)
document.getElementById("car"+curseur_err_pos).style.backgroundColor = cur_col_err;
}


// fonction pour mélanger 2 couleurs
function mix_colors(a,b)
{
a = a.substring(1); // on enlève les #
b = b.substring(1);
return "#"+d2h((h2d(a)+h2d(b))/2).substring(0,6); // on ajoute le # et seulement des 6 premier caractères (il peut y avoir des décimales)
}
// trouvé ici : http://javascript.about.com/library/blh2d.htm
function d2h(d) {return d.toString(16);} // pour convertir décimal —> hexa
function h2d(h) {return parseInt(h,16);} // pour convertir hexa —> décimal

+ 453
- 0
dactylotest/js/functions_page.js View File

@@ -0,0 +1,453 @@
/*******************************************************************************
Toutes les fonctions liées à la page pour le gestion des cadres des options,
demande d'un nouveau texte…
*******************************************************************************/
//cette fonction permet d'avoir un nouveau texte
var texte_en_cours = ""; //c'est le texte original comme il est obtenu
var le_texte = ""; //c'est le texte avec les corrections typo validées dans les options
var text_nb;
var text_source;
function new_text(a)
{
//on réinitialise les variables
lost_time = 0;
nb_err = 0;
nb_fois_err = 0;
t_car = new Array;
list_f = new Array;
j = 0;
g=0;
posghost=0;
stop_ghost = true;
ghost_is_start = false;
curseur_err_bol = false;
val_result("reset");
if(a=="new")
{
// requète javascript pour récupérer numéro###credit###texte
var req = "new_text.php?t="+text_nb+"&l="+document.getElementById("lang").value;
if (document.getElementById("methode").value == "number")
{
var prompt_result = prompt("Indiquer ici le numéro du texte que vous souhaitez charger.",text_nb);
if (prompt_result == null)
return;
req += "&force="+prompt_result;
}
var req_text = request(req,"text_nmbr");
var reg = new RegExp("###","g");
var t_get = req_text.split(reg);
texte_en_cours = t_get[2];
text_source = t_get[1];
text_nb = t_get[0];
clean_ghost();
}
document.getElementById("txt").value = ""; //on efface le texte précédement tapé
val=document.getElementById("txt").value;
options(); //on passe par les options pour le mise en forme typographique et l'affichage du texte
document.getElementById("err").style.visibility = "hidden"; //on cache le champ d'erreur (pas vraiment utile car on ne peut pas finir sur une erreur)
document.getElementById("txt").style.backgroundColor = "#f0fff0"; //on met le fond de la zone de frappe en vert
document.getElementById("d_replay").style.visibility = "hidden"; //on cache le bouton de replay
document.getElementById("txt").readOnly = false; //et en écriture
document.getElementById("resultats").innerHTML = ""; //on efface les résultats de la session précédente
document.getElementById("resultats").style.backgroundColor = "inherit"; //on met le fond en blanc
document.getElementById("resultats").style.border = "none"; //et sans bordure pour rendre le tout invisible
if (text_source.length > 45)
var txt_link = text_source.substr(0,42)+"…";
else
var txt_link = text_source;
document.getElementById("text_nmbr").innerHTML = "Texte nº"+text_nb+' — source : <a title="'+text_source+'" href="'+text_source+'">'+txt_link+"</a>";
}
//cette fonction permet de faire la mise en forme typographique et d'afficher le texte modifié
function options()
{
le_texte = texte_en_cours;
//on passe par une autre variable pour conserver le texte original
//apostrophes
if (document.getElementById("apo_typ").checked == false)
{
le_texte = le_texte.replace(/’/g,"'");
}
//majuscules accentuées
if (document.getElementById("maj_acc").checked == false)
{
le_texte = le_texte.replace(/[ÉÈÊË]/g,"E");
le_texte = le_texte.replace(/À/g,"A");
//on peut bien entendu en ajouter d'autres
}
//ligatures æ, Æ, œ et Œ
if (document.getElementById("ligat").checked == false)
{
le_texte = le_texte.replace(/œ/g,"oe");
le_texte = le_texte.replace(/Œ/g,"Oe");
le_texte = le_texte.replace(/æ/g,"ae");
le_texte = le_texte.replace(/Æ/g,"Ae");
}
//guillemets français « »
if (document.getElementById("quote_fr").checked == false)
{
le_texte = le_texte.replace(/« /g,'"');
le_texte = le_texte.replace(/ »/g,'"');
}
//espaces insécables
if (document.getElementById("no_brk_spc").checked == false)
{
le_texte = le_texte.replace(/ /g," ");
}
//points de suspension
if (document.getElementById("pds").checked == false)
le_texte = le_texte.replace(/…/g,'...');
var tt = new Array;
tt = le_texte.split(""); //on split le texte pour récupérer tous les caractères indépendament
// on ajoute les espaces incécables en même temps qu'on englobe chaque caractères dans un span pour le curseur
for (var i=0 ; i<le_texte.length ; i++)
{
if (document.getElementById("no_brk_spc_display").checked == true && tt[i] == " ")
tt[i] = '<span style="background-color:#cccccc"><span id="car'+(i+1)+'">'+tt[i]+'</span></span>';
else
tt[i] = '<span id="car'+(i+1)+'">'+tt[i]+'</span>';
}
// et on met tout le texte dans la zone de lecture en recolant le tout
document.getElementById("rd_txt").innerHTML = '<span id="car-3"></span><span id="car-2"></span><span id="car-1"></span><span id="car0"></span>'+tt.join("");
if (document.getElementById("curseur_actif").checked) //si l'utilisateur en veut
document.getElementById("car1").style.backgroundColor = cur_col; //on affiche le curseur jaune
document.getElementById("txt").focus(); //on donne le focus à la zone de frappe
}
//cette fonction permet de faire une mise en forme des temps pour les résultats, utile dans la fonction calcul()
function form_time(time)
{
var min = time.getMinutes();
var sec = time.getSeconds();
var mil = time.getMilliseconds();
mil = Math.round(mil/100);
return min +" min. "+ sec +","+ mil +" s";
}
//cette fonction permet de faire les calculs de la session
var mpm_session=0; //c'est la vitesse en mpm (pour l'enregistrer avec le fantôme)
var debug=false;
function calcul()
{
var dt = new Array; //tableau des Δt(i)
for (var i=0;i<nb_car-1;i++)
{
if (!isNaN(t_car[i+1]) && !isNaN(t_car[i]))
dt[i] = t_car[i+1]-t_car[i]; // on récupère les interval de temps entre chaque frappe
else
{
if (isNaN(t_car[i]))
{
dt[i] = t_car[i+1]-((t_car[i-1]+t_car[i+1])/2); // on récupère les interval de temps entre chaque frappe
}
else if (isNaN(t_car[i+1]))
{
dt[i] = ((t_car[i]+t_car[i+2])/2)-t_car[i]; // on récupère les interval de temps entre chaque frappe
}
}
}
// on calcul le temps entre le 1er et le dernier caractère tapé
// la particularité c'est que quand on revient au premier pendant la frappe, le temps du caractère 0 (le premier en fait) est réinitialisé, on peut donc recommencé dans recharger de texte par exemple si on le souhaite
var total_time = t_car[nb_car-1] - t_car[0];
//on calcul les différentes statistiques de la session
var cps = Math.round(100000 * nb_car / total_time)/100; //coups par seconde
var mpm = Math.round(cps * 600 / lettre_par_mot)/10; //mots par minute
mpm_session = mpm; //on sauvegarde temporairement pour la donner au fantôme si on enregistre la session
var precision = Math.round(1000*(nb_car-nb_err)/nb_car)/10; //précision
//moyenne de la somme des fréquence de frappe
//----------------------------------------------
var msf = 0;
for (var i=0 ; i<nb_car-1 ; i++)
{
msf = msf + 1 / (dt[i]/1000);
}
msf = msf/(nb_car-1);
var fl = Math.round(cps/msf*10000)/100; // et la fluidité « fl » qui en découle
//------------------------------------------------
// la vitesse (en mots par minute) qui aurait pu être atteinte sans les erreurs et le pourcentage de temps perdu
var mpm_top = Math.round((1000 * nb_car / (total_time-lost_time))* 600 / lettre_par_mot)/10;
var lost_time_percent = Math.round(1000*lost_time/total_time)/10;
if (debug)
{
alert("lost_time"+lost_time);
alert("lost_time_percent"+lost_time_percent);
}
// le temps perdu et le temps total au format texte
lost_time = form_time(new Date(lost_time));
total_time = form_time(new Date(total_time));
// on lance l'affichage des statistiques de la session
aff_session(cps,mpm,precision,fl,mpm_top,lost_time_percent,lost_time,total_time);
}
//cette fonction affiche des résultats de la session
function aff_session(cps,mpm,precision,fl,mpm_top,lost_time_percent,lost_time,total_time)
{
var result = "";
var nl = "<br/>";
// juste pour l'orthographe
//------------------------------------
if (nb_fois_err >= 2)
var txt1 = nb_fois_err+" erreurs";
else
var txt1 = nb_fois_err+" erreur";
if (nb_err >= 2)
var txt2 = nb_err+" fautes";
else
var txt2 = nb_err+" faute";
//------------------------------------
//on complète la variable de résultats
result += "Temps : "+ total_time +nl
+"Vous avez fait "+txt1+" ("+txt2+" de frappe)."+nl
+'Précision : <span title="Précision : > 97 :) ; 92-97 :| ; < 92 :(" id="precision_col" style="color:red"><strong>'+precision+" %</strong></span>"+nl
+"Coups par seconde : "+cps+" ("+Math.round(cps*60)+" coups/min.)"+nl
//+'Mots par minute : <span title="Ce chiffre n’est coloré que pour représenter une vitesse à laquelle la frappe devient agréable — 50 mots par minute. Dès que vous atteindrez — ou dépasserez — cette vitesse régulièrement, vous aurez une grande aisance avec le clavier." id="mpm_col" style="color:orange"><strong>'+mpm+"</strong></span>"+nl;
+'Mots par minute : <span id="mpm_col" style="color:orange"><strong>'+mpm+"</strong></span>"+nl
+'Fluidité : <span id="fl_col" style="color:red"><strong>'+fl+' %</strong></span>'+nl;
// +nl+'<input style="border:none;background-color:none;width:100%" type="text" onclick="this.select()" value="texte nº '+text_nb+' ; '+mpm+'mpm ; Fluid '+fl+'% ; '+txt1+'"/>'+nl;
//si il y a des erreurs
if (nb_err != 0)
{
result += nl+"Sans erreurs, vous auriez pu atteindre <strong>"+mpm_top+"</strong> mots par minute."+nl //on donne la vitesse
+ "Temps perdu en erreurs : "+ lost_time //le temps perdu
+ " soit " + lost_time_percent + "%" +nl; //et le pourcentage de temps perdu
}
//résultats sur la précision
if (precision >= 97)
{
result += nl+"Félicitations ! Votre précision est excellente."; //petite phrase d'encouragement
result = result.replace('id="precision_col" style="color:red"','id="precision_col" style="color:green"'); //et on passe la précision en vert
}
else if (precision > 92)
{
result += nl+"Votre précision est correcte."; //petite phrase pour dire que c'est bon (mais sans plus)
result = result.replace('id="precision_col" style="color:red"','id="precision_col" style="color:orange"');//et on passe la précision en orange
}
else
result += nl+"Essayez de gagner en précision et la vitesse augmentera."; //petite phrase pour dire que ça sert à rien de taper comme un dinque
//résultats sur la vitesse
if (mpm >= 50)
{
if (mpm > 90)
result += nl+"Vous vous entrainez pour un concours !?";
else
result += nl+"Félicitations ! Votre vitesse de frappe est excellente."; //petite phrase d'encouragement
result = result.replace('id="mpm_col" style="color:orange"','id="mpm_col" style="color:green"'); //et on passe la vitesse en vert
}
//résultats sur la fluidité
if (fl >= 65)
{
if (fl > 90)
result+= nl+"Vous tapez avec beaucoup de régularité ! On pourrait croire que vous êtes un robot !";
result = result.replace('id="fl_col" style="color:red"','id="fl_col" style="color:green"'); //mise en vert parce que c'est bien
}
else
{
result += nl+"Vous n'êtes pas très régulier dans votre frappe."; //sinon petite phrase parce que c'est pas trop bon
}
result += '<hr><input type="button" class="full_width" onclick="make_ghost_from_session()" value="Créer un fantôme local temporaire"/><br/><input type="button" class="full_width" onclick="this.onclick=make_ghost_from_session_and_save_it()" value="Créer un fantôme et l\'enregistrer sur le serveur"/><div id="result_ghost"></div>'
//affichage des stats de la session
document.getElementById("resultats").innerHTML = result; //on affiche
document.getElementById("resultats").style.backgroundColor = "#f0fff0"; //on colorise
document.getElementById("resultats").style.border = "1px solid black"; //on met une bordure
}
//cette fonction permet de sauvegarder la totalité de la zone de résultats et de la restaurer ensuite si besoin
var old_result = new Array; //le tableau ou est enregistré la zone de résultats
var val_result_bol = false; //true si on a déjà fait un sauvegarde
function val_result(a)
{
if (a == "save" && val_result_bol == false) //on sauvegarde
{
old_result[0] = document.getElementById("resultats").innerHTML;
old_result[1] = document.getElementById("resultats").style.backgroundColor;
old_result[2] = document.getElementById("resultats").style.border;
val_result_bol = true;
}
if (a == "resto" && val_result_bol == true) //on restaure
{
document.getElementById("resultats").innerHTML = old_result[0];
document.getElementById("resultats").style.backgroundColor = old_result[1];
document.getElementById("resultats").style.border = old_result[2];
val_result_bol = false;
}
if (a == "reset") // permet de supprimer la sauvegarde de la zone de résultats
{
old_result[0] = "";
old_result[1] = "inherit";
old_result[2] = "inherit";
}
}
// cette fonction permet de sauver les préférences des options en enregistrant des cookies
function save_opt()
{
var id_ = ""; // le nom temporaire de l'ID de l'input
var check_ = ""; // l'état temporaire du checkbox de l'input
// url pour la requete
var url = "save_pref.php?";
// un tableau de tous les inputs qui se trouvent dans les options
var list = document.getElementById("options").getElementsByTagName("input");
for (var i=0 ; i<list.length ; i++)
{
id_ = document.getElementById("options").getElementsByTagName("input")[i].id;
check_ = document.getElementById(id_).checked;
url += "&"+id_+"="+check_;
}
val_result("save"); // sauvegarde du champ de résultats
var req_rep = request(url,"resultats");
// affichage du retour de la requête
document.getElementById("resultats").innerHTML="<strong>"+req_rep+"</strong>";
document.getElementById("resultats").style.border = "none";
document.getElementById("resultats").style.backgroundColor = "inherit";
setTimeout('val_result("resto")',1500); // restauration du champ de résultats dans 1s
}
// pour afficher ou cacher le cadre des options
function view_options()
{
if (document.getElementById("view_options").style.display == "none")
{
document.getElementById("view_options").style.display = "block";
return "Cacher les options";
}
else
{
document.getElementById("view_options").style.display = "none";
return "Afficher les options";
}
}
// cette fonction permet d'avoir des raccourcis clavier
esc_key = false;
function vidactyl(e)
{
var touche = window.event ? e.keyCode : e.which; //on regarde quelle touche est frappée
if (touche == 27) // c'est la touche échap
{
if (esc_key == true)
{
esc_key = false;
val_result("resto");
if (document.getElementById("txt").readOnly == false)
document.getElementById("txt").focus();
}
else
{
esc_key = true;
document.getElementById("txt").blur();
val_result("save");
document.getElementById("resultats").innerHTML="<p><strong>Mode commande :</strong></p>n : nouveau texte<br/>r : recommencer le texte";
document.getElementById("resultats").style.border = "none";
document.getElementById("resultats").style.backgroundColor = "inherit";
}
}
else
{
if (esc_key == true)
{
esc_key = false; // dans tous les cas ça évite d'avoir des action alors qu'on est en train de taper du texte
switch(touche)
{
case 78:
new_text("new");
break;
case 82:
new_text();
break;
case 68:
err_test();
/*var a="";
var b="";
var err=0;
document.getElementById("resultats").innerHTML = "";
for (var i=0;i<list_f.length;i++)
{
a=list_f[i].val;
b=le_texte.substring(0,list_f[i].val.length);
if (a!=b)
{
err++;
a='<span style="color:red">'+a+'</span>';
document.getElementById("resultats").innerHTML+=b+'<br/>'+a+'<br/><br/>';
}
else
{
a='<span style="color:green">'+a+'</span>';
document.getElementById("resultats").innerHTML+=b+'<br/>'+a+'<br/><br/>';
}
}*/
break;
case 67:
alert(GetCookie(prompt("nom du cookie ?")));
break;
default:
esc_key = false;
val_result("resto");
if (document.getElementById("txt").readOnly == false)
document.getElementById("txt").focus();
break;
}
}
else
{
esc_key = false;
val_result("resto");
if (document.getElementById("txt").readOnly == false)
document.getElementById("txt").focus();
}
}
}

+ 459
- 0
dactylotest/js/functions_page_test.js View File

@@ -0,0 +1,459 @@
/*******************************************************************************
Toutes les fonctions liées à la page pour le gestion des cadres des options,
demande d'un nouveau texte…
*******************************************************************************/
//cette fonction permet d'avoir un nouveau texte
var texte_en_cours = ""; //c'est le texte original comme il est obtenu
var le_texte = ""; //c'est le texte avec les corrections typo validées dans les options
var text_nb;
var text_source;
function new_text(a)
{
//on réinitialise les variables
lost_time = 0;
nb_err = 0;
nb_fois_err = 0;
t_car = new Array;
list_f = new Array;
j = 0;
g=0;
posghost=0;
stop_ghost = true;
ghost_is_start = false;
curseur_err_bol = false;
val_result("reset");
if(a=="new")
{
// requète javascript pour récupérer numéro###credit###texte
var req = "new_text.php?t="+text_nb+"&l="+document.getElementById("lang").value;
if (document.getElementById("methode").value == "number")
{
var prompt_result = prompt("Indiquer ici le numéro du texte que vous souhaitez charger.",text_nb);
if (prompt_result == null)
return;
req += "&force="+prompt_result;
}
var req_text = request(req,"text_nmbr");
var reg = new RegExp("###","g");
var t_get = req_text.split(reg);
texte_en_cours = t_get[2];
text_source = t_get[1];
text_nb = t_get[0];
clean_ghost();
}
document.getElementById("txt").value = ""; //on efface le texte précédement tapé
val=document.getElementById("txt").value;
options(); //on passe par les options pour le mise en forme typographique et l'affichage du texte
document.getElementById("err").style.visibility = "hidden"; //on cache le champ d'erreur (pas vraiment utile car on ne peut pas finir sur une erreur)
document.getElementById("txt").style.backgroundColor = "#f0fff0"; //on met le fond de la zone de frappe en vert
document.getElementById("d_replay").style.visibility = "hidden"; //on cache le bouton de replay
document.getElementById("txt").readOnly = false; //et en écriture
document.getElementById("resultats").innerHTML = ""; //on efface les résultats de la session précédente
document.getElementById("resultats").style.backgroundColor = "inherit"; //on met le fond en blanc
document.getElementById("resultats").style.border = "none"; //et sans bordure pour rendre le tout invisible
if (text_source.length > 45)
var txt_link = text_source.substr(0,42)+"…";
else
var txt_link = text_source;
document.getElementById("text_nmbr").innerHTML = "Texte nº"+text_nb+' — source : <a title="'+text_source+'" href="'+text_source+'">'+txt_link+"</a>";
}
//cette fonction permet de faire la mise en forme typographique et d'afficher le texte modifié
function options()
{
le_texte = texte_en_cours;
//on passe par une autre variable pour conserver le texte original
//apostrophes
if (document.getElementById("apo_typ").checked == false)
{
le_texte = le_texte.replace(/’/g,"'");
}
//majuscules accentuées
if (document.getElementById("maj_acc").checked == false)
{
le_texte = le_texte.replace(/[ÉÈÊË]/g,"E");
le_texte = le_texte.replace(/À/g,"A");
//on peut bien entendu en ajouter d'autres
}
//ligatures æ, Æ, œ et Œ
if (document.getElementById("ligat").checked == false)
{
le_texte = le_texte.replace(/œ/g,"oe");
le_texte = le_texte.replace(/Œ/g,"Oe");
le_texte = le_texte.replace(/æ/g,"ae");
le_texte = le_texte.replace(/Æ/g,"Ae");
}
//guillemets français « »
if (document.getElementById("quote_fr").checked == false)
{
le_texte = le_texte.replace(/« /g,'"');
le_texte = le_texte.replace(/ »/g,'"');
}
//espaces insécables
if (document.getElementById("no_brk_spc").checked == false)
{
le_texte = le_texte.replace(/ /g," ");
}
//points de suspension
if (document.getElementById("pds").checked == false)
le_texte = le_texte.replace(/…/g,'...');
// tiret quadratin
if (document.getElementById("tiret").checked == false)
le_texte = le_texte.replace(/[–—]/g,"-");
var tt = new Array;
tt = le_texte.split(""); //on split le texte pour récupérer tous les caractères indépendament
// on ajoute les espaces incécables en même temps qu'on englobe chaque caractères dans un span pour le curseur
for (var i=0 ; i<le_texte.length ; i++)
{
if (document.getElementById("no_brk_spc_display").checked == true && tt[i] == " ")
tt[i] = '<span style="background-color:#cccccc"><span id="car'+(i+1)+'">'+tt[i]+'</span></span>';
else
tt[i] = '<span id="car'+(i+1)+'">'+tt[i]+'</span>';
}
// et on met tout le texte dans la zone de lecture en recolant le tout
document.getElementById("rd_txt").innerHTML = '<span id="car-3"></span><span id="car-2"></span><span id="car-1"></span><span id="car0"></span>'+tt.join("");
if (document.getElementById("curseur_actif").checked) //si l'utilisateur en veut
document.getElementById("car1").style.backgroundColor = cur_col; //on affiche le curseur jaune
document.getElementById("txt").focus(); //on donne le focus à la zone de frappe
}
//cette fonction permet de faire une mise en forme des temps pour les résultats, utile dans la fonction calcul()
function form_time(time)
{
var min = time.getMinutes();
var sec = time.getSeconds();
var mil = time.getMilliseconds();
mil = Math.round(mil/100);
return min +" min. "+ sec +","+ mil +" s";
}
//cette fonction permet de faire les calculs de la session
var mpm_session=0; //c'est la vitesse en mpm (pour l'enregistrer avec le fantôme)
var debug=false;
function calcul()
{
var dt = new Array; //tableau des Δt(i)
for (var i=0;i<nb_car-1;i++)
{
if (!isNaN(t_car[i+1]) && !isNaN(t_car[i]))
dt[i] = t_car[i+1]-t_car[i]; // on récupère les interval de temps entre chaque frappe
else
{
if (isNaN(t_car[i]))
{
dt[i] = t_car[i+1]-((t_car[i-1]+t_car[i+1])/2); // on récupère les interval de temps entre chaque frappe
}
else if (isNaN(t_car[i+1]))
{
dt[i] = ((t_car[i]+t_car[i+2])/2)-t_car[i]; // on récupère les interval de temps entre chaque frappe
}
}
}
// on calcul le temps entre le 1er et le dernier caractère tapé
// la particularité c'est que quand on revient au premier pendant la frappe, le temps du caractère 0 (le premier en fait) est réinitialisé, on peut donc recommencé dans recharger de texte par exemple si on le souhaite
var total_time = t_car[nb_car-1] - t_car[0];
//on calcul les différentes statistiques de la session
var cps = Math.round(100000 * nb_car / total_time)/100; //coups par seconde
var mpm = Math.round(cps * 600 / lettre_par_mot)/10; //mots par minute
mpm_session = mpm; //on sauvegarde temporairement pour la donner au fantôme si on enregistre la session
var precision = Math.round(1000*(nb_car-nb_err)/nb_car)/10; //précision
//moyenne de la somme des fréquence de frappe
//----------------------------------------------
var msf = 0;
for (var i=0 ; i<nb_car-1 ; i++)
{
msf = msf + 1 / (dt[i]/1000);
}
msf = msf/(nb_car-1);
var fl = Math.round(cps/msf*10000)/100; // et la fluidité « fl » qui en découle
//------------------------------------------------
// la vitesse (en mots par minute) qui aurait pu être atteinte sans les erreurs et le pourcentage de temps perdu
var mpm_top = Math.round((1000 * nb_car / (total_time-lost_time))* 600 / lettre_par_mot)/10;
var lost_time_percent = Math.round(1000*lost_time/total_time)/10;
if (debug)
{
alert("lost_time"+lost_time);
alert("lost_time_percent"+lost_time_percent);
}
// le temps perdu et le temps total au format texte
lost_time = form_time(new Date(lost_time));
total_time = form_time(new Date(total_time));
// on lance l'affichage des statistiques de la session
aff_session(cps,mpm,precision,fl,mpm_top,lost_time_percent,lost_time,total_time);
}
//cette fonction affiche des résultats de la session
function aff_session(cps,mpm,precision,fl,mpm_top,lost_time_percent,lost_time,total_time)
{
var result = "";
var nl = "<br/>";
if (document.getElementById("short_aff").checked == false)
{
// juste pour l'orthographe
//------------------------------------
if (nb_fois_err >= 2)
var txt1 = nb_fois_err+" erreurs";
else
var txt1 = nb_fois_err+" erreur";
if (nb_err >= 2)
var txt2 = nb_err+" fautes";
else
var txt2 = nb_err+" faute";
//------------------------------------
//on complète la variable de résultats
result += "Temps : "+ total_time +nl
+"Vous avez fait "+txt1+" ("+txt2+" de frappe)."+nl
+'Précision : <span title="Précision : > 97 :) ; 92-97 :| ; < 92 :(" id="precision_col" style="color:red"><strong>'+precision+" %</strong></span>"+nl
+"Coups par seconde : "+cps+nl
//+'Mots par minute : <span title="Ce chiffre n’est coloré que pour représenter une vitesse à laquelle la frappe devient agréable — 50 mots par minute. Dès que vous atteindrez — ou dépasserez — cette vitesse régulièrement, vous aurez une grande aisance avec le clavier." id="mpm_col" style="color:orange"><strong>'+mpm+"</strong></span>"+nl;
+'Mots par minute : <span id="mpm_col" style="color:orange"><strong>'+mpm+"</strong></span>"+nl
+'Fluidité : <span id="fl_col" style="color:red"><strong>'+fl+' %</strong></span>'+nl;
// +nl+'<input style="border:none;background-color:none;width:100%" type="text" onclick="this.select()" value="texte nº '+text_nb+' ; '+mpm+'mpm ; Fluid '+fl+'% ; '+txt1+'"/>'+nl;
//si il y a des erreurs
if (nb_err != 0)
{
result += nl+"Sans erreurs, vous auriez pu atteindre <strong>"+mpm_top+"</strong> mots par minute."+nl //on donne la vitesse
+ "Temps perdu en erreurs : "+ lost_time //le temps perdu
+ " soit " + lost_time_percent + "%" +nl; //et le pourcentage de temps perdu
}
}
else
{
result += 'Texte nº'+text_nb+' en '+total_time+' à '+mpm+'mpm ('+cps+'cps ; précision : '+precision+'%) ; fluidité : '+fl+'.'+nl;
}
//résultats sur la précision
if (precision >= 97)
{
result += nl+"Félicitations ! Votre précision est excellente."; //petite phrase d'encouragement
result = result.replace('id="precision_col" style="color:red"','id="precision_col" style="color:green"'); //et on passe la précision en vert
}
else if (precision > 92)
{
result += nl+"Votre précision est correcte."; //petite phrase pour dire que c'est bon (mais sans plus)
result = result.replace('id="precision_col" style="color:red"','id="precision_col" style="color:orange"');//et on passe la précision en orange
}
else
result += nl+"Essayez de gagner en précision et la vitesse augmentera."; //petite phrase pour dire que ça sert à rien de taper comme un dinque
//résultats sur la vitesse
if (mpm >= 50)
{
if (mpm > 90)
result += nl+"Vous vous entrainez pour un concours !?";
else
result += nl+"Félicitations ! Votre vitesse de frappe est excellente."; //petite phrase d'encouragement
result = result.replace('id="mpm_col" style="color:orange"','id="mpm_col" style="color:green"'); //et on passe la vitesse en vert
}
//résultats sur la fluidité
if (fl >= 65)
{
if (fl > 90)
result+= nl+"Vous tapez avec beaucoup de régularité ! On pourrait croire que vous êtes un robot !";
result = result.replace('id="fl_col" style="color:red"','id="fl_col" style="color:green"'); //mise en vert parce que c'est bien
}
else
{
result += nl+"Vous n'êtes pas très régulier dans votre frappe."; //sinon petite phrase parce que c'est pas trop bon
}
//result += '<hr><input type="button" class="full_width" onclick="make_ghost_from_session()" value="Créer un fantôme local temporaire"/><br/><input type="button" class="full_width" onclick="this.onclick=make_ghost_from_session_and_save_it()" value="Créer un fantôme et l\'enregistrer sur le serveur"/><div id="result_ghost"></div>'
//affichage des stats de la session
document.getElementById("resultats").innerHTML = result; //on affiche
document.getElementById("resultats").style.backgroundColor = "#f0fff0"; //on colorise
document.getElementById("resultats").style.border = "1px solid black"; //on met une bordure
}
//cette fonction permet de sauvegarder la totalité de la zone de résultats et de la restaurer ensuite si besoin
var old_result = new Array; //le tableau ou est enregistré la zone de résultats
var val_result_bol = false; //true si on a déjà fait un sauvegarde
function val_result(a)
{
if (a == "save" && val_result_bol == false) //on sauvegarde
{
old_result[0] = document.getElementById("resultats").innerHTML;
old_result[1] = document.getElementById("resultats").style.backgroundColor;
old_result[2] = document.getElementById("resultats").style.border;
val_result_bol = true;
}
if (a == "resto" && val_result_bol == true) //on restaure
{
document.getElementById("resultats").innerHTML = old_result[0];
document.getElementById("resultats").style.backgroundColor = old_result[1];
document.getElementById("resultats").style.border = old_result[2];
val_result_bol = false;
}
if (a == "reset") // permet de supprimer la sauvegarde de la zone de résultats
{
old_result[0] = "";
old_result[1] = "inherit";
old_result[2] = "inherit";
}
}
// cette fonction permet de sauver les préférences des options en enregistrant des cookies
function save_opt()
{
var id_ = ""; // le nom temporaire de l'ID de l'input
var check_ = ""; // l'état temporaire du checkbox de l'input
// url pour la requete
var url = "save_pref.php?";
// un tableau de tous les inputs qui se trouvent dans les options
var list = document.getElementById("options").getElementsByTagName("input");
for (var i=0 ; i<list.length ; i++)
{
id_ = document.getElementById("options").getElementsByTagName("input")[i].id;
check_ = document.getElementById(id_).checked;
url += "&"+id_+"="+check_;
}
val_result("save"); // sauvegarde du champ de résultats
var req_rep = request(url,"resultats");
// affichage du retour de la requête
document.getElementById("resultats").innerHTML="<strong>"+req_rep+"</strong>";
document.getElementById("resultats").style.border = "none";
document.getElementById("resultats").style.backgroundColor = "inherit";
setTimeout('val_result("resto")',1500); // restauration du champ de résultats dans 1s
}
// pour afficher ou cacher le cadre des options
function view_options()
{
if (document.getElementById("view_options").style.display == "none")
{
document.getElementById("view_options").style.display = "block";
return "Cacher les options";
}
else
{
document.getElementById("view_options").style.display = "none";
return "Afficher les options";
}
}
// cette fonction permet d'avoir des raccourcis clavier
esc_key = false;
function vidactyl(e)
{
var touche = window.event ? e.keyCode : e.which; //on regarde quelle touche est frappée
if (touche == 27) // c'est la touche échap
{
if (esc_key == true)
{
esc_key = false;
val_result("resto");
if (document.getElementById("txt").readOnly == false)
document.getElementById("txt").focus();
}
else
{
esc_key = true;
document.getElementById("txt").blur();
val_result("save");
document.getElementById("resultats").innerHTML="<p><strong>Mode commande :</strong></p>n : nouveau texte<br/>r : recommencer le texte";
document.getElementById("resultats").style.border = "none";
document.getElementById("resultats").style.backgroundColor = "inherit";
}
}
else
{
if (esc_key == true)
{
esc_key = false; // dans tous les cas ça évite d'avoir des action alors qu'on est en train de taper du texte
switch(touche)
{
case 78:
new_text("new");
break;
case 82:
new_text();
break;
case 68:
var a="";
var b="";
var err=0;
document.getElementById("resultats").innerHTML = "";
for (var i=0;i<list_f.length;i++)
{
a=list_f[i].val;
b=le_texte.substring(0,list_f[i].val.length);
if (a!=b)
{
err++;
a='<span style="color:red">'+a+'</span>';
document.getElementById("resultats").innerHTML+=b+'<br/>'+a+'<br/><br/>';
}
else
{
a='<span style="color:green">'+a+'</span>';
document.getElementById("resultats").innerHTML+=b+'<br/>'+a+'<br/><br/>';
}
}
break;
default:
esc_key = false;
val_result("resto");
if (document.getElementById("txt").readOnly == false)
document.getElementById("txt").focus();
break;
}
}
else
{
esc_key = false;
val_result("resto");
if (document.getElementById("txt").readOnly == false)
document.getElementById("txt").focus();
}
}
}

+ 329
- 0
dactylotest/js/ghost.js View File

@@ -0,0 +1,329 @@
/*******************************************************************************
fichier de gestion des fantômes, lecture, création, chargement…
*******************************************************************************/
var stop_ghost = false; // par défaut, le fantôme est prêt
var posghost=0;
var g=0;
var cur_col_ghost = "#ffcfff";
var ghost = "";
function play_ghost()
{
if (stop_ghost) // si le fantôme se fait stopper
return; // on stoppe la fonction
posghost = ghost[g].pos; // sinon on valide la prochaine position
curseur(); // on affiche le curseur
if(g < (ghost.length-1)) // si la valeur du compteur de fantôme est inférieur au nombre d'entrées dans le tableau
setTimeout("g++;play_ghost()",ghost[g].time); // on incrémente le compteur et on lance le prochain affichage
}
// fonction qui permet la création d'un fantôme
var ghost = new Array;
function pos_time_gh(a,b)
{
this.pos = a;
this.time = b;
}
// fonction pour créer un fantôme depuis la session précédente
function make_ghost_from_session(type)
{
//il faut ajouter une valeur dans la liste de frappe
list_f[-1] = new list(""); //le -1 ne vaut rien, c'est juste pour que les temps soient bon
list_f[-1].time = list_f[0].time; //et on donne la valeur du temps 0 au temps -1
list_f[-2] = new list(""); //le -1 ne vaut rien, c'est juste pour que les temps soient bon
list_f[-2].time = list_f[0].time; //et on donne la valeur du temps 0 au temps -1
ghost = new Array; // on réinitialise le fantôme
// on cré le fantôme
for (var i=0 ; i<list_f.length ; i++)
{
ghost[i] = new pos_time_gh(list_f[i].val.length,list_f[i-1].time-list_f[i-2].time);
}
// on cré la dernière valeur pour déplacer le curseur une dernière fois comme pour la frappe normale
ghost[ghost.length] = new pos_time_gh(ghost[ghost.length-1].pos+1,"fin");
/*document.getElementById("resultats").innerHTML = "i : position temps<br/>";
for (var i = 0 ; i < list_f.length ; i++)
{
document.getElementById("resultats").innerHTML += i + " : " + ghost[i].pos + " " + ghost[i].time +" - "+ list_f[i].val.length + " "+ list_f[i-1].time +"<br/>";
}*/
// on affiche le fait que le fantôme est créé
if (type != "server")
{
document.getElementById("result_ghost").innerHTML = "<strong>Le fantôme a été créé en local.</strong>";
setTimeout('document.getElementById("result_ghost").innerHTML=""',1500); // et on enlève 1,5s après
}
}
function make_ghost_from_session_and_save_it()
{
make_ghost_from_session("server");
//alert(GetCookie("name"));
if (GetCookie("name"))
var pseudo = prompt("Une personne a déjà enregistré un fantôme depuis cette ordinateur.\nVous pouvez modifier le nom si vous le souhaitez, sinon validez.",GetCookie("name"));
else
var pseudo = prompt("Indiquez votre nom pour la sauvegarde.\nSi vous n'indiquez pas de nom, il sera enregistré sous \"anonym\".\nAnnuler pour ne pas enregistrer.");
if(pseudo != null)
{
//remplacement des espaces par des espaces insécables (pour l'avoir qu'un block pour le pseudo)
pseudo = pseudo.replace(/ /g," ");
var lang = document.getElementById("lang").value;
// mpm c'est mpm_session
// le numéro du texte c'est text_nb
// on génère le fantôme à enregistrer
var gh = "";
for (var i=0 ; i<ghost.length ; i++)
{
gh += ghost[i].pos+"--"+ghost[i].time+"__";
}
// fablication de la requète
var req = "save_ghost.php?auteur="+pseudo+"&mpm="+mpm_session+"&text="+text_nb+"&lang="+lang+"&ghost="+gh;
// envoi de la requète
var req_text = request(req,"result_ghost");
document.getElementById("result_ghost").innerHTML = req_text;
//setTimeout('document.getElementById("result_ghost").innerHTML=""',3000); // et on enlève 3s après
return "alert('Vous ne pouvez pas enregistrer deux fois le même fantôme !')";
}
}
// fonction qui permet de charger un fantôme depuis le serveur
var ghost_to_load = ""; // le nom du fantôme quand on clic sur les boutons radio
Array.prototype.inArray = function(p_val) {
var l = this.length;
for(var i = 0; i < l; i++) {
if(this[i] == p_val) {
return true;
}
}
return false;
}
function load_ghost(a)
{
//affichage des fantôme disponible a="list"
if(a == "list" || a == "all")
{
val_result("save");
document.getElementById("resultats").style.border = "none";
document.getElementById("resultats").style.backgroundColor = "inherit";
var lang = document.getElementById("lang").value;
// fablication de la requète
var req = "list_ghost.php?text="+text_nb+"&lang="+lang;
// envoi de la requète
var req_text = request(req,"resultats");
var a_afficher="Choisissez un fantôme pour le texte nº"+text_nb+'<br/><div id="result_load_ghost"></div><hr/>';
if(req_text == "no_ghost")
{
a_afficher+='Il n’y a pas encore de fantôme pour ce texte.<br/><input type="button" value="Fermer" onclick="val_result(\'resto\')" />';
}
else
{
var list = new Array;
list = req_text.split("###"); // on a donc dans list les différentes lignes
var temp_;
var limit = 10; // nombre de fantômes maximum chargés (les meilleurs)
if (list.length < limit || a == "all")
limit = list.length;
if (a != "all")
{
// début du patch EyEBURNeR
// On affiche que des résultats par pseudos « uniques » ainsi que au minimum celui de l'utilisateur
var uNick=[]; // jeu de mot avec unique et nick
var ghostCount=0; // nombre de ghost actuellement affichés
var ghostNick; // nick du ghost en cours d'analyse
var showGhost=false; // doit on afficher ce ghost
var cheatLimit=200; // valeur au-delà on considère qu'il y a cheat.
var currentNick=GetCookie("name");
for ( i in list)
{
var medaille = "";
switch(ghostCount)
{
case 0:
medaille = '<img src="img/or.png" alt="or" title="Médaille d\'or" />';
break;
case 1:
medaille = '<img src="img/argent.png" alt="argent" title="Médaille d\'argent" />';
break;
case 2:
medaille = '<img src="img/bronze.png" alt="bronze" title="Médaille de bronze" />';
break;
case 3:
medaille = '<img src="img/choco.png" alt="chocolat" title="Médaille en chocolat" />';
break;
default:
medaille = '<img src="img/none.png" alt="pas de médaille" />';
break;
}
showGhost=true;
if(typeof(list[i])=='string') // ghost valide?
{
temp_ = list[i].split(" ");
ghostNick=temp_[2];
if(uNick.inArray(ghostNick) || ghostCount>=limit) // jamais de doublon, et on affiche un nombre limité
{
showGhost=false;
}
if(ghostNick==currentNick && !uNick.inArray(currentNick)) // mais on fait une exception pour afficher au moins une fois le nick de l'utilisateur
showGhost=true;
if(temp_[3]>cheatLimit)
showGhost=false;
}
else
{
showGhost=false;
}
if(showGhost)
{
ghostCount++;
uNick.push(ghostNick);
if(ghostNick==currentNick)
ghostNick='<b>'+ghostNick+'</b>';
a_afficher += medaille+'<input type="radio" name="radio" onclick="ghost_to_load=this.id" id="'+temp_[0]+'" /> à '+temp_[3]+" mpm par "+ghostNick+" le "+temp_[1]+"<br/>";
}
}
// fin du patch EyEBURNeR
}
else{
//###################################
// ancien code
var nick = GetCookie("name"); // le nom de l'utilisateur pour mettre son nom en gras
for (var i=0 ; i<limit ; i++)
{
var medaille = "";
switch(i)
{
case 0:
medaille = '<img src="img/or.png" alt="or" title="Médaille d\'or" />';
break;
case 1:
medaille = '<img src="img/argent.png" alt="argent" title="Médaille d\'argent" />';
break;
case 2:
medaille = '<img src="img/bronze.png" alt="bronze" title="Médaille de bronze" />';
break;
case 3:
medaille = '<img src="img/choco.png" alt="chocolat" title="Médaille en chocolat" />';
break;
default:
medaille = '<img src="img/none.png" alt="pas de médaille" />';
break;
}
temp_ = list[i].split(" ");
if (nick != null && temp_[2] == nick)
temp_[2]= "<strong>"+temp_[2]+"</strong>";
a_afficher += medaille+'<input type="radio" name="radio" onclick="ghost_to_load=this.id" id="'+temp_[0]+'" /> à '+temp_[3]+" mpm par "+temp_[2]+" le "+temp_[1]+"<br/>";
}}
//################################
if (a!="all")
var list_all='<input type="button" value="Liste complète" onclick="load_ghost(\'all\')" /> ';
else
var list_all="";
a_afficher = '<p>'+a_afficher+'</p><br/><input type="button" onclick="load_ghost(\'load\')" value="Charger le fantôme" /> '+list_all+'<input type="button" value="Fermer" onclick="val_result(\'resto\')" />';
}
document.getElementById("resultats").innerHTML = a_afficher;
}
//chargement du fantôme a="load"
if (a == "load")
{
//alert(ghost_to_load);
// fablication de la requète
var req = "load_ghost.php?ghost="+ghost_to_load;
// envoi de la requète
var req_text = request(req,"result_load_ghost");
var list = new Array();
list = req_text.split("__");
var temp_;
ghost = new Array;
for (var i=0 ; i<(list.length-1) ; i++)
{
temp_ = list[i].split("--");
ghost[i] = new pos_time_gh(parseInt(temp_[0]),parseInt(temp_[1]));
}
//val_result("save");
document.getElementById("result_load_ghost").innerHTML = "Le fantôme a été chargé !";
document.getElementById("ghost_actif").checked = true;
//document.getElementById("resultats").style.backgroundColor = "inherit";
//document.getElementById("resultats").style.border = "none";
//setTimeout('val_result("resto")',1500); // et on enlève 1,5s après
}
}
function clean_ghost()
{
ghost = new Array;
ghost[0] = new pos_time_gh(0,500); //on cré par défaut un fantôme inutile pour éviter une erreur
ghost[1] = new pos_time_gh(0,500); //on cré par défaut un fantôme inutile pour éviter une erreur
}
// fonction utile pour le débug —> donne les valeur du fantôme dans le champ "resultats"
function aff_gh()
{
document.getElementById("resultats").innerHTML = "i : position temps<br/>";
for (var i = 0 ; i < ghost.length ; i++)
{
document.getElementById("resultats").innerHTML += i + " : " + ghost[i].pos + " " + ghost[i].time +"<br/>";
}
}
//http://www.toutjavascript.com/savoir/savoir02.php3
function getCookieVal(offset) {
var endstr=document.cookie.indexOf (";", offset);
if (endstr==-1)
endstr=document.cookie.length;
return unescape(document.cookie.substring(offset, endstr));
}
function GetCookie(name) {
var arg=name+"=";
var alen=arg.length;
var clen=document.cookie.length;
var i=0;
while (i<clen)
{
var j=i+alen;
if (document.cookie.substring(i, j)==arg)
return getCookieVal(j);
i=document.cookie.indexOf(" ",i)+1;
if (i==0)
break;
}
return null;
}

BIN
dactylotest/js/jscolor/arrow.gif View File

Before After
Width: 7  |  Height: 11  |  Size: 66 B

BIN
dactylotest/js/jscolor/cross.gif View File

Before After
Width: 15  |  Height: 15  |  Size: 83 B

BIN
dactylotest/js/jscolor/hs.png View File

Before After
Width: 181  |  Height: 101  |  Size: 2.6 KiB

BIN
dactylotest/js/jscolor/hv.png View File

Before After
Width: 181  |  Height: 101  |  Size: 2.8 KiB

+ 995
- 0
dactylotest/js/jscolor/jscolor.js View File

@@ -0,0 +1,995 @@
/**
* jscolor, JavaScript Color Picker
*
* @version 1.4.1
* @license GNU Lesser General Public License, http://www.gnu.org/copyleft/lesser.html
* @author Jan Odvarko, http://odvarko.cz
* @created 2008-06-15
* @updated 2013-04-08
* @link http://jscolor.com
*/
var jscolor = {
dir : '', // location of jscolor directory (leave empty to autodetect)
bindClass : 'color', // class name
binding : true, // automatic binding via <input class="...">
preloading : true, // use image preloading?
install : function() {
jscolor.addEvent(window, 'load', jscolor.init);
},
init : function() {
if(jscolor.binding) {
jscolor.bind();
}
if(jscolor.preloading) {
jscolor.preload();
}
},
getDir : function() {
if(!jscolor.dir) {
var detected = jscolor.detectDir();
jscolor.dir = detected!==false ? detected : 'jscolor/';
}
return jscolor.dir;
},
detectDir : function() {
var base = location.href;
var e = document.getElementsByTagName('base');
for(var i=0; i<e.length; i+=1) {
if(e[i].href) { base = e[i].href; }
}
var e = document.getElementsByTagName('script');
for(var i=0; i<e.length; i+=1) {
if(e[i].src && /(^|\/)jscolor\.js([?#].*)?$/i.test(e[i].src)) {
var src = new jscolor.URI(e[i].src);
var srcAbs = src.toAbsolute(base);
srcAbs.path = srcAbs.path.replace(/[^\/]+$/, ''); // remove filename
srcAbs.query = null;
srcAbs.fragment = null;
return srcAbs.toString();
}
}
return false;
},
bind : function() {
var matchClass = new RegExp('(^|\\s)('+jscolor.bindClass+')\\s*(\\{[^}]*\\})?', 'i');
var e = document.getElementsByTagName('input');
for(var i=0; i<e.length; i+=1) {
var m;
if(!e[i].color && e[i].className && (m = e[i].className.match(matchClass))) {
var prop = {};
if(m[3]) {
try {
prop = (new Function ('return (' + m[3] + ')'))();
} catch(eInvalidProp) {}
}
e[i].color = new jscolor.color(e[i], prop);
}
}
},
preload : function() {
for(var fn in jscolor.imgRequire) {
if(jscolor.imgRequire.hasOwnProperty(fn)) {
jscolor.loadImage(fn);
}
}
},
images : {
pad : [ 181, 101 ],
sld : [ 16, 101 ],
cross : [ 15, 15 ],
arrow : [ 7, 11 ]
},
imgRequire : {},
imgLoaded : {},
requireImage : function(filename) {
jscolor.imgRequire[filename] = true;
},
loadImage : function(filename) {
if(!jscolor.imgLoaded[filename]) {
jscolor.imgLoaded[filename] = new Image();
jscolor.imgLoaded[filename].src = jscolor.getDir()+filename;
}
},
fetchElement : function(mixed) {
return typeof mixed === 'string' ? document.getElementById(mixed) : mixed;
},
addEvent : function(el, evnt, func) {
if(el.addEventListener) {
el.addEventListener(evnt, func, false);
} else if(el.attachEvent) {
el.attachEvent('on'+evnt, func);
}
},
fireEvent : function(el, evnt) {
if(!el) {
return;
}
if(document.createEvent) {
var ev = document.createEvent('HTMLEvents');
ev.initEvent(evnt, true, true);
el.dispatchEvent(ev);
} else if(document.createEventObject) {
var ev = document.createEventObject();
el.fireEvent('on'+evnt, ev);
} else if(el['on'+evnt]) { // alternatively use the traditional event model (IE5)
el['on'+evnt]();
}
},
getElementPos : function(e) {
var e1=e, e2=e;
var x=0, y=0;
if(e1.offsetParent) {
do {
x += e1.offsetLeft;
y += e1.offsetTop;
} while(e1 = e1.offsetParent);
}
while((e2 = e2.parentNode) && e2.nodeName.toUpperCase() !== 'BODY') {
x -= e2.scrollLeft;
y -= e2.scrollTop;
}
return [x, y];
},
getElementSize : function(e) {
return [e.offsetWidth, e.offsetHeight];
},
getRelMousePos : function(e) {
var x = 0, y = 0;
if (!e) { e = window.event; }
if (typeof e.offsetX === 'number') {
x = e.offsetX;
y = e.offsetY;
} else if (typeof e.layerX === 'number') {
x = e.layerX;
y = e.layerY;
}
return { x: x, y: y };
},
getViewPos : function() {
if(typeof window.pageYOffset === 'number') {
return [window.pageXOffset, window.pageYOffset];
} else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
return [document.body.scrollLeft, document.body.scrollTop];
} else if(document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
return [document.documentElement.scrollLeft, document.documentElement.scrollTop];
} else {
return [0, 0];
}
},
getViewSize : function() {
if(typeof window.innerWidth === 'number') {
return [window.innerWidth, window.innerHeight];
} else if(document.body && (document.body.clientWidth || document.body.clientHeight)) {
return [document.body.clientWidth, document.body.clientHeight];
} else if(document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
return [document.documentElement.clientWidth, document.documentElement.clientHeight];
} else {
return [0, 0];
}
},
URI : function(uri) { // See RFC3986
this.scheme = null;
this.authority = null;
this.path = '';
this.query = null;
this.fragment = null;
this.parse = function(uri) {
var m = uri.match(/^(([A-Za-z][0-9A-Za-z+.-]*)(:))?((\/\/)([^\/?#]*))?([^?#]*)((\?)([^#]*))?((#)(.*))?/);
this.scheme = m[3] ? m[2] : null;
this.authority = m[5] ? m[6] : null;
this.path = m[7];
this.query = m[9] ? m[10] : null;
this.fragment = m[12] ? m[13] : null;
return this;
};
this.toString = function() {
var result = '';
if(this.scheme !== null) { result = result + this.scheme + ':'; }
if(this.authority !== null) { result = result + '//' + this.authority; }
if(this.path !== null) { result = result + this.path; }
if(this.query !== null) { result = result + '?' + this.query; }
if(this.fragment !== null) { result = result + '#' + this.fragment; }
return result;
};
this.toAbsolute = function(base) {
var base = new jscolor.URI(base);
var r = this;
var t = new jscolor.URI;
if(base.scheme === null) { return false; }
if(r.scheme !== null && r.scheme.toLowerCase() === base.scheme.toLowerCase()) {
r.scheme = null;
}
if(r.scheme !== null) {
t.scheme = r.scheme;
t.authority = r.authority;
t.path = removeDotSegments(r.path);
t.query = r.query;
} else {
if(r.authority !== null) {
t.authority = r.authority;
t.path = removeDotSegments(r.path);
t.query = r.query;
} else {
if(r.path === '') {
t.path = base.path;
if(r.query !== null) {
t.query = r.query;
} else {
t.query = base.query;
}
} else {
if(r.path.substr(0,1) === '/') {
t.path = removeDotSegments(r.path);
} else {
if(base.authority !== null && base.path === '') {
t.path = '/'+r.path;
} else {
t.path = base.path.replace(/[^\/]+$/,'')+r.path;
}
t.path = removeDotSegments(t.path);
}
t.query = r.query;
}
t.authority = base.authority;
}
t.scheme = base.scheme;
}
t.fragment = r.fragment;
return t;
};
function removeDotSegments(path) {
var out = '';
while(path) {
if(path.substr(0,3)==='../' || path.substr(0,2)==='./') {
path = path.replace(/^\.+/,'').substr(1);
} else if(path.substr(0,3)==='/./' || path==='/.') {
path = '/'+path.substr(3);
} else if(path.substr(0,4)==='/../' || path==='/..') {
path = '/'+path.substr(4);
out = out.replace(/\/?[^\/]*$/, '');
} else if(path==='.' || path==='..') {
path = '';
} else {
var rm = path.match(/^\/?[^\/]*/)[0];
path = path.substr(rm.length);
out = out + rm;
}
}
return out;
}
if(uri) {
this.parse(uri);
}
},
//
// Usage example:
// var myColor = new jscolor.color(myInputElement)
//
color : function(target, prop) {
this.required = true; // refuse empty values?
this.adjust = true; // adjust value to uniform notation?
this.hash = false; // prefix color with # symbol?
this.caps = true; // uppercase?
this.slider = true; // show the value/saturation slider?
this.valueElement = target; // value holder
this.styleElement = target; // where to reflect current color
this.onImmediateChange = null; // onchange callback (can be either string or function)
this.hsv = [0, 0, 1]; // read-only 0-6, 0-1, 0-1
this.rgb = [1, 1, 1]; // read-only 0-1, 0-1, 0-1
this.minH = 0; // read-only 0-6
this.maxH = 6; // read-only 0-6
this.minS = 0; // read-only 0-1
this.maxS = 1; // read-only 0-1
this.minV = 0; // read-only 0-1
this.maxV = 1; // read-only 0-1
this.pickerOnfocus = true; // display picker on focus?
this.pickerMode = 'HSV'; // HSV | HVS
this.pickerPosition = 'bottom'; // left | right | top | bottom
this.pickerSmartPosition = true; // automatically adjust picker position when necessary
this.pickerButtonHeight = 20; // px
this.pickerClosable = false;
this.pickerCloseText = 'Close';
this.pickerButtonColor = 'ButtonText'; // px
this.pickerFace = 10; // px
this.pickerFaceColor = 'ThreeDFace'; // CSS color
this.pickerBorder = 1; // px
this.pickerBorderColor = 'ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight'; // CSS color
this.pickerInset = 1; // px
this.pickerInsetColor = 'ThreeDShadow ThreeDHighlight ThreeDHighlight ThreeDShadow'; // CSS color
this.pickerZIndex = 10000;
for(var p in prop) {
if(prop.hasOwnProperty(p)) {
this[p] = prop[p];
}
}
this.hidePicker = function() {
if(isPickerOwner()) {
removePicker();
}
};
this.showPicker = function() {
if(!isPickerOwner()) {
var tp = jscolor.getElementPos(target); // target pos
var ts = jscolor.getElementSize(target); // target size
var vp = jscolor.getViewPos(); // view pos
var vs = jscolor.getViewSize(); // view size
var ps = getPickerDims(this); // picker size
var a, b, c;
switch(this.pickerPosition.toLowerCase()) {
case 'left': a=1; b=0; c=-1; break;
case 'right':a=1; b=0; c=1; break;
case 'top': a=0; b=1; c=-1; break;
default: a=0; b=1; c=1; break;
}
var l = (ts[b]+ps[b])/2;
// picker pos
if (!this.pickerSmartPosition) {
var pp = [
tp[a],
tp[b]+ts[b]-l+l*c
];
} else {
var pp = [
-vp[a]+tp[a]+ps[a] > vs[a] ?
(-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) :
tp[a],
-vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ?
(-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) :
(tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c)
];
}
drawPicker(pp[a], pp[b]);
}
};
this.importColor = function() {
if(!valueElement) {
this.exportColor();
} else {
if(!this.adjust) {
if(!this.fromString(valueElement.value, leaveValue)) {
styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage;
styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
styleElement.style.color = styleElement.jscStyle.color;
this.exportColor(leaveValue | leaveStyle);
}
} else if(!this.required && /^\s*$/.test(valueElement.value)) {
valueElement.value = '';
styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage;
styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
styleElement.style.color = styleElement.jscStyle.color;
this.exportColor(leaveValue | leaveStyle);
} else if(this.fromString(valueElement.value)) {
// OK
} else {
this.exportColor();
}
}
};
this.exportColor = function(flags) {
if(!(flags & leaveValue) && valueElement) {
var value = this.toString();
if(this.caps) { value = value.toUpperCase(); }
if(this.hash) { value = '#'+value; }
valueElement.value = value;
}
if(!(flags & leaveStyle) && styleElement) {
styleElement.style.backgroundImage = "none";
styleElement.style.backgroundColor =
'#'+this.toString();
styleElement.style.color =
0.213 * this.rgb[0] +
0.715 * this.rgb[1] +
0.072 * this.rgb[2]
< 0.5 ? '#FFF' : '#000';
}
if(!(flags & leavePad) && isPickerOwner()) {
redrawPad();
}
if(!(flags & leaveSld) && isPickerOwner()) {
redrawSld();
}
};
this.fromHSV = function(h, s, v, flags) { // null = don't change
if(h !== null) { h = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, h)); }
if(s !== null) { s = Math.max(0.0, this.minS, Math.min(1.0, this.maxS, s)); }
if(v !== null) { v = Math.max(0.0, this.minV, Math.min(1.0, this.maxV, v)); }
this.rgb = HSV_RGB(
h===null ? this.hsv[0] : (this.hsv[0]=h),
s===null ? this.hsv[1] : (this.hsv[1]=s),
v===null ? this.hsv[2] : (this.hsv[2]=v)
);
this.exportColor(flags);
};
this.fromRGB = function(r, g, b, flags) { // null = don't change
if(r !== null) { r = Math.max(0.0, Math.min(1.0, r)); }
if(g !== null) { g = Math.max(0.0, Math.min(1.0, g)); }
if(b !== null) { b = Math.max(0.0, Math.min(1.0, b)); }
var hsv = RGB_HSV(
r===null ? this.rgb[0] : r,
g===null ? this.rgb[1] : g,
b===null ? this.rgb[2] : b
);
if(hsv[0] !== null) {
this.hsv[0] = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, hsv[0]));
}
if(hsv[2] !== 0) {
this.hsv[1] = hsv[1]===null ? null : Math.max(0.0, this.minS, Math.min(1.0, this.maxS, hsv[1]));
}
this.hsv[2] = hsv[2]===null ? null : Math.max(0.0, this.minV, Math.min(1.0, this.maxV, hsv[2]));
// update RGB according to final HSV, as some values might be trimmed
var rgb = HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]);
this.rgb[0] = rgb[0];
this.rgb[1] = rgb[1];
this.rgb[2] = rgb[2];
this.exportColor(flags);
};
this.fromString = function(hex, flags) {
var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i);
if(!m) {
return false;
} else {
if(m[1].length === 6) { // 6-char notation
this.fromRGB(
parseInt(m[1].substr(0,2),16) / 255,
parseInt(m[1].substr(2,2),16) / 255,
parseInt(m[1].substr(4,2),16) / 255,
flags
);
} else { // 3-char notation
this.fromRGB(
parseInt(m[1].charAt(0)+m[1].charAt(0),16) / 255,
parseInt(m[1].charAt(1)+m[1].charAt(1),16) / 255,
parseInt(m[1].charAt(2)+m[1].charAt(2),16) / 255,
flags
);
}
return true;
}
};
this.toString = function() {
return (
(0x100 | Math.round(255*this.rgb[0])).toString(16).substr(1) +
(0x100 | Math.round(255*this.rgb[1])).toString(16).substr(1) +
(0x100 | Math.round(255*this.rgb[2])).toString(16).substr(1)
);
};
function RGB_HSV(r, g, b) {
var n = Math.min(Math.min(r,g),b);
var v = Math.max(Math.max(r,g),b);
var m = v - n;
if(m === 0) { return [ null, 0, v ]; }
var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m);
return [ h===6?0:h, m/v, v ];
}
function HSV_RGB(h, s, v) {
if(h === null) { return [ v, v, v ]; }
var i = Math.floor(h);
var f = i%2 ? h-i : 1-(h-i);
var m = v * (1 - s);
var n = v * (1 - s*f);
switch(i) {
case 6:
case 0: return [v,n,m];
case 1: return [n,v,m];
case 2: return [m,v,n];
case 3: return [m,n,v];
case 4: return [n,m,v];
case 5: return [v,m,n];
}
}
function removePicker() {
delete jscolor.picker.owner;
document.getElementsByTagName('body')[0].removeChild(jscolor.picker.boxB);
}
function drawPicker(x, y) {
if(!jscolor.picker) {
jscolor.picker = {
box : document.createElement('div'),
boxB : document.createElement('div'),
pad : document.createElement('div'),
padB : document.createElement('div'),
padM : document.createElement('div'),
sld : document.createElement('div'),
sldB : document.createElement('div'),
sldM : document.createElement('div'),
btn : document.createElement('div'),
btnS : document.createElement('span'),
btnT : document.createTextNode(THIS.pickerCloseText)
};
for(var i=0,segSize=4; i<jscolor.images.sld[1]; i+=segSize) {
var seg = document.createElement('div');
seg.style.height = segSize+'px';
seg.style.fontSize = '1px';
seg.style.lineHeight = '0';
jscolor.picker.sld.appendChild(seg);
}
jscolor.picker.sldB.appendChild(jscolor.picker.sld);
jscolor.picker.box.appendChild(jscolor.picker.sldB);
jscolor.picker.box.appendChild(jscolor.picker.sldM);
jscolor.picker.padB.appendChild(jscolor.picker.pad);
jscolor.picker.box.appendChild(jscolor.picker.padB);
jscolor.picker.box.appendChild(jscolor.picker.padM);
jscolor.picker.btnS.appendChild(jscolor.picker.btnT);
jscolor.picker.btn.appendChild(jscolor.picker.btnS);
jscolor.picker.box.appendChild(jscolor.picker.btn);
jscolor.picker.boxB.appendChild(jscolor.picker.box);
}
var p = jscolor.picker;
// controls interaction
p.box.onmouseup =
p.box.onmouseout = function() { target.focus(); };
p.box.onmousedown = function() { abortBlur=true; };
p.box.onmousemove = function(e) {
if (holdPad || holdSld) {
holdPad && setPad(e);
holdSld && setSld(e);
if (document.selection) {
document.selection.empty();
} else if (window.getSelection) {
window.getSelection().removeAllRanges();
}
dispatchImmediateChange();
}
};
if('ontouchstart' in window) { // if touch device
p.box.addEventListener('touchmove', function(e) {
var event={
'offsetX': e.touches[0].pageX-touchOffset.X,
'offsetY': e.touches[0].pageY-touchOffset.Y
};
if (holdPad || holdSld) {
holdPad && setPad(event);
holdSld && setSld(event);
dispatchImmediateChange();
}
e.stopPropagation(); // prevent move "view" on broswer
e.preventDefault(); // prevent Default - Android Fix (else android generated only 1-2 touchmove events)
}, false);
}
p.padM.onmouseup =
p.padM.onmouseout = function() { if(holdPad) { holdPad=false; jscolor.fireEvent(valueElement,'change'); } };
p.padM.onmousedown = function(e) {
// if the slider is at the bottom, move it up
switch(modeID) {
case 0: if (THIS.hsv[2] === 0) { THIS.fromHSV(null, null, 1.0); }; break;
case 1: if (THIS.hsv[1] === 0) { THIS.fromHSV(null, 1.0, null); }; break;
}
holdSld=false;
holdPad=true;
setPad(e);
dispatchImmediateChange();
};
if('ontouchstart' in window) {
p.padM.addEventListener('touchstart', function(e) {
touchOffset={
'X': e.target.offsetParent.offsetLeft,
'Y': e.target.offsetParent.offsetTop
};
this.onmousedown({
'offsetX':e.touches[0].pageX-touchOffset.X,
'offsetY':e.touches[0].pageY-touchOffset.Y
});
});
}
p.sldM.onmouseup =
p.sldM.onmouseout = function() { if(holdSld) { holdSld=false; jscolor.fireEvent(valueElement,'change'); } };
p.sldM.onmousedown = function(e) {
holdPad=false;
holdSld=true;
setSld(e);
dispatchImmediateChange();
};
if('ontouchstart' in window) {
p.sldM.addEventListener('touchstart', function(e) {
touchOffset={
'X': e.target.offsetParent.offsetLeft,
'Y': e.target.offsetParent.offsetTop
};
this.onmousedown({
'offsetX':e.touches[0].pageX-touchOffset.X,
'offsetY':e.touches[0].pageY-touchOffset.Y
});
});
}
// picker
var dims = getPickerDims(THIS);
p.box.style.width = dims[0] + 'px';
p.box.style.height = dims[1] + 'px';
// picker border
p.boxB.style.position = 'absolute';
p.boxB.style.clear = 'both';
p.boxB.style.left = x+'px';
p.boxB.style.top = y+'px';
p.boxB.style.zIndex = THIS.pickerZIndex;
p.boxB.style.border = THIS.pickerBorder+'px solid';
p.boxB.style.borderColor = THIS.pickerBorderColor;
p.boxB.style.background = THIS.pickerFaceColor;
// pad image
p.pad.style.width = jscolor.images.pad[0]+'px';
p.pad.style.height = jscolor.images.pad[1]+'px';
// pad border
p.padB.style.position = 'absolute';
p.padB.style.left = THIS.pickerFace+'px';
p.padB.style.top = THIS.pickerFace+'px';
p.padB.style.border = THIS.pickerInset+'px solid';
p.padB.style.borderColor = THIS.pickerInsetColor;
// pad mouse area
p.padM.style.position = 'absolute';
p.padM.style.left = '0';
p.padM.style.top = '0';
p.padM.style.width = THIS.pickerFace + 2*THIS.pickerInset + jscolor.images.pad[0] + jscolor.images.arrow[0] + 'px';
p.padM.style.height = p.box.style.height;
p.padM.style.cursor = 'crosshair';
// slider image
p.sld.style.overflow = 'hidden';
p.sld.style.width = jscolor.images.sld[0]+'px';
p.sld.style.height = jscolor.images.sld[1]+'px';
// slider border
p.sldB.style.display = THIS.slider ? 'block' : 'none';
p.sldB.style.position = 'absolute';
p.sldB.style.right = THIS.pickerFace+'px';
p.sldB.style.top = THIS.pickerFace+'px';
p.sldB.style.border = THIS.pickerInset+'px solid';
p.sldB.style.borderColor = THIS.pickerInsetColor;
// slider mouse area
p.sldM.style.display = THIS.slider ? 'block' : 'none';
p.sldM.style.position = 'absolute';
p.sldM.style.right = '0';
p.sldM.style.top = '0';
p.sldM.style.width = jscolor.images.sld[0] + jscolor.images.arrow[0] + THIS.pickerFace + 2*THIS.pickerInset + 'px';
p.sldM.style.height = p.box.style.height;
try {
p.sldM.style.cursor = 'pointer';
} catch(eOldIE) {
p.sldM.style.cursor = 'hand';
}
// "close" button
function setBtnBorder() {
var insetColors = THIS.pickerInsetColor.split(/\s+/);
var pickerOutsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1];
p.btn.style.borderColor = pickerOutsetColor;
}
p.btn.style.display = THIS.pickerClosable ? 'block' : 'none';
p.btn.style.position = 'absolute';
p.btn.style.left = THIS.pickerFace + 'px';
p.btn.style.bottom = THIS.pickerFace + 'px';
p.btn.style.padding = '0 15px';
p.btn.style.height = '18px';
p.btn.style.border = THIS.pickerInset + 'px solid';
setBtnBorder();
p.btn.style.color = THIS.pickerButtonColor;
p.btn.style.font = '12px sans-serif';
p.btn.style.textAlign = 'center';
try {
p.btn.style.cursor = 'pointer';
} catch(eOldIE) {
p.btn.style.cursor = 'hand';
}
p.btn.onmousedown = function () {
THIS.hidePicker();
};
p.btnS.style.lineHeight = p.btn.style.height;
// load images in optimal order
switch(modeID) {
case 0: var padImg = 'hs.png'; break;
case 1: var padImg = 'hv.png'; break;
}
p.padM.style.backgroundImage = "url('"+jscolor.getDir()+"cross.gif')";
p.padM.style.backgroundRepeat = "no-repeat";
p.sldM.style.backgroundImage = "url('"+jscolor.getDir()+"arrow.gif')";
p.sldM.style.backgroundRepeat = "no-repeat";
p.pad.style.backgroundImage = "url('"+jscolor.getDir()+padImg+"')";
p.pad.style.backgroundRepeat = "no-repeat";
p.pad.style.backgroundPosition = "0 0";
// place pointers
redrawPad();
redrawSld();
jscolor.picker.owner = THIS;
document.getElementsByTagName('body')[0].appendChild(p.boxB);
}
function getPickerDims(o) {
var dims = [
2*o.pickerInset + 2*o.pickerFace + jscolor.images.pad[0] +
(o.slider ? 2*o.pickerInset + 2*jscolor.images.arrow[0] + jscolor.images.sld[0] : 0),
o.pickerClosable ?
4*o.pickerInset + 3*o.pickerFace + jscolor.images.pad[1] + o.pickerButtonHeight :
2*o.pickerInset + 2*o.pickerFace + jscolor.images.pad[1]
];
return dims;
}
function redrawPad() {
// redraw the pad pointer
switch(modeID) {
case 0: var yComponent = 1; break;
case 1: var yComponent = 2; break;
}
var x = Math.round((THIS.hsv[0]/6) * (jscolor.images.pad[0]-1));
var y = Math.round((1-THIS.hsv[yComponent]) * (jscolor.images.pad[1]-1));
jscolor.picker.padM.style.backgroundPosition =
(THIS.pickerFace+THIS.pickerInset+x - Math.floor(jscolor.images.cross[0]/2)) + 'px ' +
(THIS.pickerFace+THIS.pickerInset+y - Math.floor(jscolor.images.cross[1]/2)) + 'px';
// redraw the slider image
var seg = jscolor.picker.sld.childNodes;
switch(modeID) {
case 0:
var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 1);
for(var i=0; i<seg.length; i+=1) {
seg[i].style.backgroundColor = 'rgb('+
(rgb[0]*(1-i/seg.length)*100)+'%,'+
(rgb[1]*(1-i/seg.length)*100)+'%,'+
(rgb[2]*(1-i/seg.length)*100)+'%)';
}
break;
case 1:
var rgb, s, c = [ THIS.hsv[2], 0, 0 ];
var i = Math.floor(THIS.hsv[0]);
var f = i%2 ? THIS.hsv[0]-i : 1-(THIS.hsv[0]-i);
switch(i) {
case 6:
case 0: rgb=[0,1,2]; break;
case 1: rgb=[1,0,2]; break;
case 2: rgb=[2,0,1]; break;
case 3: rgb=[2,1,0]; break;
case 4: rgb=[1,2,0]; break;
case 5: rgb=[0,2,1]; break;
}
for(var i=0; i<seg.length; i+=1) {
s = 1 - 1/(seg.length-1)*i;
c[1] = c[0] * (1 - s*f);
c[2] = c[0] * (1 - s);
seg[i].style.backgroundColor = 'rgb('+
(c[rgb[0]]*100)+'%,'+
(c[rgb[1]]*100)+'%,'+
(c[rgb[2]]*100)+'%)';
}
break;
}
}
function redrawSld() {
// redraw the slider pointer
switch(modeID) {
case 0: var yComponent = 2; break;
case 1: var yComponent = 1; break;
}
var y = Math.round((1-THIS.hsv[yComponent]) * (jscolor.images.sld[1]-1));
jscolor.picker.sldM.style.backgroundPosition =
'0 ' + (THIS.pickerFace+THIS.pickerInset+y - Math.floor(jscolor.images.arrow[1]/2)) + 'px';
}
function isPickerOwner() {
return jscolor.picker && jscolor.picker.owner === THIS;
}
function blurTarget() {
if(valueElement === target) {
THIS.importColor();
}
if(THIS.pickerOnfocus) {
THIS.hidePicker();
}
}
function blurValue() {
if(valueElement !== target) {
THIS.importColor();
}
}
function setPad(e) {
var mpos = jscolor.getRelMousePos(e);
var x = mpos.x - THIS.pickerFace - THIS.pickerInset;
var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
switch(modeID) {
case 0: THIS.fromHSV(x*(6/(jscolor.images.pad[0]-1)), 1 - y/(jscolor.images.pad[1]-1), null, leaveSld); break;
case 1: THIS.fromHSV(x*(6/(jscolor.images.pad[0]-1)), null, 1 - y/(jscolor.images.pad[1]-1), leaveSld); break;
}
}
function setSld(e) {
var mpos = jscolor.getRelMousePos(e);
var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
switch(modeID) {
case 0: THIS.fromHSV(null, null, 1 - y/(jscolor.images.sld[1]-1), leavePad); break;
case 1: THIS.fromHSV(null, 1 - y/(jscolor.images.sld[1]-1), null, leavePad); break;
}
}
function dispatchImmediateChange() {
if (THIS.onImmediateChange) {
var callback;
if (typeof THIS.onImmediateChange === 'string') {
callback = new Function (THIS.onImmediateChange);
} else {
callback = THIS.onImmediateChange;
}
callback.call(THIS);
}
}
var THIS = this;
var modeID = this.pickerMode.toLowerCase()==='hvs' ? 1 : 0;
var abortBlur = false;
var
valueElement = jscolor.fetchElement(this.valueElement),
styleElement = jscolor.fetchElement(this.styleElement);
var
holdPad = false,
holdSld = false,
touchOffset = {};
var
leaveValue = 1<<0,
leaveStyle = 1<<1,
leavePad = 1<<2,
leaveSld = 1<<3;
// target
jscolor.addEvent(target, 'focus', function() {
if(THIS.pickerOnfocus) { THIS.showPicker(); }
});
jscolor.addEvent(target, 'blur', function() {
if(!abortBlur) {
window.setTimeout(function(){ abortBlur || blurTarget(); abortBlur=false; }, 0);
} else {
abortBlur = false;
}
});
// valueElement
if(valueElement) {
var updateField = function() {
THIS.fromString(valueElement.value, leaveValue);
dispatchImmediateChange();
};
jscolor.addEvent(valueElement, 'keyup', updateField);
jscolor.addEvent(valueElement, 'input', updateField);
jscolor.addEvent(valueElement, 'blur', blurValue);
valueElement.setAttribute('autocomplete', 'off');
}
// styleElement
if(styleElement) {
styleElement.jscStyle = {
backgroundImage : styleElement.style.backgroundImage,
backgroundColor : styleElement.style.backgroundColor,
color : styleElement.style.color
};
}
// require images
switch(modeID) {
case 0: jscolor.requireImage('hs.png'); break;
case 1: jscolor.requireImage('hv.png'); break;
}
jscolor.requireImage('cross.gif');
jscolor.requireImage('arrow.gif');
this.importColor();
}
};
jscolor.install();

+ 56
- 0
dactylotest/js/replay.js View File

@@ -0,0 +1,56 @@
/*******************************************************************************
Les fonctions pour le replay de la session qui vient d'être frappée.
*******************************************************************************/
var stop = true; //true on arrête tout et on repasse j à 0
var vitesse = 1; // la vitesse de lecture
function play()
{
if (stop) return;
document.getElementById("txt").value = list_f[j].val+"▌";
if(j == (list_f.length-1))
{
replay("stop_auto");
}
else
{
j++;
setTimeout("play()",Math.round((list_f[j-1].time-list_f[j-2].time)/vitesse));
}
}
function replay(act)
{
if (act == "stop" || act=="stop_auto")
{
j=0; //on initialise pour le stop mais pas pour le pause pour reprendre au même endroit
document.getElementById("replay").value = "Play";
stop = true;
if (act == "stop")
document.getElementById("txt").value = "";
}
else if (stop)
{
document.getElementById("replay").value = "Pause";
//il faut ajouter une valeur dans la liste de frappe
list_f[-2] = new list(""); //le -2 ne vaut rien, c'est juste pour que les temps soient bon
list_f[-2].time = list_f[0].time; //et on donne la valeur du temps -1 au temps -2
list_f[-1] = new list(""); //le -1 ne vaut rien, c'est juste pour que les temps soient bon
list_f[-1].time = list_f[0].time; //et on donne la valeur du temps 0 au temps -1
stop = false;
play();
}
else
{
document.getElementById("replay").value = "Play";
stop = true;
}
}

+ 34
- 0
dactylotest/js/req.js View File

@@ -0,0 +1,34 @@
/*******************************************************************************
La fonction pour les requêtes serveur.
*******************************************************************************/
//cette fonction permet de faire les requêtes serveur
//get = la requete
//id = le champ ou inscrire l'état de la requete
function request(get,id)
{
var req = null;
document.getElementById(id).innerHTML = '<img src="img/indicator.gif" alt="indic" /> Initialisation';
if(window.XMLHttpRequest)
req = new XMLHttpRequest();
else if (window.ActiveXObject)
req = new ActiveXObject(Microsoft.XMLHTTP);
req.onreadystatechange = function()
{
document.getElementById(id).innerHTML='<img src="img/indicator.gif" alt="indic" /> Connexion au serveur';
if(req.readyState == 4)
{
if(req.status == 200)
document.getElementById(id).innerHTML="";
else
document.getElementById(id).innerHTML="Error: returned status code " + req.status + " " + req.statusText;
}
};
req.open("GET", get, false); // requète non synchronisée sinon on ne peut pas avoir la valeur de la réponse
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send(null);
return req.responseText; //retourne le résultat de la requete
}

+ 44
- 0
dactylotest/js/start.js View File

@@ -0,0 +1,44 @@
/*******************************************************************************
À inclure en fin de page pour le démarrage
*******************************************************************************/
document.getElementById("rd_txt").innerHTML = ""; // effacement du message javascipt
document.getElementById("demo_ghost").style.backgroundColor = cur_col_ghost;
document.getElementById("demo_curseur").style.backgroundColor = cur_col;
document.getElementById("view_options").style.display = "none";
document.getElementById("d_replay").style.visibility = "hidden";
var cur_mix = mix_colors(cur_col,cur_col_ghost) // c'est le mélange des 2 couleurs des curseur du fantôme et de la frappe
clean_ghost();
if (GetCookie("apo_typ") == "true") document.getElementById("apo_typ").checked = true;
if (GetCookie("maj_acc") == "true") document.getElementById("maj_acc").checked = true;
if (GetCookie("ligat") == "true") document.getElementById("ligat").checked = true;
if (GetCookie("pds") == "true") document.getElementById("pds").checked = true;
if (GetCookie("cadratin") == "true") document.getElementById("cadratin").checked = true;
if (GetCookie("no_brk_spc") == "true")
{
document.getElementById("no_brk_spc").checked = true;
//document.getElementById("nbspd").style.display = "block";
}
//else
// document.getElementById("nbspd").style.display = "none";
if (GetCookie("no_brk_spc_display") == "true") document.getElementById("no_brk_spc_display").checked = true;
if (GetCookie("quote_fr") == "true") document.getElementById("quote_fr").checked = true;
if (GetCookie("name") != null) document.getElementById("welcome").innerHTML = "Bienvenue "+GetCookie("name");
// http://www.javascripter.net/faq/operatin.htm
// This script sets OSName variable as follows:
// "Windows" for all versions of Windows
// "MacOS" for all versions of Macintosh OS
// "Linux" for all versions of Linux
// "UNIX" for all other UNIX flavors
// "Unknown OS" indicates failure to detect the OS
var OSName="Unknown OS";
if (navigator.appVersion.indexOf("Win")!=-1) OSName="Windows";
if (navigator.appVersion.indexOf("Mac")!=-1) OSName="MacOS";
if (navigator.appVersion.indexOf("X11")!=-1) OSName="UNIX";
if (navigator.appVersion.indexOf("Linux")!=-1) OSName="Linux";
new_text('new');

+ 32
- 0
dactylotest/list_ghost.php View File

@@ -0,0 +1,32 @@
<?php
// sauvegarde des fantômes suivant les différents textes et les langues
// synthaxe :
// list_ghost.php?text=<nb_text>&lang=<lang>
// text = le numéro du texte
// lang = la langue du texte
// on envoie la liste des fantômes sous forme de chaine décodable par js
//
if (file_exists("ghost/gh_top_".$_GET["lang"]."_".$_GET["text"]))
{
$gh = file("ghost/gh_top_".$_GET["lang"]."_".$_GET["text"]); // on met le contenu du fichier dans un tableau
$gh_ = array();
// il serait bien de renvoyer la date dans un format lisible car pour l'instant elle n'est pas utilisable
foreach($gh as $val)
{
$gh_tmp = explode(" ",$val);
$gh_tmp[1] = date("d M Y à H:i",$gh_tmp[1]); // on modifie le format de date de timestamp en date lisible
$gh_[] = implode(" ",$gh_tmp);
}
$a = str_replace("\n","",implode("###",$gh_));
$a = str_replace("\r","",$a);
echo $a;
}
else
{
echo "no_ghost";
}
?>

+ 10
- 0
dactylotest/load_ghost.php View File

@@ -0,0 +1,10 @@
<?php
// sauvegarde des fantômes suivant les différents textes et les langues
// synthaxe :
// load_ghost.php?ghost=<le fantôme>
// ghost = le fantôme
// on envoie le ghost tel quel sans modification
echo file_get_contents("ghost/".$_GET["ghost"].".gh");
?>

+ 36
- 0
dactylotest/new_text.php View File

@@ -0,0 +1,36 @@
<?php
// $_GET["l"] = la langue
// $_GET["t"] = le texte en cours (pour éviter de le redonner)
// $_GET["force"] = le numéro de texte explicitement demandé
// format à envoyer : new_text.php?l=<lang>&t=<num>[&force=<num>]
$textes = array();
if (file_exists("text/".$_GET["l"].".php"))
{
include "text/".$_GET["l"].".php"; // les textes en français seulement pour l'instant
if (isset($_GET["force"]))
{
if (!$textes[$_GET["force"]]["txt"] && !$textes[$_GET["force"]]["source"])
echo $_GET["force"]."###./###Le texte nº".$_GET["force"]." n’existe pas. Les numéros de textes disponible pour cette langue vont de 0 à ".(count($textes)-1).".";
else
echo $_GET["force"]."###".$textes[$_GET["force"]]["source"]."###".$textes[$_GET["force"]]["txt"];
}
else
{
do {
$rand = rand(0,count($textes)-1);
} while ($rand == $_GET["t"]);
// envoi nºtexte###source###texte ; à décoder en js
echo $rand."###".$textes[$rand]["source"]."###".$textes[$rand]["txt"];
}
}
else
{
echo "x###./###Aucun texte n’est encore disponible dans cette langue.";
}
?>

+ 128
- 0
dactylotest/save_ghost.php View File

@@ -0,0 +1,128 @@
<?php
// sauvegarde des fantômes suivant les différents textes et les langues
// synthaxe :
// save_ghost.php?auteur=<un_nom>&mpm=<vitesse>&text=<nb_text>&lang=<lang>&ghost=<le fantôme>
// auteur = le nom de la personne qui a créé le fantôme
// mpm = mot par minute du fantôme
// text = le numéro du texte
// lang = la langue du texte
// ghost = le fantôme avec position1––temps1##position2--temps2##...##positionX--tempsX
// on enregistre le ghost tel quel sans modification, il sera redonné à la page par load_ghost.php
// par la même occasion est enregistré dans un fichier gh_top_<lang>_<text> les informations sur les fantômes.
// ces infos sont organisées comme suit :
// <nom du fantôme> <timestamp> <auteur> <mpm> <options>
// nom du fantôme = c'est le nom généré aléatoirement qui est le nom du fantôme (fichier.gh)
// timestamp = pour retrouver la date à la quelle le fantôme a été créé
// auteur = le nom de la personne qui a créé le fantôme
// mpm = mot par minute du fantôme
// options = les options typographiques choisies listées dans la variable $cookie_tab. Elles sont à 1 si elles sont actives sinon à 0
function random($car)
{
$string = "";
$chaine = "0123456789abcdef";
srand((double)microtime()*1000000);
for($i=0; $i<$car; $i++)
{
$string .= substr($chaine,rand(1,strlen($chaine))-1,1);
}
return $string;
}
function options()
{
// tableau des différents cookies à tester
$cookie_tab = array("apo_typ","maj_acc","ligat","pds","no_brk_spc","no_brk_spc_display","quote_fr","cadratin");
$opt = "";
foreach ($cookie_tab as $cookie)
{
if ($_COOKIE[$cookie] == "true")
$opt.="1";
else
$opt.="0";
}
return $opt;
}
/*function random($car)
{
$string = "";
$chaine = "0123456789abcdef";
srand((double)microtime()*1000000);
for($i=0; $i<$car; $i++)
{
$string .= $chaine[rand()%strlen($chaine)];
}
return $string;
}*/
do {
$gh_name = random(8);
} while (file_exists("ghost/".$gh_name.".gh")); // on test si le fichier existe et si c'est la cas on génère un autre nom (même si il y a peu de chance que ça se produise)
//cookie auteur pour pas avoir à l'écrire à chaque fois
setcookie("name",$_GET["auteur"],time()+31536000);
// si le mec ne met pas de nom, on peut inscrire "anonym" par exemple
if ($_GET["auteur"] == "")
$_GET["auteur"] = "anonym"; // /!\ je sais pas si on peut modifier un GET ???
// création de l'entrée pour ce fantôme si il est dans les 10 (??? valeurs à définir) premiers
if(file_exists("ghost/gh_top_".$_GET["lang"]."_".$_GET["text"]))
{
$f_gh_top = file("ghost/gh_top_".$_GET["lang"]."_".$_GET["text"]);
$new_gh_top = array();
$non_ajout = true;
$i = 1; // c'est la position dans le classement, c'est juste à donner comme info
foreach($f_gh_top as $value)
{
$champ = explode(" ",str_replace("\n","",$value));
// ghost time auteur mpm
if ($champ[3] < $_GET["mpm"] && $non_ajout)
{
$new_gh_top[] = $gh_name." ".time()." ".$_GET["auteur"]." ".$_GET["mpm"]." ".options();
$non_ajout = false;
$position = $i;
}
//$new_gh_top []= $champ[0]." ".$champ[1]." ".$champ[2]." ".$champ[3];
$new_gh_top[] = str_replace("\n","",$value);
$i++;
}
if ($non_ajout) // si on l'a pas ajouté, c'est qu'il passe à la fin
{
$new_gh_top[] = $gh_name." ".time()." ".$_GET["auteur"]." ".$_GET["mpm"]." ".options();
$position = $i; // et donc il est dernier
}
$new_gh_top = implode("\n",$new_gh_top);
}
else
{
$new_gh_top= $gh_name." ".time()." ".$_GET["auteur"]." ".$_GET["mpm"]." ".options();
$position = 1;
$i = 1;
}
$f = fopen("ghost/gh_top_".$_GET["lang"]."_".$_GET["text"],"w");
fwrite($f,$new_gh_top);
fclose($f);
$gh = true;
// création du fantome
$f=fopen("ghost/".$gh_name.".gh","a+");
$gh = fwrite($f,$_GET["ghost"]);
fclose($f);
if ($gh)
echo "Le fantôme a été créé sous le pseudo de <em>".$_GET["auteur"]."</em> à ".$_GET["mpm"]." mots par minute pour le texte numéro ".$_GET["text"].".<br/>Ce fantôme est classé ".$position."/".$i.".";
else
echo "Le fantôme n'a pas pu être créé.";
?>

+ 41
- 0
dactylotest/save_pref.php View File

@@ -0,0 +1,41 @@
<?php
$un_an = time()+31536000;
if (isset($_GET["curseur"]) && $_GET["curseur"] == "true")
{
// sauvegarde de la couleur des curseurs
if ( setcookie("cur_col",$_GET["cur_col"],$un_an) && setcookie("cur_col_ghost",$_GET["cur_col_ghost"],$un_an) )
{
echo "Vos couleurs de curseurs ont été enregistrées.<br/>";
//echo "cur_cul : ".$_GET["cur_col"]."<br/>";
//echo "cur_col_ghost : ".$_GET["cur_col_ghost"]."<br/>";
}
else
{
echo "Un problème est survenu lors de l'enregistement. Vous pouvez réessayer. Si le problème persiste, veuillez contacter le webmestre à l'adresse tazzon@free.fr.";
}
}
else
{
// sauvegarde en cookie les préférences typographiques
if ( setcookie("apo_typ",$_GET["apo_typ"],$un_an) &&
setcookie("maj_acc",$_GET["maj_acc"],$un_an) &&
setcookie("ligat",$_GET["ligat"],$un_an) &&
setcookie("pds",$_GET["pds"],$un_an) &&
setcookie("cadratin",$_GET["cadratin"],$un_an) &&
setcookie("no_brk_spc",$_GET["no_brk_spc"],$un_an) &&
setcookie("no_brk_spc_display",$_GET["no_brk_spc_display"],$un_an) &&
setcookie("quote_fr",$_GET["quote_fr"],$un_an) )
{
echo "Vos préférences ont été enregistrées.";
}
else
{
echo "Un problème est survenu lors de l'enregistement de vos préférences. Vous pouvez réessayer. Si le problème persiste, veuillez contacter le webmestre à l'adresse tazzon@free.fr.";
}
}
?>

+ 162
- 0
dactylotest/style.css View File

@@ -0,0 +1,162 @@
body {
background-color:#fafafa;
color: black;
font-size: 14px;
font-family:monospace;
margin:0px;
}
.bar {
background-color:black;
/*z-index:150;*/
width:99%;
/*border:1px black dotted;*/
padding:3px;
margin:auto;
}
.main a {
color:#003399;
text-decoration:none;
}
.main a:visited {
color:#003399;
text-decoration:none;
}
.text_nmbr a {
color:#003399;
text-decoration:none;
}
.text_nmbr a:visited {
color:#003399;
text-decoration:none;
}
a:hover {
text-decoration:underline;
}
.bar a,a:visited {
margin:10px;
text-decoration:none;
color:#fafafa;
}
.bar a:hover {
color:#ffd700;
}
h1 {
text-align:center
}
p {
margin:0;
padding:0px 0px 0px 0px;
}
input[type=button] {
border:1px black solid;
background-color:#ebebeb;
font-size: 12px;
color: black;
font-family: monospace;
margin-bottom:3px;
-moz-border-radius: 5px;
border-radius:5px;
}
.full_width {
width:100%;
text-align:center;
}
input[type=button]:hover {
background-color:#fafafa;
}
input[type=text] {
font-size: 14px;
color: black;
font-family: monospace;
}
hr {
border-top : dotted 1px black;
border-bottom : none;
border-left:none;
border-right:none;
}
select {
border:none;
font-family:monospace;
font-size:14px;
background-color:#fafafa;
width:100px;
}
img {
vertical-align:middle;
}
.main {
text-align:center;
width:750px;
margin:auto;
}
.text_nmbr {
width:100%;
border:none;
text-align:center;
}
.err {
visibility:hidden;
color:red;
font-weight:bold;
font-size:18px;
background-color:#ffbbbb;
}
.new_text {
border:none;
text-align:left;
padding:5px;
font-family:monospace;
font-size:14px;
}
.options {
border:none;
text-align:left;
width:270px;
float:left;
padding:0px 5px 5px 5px;
font-family:monospace;
font-size:14px;
}
.view_options {
display:block;
}
.result {
float:right;
text-align:left;
width:450px;
padding:5px;
font-family:monospace;
font-size:14px;
}
.txt {
border:1px black solid;
width:748px;
height:120px;
font-family:monospace;
font-size:14px;
margin-bottom:5px;
}
.rd_txt {
height:auto;
text-align:left;
width:748px;
height:125px;
font-family:monospace;
font-size:14px;
/*text-align:justify;*/
/*background-color:white;*/
}
.d_replay {
visibility:visible;
float:right;
}

Loading…
Cancel
Save