@@ -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/>"; | |||
?> |
@@ -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; | |||
} | |||
@@ -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> | |||
@@ -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 : <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="cadratin" /> tiret cadratin<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()"/> | |||
<!--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()"> </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()"> </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> | |||
@@ -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]; | |||
} |
@@ -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); |
@@ -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(); | |||
} | |||
} | |||
} | |||
@@ -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 |
@@ -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 | |||
@@ -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 |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
@@ -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(); |
@@ -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; | |||
} | |||
} |
@@ -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 | |||
} |
@@ -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'); | |||
@@ -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"; | |||
} | |||
?> |
@@ -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"); | |||
?> |
@@ -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."; | |||
} | |||
?> |
@@ -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éé."; | |||
?> |
@@ -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."; | |||
} | |||
} | |||
?> |
@@ -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; | |||
} |