<html>
<head>
<title>Keyboard Typing Testing - RJM Programming - March, 2023</title>
<head>
<meta charset='UTF-8'/>
<script type=text/javascript>
var wpm=0.0;
var cpm=0.0;
var accuracy=0.0;
var retakes=0.0;

var numwords=-1;
var numsecs=0;
var numchars=0;
var numkds=0;
var numkps=0;

var vswords=0;
var vschars=0;

// Thanks to https://stackoverflow.com/questions/1226574/disable-pasting-text-into-html-form

// Register onpaste on inputs and textareas in browsers that don't
// natively support it.
(function () {
var onload = window.onload;

window.onload = function () {
if (typeof onload == "function") {
onload.apply(this, arguments);
}

var fields = [];
var inputs = document.getElementsByTagName("input");
var textareas = document.getElementsByTagName("textarea");

for (var i = 0; i < inputs.length; i++) {
fields.push(inputs[i]);
}

for (var i = 0; i < textareas.length; i++) {
fields.push(textareas[i]);
}

for (var i = 0; i < fields.length; i++) {
var field = fields[i];

if (typeof field.onpaste != "function" && !!field.getAttribute("onpaste")) {
field.onpaste = eval("(function () { " + field.getAttribute("onpaste") + " })");
}

if (typeof field.onpaste == "function") {
var oninput = field.oninput;

field.oninput = function () {
if (typeof oninput == "function") {
oninput.apply(this, arguments);
}

if (typeof this.previousValue == "undefined") {
this.previousValue = this.value;
}

var pasted = (Math.abs(this.previousValue.length - this.value.length) > 1 && this.value != "");

if (pasted && !this.onpaste.apply(this, arguments)) {
this.value = this.previousValue;
}

this.previousValue = this.value;
};

if (field.addEventListener) {
field.addEventListener("input", field.oninput, false);
} else if (field.attachEvent) {
field.attachEvent("oninput", field.oninput);
}
}
}
}
})();

function maybeokay(ing) {
if (eval('' + ing.length) > 1) {
var fl=ing.substring(0,1);
var el=ing.slice(-1);
if (fl != el) {
if ((fl < '0' || fl > 'z') && ing.substring(1).indexOf(fl) != -1) {
return '"' + ing.substring(1).split(fl)[0] + '"';
}
} else {
if ((fl < '0' || fl > 'z')) {
return '"' + ing.substring(1).split(fl)[0] + '"';
}
}
}
return ing;
}

function maybeok(ing) {
if (eval('' + ing.length) > 1 && document.getElementById('myif').src.indexOf('added') != -1) {
var fl=ing.substring(0,1);
var el=ing.slice(-1);
if (fl == el) {
if (fl < '0' || fl > 'z') {
return 'x';
}
}
}
return ing;
}

function noneagain() {
var ideaone='';
document.getElementById('oops').style.display='none';
if (document.getElementById('results').innerHTML != '' && numwords < 0) {
if (document.getElementById('results').innerText.indexOf(' ... ') != -1) {
ideaone=maybeokay(document.getElementById('results').innerText.split(' ... ')[1].replace(/\<br\>/g, String.fromCharCode(10)).replace(/“/g,String.fromCharCode(34)).replace('“', '"').replace('“', '"').replace('“', '"').replace('“', '"').replace('“', '"').replace('“', '"').replace('“', '"').replace('“', '"').trim());
if ((maybeok(ideaone) + ' ').substring(0,1) != '"' && document.getElementById('myif').src.indexOf('added') != -1) {
//alert('ideaone=' + ideaone);
document.getElementById('results').innerHTML='';
document.getElementById('myif').src=document.getElementById('myif').src.replace('added', 'created');
return '';
} else {
//alert('IdeaOnE=' + ideaone);
document.getElementById('yourta').value=ideaone;
}
} else {
ideaone=maybeokay(document.getElementById('results').innerText.replace(/\<br\>/g, String.fromCharCode(10)).replace(/“/g,String.fromCharCode(34)).replace('“', '"').replace('“', '"').replace('“', '"').replace('“', '"').replace('“', '"').replace('“', '"').replace('“', '"').replace('“', '"').trim());
if ((maybeok(ideaone) + ' ').substring(0,1) != '"' && document.getElementById('myif').src.indexOf('added') != -1) {
//alert('Ideaone=' + ideaone);
document.getElementById('results').innerHTML='';
document.getElementById('myif').src=document.getElementById('myif').src.replace('added', 'created');
return '';
} else {
//alert('IdeaONE=' + ideaone);
document.getElementById('yourta').value=ideaone;
}
}
numwords=document.getElementById('yourta').value.split(' ').length;
document.getElementById('yourta').style.cursor='pointer';
document.body.style.cursor='pointer';
}
}

function nsgo() {
if (numkds < 0) {
numkds=-numkds;
} else {
setTimeout(nsgo, 1000);
numsecs++;
}
}

