Skip to content

Commit 62fd609

Browse files
non-minified version
1 parent dec939e commit 62fd609

File tree

1 file changed

+329
-0
lines changed

1 file changed

+329
-0
lines changed

index_original.html

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
<html>
2+
3+
<head><title>Typing</title></head>
4+
5+
<body>
6+
7+
<div id="selectDiv">
8+
<p>Enter raw GitHub link</p>
9+
<p class="small">Or, leave blank for default code</p>
10+
<input id="githubinput" type="text" size=50></input>
11+
<button id="githubbutton" style="display: inline-block;">-></button>
12+
</div>
13+
14+
<div id="writingDiv" class="displaynone">
15+
<div id="timer">00:00</div>
16+
<div tabindex="0" id="words"></div>
17+
</div>
18+
19+
<div id="resultDiv" class="displaynone">
20+
Your speed is <span id="cpmDiv"></span> CPM!
21+
<br/>
22+
Accuracy: <span id="accuracy"></span>%
23+
</div>
24+
25+
<script>
26+
var wordsDiv = document.getElementById("words");
27+
28+
var myCode = `import os
29+
import sqlite3
30+
from flask import Flask, request, redirect
31+
32+
app = Flask(__name__)
33+
34+
script_folder = os.path.dirname(os.path.realpath(__file__))
35+
dbs = [f.replace(".db", "") for f in os.listdir(script_folder) if f.endswith(".db")]
36+
37+
@app.route("/")
38+
def home():
39+
municipality = request.args.get("m")
40+
case_id = request.args.get("id")
41+
42+
if case_id is None or municipality is None:
43+
return "Use endpoint /?m=MUNICIPALITY&?id=CASE_ID to view a case"
44+
45+
if not municipality in dbs:
46+
return "Invalid municipality, try: " + ", ".join(dbs)
47+
48+
result = "Invalid case id"
49+
conn = sqlite3.connect("{}.db".format(municipality))
50+
51+
row = conn.execute("SELECT htmldocument FROM PostCase WHERE id={}".format(case_id)).fetchone()
52+
if row is not None:
53+
result = row[0]
54+
55+
conn.close()
56+
57+
return result
58+
59+
@app.route("/<path:path>")
60+
def external_redirect(path):
61+
return redirect("https://innsyn.ddv.no/{}".format(path))`;
62+
63+
var lines = myCode.split("\n");
64+
var allCharacters = [];
65+
66+
function generateCode() {
67+
lines = myCode.split("\n");
68+
allCharacters = [];
69+
70+
for (var i = 0; i < lines.length; i++) {
71+
var line = lines[i];
72+
73+
var lineDiv = document.createElement("div");
74+
75+
for (var j = 0; j < line.length; j++) {
76+
const character = document.createElement("character");
77+
character.innerHTML = line[j];
78+
79+
if (i > 0 && j == line.length - 1) {
80+
character.classList.add("last");
81+
}
82+
83+
lineDiv.appendChild(character);
84+
allCharacters.push(character);
85+
}
86+
87+
if (line.length > 0) wordsDiv.appendChild(lineDiv);
88+
}
89+
90+
allCharacters[0].classList.add("active");
91+
allCharacters[allCharacters.length-1].classList.add("finalElement");
92+
}
93+
94+
var characterProgress = 0;
95+
var numCorrect = 0;
96+
var numErrors = 0;
97+
98+
var elapsedTime = 0;
99+
var intervalId = undefined;
100+
var isTimerRunning = false;
101+
function startTimer() {
102+
if (isTimerRunning) return;
103+
isTimerRunning = true;
104+
105+
const timer = document.getElementById("timer");
106+
timer.classList.add("running");
107+
108+
var startTime = Date.now();
109+
110+
intervalId = setInterval(function() {
111+
var newTime = Date.now();
112+
elapsedTime = Math.floor((newTime - startTime) / 1000);
113+
114+
var minutes = Math.floor(elapsedTime / 60);
115+
var seconds = elapsedTime - minutes * 60;
116+
117+
var minutesText = "";
118+
if (minutes < 10) minutesText = "0" + minutes;
119+
else minutesText += minutes;
120+
121+
var secondsText = "";
122+
if (seconds < 10) secondsText = "0" + seconds;
123+
else secondsText += seconds;
124+
125+
timer.innerHTML = minutesText + ":" + secondsText;
126+
}, 100);
127+
}
128+
129+
function writing_done() {
130+
clearInterval(intervalId);
131+
document.getElementById("words").removeEventListener("keydown", onKeyDown_handler);
132+
133+
var length = myCode.replaceAll("\n", "").length;
134+
135+
var cpm = Math.round(60 * (length / elapsedTime));
136+
var accuracy = Math.round(100 * numCorrect / length);
137+
138+
document.getElementById("writingDiv").classList.add("displaynone");
139+
document.getElementById("resultDiv").classList.remove("displaynone");
140+
141+
document.getElementById("cpmDiv").innerHTML = "" + cpm;
142+
document.getElementById("accuracy").innerHTML = "" + accuracy;
143+
}
144+
145+
function onKeyDown_handler(key) {
146+
key.preventDefault();
147+
148+
startTimer();
149+
150+
if (key.key == "Backspace") {
151+
if (characterProgress === 0) return false;
152+
153+
allCharacters[characterProgress].classList.remove("active");
154+
characterProgress--;
155+
156+
if (allCharacters[characterProgress].classList.contains("correct")) {
157+
numCorrect--;
158+
} else {
159+
numErrors--;
160+
}
161+
162+
allCharacters[characterProgress].classList.remove("correct");
163+
allCharacters[characterProgress].classList.remove("error");
164+
allCharacters[characterProgress].classList.add("active");
165+
}
166+
167+
if (key.key.length > 1) return false;
168+
169+
if (allCharacters[characterProgress].innerHTML === key.key) {
170+
allCharacters[characterProgress].classList.add("correct");
171+
numCorrect++;
172+
} else {
173+
allCharacters[characterProgress].classList.add("error");
174+
numErrors++;
175+
}
176+
177+
allCharacters[characterProgress].classList.remove("active")
178+
179+
if (allCharacters[characterProgress].classList.contains("finalElement")) {
180+
writing_done();
181+
return false;
182+
}
183+
184+
if (allCharacters[characterProgress].classList.contains("last")) {
185+
var line = wordsDiv.childNodes[0];
186+
for (let i = 0; i < line.childNodes.length; i++) {
187+
var j = allCharacters.indexOf(line.childNodes[i]);
188+
allCharacters.splice(j, 1);
189+
}
190+
191+
wordsDiv.removeChild(wordsDiv.childNodes[0]);
192+
characterProgress = wordsDiv.childNodes[0].childNodes.length;
193+
allCharacters[characterProgress].classList.add("active");
194+
return false;
195+
}
196+
197+
characterProgress++;
198+
allCharacters[characterProgress].classList.add("active")
199+
return false;
200+
}
201+
202+
document.getElementById("words").addEventListener("keydown", onKeyDown_handler);
203+
204+
document.getElementById("githubbutton").addEventListener("click", function() {
205+
var link = document.getElementById("githubinput").value;
206+
if (link.length === 0) {
207+
generateCode();
208+
document.getElementById("selectDiv").classList.add("displaynone");
209+
document.getElementById("writingDiv").classList.remove("displaynone");
210+
return;
211+
}
212+
213+
fetch(link).then((response) => {
214+
response.text().then((data) => {
215+
myCode = data;
216+
generateCode();
217+
document.getElementById("selectDiv").classList.add("displaynone");
218+
document.getElementById("writingDiv").classList.remove("displaynone");
219+
});
220+
});
221+
});
222+
</script>
223+
224+
<style>
225+
226+
body {
227+
background: #323437;
228+
}
229+
230+
#timer {
231+
font-family: monospace;
232+
font-size: 48px;
233+
color: #646669;;
234+
}
235+
236+
#words {
237+
font-family: monospace;
238+
font-size: 24px;
239+
overflow: hidden;
240+
height: 100px;
241+
min-width: 800px;
242+
margin: 0 auto;
243+
background: #323437;
244+
padding: 15px;
245+
position: absolute;
246+
top: 50%;
247+
left: 50%;
248+
-ms-transform: translateX(-50%) translateY(-50%);
249+
-webkit-transform: translate(-50%,-50%);
250+
transform: translate(-50%,-50%);
251+
}
252+
253+
#resultDiv {
254+
font-family: monospace;
255+
font-size: 36px;
256+
overflow: hidden;
257+
height: 100px;
258+
color: #d1d0c5;
259+
margin: 0 auto;
260+
background: #323437;
261+
padding: 15px;
262+
position: absolute;
263+
top: 50%;
264+
left: 50%;
265+
-ms-transform: translateX(-50%) translateY(-50%);
266+
-webkit-transform: translate(-50%,-50%);
267+
transform: translate(-50%,-50%);
268+
text-align: center;
269+
}
270+
271+
#selectDiv {
272+
font-family: monospace;
273+
font-size: 36px;
274+
overflow: hidden;
275+
height: 250px;
276+
color: #d1d0c5;
277+
margin: 0 auto;
278+
background: #323437;
279+
padding: 15px;
280+
position: absolute;
281+
top: 50%;
282+
left: 50%;
283+
-ms-transform: translateX(-50%) translateY(-50%);
284+
-webkit-transform: translate(-50%,-50%);
285+
transform: translate(-50%,-50%);
286+
text-align: center;
287+
}
288+
289+
character {
290+
white-space: pre;
291+
color: #646669;
292+
}
293+
294+
.correct {
295+
color: #d1d0c5;
296+
}
297+
298+
#timer.running {
299+
color: #d1d0c5;
300+
}
301+
302+
.error {
303+
color: #ca4754;
304+
}
305+
306+
.active {
307+
border-bottom: 2px dashed yellow;
308+
}
309+
310+
.displaynone {
311+
display: none;
312+
}
313+
314+
p.small {
315+
margin-top: -25px;
316+
font-size: 14px;
317+
}
318+
319+
button,input {
320+
outline: none;
321+
border: none;
322+
height: 25px;
323+
}
324+
325+
</style>
326+
327+
</body>
328+
329+
</html>

0 commit comments

Comments
 (0)