-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
167 lines (133 loc) · 4.97 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// Set accuracy value
let accuracy = 100;
// Set seconds counter
let seconds = 0;
// Getting the text data from API
var quoteText = "";
const MIN_LENGTH = 100;
const MAX_LENGTH = 200;
const API_URL = `https://api.quotable.io/random?minLength=${MIN_LENGTH}&maxLength=${MAX_LENGTH}`
async function getQuote(url) {
// Reset seconds counter
seconds = 0;
// Get response from API
const res = await fetch(url);
// Get data as JSON format and extract the content element
const data = await res.json();
quoteText = data.content;
// Remove em dashes
quoteText = quoteText.replace(/—/g, "-");
// Check if the check boxes are checked
if (!document.getElementById("include-uppercase").checked) {
quoteText = quoteText.toLowerCase();
}
if (!document.getElementById("include-punctuation").checked) {
quoteText = removePunctuation(quoteText);
}
// Reset textbox and input
const textBox = document.querySelector('.textbox-text');
textBox.innerHTML = ""
const textInput = document.querySelector(".text-input")
textInput.value = ""
// Add each character from the quote as a span element
for (let i = 0; i < quoteText.length; i++) {
const spanItem = document.createElement('span');
if (quoteText[i] === " ") {
spanItem.innerHTML = "⎵";
} else {
spanItem.innerText = quoteText[i];
}
if (i === 0) {
spanItem.classList.add("current");
}
textBox.append(spanItem);
}
}
getQuote(API_URL);
// Event listeners
document.addEventListener("DOMContentLoaded", function () {
// Event listeners for checkboxes
document.getElementById("include-uppercase").addEventListener("change", function () {
getQuote(API_URL);
});
document.getElementById("include-punctuation").addEventListener("change", function () {
getQuote(API_URL);
});
// Event listeners for text focus
const textInput = document.querySelector(".text-input")
const blurOverlay = document.querySelector(".blur-overlay")
const textOverlay = document.querySelector(".overlay-text")
textInput.addEventListener("focus", function () {
blurOverlay.classList.remove("blur");
textOverlay.classList.add("disable");
});
textInput.addEventListener("blur", function () {
blurOverlay.classList.add("blur");
textOverlay.classList.remove("disable");
});
// Event listener for typing
textInput.addEventListener("input", onType);
});
// Removes the punctuation from the quote
function removePunctuation(quote) {
const punctuation = [".", "\?", "!", ",", ";", ":", "—", "-", "(", ")", "[", "]", "{", "}", "\'", "\""];
for (let i = 0; i < punctuation.length; i++) {
quote = quote.replace(/[^a-zA-Z0-9\s]/g, "");
}
return quote;
}
// Toggle focus on the text input when the user clicks on the textwrapper
function toggleInputFocus() {
const textInput = document.querySelector(".text-input");
if (textInput === document.activeElement) {
textInput.blur()
} else {
textInput.focus()
}
}
// Create interval for iterating timer
setInterval(addTime, 1000);
function addTime() {
const textInput = document.querySelector(".text-input");
if (textInput === document.activeElement) {
seconds += 1;
}
};
// Change letter styles based on user input
function onType() {
const textInput = document.querySelector(".text-input");
const spanList = document.getElementsByTagName("span");
const textLength = textInput.value.length;
const spanLength = spanList.length;
if (textLength < spanLength) {
// Set the current letter style
for (let i = 0; i < spanLength; i++) {
spanList[i].classList.remove("current");
}
spanList[textLength].className = "current";
// Set correct and error
for (let j = 0; j < textLength; j++) {
// Convert non-breaking spaces to regular spaces
// Non-breaking spaces were used in the HTML to keep consistant spacing size
const spanItemValue = spanList[j].innerText.replace(/\u23b5/g, " ");
// Compare span item to input value
if (spanItemValue === textInput.value[j]) {
spanList[j].className = "correct";
} else {
spanList[j].className = "incorrect";
}
}
}
// Reset the quote as well as update WPM and Accuracy
if (textLength === spanLength) {
// Update Accuracy
let currentAccuracy = (document.querySelectorAll(".correct").length / spanLength) * 100;
accuracy = Math.round((accuracy + currentAccuracy) / 2);
document.getElementById("accuracy").innerText = `Accuracy: ${accuracy}%`
// Update WPM
let cpm = spanLength / (seconds / 60);
let wpm = Math.floor(cpm / 5);
document.getElementById("wpm").innerText = `${wpm} WPM`
getQuote(API_URL);
}
}