function show() {
numkds=-numkds;
//alert('word count=' + document.getElementById('myta').value.split(' ').length + ' and character count=' + document.getElementById('myta').value.split('').length);
document.getElementById('wpm').value='' + parseFloat(eval(eval('' + document.getElementById('myta').value.split(' ').length) / eval(numsecs / 60.0)).toPrecision(1)) + ' words/minute';
document.getElementById('cpm').value='' + parseFloat(eval(eval('' + document.getElementById('myta').value.split('').length) / eval(numsecs / 60.0)).toPrecision(1)) + ' characters/minute';
if (document.getElementById('myta').value == document.getElementById('yourta').value) {
document.getElementById('accuracy').value='100.0% accuracy';
} else {
var ourcchars=0;
for (var ii=0; ii<document.getElementById('yourta').value.length; ii++) {
if (ii < document.getElementById('myta').value.length) {
if (document.getElementById('myta').value.substring(ii).substring(0,1) == document.getElementById('yourta').value.substring(ii).substring(0,1)) {
ourcchars++;
}
}
}
document.getElementById('accuracy').value='' + parseFloat(eval(eval('' + ourcchars) * 100.0 / document.getElementById('yourta').value.length).toPrecision(3)) + '% accuracy';
}
if (Math.abs(numkds) == numkps) {
document.getElementById('retakes').value='0.0% retakes';
} else {
document.getElementById('retakes').value='' + parseFloat(eval(eval(Math.abs(numkds) - numkps) * 100.0 / numkps).toPrecision(1)) + '% retakes';
}
document.getElementById('rbut').style.display='inline-block';
}

function resetit() {
document.getElementById('myta').value='';
wpm=0.0;
cpm=0.0;
accuracy=0.0;
retakes=0.0;

numwords=-1;
numsecs=0;
numchars=0;
numkds=0;
numkps=0;

vswords=0;
vschars=0;
document.getElementById('wpm').value='';
document.getElementById('cpm').value='';
document.getElementById('accuracy').value='';
document.getElementById('retakes').value='';
document.getElementById('rbut').style.display='none';
document.getElementById('myta').focus();
}

function huhcols() {
if (1 == 2) {
document.getElementById('myta').cols='' + Math.floor(eval('' + screen.width) * 66.0 / 1440.0);
document.getElementById('yourta').cols='' + Math.floor(eval('' + screen.width) * 66.0 / 1440.0);
}
}

setInterval(noneagain, 5000);
</script>
</head>
<body style=cursor:progress; onload="huhcols(); if (window.self !== window.top) { document.getElementById('myta').rows=document.getElementById('myta').rows; } else { document.getElementById('myta').focus(); }">
<h1>Keyboard Typing Practice</h1>
<h3>RJM Programming - March, 2023<span id=oops style=color:red;display:none;font-size:8px;> ... Sorry, but Copy and Paste disabled</span></h3>
<h4>Thanks to <a target=_blank title='https://stackoverflow.com/questions/1226574/disable-pasting-text-into-html-form' href='https://stackoverflow.com/questions/1226574/disable-pasting-text-into-html-form'>https://stackoverflow.com/questions/1226574/disable-pasting-text-into-html-form</a> and <a target=_blank title='goodreads' ... thanks' href='https://www.goodreads.com/quotes'>https://www.goodreads.com/quotes</a></h4>
<table style=width:100%;><tr><th style=width:50%;>Please type this ... <input type=text id=wpm title='Words per minute' placeholder='Words per minute'></input> <input type=text id=cpm title='Characters per minute' placeholder='Characters per minute'></input> </th><th style=width:50%;> ... Here <button onclick=resetit(); id=rbut style=display:none;>Again</button> ... <input type=text id=accuracy title='Accuracy%' placeholder='Accuracy%'></input> <input type=text id=retakes title='Retakes%' placeholder='Retakes%'></input></th></tr>
<tr><td>
<textarea id=yourta style="width:98%;background-color:rgba(102,255,255,0.5);cursor:progress;" rows=20 cols=66 data-onpaste="document.getElementById('oops').style.display='inline'; return false;"></textarea>
</td><td>
<textarea onkeydown="event.handled=true; if (numkds == 0) { setTimeout(nsgo,1000); } if (event.key === 'Backspace' || event.key === 'Delete') { numkds++ }" onkeypress="numkds++; numkps++;" onblur="if (numkds > 0 && numkps > 0) { show(); }" id=myta style="width:98%;background-color:rgba(255,255,102,0.5);" rows=20 cols=66 onpaste="document.getElementById('oops').style.display='inline'; return false;"></textarea>
</td></tr></table>
<div id=results style=display:none;></div>
<iframe id=myif src='./remote_files.php?url=http%3A%2F%2Fwww.goodreads.com%2Fquotes%2Frecently_added&type=+class%3D"quoteText"&ord=3&starting=&middling=&containing=' style='display:none;'></iframe>
</body>
</html>