mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-12-09 12:56:07 +08:00
added test words and test input
fixes 6 circular dependencies part of #2462
This commit is contained in:
parent
d808d8a2d0
commit
56aaa3dc2a
15 changed files with 680 additions and 654 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import Chart from "chart.js";
|
||||
import * as TestStats from "../test/test-stats";
|
||||
import * as TestInput from "./../test/test-input";
|
||||
import * as ThemeColors from "../elements/theme-colors";
|
||||
import * as Misc from "../misc";
|
||||
import Config, * as UpdateConfig from "../config";
|
||||
|
|
@ -61,7 +61,7 @@ export let result = new Chart($("#wpmChart"), {
|
|||
$(".wordInputAfter").remove();
|
||||
|
||||
let wordsToHighlight =
|
||||
TestStats.keypressPerSecond[parseInt(ti.xLabel) - 1].words;
|
||||
TestInput.keypressPerSecond[parseInt(ti.xLabel) - 1].words;
|
||||
|
||||
let unique = [...new Set(wordsToHighlight)];
|
||||
unique.forEach((wordIndex) => {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ import * as WeakSpot from "../test/weak-spot";
|
|||
import * as Leaderboards from "../elements/leaderboards";
|
||||
import * as ActivePage from "./../states/active-page";
|
||||
import * as TestActive from "./../states/test-active";
|
||||
import * as TestInput from "./../test/test-input";
|
||||
import * as TestWords from "./../test/test-words";
|
||||
|
||||
let dontInsertSpace = false;
|
||||
let correctShiftUsed = true;
|
||||
|
|
@ -47,9 +49,9 @@ function updateUI() {
|
|||
|
||||
if (Config.keymapMode === "next" && Config.mode !== "zen") {
|
||||
Keymap.highlightKey(
|
||||
TestLogic.words
|
||||
TestWords.words
|
||||
.getCurrent()
|
||||
.charAt(TestLogic.input.current.length)
|
||||
.charAt(TestInput.input.current.length)
|
||||
.toString()
|
||||
.toUpperCase()
|
||||
);
|
||||
|
|
@ -60,16 +62,16 @@ function backspaceToPrevious() {
|
|||
if (!TestActive.get()) return;
|
||||
|
||||
if (
|
||||
TestLogic.input.history.length == 0 ||
|
||||
TestInput.input.history.length == 0 ||
|
||||
TestUI.currentWordElementIndex == 0
|
||||
)
|
||||
return;
|
||||
|
||||
if (
|
||||
(TestLogic.input.history[TestLogic.words.currentIndex - 1] ==
|
||||
TestLogic.words.get(TestLogic.words.currentIndex - 1) &&
|
||||
(TestInput.input.history[TestWords.words.currentIndex - 1] ==
|
||||
TestWords.words.get(TestWords.words.currentIndex - 1) &&
|
||||
!Config.freedomMode) ||
|
||||
$($(".word")[TestLogic.words.currentIndex - 1]).hasClass("hidden")
|
||||
$($(".word")[TestWords.words.currentIndex - 1]).hasClass("hidden")
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -78,15 +80,15 @@ function backspaceToPrevious() {
|
|||
return;
|
||||
}
|
||||
|
||||
TestLogic.input.current = TestLogic.input.popHistory();
|
||||
TestLogic.corrected.popHistory();
|
||||
TestInput.input.current = TestInput.input.popHistory();
|
||||
TestInput.corrected.popHistory();
|
||||
if (Config.funbox === "nospace" || Config.funbox === "arrows") {
|
||||
TestLogic.input.current = TestLogic.input.current.slice(0, -1);
|
||||
TestInput.input.current = TestInput.input.current.slice(0, -1);
|
||||
}
|
||||
TestLogic.words.decreaseCurrentIndex();
|
||||
TestWords.words.decreaseCurrentIndex();
|
||||
TestUI.setCurrentWordElementIndex(TestUI.currentWordElementIndex - 1);
|
||||
TestUI.updateActiveElement(true);
|
||||
Funbox.toggleScript(TestLogic.words.getCurrent());
|
||||
Funbox.toggleScript(TestWords.words.getCurrent());
|
||||
TestUI.updateWordElement();
|
||||
|
||||
Caret.updatePosition();
|
||||
|
|
@ -96,23 +98,23 @@ function backspaceToPrevious() {
|
|||
function handleSpace() {
|
||||
if (!TestActive.get()) return;
|
||||
|
||||
if (TestLogic.input.current === "") return;
|
||||
if (TestInput.input.current === "") return;
|
||||
|
||||
if (Config.mode == "zen") {
|
||||
$("#words .word.active").removeClass("active");
|
||||
$("#words").append("<div class='word active'></div>");
|
||||
}
|
||||
|
||||
let currentWord = TestLogic.words.getCurrent();
|
||||
let currentWord = TestWords.words.getCurrent();
|
||||
if (Config.funbox === "layoutfluid" && Config.mode !== "time") {
|
||||
// here I need to check if Config.customLayoutFluid exists because of my scuffed solution of returning whenever value is undefined in the setCustomLayoutfluid function
|
||||
const layouts = Config.customLayoutfluid
|
||||
? Config.customLayoutfluid.split("#")
|
||||
: ["qwerty", "dvorak", "colemak"];
|
||||
let index = 0;
|
||||
let outof = TestLogic.words.length;
|
||||
let outof = TestWords.words.length;
|
||||
index = Math.floor(
|
||||
(TestLogic.input.history.length + 1) / (outof / layouts.length)
|
||||
(TestInput.input.history.length + 1) / (outof / layouts.length)
|
||||
);
|
||||
if (Config.layout !== layouts[index] && layouts[index] !== undefined) {
|
||||
Notifications.add(`--- !!! ${layouts[index]} !!! ---`, 0);
|
||||
|
|
@ -120,9 +122,9 @@ function handleSpace() {
|
|||
UpdateConfig.setLayout(layouts[index]);
|
||||
UpdateConfig.setKeymapLayout(layouts[index]);
|
||||
Keymap.highlightKey(
|
||||
TestLogic.words
|
||||
TestWords.words
|
||||
.getCurrent()
|
||||
.charAt(TestLogic.input.current.length)
|
||||
.charAt(TestInput.input.current.length)
|
||||
.toString()
|
||||
.toUpperCase()
|
||||
);
|
||||
|
|
@ -136,19 +138,19 @@ function handleSpace() {
|
|||
|
||||
//correct word or in zen mode
|
||||
const isWordCorrect =
|
||||
currentWord == TestLogic.input.current || Config.mode == "zen";
|
||||
currentWord == TestInput.input.current || Config.mode == "zen";
|
||||
MonkeyPower.addPower(isWordCorrect, true);
|
||||
TestStats.incrementAccuracy(isWordCorrect);
|
||||
TestInput.incrementAccuracy(isWordCorrect);
|
||||
if (isWordCorrect) {
|
||||
PaceCaret.handleSpace(true, currentWord);
|
||||
TestLogic.input.pushHistory();
|
||||
TestLogic.words.increaseCurrentIndex();
|
||||
TestInput.input.pushHistory();
|
||||
TestWords.words.increaseCurrentIndex();
|
||||
TestUI.setCurrentWordElementIndex(TestUI.currentWordElementIndex + 1);
|
||||
TestUI.updateActiveElement();
|
||||
Funbox.toggleScript(TestLogic.words.getCurrent());
|
||||
Funbox.toggleScript(TestWords.words.getCurrent());
|
||||
Caret.updatePosition();
|
||||
TestStats.incrementKeypressCount();
|
||||
TestStats.pushKeypressWord(TestLogic.words.currentIndex);
|
||||
TestInput.incrementKeypressCount();
|
||||
TestInput.pushKeypressWord(TestWords.words.currentIndex);
|
||||
if (Config.funbox !== "nospace" && Config.funbox !== "arrows") {
|
||||
Sound.playClick(Config.playSoundOnClick);
|
||||
}
|
||||
|
|
@ -161,17 +163,17 @@ function handleSpace() {
|
|||
Sound.playError(Config.playSoundOnError);
|
||||
}
|
||||
}
|
||||
TestStats.pushMissedWord(TestLogic.words.getCurrent());
|
||||
TestStats.incrementKeypressErrors();
|
||||
let cil = TestLogic.input.current.length;
|
||||
if (cil <= TestLogic.words.getCurrent().length) {
|
||||
if (cil >= TestLogic.corrected.current.length) {
|
||||
TestLogic.corrected.current += "_";
|
||||
TestInput.pushMissedWord(TestWords.words.getCurrent());
|
||||
TestInput.incrementKeypressErrors();
|
||||
let cil = TestInput.input.current.length;
|
||||
if (cil <= TestWords.words.getCurrent().length) {
|
||||
if (cil >= TestInput.corrected.current.length) {
|
||||
TestInput.corrected.current += "_";
|
||||
} else {
|
||||
TestLogic.corrected.current =
|
||||
TestLogic.corrected.current.substring(0, cil) +
|
||||
TestInput.corrected.current =
|
||||
TestInput.corrected.current.substring(0, cil) +
|
||||
"_" +
|
||||
TestLogic.corrected.current.substring(cil + 1);
|
||||
TestInput.corrected.current.substring(cil + 1);
|
||||
}
|
||||
}
|
||||
if (Config.stopOnError != "off") {
|
||||
|
|
@ -190,20 +192,20 @@ function handleSpace() {
|
|||
}
|
||||
PaceCaret.handleSpace(false, currentWord);
|
||||
if (Config.blindMode) $("#words .word.active letter").addClass("correct");
|
||||
TestLogic.input.pushHistory();
|
||||
TestInput.input.pushHistory();
|
||||
TestUI.highlightBadWord(TestUI.currentWordElementIndex, !Config.blindMode);
|
||||
TestLogic.words.increaseCurrentIndex();
|
||||
TestWords.words.increaseCurrentIndex();
|
||||
TestUI.setCurrentWordElementIndex(TestUI.currentWordElementIndex + 1);
|
||||
TestUI.updateActiveElement();
|
||||
Funbox.toggleScript(TestLogic.words.getCurrent());
|
||||
Funbox.toggleScript(TestWords.words.getCurrent());
|
||||
Caret.updatePosition();
|
||||
TestStats.incrementKeypressCount();
|
||||
TestStats.pushKeypressWord(TestLogic.words.currentIndex);
|
||||
TestStats.updateLastKeypress();
|
||||
TestInput.incrementKeypressCount();
|
||||
TestInput.pushKeypressWord(TestWords.words.currentIndex);
|
||||
TestInput.updateLastKeypress();
|
||||
if (Config.difficulty == "expert" || Config.difficulty == "master") {
|
||||
TestLogic.fail("difficulty");
|
||||
return;
|
||||
} else if (TestLogic.words.currentIndex == TestLogic.words.length) {
|
||||
} else if (TestWords.words.currentIndex == TestWords.words.length) {
|
||||
//submitted last word that is incorrect
|
||||
TestLogic.finish();
|
||||
return;
|
||||
|
|
@ -213,9 +215,9 @@ function handleSpace() {
|
|||
|
||||
let wordLength;
|
||||
if (Config.mode === "zen") {
|
||||
wordLength = TestLogic.input.current.length;
|
||||
wordLength = TestInput.input.current.length;
|
||||
} else {
|
||||
wordLength = TestLogic.words.getCurrent().length;
|
||||
wordLength = TestWords.words.getCurrent().length;
|
||||
}
|
||||
|
||||
let flex = Misc.whorf(Config.minBurstCustomSpeed, wordLength);
|
||||
|
|
@ -227,7 +229,7 @@ function handleSpace() {
|
|||
return;
|
||||
}
|
||||
|
||||
TestLogic.corrected.pushHistory();
|
||||
TestInput.corrected.pushHistory();
|
||||
|
||||
if (
|
||||
!Config.showAllLines ||
|
||||
|
|
@ -284,7 +286,7 @@ function isCharCorrect(char, charIndex) {
|
|||
return true;
|
||||
}
|
||||
|
||||
const originalChar = TestLogic.words.getCurrent()[charIndex];
|
||||
const originalChar = TestWords.words.getCurrent()[charIndex];
|
||||
|
||||
if (originalChar == char) {
|
||||
return true;
|
||||
|
|
@ -389,7 +391,7 @@ function handleChar(char, charIndex) {
|
|||
|
||||
if (
|
||||
Config.mode !== "zen" &&
|
||||
TestLogic.words.getCurrent()[charIndex] !== "\n" &&
|
||||
TestWords.words.getCurrent()[charIndex] !== "\n" &&
|
||||
char === "\n"
|
||||
) {
|
||||
return;
|
||||
|
|
@ -406,40 +408,40 @@ function handleChar(char, charIndex) {
|
|||
let thisCharCorrect = isCharCorrect(char, charIndex);
|
||||
|
||||
if (thisCharCorrect && Config.mode !== "zen") {
|
||||
char = TestLogic.words.getCurrent().charAt(charIndex);
|
||||
char = TestWords.words.getCurrent().charAt(charIndex);
|
||||
}
|
||||
|
||||
if (!thisCharCorrect && char === "\n") {
|
||||
if (TestLogic.input.current === "") return;
|
||||
if (TestInput.input.current === "") return;
|
||||
char = " ";
|
||||
}
|
||||
|
||||
if (TestLogic.input.current === "") {
|
||||
TestStats.setBurstStart(performance.now());
|
||||
if (TestInput.input.current === "") {
|
||||
TestInput.setBurstStart(performance.now());
|
||||
}
|
||||
|
||||
const resultingWord =
|
||||
TestLogic.input.current.substring(0, charIndex) +
|
||||
TestInput.input.current.substring(0, charIndex) +
|
||||
char +
|
||||
TestLogic.input.current.substring(charIndex + 1);
|
||||
TestInput.input.current.substring(charIndex + 1);
|
||||
|
||||
if (!thisCharCorrect && Misc.trailingComposeChars.test(resultingWord)) {
|
||||
TestLogic.input.current = resultingWord;
|
||||
TestInput.input.current = resultingWord;
|
||||
TestUI.updateWordElement();
|
||||
Caret.updatePosition();
|
||||
return;
|
||||
}
|
||||
|
||||
MonkeyPower.addPower(thisCharCorrect);
|
||||
TestStats.incrementAccuracy(thisCharCorrect);
|
||||
TestInput.incrementAccuracy(thisCharCorrect);
|
||||
|
||||
if (!thisCharCorrect) {
|
||||
TestStats.incrementKeypressErrors();
|
||||
TestStats.pushMissedWord(TestLogic.words.getCurrent());
|
||||
TestInput.incrementKeypressErrors();
|
||||
TestInput.pushMissedWord(TestWords.words.getCurrent());
|
||||
}
|
||||
|
||||
WeakSpot.updateScore(
|
||||
Config.mode === "zen" ? char : TestLogic.words.getCurrent()[charIndex],
|
||||
Config.mode === "zen" ? char : TestWords.words.getCurrent()[charIndex],
|
||||
thisCharCorrect
|
||||
);
|
||||
|
||||
|
|
@ -456,22 +458,22 @@ function handleChar(char, charIndex) {
|
|||
if (!correctShiftUsed && Config.difficulty != "master") return;
|
||||
|
||||
//update current corrected version. if its empty then add the current char. if its not then replace the last character with the currently pressed one / add it
|
||||
if (TestLogic.corrected.current === "") {
|
||||
TestLogic.corrected.current += resultingWord;
|
||||
if (TestInput.corrected.current === "") {
|
||||
TestInput.corrected.current += resultingWord;
|
||||
} else {
|
||||
if (charIndex >= TestLogic.corrected.current.length) {
|
||||
TestLogic.corrected.current += char;
|
||||
if (charIndex >= TestInput.corrected.current.length) {
|
||||
TestInput.corrected.current += char;
|
||||
} else if (!thisCharCorrect) {
|
||||
TestLogic.corrected.current =
|
||||
TestLogic.corrected.current.substring(0, charIndex) +
|
||||
TestInput.corrected.current =
|
||||
TestInput.corrected.current.substring(0, charIndex) +
|
||||
char +
|
||||
TestLogic.corrected.current.substring(charIndex + 1);
|
||||
TestInput.corrected.current.substring(charIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
TestStats.incrementKeypressCount();
|
||||
TestStats.updateLastKeypress();
|
||||
TestStats.pushKeypressWord(TestLogic.words.currentIndex);
|
||||
TestInput.incrementKeypressCount();
|
||||
TestInput.updateLastKeypress();
|
||||
TestInput.pushKeypressWord(TestWords.words.currentIndex);
|
||||
|
||||
if (Config.stopOnError == "letter" && !thisCharCorrect) {
|
||||
return;
|
||||
|
|
@ -484,8 +486,8 @@ function handleChar(char, charIndex) {
|
|||
|
||||
//update the active word top, but only once
|
||||
if (
|
||||
TestLogic.input.current.length === 1 &&
|
||||
TestLogic.words.currentIndex === 0
|
||||
TestInput.input.current.length === 1 &&
|
||||
TestWords.words.currentIndex === 0
|
||||
) {
|
||||
TestUI.setActiveWordTop(document.querySelector("#words .active").offsetTop);
|
||||
}
|
||||
|
|
@ -494,14 +496,14 @@ function handleChar(char, charIndex) {
|
|||
if (
|
||||
(Config.mode === "zen" && charIndex < 30) ||
|
||||
(Config.mode !== "zen" &&
|
||||
charIndex < TestLogic.words.getCurrent().length + 20)
|
||||
charIndex < TestWords.words.getCurrent().length + 20)
|
||||
) {
|
||||
TestLogic.input.current = resultingWord;
|
||||
TestInput.input.current = resultingWord;
|
||||
}
|
||||
|
||||
if (!thisCharCorrect && Config.difficulty == "master") {
|
||||
TestLogic.input.pushHistory();
|
||||
TestLogic.corrected.pushHistory();
|
||||
TestInput.input.pushHistory();
|
||||
TestInput.corrected.pushHistory();
|
||||
TestLogic.fail("difficulty");
|
||||
return;
|
||||
}
|
||||
|
|
@ -514,17 +516,17 @@ function handleChar(char, charIndex) {
|
|||
if (Config.mode != "zen") {
|
||||
//not applicable to zen mode
|
||||
//auto stop the test if the last word is correct
|
||||
let currentWord = TestLogic.words.getCurrent();
|
||||
let lastindex = TestLogic.words.currentIndex;
|
||||
let currentWord = TestWords.words.getCurrent();
|
||||
let lastindex = TestWords.words.currentIndex;
|
||||
if (
|
||||
(currentWord == TestLogic.input.current ||
|
||||
(currentWord == TestInput.input.current ||
|
||||
(Config.quickEnd &&
|
||||
currentWord.length == TestLogic.input.current.length &&
|
||||
currentWord.length == TestInput.input.current.length &&
|
||||
Config.stopOnError == "off")) &&
|
||||
lastindex == TestLogic.words.length - 1
|
||||
lastindex == TestWords.words.length - 1
|
||||
) {
|
||||
TestLogic.input.pushHistory();
|
||||
TestLogic.corrected.pushHistory();
|
||||
TestInput.input.pushHistory();
|
||||
TestInput.corrected.pushHistory();
|
||||
TestLogic.finish();
|
||||
return;
|
||||
}
|
||||
|
|
@ -540,7 +542,7 @@ function handleChar(char, charIndex) {
|
|||
if (
|
||||
activeWordTopBeforeJump < newActiveTop &&
|
||||
!TestUI.lineTransition &&
|
||||
TestLogic.input.current.length > 1
|
||||
TestInput.input.current.length > 1
|
||||
) {
|
||||
if (Config.mode == "zen") {
|
||||
let currentTop = Math.floor(
|
||||
|
|
@ -550,7 +552,7 @@ function handleChar(char, charIndex) {
|
|||
);
|
||||
if (!Config.showAllLines) TestUI.lineJump(currentTop);
|
||||
} else {
|
||||
TestLogic.input.current = TestLogic.input.current.slice(0, -1);
|
||||
TestInput.input.current = TestInput.input.current.slice(0, -1);
|
||||
TestUI.updateWordElement();
|
||||
}
|
||||
}
|
||||
|
|
@ -559,7 +561,7 @@ function handleChar(char, charIndex) {
|
|||
//simulate space press in nospace funbox
|
||||
if (
|
||||
((Config.funbox === "nospace" || Config.funbox === "arrows") &&
|
||||
TestLogic.input.current.length === TestLogic.words.getCurrent().length) ||
|
||||
TestInput.input.current.length === TestWords.words.getCurrent().length) ||
|
||||
(char === "\n" && thisCharCorrect)
|
||||
) {
|
||||
handleSpace();
|
||||
|
|
@ -613,7 +615,7 @@ function handleTab(event) {
|
|||
TestUI.resultVisible ||
|
||||
!(
|
||||
(Config.mode == "zen" && !event.shiftKey) ||
|
||||
(TestLogic.hasTab && !event.shiftKey)
|
||||
(TestWords.hasTab && !event.shiftKey)
|
||||
)
|
||||
) {
|
||||
if (event.shiftKey) {
|
||||
|
|
@ -633,21 +635,21 @@ function handleTab(event) {
|
|||
}
|
||||
} else {
|
||||
event.preventDefault();
|
||||
handleChar("\t", TestLogic.input.current.length);
|
||||
setWordsInput(" " + TestLogic.input.current);
|
||||
handleChar("\t", TestInput.input.current.length);
|
||||
setWordsInput(" " + TestInput.input.current);
|
||||
}
|
||||
} else if (!TestUI.resultVisible) {
|
||||
if (
|
||||
(TestLogic.hasTab && event.shiftKey) ||
|
||||
(!TestLogic.hasTab && Config.mode !== "zen") ||
|
||||
(TestWords.hasTab && event.shiftKey) ||
|
||||
(!TestWords.hasTab && Config.mode !== "zen") ||
|
||||
(Config.mode === "zen" && event.shiftKey)
|
||||
) {
|
||||
event.preventDefault();
|
||||
$("#restartTestButton").focus();
|
||||
} else {
|
||||
event.preventDefault();
|
||||
handleChar("\t", TestLogic.input.current.length);
|
||||
setWordsInput(" " + TestLogic.input.current);
|
||||
handleChar("\t", TestInput.input.current.length);
|
||||
setWordsInput(" " + TestInput.input.current);
|
||||
}
|
||||
}
|
||||
} else if (Config.quickTab) {
|
||||
|
|
@ -706,17 +708,17 @@ $(document).keydown((event) => {
|
|||
return;
|
||||
}
|
||||
|
||||
if (TestStats.spacingDebug)
|
||||
if (TestInput.spacingDebug)
|
||||
console.log(
|
||||
"spacing debug",
|
||||
"keypress",
|
||||
event.key,
|
||||
"length",
|
||||
TestStats.keypressTimings.spacing.array.length
|
||||
TestInput.keypressTimings.spacing.array.length
|
||||
);
|
||||
TestStats.recordKeypressSpacing();
|
||||
TestStats.setKeypressDuration(performance.now());
|
||||
TestStats.setKeypressNotAfk();
|
||||
TestInput.recordKeypressSpacing();
|
||||
TestInput.setKeypressDuration(performance.now());
|
||||
TestInput.setKeypressNotAfk();
|
||||
|
||||
//blocking firefox from going back in history with backspace
|
||||
if (event.key === "Backspace") {
|
||||
|
|
@ -743,10 +745,10 @@ $(document).keydown((event) => {
|
|||
|
||||
Monkey.type();
|
||||
|
||||
if (event.key === "Backspace" && TestLogic.input.current.length === 0) {
|
||||
if (event.key === "Backspace" && TestInput.input.current.length === 0) {
|
||||
backspaceToPrevious();
|
||||
if (TestLogic.input.current)
|
||||
setWordsInput(" " + TestLogic.input.current + " ");
|
||||
if (TestInput.input.current)
|
||||
setWordsInput(" " + TestInput.input.current + " ");
|
||||
}
|
||||
|
||||
if (event.key === "Enter") {
|
||||
|
|
@ -760,20 +762,20 @@ $(document).keydown((event) => {
|
|||
TestLogic.setBailout(true);
|
||||
TestLogic.finish();
|
||||
} else {
|
||||
handleChar("\n", TestLogic.input.current.length);
|
||||
setWordsInput(" " + TestLogic.input.current);
|
||||
handleChar("\n", TestInput.input.current.length);
|
||||
setWordsInput(" " + TestInput.input.current);
|
||||
}
|
||||
}
|
||||
|
||||
//show dead keys
|
||||
if (
|
||||
event.key === "Dead" &&
|
||||
!Misc.trailingComposeChars.test(TestLogic.input.current)
|
||||
!Misc.trailingComposeChars.test(TestInput.input.current)
|
||||
) {
|
||||
Sound.playClick(Config.playSoundOnClick);
|
||||
$(
|
||||
document.querySelector("#words .word.active").querySelectorAll("letter")[
|
||||
TestLogic.input.current.length
|
||||
TestInput.input.current.length
|
||||
]
|
||||
).toggleClass("dead");
|
||||
}
|
||||
|
|
@ -789,9 +791,9 @@ $(document).keydown((event) => {
|
|||
if (char === "ArrowDown") char = "s";
|
||||
if (char === "ArrowUp") char = "w";
|
||||
event.preventDefault();
|
||||
handleChar(char, TestLogic.input.current.length);
|
||||
handleChar(char, TestInput.input.current.length);
|
||||
updateUI();
|
||||
setWordsInput(" " + TestLogic.input.current);
|
||||
setWordsInput(" " + TestInput.input.current);
|
||||
}
|
||||
} else if (
|
||||
Config.layout !== "default" &&
|
||||
|
|
@ -803,9 +805,9 @@ $(document).keydown((event) => {
|
|||
const char = LayoutEmulator.getCharFromEvent(event);
|
||||
if (char !== null) {
|
||||
event.preventDefault();
|
||||
handleChar(char, TestLogic.input.current.length);
|
||||
handleChar(char, TestInput.input.current.length);
|
||||
updateUI();
|
||||
setWordsInput(" " + TestLogic.input.current);
|
||||
setWordsInput(" " + TestInput.input.current);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -818,11 +820,11 @@ $("#wordsInput").keyup((event) => {
|
|||
|
||||
if (TestUI.resultVisible) return;
|
||||
let now = performance.now();
|
||||
if (TestStats.keypressTimings.duration.current !== -1) {
|
||||
let diff = Math.abs(TestStats.keypressTimings.duration.current - now);
|
||||
TestStats.pushKeypressDuration(diff);
|
||||
if (TestInput.keypressTimings.duration.current !== -1) {
|
||||
let diff = Math.abs(TestInput.keypressTimings.duration.current - now);
|
||||
TestInput.pushKeypressDuration(diff);
|
||||
}
|
||||
TestStats.setKeypressDuration(now);
|
||||
TestInput.setKeypressDuration(now);
|
||||
Monkey.stop();
|
||||
});
|
||||
|
||||
|
|
@ -839,7 +841,7 @@ $("#wordsInput").on("input", (event) => {
|
|||
return;
|
||||
}
|
||||
|
||||
TestStats.setKeypressNotAfk();
|
||||
TestInput.setKeypressNotAfk();
|
||||
|
||||
const realInputValue = event.target.value.normalize();
|
||||
const inputValue = realInputValue.slice(1);
|
||||
|
|
@ -849,25 +851,25 @@ $("#wordsInput").on("input", (event) => {
|
|||
// the effects of that and takes the input out of compose mode.
|
||||
if (
|
||||
Config.layout !== "default" &&
|
||||
inputValue.length >= TestLogic.input.current.length
|
||||
inputValue.length >= TestInput.input.current.length
|
||||
) {
|
||||
setWordsInput(" " + TestLogic.input.current);
|
||||
setWordsInput(" " + TestInput.input.current);
|
||||
return;
|
||||
}
|
||||
|
||||
if (realInputValue.length === 0 && TestLogic.input.current.length === 0) {
|
||||
if (realInputValue.length === 0 && TestInput.input.current.length === 0) {
|
||||
// fallback for when no Backspace keydown event (mobile)
|
||||
backspaceToPrevious();
|
||||
} else if (inputValue.length < TestLogic.input.current.length) {
|
||||
TestLogic.input.current = inputValue;
|
||||
} else if (inputValue.length < TestInput.input.current.length) {
|
||||
TestInput.input.current = inputValue;
|
||||
TestUI.updateWordElement();
|
||||
Caret.updatePosition();
|
||||
if (!Misc.trailingComposeChars.test(TestLogic.input.current)) {
|
||||
Replay.addReplayEvent("setLetterIndex", TestLogic.input.current.length);
|
||||
if (!Misc.trailingComposeChars.test(TestInput.input.current)) {
|
||||
Replay.addReplayEvent("setLetterIndex", TestInput.input.current.length);
|
||||
}
|
||||
} else if (inputValue !== TestLogic.input.current) {
|
||||
} else if (inputValue !== TestInput.input.current) {
|
||||
let diffStart = 0;
|
||||
while (inputValue[diffStart] === TestLogic.input.current[diffStart])
|
||||
while (inputValue[diffStart] === TestInput.input.current[diffStart])
|
||||
diffStart++;
|
||||
|
||||
for (let i = diffStart; i < inputValue.length; i++) {
|
||||
|
|
@ -875,7 +877,7 @@ $("#wordsInput").on("input", (event) => {
|
|||
}
|
||||
}
|
||||
|
||||
setWordsInput(" " + TestLogic.input.current);
|
||||
setWordsInput(" " + TestInput.input.current);
|
||||
updateUI();
|
||||
|
||||
// force caret at end of input
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import * as TestStats from "./test/test-stats";
|
|||
import * as Replay from "./test/replay";
|
||||
import * as TestTimer from "./test/test-timer";
|
||||
import * as Result from "./test/result";
|
||||
import * as TestInput from "./test/test-input";
|
||||
|
||||
//try to keep this list short because we need to eliminate it eventually
|
||||
global.getuid = Misc.getuid;
|
||||
|
|
@ -48,4 +49,4 @@ global.getTimerStats = TestTimer.getTimerStats;
|
|||
|
||||
global.toggleUnsmoothedRaw = Result.toggleUnsmoothedRaw;
|
||||
|
||||
global.enableSpacingDebug = TestStats.enableSpacingDebug;
|
||||
global.enableSpacingDebug = TestInput.enableSpacingDebug;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import * as Misc from "../misc";
|
||||
import Config from "../config";
|
||||
import * as TestLogic from "./test-logic";
|
||||
import * as TestInput from "./test-input";
|
||||
import * as SlowTimer from "../states/slow-timer";
|
||||
import * as TestActive from "./../states/test-active";
|
||||
|
||||
|
|
@ -37,9 +37,9 @@ export async function updatePosition() {
|
|||
|
||||
let caret = $("#caret");
|
||||
|
||||
let inputLen = TestLogic.input.current.length;
|
||||
inputLen = Misc.trailingComposeChars.test(TestLogic.input.current)
|
||||
? TestLogic.input.current.search(Misc.trailingComposeChars) + 1
|
||||
let inputLen = TestInput.input.current.length;
|
||||
inputLen = Misc.trailingComposeChars.test(TestInput.input.current)
|
||||
? TestInput.input.current.search(Misc.trailingComposeChars) + 1
|
||||
: inputLen;
|
||||
let currentLetterIndex = inputLen - 1;
|
||||
if (currentLetterIndex == -1) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import * as TestLogic from "./test-logic";
|
||||
import * as TestWords from "./test-words";
|
||||
import * as Notifications from "../elements/notifications";
|
||||
import * as TestUI from "./test-ui";
|
||||
import * as Misc from "../misc";
|
||||
|
|
@ -60,7 +61,7 @@ function updateMemoryTimer(sec) {
|
|||
|
||||
export function startMemoryTimer() {
|
||||
resetMemoryTimer();
|
||||
memoryTimer = Math.round(Math.pow(TestLogic.words.length, 1.2));
|
||||
memoryTimer = Math.round(Math.pow(TestWords.words.length, 1.2));
|
||||
updateMemoryTimer(memoryTimer);
|
||||
showMemoryTimer();
|
||||
memoryInterval = setInterval(() => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import * as TestLogic from "./test-logic";
|
||||
import * as TestWords from "./test-words";
|
||||
import * as TestUI from "./test-ui";
|
||||
import Config, * as UpdateConfig from "../config";
|
||||
import * as DB from "../db";
|
||||
|
|
@ -34,7 +35,7 @@ function resetCaretPosition() {
|
|||
|
||||
export async function init() {
|
||||
$("#paceCaret").addClass("hidden");
|
||||
let mode2 = Misc.getMode2(Config, TestLogic.randomQuote);
|
||||
let mode2 = Misc.getMode2(Config, TestWords.randomQuote);
|
||||
let wpm;
|
||||
if (Config.paceCaret === "pb") {
|
||||
wpm = await DB.getLocalPB(
|
||||
|
|
@ -47,7 +48,7 @@ export async function init() {
|
|||
Config.funbox
|
||||
);
|
||||
} else if (Config.paceCaret === "average") {
|
||||
let mode2 = Misc.getMode2(Config, TestLogic.randomQuote);
|
||||
let mode2 = Misc.getMode2(Config, TestWords.randomQuote);
|
||||
wpm = await DB.getUserAverageWpm10(
|
||||
Config.mode,
|
||||
mode2,
|
||||
|
|
@ -97,7 +98,7 @@ export function update(expectedStepEnd) {
|
|||
settings.currentLetterIndex++;
|
||||
if (
|
||||
settings.currentLetterIndex >=
|
||||
TestLogic.words.get(settings.currentWordIndex).length
|
||||
TestWords.words.get(settings.currentWordIndex).length
|
||||
) {
|
||||
//go to the next word
|
||||
settings.currentLetterIndex = -1;
|
||||
|
|
@ -110,7 +111,7 @@ export function update(expectedStepEnd) {
|
|||
if (settings.currentLetterIndex <= -2) {
|
||||
//go to the previous word
|
||||
settings.currentLetterIndex =
|
||||
TestLogic.words.get(settings.currentWordIndex - 1).length - 1;
|
||||
TestWords.words.get(settings.currentWordIndex - 1).length - 1;
|
||||
settings.currentWordIndex--;
|
||||
}
|
||||
settings.correction++;
|
||||
|
|
@ -120,7 +121,7 @@ export function update(expectedStepEnd) {
|
|||
settings.currentLetterIndex++;
|
||||
if (
|
||||
settings.currentLetterIndex >=
|
||||
TestLogic.words.get(settings.currentWordIndex).length
|
||||
TestWords.words.get(settings.currentWordIndex).length
|
||||
) {
|
||||
//go to the next word
|
||||
settings.currentLetterIndex = -1;
|
||||
|
|
@ -145,7 +146,7 @@ export function update(expectedStepEnd) {
|
|||
try {
|
||||
let newIndex =
|
||||
settings.currentWordIndex -
|
||||
(TestLogic.words.currentIndex - TestUI.currentWordElementIndex);
|
||||
(TestWords.words.currentIndex - TestUI.currentWordElementIndex);
|
||||
let word = document.querySelectorAll("#words .word")[newIndex];
|
||||
if (settings.currentLetterIndex === -1) {
|
||||
currentLetter = word.querySelectorAll("letter")[0];
|
||||
|
|
@ -217,19 +218,19 @@ export function handleSpace(correct, currentWord) {
|
|||
if (correct) {
|
||||
if (
|
||||
settings !== null &&
|
||||
settings.wordsStatus[TestLogic.words.currentIndex] === true &&
|
||||
settings.wordsStatus[TestWords.words.currentIndex] === true &&
|
||||
!Config.blindMode
|
||||
) {
|
||||
settings.wordsStatus[TestLogic.words.currentIndex] = undefined;
|
||||
settings.wordsStatus[TestWords.words.currentIndex] = undefined;
|
||||
settings.correction -= currentWord.length + 1;
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
settings !== null &&
|
||||
settings.wordsStatus[TestLogic.words.currentIndex] === undefined &&
|
||||
settings.wordsStatus[TestWords.words.currentIndex] === undefined &&
|
||||
!Config.blindMode
|
||||
) {
|
||||
settings.wordsStatus[TestLogic.words.currentIndex] = true;
|
||||
settings.wordsStatus[TestWords.words.currentIndex] = true;
|
||||
settings.correction += currentWord.length + 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import * as TestStats from "./test-stats";
|
||||
import * as TestWords from "./test-words";
|
||||
import * as Notifications from "../elements/notifications";
|
||||
import Config, * as UpdateConfig from "../config";
|
||||
import * as CustomText from "./custom-text";
|
||||
import * as TestLogic from "./test-logic";
|
||||
import * as TestInput from "./test-input";
|
||||
|
||||
export let before = {
|
||||
mode: null,
|
||||
|
|
@ -21,8 +23,8 @@ export function init(missed, slow) {
|
|||
|
||||
let sortableMissedWords = [];
|
||||
if (missed) {
|
||||
Object.keys(TestStats.missedWords).forEach((missedWord) => {
|
||||
sortableMissedWords.push([missedWord, TestStats.missedWords[missedWord]]);
|
||||
Object.keys(TestInput.missedWords).forEach((missedWord) => {
|
||||
sortableMissedWords.push([missedWord, TestInput.missedWords[missedWord]]);
|
||||
});
|
||||
sortableMissedWords.sort((a, b) => {
|
||||
return b[1] - a[1];
|
||||
|
|
@ -37,7 +39,7 @@ export function init(missed, slow) {
|
|||
|
||||
let sortableSlowWords = [];
|
||||
if (slow) {
|
||||
sortableSlowWords = TestLogic.words.get().map(function (e, i) {
|
||||
sortableSlowWords = TestWords.words.get().map(function (e, i) {
|
||||
return [e, TestStats.burstHistory[i]];
|
||||
});
|
||||
sortableSlowWords.sort((a, b) => {
|
||||
|
|
@ -45,7 +47,7 @@ export function init(missed, slow) {
|
|||
});
|
||||
sortableSlowWords = sortableSlowWords.slice(
|
||||
0,
|
||||
Math.min(limit, Math.round(TestLogic.words.length * 0.2))
|
||||
Math.min(limit, Math.round(TestWords.words.length * 0.2))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
275
frontend/src/js/test/test-input.js
Normal file
275
frontend/src/js/test/test-input.js
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
class Input {
|
||||
constructor() {
|
||||
this.current = "";
|
||||
this.history = [];
|
||||
this.length = 0;
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.current = "";
|
||||
this.history = [];
|
||||
this.length = 0;
|
||||
}
|
||||
|
||||
resetHistory() {
|
||||
this.history = [];
|
||||
this.length = 0;
|
||||
}
|
||||
|
||||
setCurrent(val) {
|
||||
this.current = val;
|
||||
this.length = this.current.length;
|
||||
}
|
||||
|
||||
appendCurrent(val) {
|
||||
this.current += val;
|
||||
this.length = this.current.length;
|
||||
}
|
||||
|
||||
resetCurrent() {
|
||||
this.current = "";
|
||||
}
|
||||
|
||||
getCurrent() {
|
||||
return this.current;
|
||||
}
|
||||
|
||||
pushHistory() {
|
||||
this.history.push(this.current);
|
||||
this.historyLength = this.history.length;
|
||||
this.resetCurrent();
|
||||
}
|
||||
|
||||
popHistory() {
|
||||
return this.history.pop();
|
||||
}
|
||||
|
||||
getHistory(i) {
|
||||
if (i === undefined) {
|
||||
return this.history;
|
||||
} else {
|
||||
return this.history[i];
|
||||
}
|
||||
}
|
||||
|
||||
getHistoryLast() {
|
||||
return this.history[this.history.length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
class Corrected {
|
||||
constructor() {
|
||||
this.current = "";
|
||||
this.history = [];
|
||||
}
|
||||
setCurrent(val) {
|
||||
this.current = val;
|
||||
}
|
||||
|
||||
appendCurrent(val) {
|
||||
this.current += val;
|
||||
}
|
||||
|
||||
resetCurrent() {
|
||||
this.current = "";
|
||||
}
|
||||
|
||||
resetHistory() {
|
||||
this.history = [];
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.resetCurrent();
|
||||
this.resetHistory();
|
||||
}
|
||||
|
||||
getHistory(i) {
|
||||
return this.history[i];
|
||||
}
|
||||
|
||||
popHistory() {
|
||||
return this.history.pop();
|
||||
}
|
||||
|
||||
pushHistory() {
|
||||
this.history.push(this.current);
|
||||
this.current = "";
|
||||
}
|
||||
}
|
||||
|
||||
export let input = new Input();
|
||||
export let corrected = new Corrected();
|
||||
|
||||
export let keypressPerSecond = [];
|
||||
export let currentKeypress = {
|
||||
count: 0,
|
||||
errors: 0,
|
||||
words: [],
|
||||
afk: true,
|
||||
};
|
||||
export let lastKeypress;
|
||||
export let currentBurstStart = 0;
|
||||
export let missedWords = {};
|
||||
export let accuracy = {
|
||||
correct: 0,
|
||||
incorrect: 0,
|
||||
};
|
||||
export let keypressTimings = {
|
||||
spacing: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
duration: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
};
|
||||
|
||||
export let spacingDebug = false;
|
||||
export function enableSpacingDebug() {
|
||||
spacingDebug = true;
|
||||
console.clear();
|
||||
}
|
||||
|
||||
export function updateLastKeypress() {
|
||||
lastKeypress = performance.now();
|
||||
}
|
||||
|
||||
export function incrementKeypressCount() {
|
||||
currentKeypress.count++;
|
||||
}
|
||||
|
||||
export function setKeypressNotAfk() {
|
||||
currentKeypress.afk = false;
|
||||
}
|
||||
|
||||
export function incrementKeypressErrors() {
|
||||
currentKeypress.errors++;
|
||||
}
|
||||
|
||||
export function pushKeypressWord(word) {
|
||||
currentKeypress.words.push(word);
|
||||
}
|
||||
|
||||
export function setBurstStart(time) {
|
||||
currentBurstStart = time;
|
||||
}
|
||||
|
||||
export function pushKeypressesToHistory() {
|
||||
keypressPerSecond.push(currentKeypress);
|
||||
currentKeypress = {
|
||||
count: 0,
|
||||
errors: 0,
|
||||
words: [],
|
||||
afk: true,
|
||||
};
|
||||
}
|
||||
|
||||
export function incrementAccuracy(correctincorrect) {
|
||||
if (correctincorrect) {
|
||||
accuracy.correct++;
|
||||
} else {
|
||||
accuracy.incorrect++;
|
||||
}
|
||||
}
|
||||
|
||||
export function setKeypressTimingsTooLong() {
|
||||
keypressTimings.spacing.array = "toolong";
|
||||
keypressTimings.duration.array = "toolong";
|
||||
}
|
||||
|
||||
export function pushKeypressDuration(val) {
|
||||
keypressTimings.duration.array.push(val);
|
||||
}
|
||||
|
||||
export function setKeypressDuration(val) {
|
||||
keypressTimings.duration.current = val;
|
||||
}
|
||||
|
||||
function pushKeypressSpacing(val) {
|
||||
keypressTimings.spacing.array.push(val);
|
||||
}
|
||||
|
||||
function setKeypressSpacing(val) {
|
||||
keypressTimings.spacing.current = val;
|
||||
}
|
||||
|
||||
export function recordKeypressSpacing() {
|
||||
let now = performance.now();
|
||||
let diff = Math.abs(keypressTimings.spacing.current - now);
|
||||
if (keypressTimings.spacing.current !== -1) {
|
||||
pushKeypressSpacing(diff);
|
||||
if (spacingDebug)
|
||||
console.log(
|
||||
"spacing debug",
|
||||
"push",
|
||||
diff,
|
||||
"length",
|
||||
keypressTimings.spacing.array.length
|
||||
);
|
||||
}
|
||||
setKeypressSpacing(now);
|
||||
if (spacingDebug)
|
||||
console.log(
|
||||
"spacing debug",
|
||||
"set",
|
||||
now,
|
||||
"length",
|
||||
keypressTimings.spacing.array.length
|
||||
);
|
||||
if (spacingDebug)
|
||||
console.log(
|
||||
"spacing debug",
|
||||
"recorded",
|
||||
"length",
|
||||
keypressTimings.spacing.array.length
|
||||
);
|
||||
}
|
||||
|
||||
export function resetKeypressTimings() {
|
||||
keypressTimings = {
|
||||
spacing: {
|
||||
current: performance.now(),
|
||||
array: [],
|
||||
},
|
||||
duration: {
|
||||
current: performance.now(),
|
||||
array: [],
|
||||
},
|
||||
};
|
||||
if (spacingDebug) console.clear();
|
||||
}
|
||||
|
||||
export function pushMissedWord(word) {
|
||||
if (!Object.keys(missedWords).includes(word)) {
|
||||
missedWords[word] = 1;
|
||||
} else {
|
||||
missedWords[word]++;
|
||||
}
|
||||
}
|
||||
|
||||
export function restart() {
|
||||
keypressPerSecond = [];
|
||||
currentKeypress = {
|
||||
count: 0,
|
||||
errors: 0,
|
||||
words: [],
|
||||
afk: true,
|
||||
};
|
||||
currentBurstStart = 0;
|
||||
missedWords = {};
|
||||
accuracy = {
|
||||
correct: 0,
|
||||
incorrect: 0,
|
||||
};
|
||||
keypressTimings = {
|
||||
spacing: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
duration: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -40,6 +40,8 @@ import * as Result from "./result";
|
|||
import * as MonkeyPower from "./../elements/monkey-power";
|
||||
import * as ActivePage from "../states/active-page";
|
||||
import * as TestActive from "./../states/test-active";
|
||||
import * as TestInput from "./test-input";
|
||||
import * as TestWords from "./test-words";
|
||||
|
||||
const objecthash = require("node-object-hash")().hash;
|
||||
|
||||
|
|
@ -67,169 +69,9 @@ export function setNotSignedInUid(uid) {
|
|||
notSignedInLastResult.hash = objecthash(notSignedInLastResult);
|
||||
}
|
||||
|
||||
class Words {
|
||||
constructor() {
|
||||
this.list = [];
|
||||
this.length = 0;
|
||||
this.currentIndex = 0;
|
||||
}
|
||||
get(i, raw = false) {
|
||||
if (i === undefined) {
|
||||
return this.list;
|
||||
} else {
|
||||
if (raw) {
|
||||
return this.list[i]?.replace(/[.?!":\-,]/g, "")?.toLowerCase();
|
||||
} else {
|
||||
return this.list[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
getCurrent() {
|
||||
return this.list[this.currentIndex];
|
||||
}
|
||||
getLast() {
|
||||
return this.list[this.list.length - 1];
|
||||
}
|
||||
push(word) {
|
||||
this.list.push(word);
|
||||
this.length = this.list.length;
|
||||
}
|
||||
reset() {
|
||||
this.list = [];
|
||||
this.currentIndex = 0;
|
||||
this.length = this.list.length;
|
||||
}
|
||||
resetCurrentIndex() {
|
||||
this.currentIndex = 0;
|
||||
}
|
||||
decreaseCurrentIndex() {
|
||||
this.currentIndex--;
|
||||
}
|
||||
increaseCurrentIndex() {
|
||||
this.currentIndex++;
|
||||
}
|
||||
clean() {
|
||||
for (let s of this.list) {
|
||||
if (/ +/.test(s)) {
|
||||
let id = this.list.indexOf(s);
|
||||
let tempList = s.split(" ");
|
||||
this.list.splice(id, 1);
|
||||
for (let i = 0; i < tempList.length; i++) {
|
||||
this.list.splice(id + i, 0, tempList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Input {
|
||||
constructor() {
|
||||
this.current = "";
|
||||
this.history = [];
|
||||
this.length = 0;
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.current = "";
|
||||
this.history = [];
|
||||
this.length = 0;
|
||||
}
|
||||
|
||||
resetHistory() {
|
||||
this.history = [];
|
||||
this.length = 0;
|
||||
}
|
||||
|
||||
setCurrent(val) {
|
||||
this.current = val;
|
||||
this.length = this.current.length;
|
||||
}
|
||||
|
||||
appendCurrent(val) {
|
||||
this.current += val;
|
||||
this.length = this.current.length;
|
||||
}
|
||||
|
||||
resetCurrent() {
|
||||
this.current = "";
|
||||
}
|
||||
|
||||
getCurrent() {
|
||||
return this.current;
|
||||
}
|
||||
|
||||
pushHistory() {
|
||||
this.history.push(this.current);
|
||||
this.historyLength = this.history.length;
|
||||
this.resetCurrent();
|
||||
}
|
||||
|
||||
popHistory() {
|
||||
return this.history.pop();
|
||||
}
|
||||
|
||||
getHistory(i) {
|
||||
if (i === undefined) {
|
||||
return this.history;
|
||||
} else {
|
||||
return this.history[i];
|
||||
}
|
||||
}
|
||||
|
||||
getHistoryLast() {
|
||||
return this.history[this.history.length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
class Corrected {
|
||||
constructor() {
|
||||
this.current = "";
|
||||
this.history = [];
|
||||
}
|
||||
setCurrent(val) {
|
||||
this.current = val;
|
||||
}
|
||||
|
||||
appendCurrent(val) {
|
||||
this.current += val;
|
||||
}
|
||||
|
||||
resetCurrent() {
|
||||
this.current = "";
|
||||
}
|
||||
|
||||
resetHistory() {
|
||||
this.history = [];
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.resetCurrent();
|
||||
this.resetHistory();
|
||||
}
|
||||
|
||||
getHistory(i) {
|
||||
return this.history[i];
|
||||
}
|
||||
|
||||
popHistory() {
|
||||
return this.history.pop();
|
||||
}
|
||||
|
||||
pushHistory() {
|
||||
this.history.push(this.current);
|
||||
this.current = "";
|
||||
}
|
||||
}
|
||||
|
||||
export let words = new Words();
|
||||
export let input = new Input();
|
||||
export let corrected = new Corrected();
|
||||
export let currentWordIndex = 0;
|
||||
export let isRepeated = false;
|
||||
export let isPaceRepeat = false;
|
||||
export let lastTestWpm = 0;
|
||||
export let hasTab = false;
|
||||
export let randomQuote = null;
|
||||
export let bailout = false;
|
||||
|
||||
export function setRepeated(tf) {
|
||||
|
|
@ -240,18 +82,10 @@ export function setPaceRepeat(tf) {
|
|||
isPaceRepeat = tf;
|
||||
}
|
||||
|
||||
export function setHasTab(tf) {
|
||||
hasTab = tf;
|
||||
}
|
||||
|
||||
export function setBailout(tf) {
|
||||
bailout = tf;
|
||||
}
|
||||
|
||||
export function setRandomQuote(rq) {
|
||||
randomQuote = rq;
|
||||
}
|
||||
|
||||
let spanishSentenceTracker = "";
|
||||
export function punctuateWord(previousWord, currentWord, index, maxindex) {
|
||||
let word = currentWord;
|
||||
|
|
@ -430,8 +264,8 @@ export function startTest() {
|
|||
}
|
||||
TestActive.set(true);
|
||||
Replay.startReplayRecording();
|
||||
Replay.replayGetWordsList(words.list);
|
||||
TestStats.resetKeypressTimings();
|
||||
Replay.replayGetWordsList(TestWords.words.list);
|
||||
TestInput.resetKeypressTimings();
|
||||
TimerProgress.restart();
|
||||
TimerProgress.show();
|
||||
$("#liveWpm").text("0");
|
||||
|
|
@ -470,7 +304,7 @@ export function restart(
|
|||
}
|
||||
if (ActivePage.get() == "pageTest" && !TestUI.resultVisible) {
|
||||
if (!ManualRestart.get()) {
|
||||
if (hasTab) {
|
||||
if (TestWords.hasTab) {
|
||||
try {
|
||||
if (!event.shiftKey) return;
|
||||
} catch {}
|
||||
|
|
@ -498,7 +332,7 @@ export function restart(
|
|||
}
|
||||
}
|
||||
if (TestActive.get()) {
|
||||
TestStats.pushKeypressesToHistory();
|
||||
TestInput.pushKeypressesToHistory();
|
||||
let testSeconds = TestStats.calculateTestSeconds(performance.now());
|
||||
let afkseconds = TestStats.calculateAfkSeconds(testSeconds);
|
||||
// incompleteTestSeconds += ;
|
||||
|
|
@ -544,7 +378,8 @@ export function restart(
|
|||
ManualRestart.reset();
|
||||
TestTimer.clear();
|
||||
TestStats.restart();
|
||||
corrected.reset();
|
||||
TestInput.restart();
|
||||
TestInput.corrected.reset();
|
||||
ShiftTracker.reset();
|
||||
Caret.hide();
|
||||
TestActive.set(false);
|
||||
|
|
@ -625,7 +460,7 @@ export function restart(
|
|||
if (!withSameWordset && !shouldQuoteRepeat) {
|
||||
setRepeated(false);
|
||||
setPaceRepeat(repeatWithPace);
|
||||
setHasTab(false);
|
||||
TestWords.setHasTab(false);
|
||||
await init();
|
||||
PaceCaret.init(nosave);
|
||||
} else {
|
||||
|
|
@ -633,8 +468,8 @@ export function restart(
|
|||
setPaceRepeat(repeatWithPace);
|
||||
TestActive.set(false);
|
||||
Replay.stopReplayRecording();
|
||||
words.resetCurrentIndex();
|
||||
input.reset();
|
||||
TestWords.words.resetCurrentIndex();
|
||||
TestInput.input.reset();
|
||||
if (Config.funbox === "plus_one" || Config.funbox === "plus_two") {
|
||||
Notifications.add(
|
||||
"Sorry, this funbox won't work with repeated tests.",
|
||||
|
|
@ -670,7 +505,7 @@ export function restart(
|
|||
}
|
||||
}
|
||||
|
||||
let mode2 = Misc.getMode2(Config, randomQuote);
|
||||
let mode2 = Misc.getMode2(Config, TestWords.randomQuote);
|
||||
let fbtext = "";
|
||||
if (Config.funbox !== "none") {
|
||||
fbtext = " " + Config.funbox;
|
||||
|
|
@ -694,9 +529,12 @@ export function restart(
|
|||
true
|
||||
);
|
||||
Keymap.highlightKey(
|
||||
words
|
||||
TestWords.words
|
||||
.getCurrent()
|
||||
.substring(input.current.length, input.current.length + 1)
|
||||
.substring(
|
||||
TestInput.input.current.length,
|
||||
TestInput.input.current.length + 1
|
||||
)
|
||||
.toString()
|
||||
.toUpperCase()
|
||||
);
|
||||
|
|
@ -779,16 +617,16 @@ function applyLazyModeToWord(word, language) {
|
|||
|
||||
async function getNextWord(wordset, language, wordsBound) {
|
||||
let randomWord = wordset.randomWord();
|
||||
const previousWord = words.get(words.length - 1, true);
|
||||
const previousWord2 = words.get(words.length - 2, true);
|
||||
const previousWord = TestWords.words.get(TestWords.words.length - 1, true);
|
||||
const previousWord2 = TestWords.words.get(TestWords.words.length - 2, true);
|
||||
if (Config.mode === "quote") {
|
||||
randomWord = randomQuote.textSplit[words.length];
|
||||
randomWord = TestWords.randomQuote.textSplit[TestWords.words.length];
|
||||
} else if (
|
||||
Config.mode == "custom" &&
|
||||
!CustomText.isWordRandom &&
|
||||
!CustomText.isTimeRandom
|
||||
) {
|
||||
randomWord = CustomText.text[words.length];
|
||||
randomWord = CustomText.text[TestWords.words.length];
|
||||
} else if (
|
||||
Config.mode == "custom" &&
|
||||
(CustomText.isWordRandom || CustomText.isTimeRandom) &&
|
||||
|
|
@ -820,9 +658,9 @@ async function getNextWord(wordset, language, wordsBound) {
|
|||
|
||||
if (Config.punctuation) {
|
||||
randomWord = punctuateWord(
|
||||
words.get(words.length - 1),
|
||||
TestWords.words.get(TestWords.words.length - 1),
|
||||
randomWord,
|
||||
words.length,
|
||||
TestWords.words.length,
|
||||
wordsBound
|
||||
);
|
||||
}
|
||||
|
|
@ -839,15 +677,15 @@ export async function init() {
|
|||
TestActive.set(false);
|
||||
MonkeyPower.reset();
|
||||
Replay.stopReplayRecording();
|
||||
words.reset();
|
||||
TestWords.words.reset();
|
||||
TestUI.setCurrentWordElementIndex(0);
|
||||
// accuracy = {
|
||||
// correct: 0,
|
||||
// incorrect: 0,
|
||||
// };
|
||||
|
||||
input.resetHistory();
|
||||
input.resetCurrent();
|
||||
TestInput.input.resetHistory();
|
||||
TestInput.input.resetCurrent();
|
||||
|
||||
let language = await Misc.getLanguage(Config.language);
|
||||
if (language && language.name !== Config.language) {
|
||||
|
|
@ -962,7 +800,7 @@ export async function init() {
|
|||
break;
|
||||
}
|
||||
wordCount++;
|
||||
words.push(word);
|
||||
TestWords.words.push(word);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -970,18 +808,18 @@ export async function init() {
|
|||
let randomWord = await getNextWord(wordset, language, wordsBound);
|
||||
|
||||
if (/\t/g.test(randomWord)) {
|
||||
setHasTab(true);
|
||||
TestWords.setHasTab(true);
|
||||
}
|
||||
|
||||
if (/ +/.test(randomWord)) {
|
||||
let randomList = randomWord.split(" ");
|
||||
let id = 0;
|
||||
while (id < randomList.length) {
|
||||
words.push(randomList[id]);
|
||||
TestWords.words.push(randomList[id]);
|
||||
id++;
|
||||
|
||||
if (
|
||||
words.length == wordsBound &&
|
||||
TestWords.words.length == wordsBound &&
|
||||
Config.mode == "custom" &&
|
||||
CustomText.isWordRandom
|
||||
) {
|
||||
|
|
@ -995,10 +833,10 @@ export async function init() {
|
|||
) {
|
||||
//
|
||||
} else {
|
||||
i = words.length - 1;
|
||||
i = TestWords.words.length - 1;
|
||||
}
|
||||
} else {
|
||||
words.push(randomWord);
|
||||
TestWords.words.push(randomWord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1045,7 +883,7 @@ export async function init() {
|
|||
quotes.groups[groupIndex][
|
||||
Math.floor(Math.random() * quotes.groups[groupIndex].length)
|
||||
];
|
||||
if (randomQuote != null && rq.id === randomQuote.id) {
|
||||
if (TestWords.randomQuote != null && rq.id === TestWords.randomQuote.id) {
|
||||
rq =
|
||||
quotes.groups[groupIndex][
|
||||
Math.floor(Math.random() * quotes.groups[groupIndex].length)
|
||||
|
|
@ -1076,9 +914,9 @@ export async function init() {
|
|||
rq.textSplit = rq.text.split(" ");
|
||||
rq.language = Config.language.replace(/_\d*k$/g, "");
|
||||
|
||||
setRandomQuote(rq);
|
||||
TestWords.setRandomQuote(rq);
|
||||
|
||||
let w = randomQuote.textSplit;
|
||||
let w = TestWords.randomQuote.textSplit;
|
||||
|
||||
if (Config.showAllLines) {
|
||||
wordsBound = w.length;
|
||||
|
|
@ -1088,14 +926,14 @@ export async function init() {
|
|||
|
||||
for (let i = 0; i < wordsBound; i++) {
|
||||
if (/\t/g.test(w[i])) {
|
||||
setHasTab(true);
|
||||
TestWords.setHasTab(true);
|
||||
}
|
||||
|
||||
w[i] = applyLazyModeToWord(w[i], language);
|
||||
w[i] = await applyBritishEnglishToWord(w[i]);
|
||||
w[i] = applyFunboxesToWord(w[i]);
|
||||
|
||||
words.push(w[i]);
|
||||
TestWords.words.push(w[i]);
|
||||
}
|
||||
}
|
||||
//handle right-to-left languages
|
||||
|
|
@ -1131,23 +969,29 @@ export function calculateWpmAndRaw() {
|
|||
let correctWordChars = 0;
|
||||
let spaces = 0;
|
||||
//check input history
|
||||
for (let i = 0; i < input.history.length; i++) {
|
||||
let word = Config.mode == "zen" ? input.getHistory(i) : words.get(i);
|
||||
if (input.getHistory(i) == word) {
|
||||
for (let i = 0; i < TestInput.input.history.length; i++) {
|
||||
let word =
|
||||
Config.mode == "zen"
|
||||
? TestInput.input.getHistory(i)
|
||||
: TestWords.words.get(i);
|
||||
if (TestInput.input.getHistory(i) == word) {
|
||||
//the word is correct
|
||||
//+1 for space
|
||||
correctWordChars += word.length;
|
||||
if (
|
||||
i < input.history.length - 1 &&
|
||||
Misc.getLastChar(input.getHistory(i)) !== "\n"
|
||||
i < TestInput.input.history.length - 1 &&
|
||||
Misc.getLastChar(TestInput.input.getHistory(i)) !== "\n"
|
||||
) {
|
||||
spaces++;
|
||||
}
|
||||
}
|
||||
chars += input.getHistory(i).length;
|
||||
chars += TestInput.input.getHistory(i).length;
|
||||
}
|
||||
if (input.current !== "") {
|
||||
let word = Config.mode == "zen" ? input.current : words.getCurrent();
|
||||
if (TestInput.input.current !== "") {
|
||||
let word =
|
||||
Config.mode == "zen"
|
||||
? TestInput.input.current
|
||||
: TestWords.words.getCurrent();
|
||||
//check whats currently typed
|
||||
let toAdd = {
|
||||
correct: 0,
|
||||
|
|
@ -1155,9 +999,9 @@ export function calculateWpmAndRaw() {
|
|||
missed: 0,
|
||||
};
|
||||
for (let c = 0; c < word.length; c++) {
|
||||
if (c < input.current.length) {
|
||||
if (c < TestInput.input.current.length) {
|
||||
//on char that still has a word list pair
|
||||
if (input.current[c] == word[c]) {
|
||||
if (TestInput.input.current[c] == word[c]) {
|
||||
toAdd.correct++;
|
||||
} else {
|
||||
toAdd.incorrect++;
|
||||
|
|
@ -1178,7 +1022,7 @@ export function calculateWpmAndRaw() {
|
|||
if (Config.funbox === "nospace" || Config.funbox === "arrows") {
|
||||
spaces = 0;
|
||||
}
|
||||
chars += input.current.length;
|
||||
chars += TestInput.input.current.length;
|
||||
let testSeconds = TestStats.calculateTestSeconds(performance.now());
|
||||
let wpm = Math.round(((correctWordChars + spaces) * (60 / testSeconds)) / 5);
|
||||
let raw = Math.round(((chars + spaces) * (60 / testSeconds)) / 5);
|
||||
|
|
@ -1191,7 +1035,10 @@ export function calculateWpmAndRaw() {
|
|||
export async function addWord() {
|
||||
let bound = 100;
|
||||
if (Config.funbox === "wikipedia" || Config.funbox == "poetry") {
|
||||
if (Config.mode == "time" && words.length - words.currentIndex < 20) {
|
||||
if (
|
||||
Config.mode == "time" &&
|
||||
TestWords.words.length - TestWords.words.currentIndex < 20
|
||||
) {
|
||||
let section =
|
||||
Config.funbox == "wikipedia"
|
||||
? await Wikipedia.getSection(Config.language)
|
||||
|
|
@ -1202,7 +1049,7 @@ export async function addWord() {
|
|||
break;
|
||||
}
|
||||
wordCount++;
|
||||
words.push(word);
|
||||
TestWords.words.push(word);
|
||||
TestUI.addWord(word);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1213,19 +1060,20 @@ export async function addWord() {
|
|||
if (Config.funbox === "plus_one") bound = 1;
|
||||
if (Config.funbox === "plus_two") bound = 2;
|
||||
if (
|
||||
words.length - input.history.length > bound ||
|
||||
TestWords.words.length - TestInput.input.history.length > bound ||
|
||||
(Config.mode === "words" &&
|
||||
words.length >= Config.words &&
|
||||
TestWords.words.length >= Config.words &&
|
||||
Config.words > 0) ||
|
||||
(Config.mode === "custom" &&
|
||||
CustomText.isWordRandom &&
|
||||
words.length >= CustomText.word &&
|
||||
TestWords.words.length >= CustomText.word &&
|
||||
CustomText.word != 0) ||
|
||||
(Config.mode === "custom" &&
|
||||
!CustomText.isWordRandom &&
|
||||
!CustomText.isTimeRandom &&
|
||||
words.length >= CustomText.text.length) ||
|
||||
(Config.mode === "quote" && words.length >= randomQuote.textSplit.length)
|
||||
TestWords.words.length >= CustomText.text.length) ||
|
||||
(Config.mode === "quote" &&
|
||||
TestWords.words.length >= TestWords.randomQuote.textSplit.length)
|
||||
)
|
||||
return;
|
||||
const language =
|
||||
|
|
@ -1244,11 +1092,11 @@ export async function addWord() {
|
|||
let split = randomWord.split(" ");
|
||||
if (split.length > 1) {
|
||||
split.forEach((word) => {
|
||||
words.push(word);
|
||||
TestWords.words.push(word);
|
||||
TestUI.addWord(word);
|
||||
});
|
||||
} else {
|
||||
words.push(randomWord);
|
||||
TestWords.words.push(randomWord);
|
||||
TestUI.addWord(randomWord);
|
||||
}
|
||||
}
|
||||
|
|
@ -1364,8 +1212,8 @@ function buildCompletedEvent(difficultyFailed) {
|
|||
difficulty: Config.difficulty,
|
||||
blindMode: Config.blindMode,
|
||||
tags: undefined,
|
||||
keySpacing: TestStats.keypressTimings.spacing.array,
|
||||
keyDuration: TestStats.keypressTimings.duration.array,
|
||||
keySpacing: TestInput.keypressTimings.spacing.array,
|
||||
keyDuration: TestInput.keypressTimings.duration.array,
|
||||
consistency: undefined,
|
||||
keyConsistency: undefined,
|
||||
funbox: Config.funbox,
|
||||
|
|
@ -1401,17 +1249,17 @@ function buildCompletedEvent(difficultyFailed) {
|
|||
let wpmAndRaw = calculateWpmAndRaw();
|
||||
TestStats.pushToWpmHistory(wpmAndRaw.wpm);
|
||||
TestStats.pushToRawHistory(wpmAndRaw.raw);
|
||||
TestStats.pushKeypressesToHistory();
|
||||
TestInput.pushKeypressesToHistory();
|
||||
}
|
||||
|
||||
//consistency
|
||||
let rawPerSecond = TestStats.keypressPerSecond.map((f) =>
|
||||
let rawPerSecond = TestInput.keypressPerSecond.map((f) =>
|
||||
Math.round((f.count / 5) * 60)
|
||||
);
|
||||
let stddev = Misc.stdDev(rawPerSecond);
|
||||
let avg = Misc.mean(rawPerSecond);
|
||||
let consistency = Misc.roundTo2(Misc.kogasa(stddev / avg));
|
||||
let keyconsistencyarray = TestStats.keypressTimings.spacing.array.slice();
|
||||
let keyconsistencyarray = TestInput.keypressTimings.spacing.array.slice();
|
||||
keyconsistencyarray = keyconsistencyarray.splice(
|
||||
0,
|
||||
keyconsistencyarray.length - 1
|
||||
|
|
@ -1448,16 +1296,16 @@ function buildCompletedEvent(difficultyFailed) {
|
|||
);
|
||||
|
||||
completedEvent.chartData.err = [];
|
||||
for (let i = 0; i < TestStats.keypressPerSecond.length; i++) {
|
||||
completedEvent.chartData.err.push(TestStats.keypressPerSecond[i].errors);
|
||||
for (let i = 0; i < TestInput.keypressPerSecond.length; i++) {
|
||||
completedEvent.chartData.err.push(TestInput.keypressPerSecond[i].errors);
|
||||
}
|
||||
|
||||
if (Config.mode === "quote") {
|
||||
completedEvent.quoteLength = randomQuote.group;
|
||||
completedEvent.quoteLength = TestWords.randomQuote.group;
|
||||
completedEvent.lang = Config.language.replace(/_\d*k$/g, "");
|
||||
}
|
||||
|
||||
completedEvent.mode2 = Misc.getMode2(Config, randomQuote);
|
||||
completedEvent.mode2 = Misc.getMode2(Config, TestWords.randomQuote);
|
||||
|
||||
if (Config.mode === "custom") {
|
||||
completedEvent.customText = {};
|
||||
|
|
@ -1494,13 +1342,13 @@ function buildCompletedEvent(difficultyFailed) {
|
|||
|
||||
export async function finish(difficultyFailed = false) {
|
||||
if (!TestActive.get()) return;
|
||||
if (Config.mode == "zen" && input.current.length != 0) {
|
||||
input.pushHistory();
|
||||
corrected.pushHistory();
|
||||
Replay.replayGetWordsList(input.history);
|
||||
if (Config.mode == "zen" && TestInput.input.current.length != 0) {
|
||||
TestInput.input.pushHistory();
|
||||
TestInput.corrected.pushHistory();
|
||||
Replay.replayGetWordsList(TestInput.input.history);
|
||||
}
|
||||
|
||||
TestStats.recordKeypressSpacing(); //this is needed in case there is afk time at the end - to make sure test duration makes sense
|
||||
TestInput.recordKeypressSpacing(); //this is needed in case there is afk time at the end - to make sure test duration makes sense
|
||||
|
||||
TestUI.setResultCalculating(true);
|
||||
TestUI.setResultVisible(true);
|
||||
|
|
@ -1519,7 +1367,7 @@ export async function finish(difficultyFailed = false) {
|
|||
Funbox.activate("none", null);
|
||||
|
||||
//need one more calculation for the last word if test auto ended
|
||||
if (TestStats.burstHistory.length !== input.getHistory().length) {
|
||||
if (TestStats.burstHistory.length !== TestInput.input.getHistory().length) {
|
||||
let burst = TestStats.calculateBurst();
|
||||
TestStats.pushBurstToHistory(burst);
|
||||
}
|
||||
|
|
@ -1536,7 +1384,7 @@ export async function finish(difficultyFailed = false) {
|
|||
///////// completed event ready
|
||||
|
||||
//afk check
|
||||
let kps = TestStats.keypressPerSecond.slice(-5);
|
||||
let kps = TestInput.keypressPerSecond.slice(-5);
|
||||
let afkDetected = kps.every((second) => second.afk);
|
||||
if (bailout) afkDetected = false;
|
||||
|
||||
|
|
@ -1626,7 +1474,7 @@ export async function finish(difficultyFailed = false) {
|
|||
afkDetected,
|
||||
isRepeated,
|
||||
tooShort,
|
||||
randomQuote,
|
||||
TestWords.randomQuote,
|
||||
dontSave
|
||||
);
|
||||
|
||||
|
|
@ -1636,7 +1484,7 @@ export async function finish(difficultyFailed = false) {
|
|||
completedEvent.chartData = "toolong";
|
||||
completedEvent.keySpacing = "toolong";
|
||||
completedEvent.keyDuration = "toolong";
|
||||
TestStats.setKeypressTimingsTooLong();
|
||||
TestInput.setKeypressTimingsTooLong();
|
||||
}
|
||||
|
||||
if (dontSave) {
|
||||
|
|
@ -1659,7 +1507,7 @@ export async function finish(difficultyFailed = false) {
|
|||
}
|
||||
|
||||
completedEvent.uid = firebase.auth().currentUser.uid;
|
||||
Result.updateRateQuote(randomQuote);
|
||||
Result.updateRateQuote(TestWords.randomQuote);
|
||||
|
||||
Result.updateGraphPBLine();
|
||||
|
||||
|
|
@ -1737,7 +1585,7 @@ export function fail(reason) {
|
|||
failReason = reason;
|
||||
// input.pushHistory();
|
||||
// corrected.pushHistory();
|
||||
TestStats.pushKeypressesToHistory();
|
||||
TestInput.pushKeypressesToHistory();
|
||||
finish(true);
|
||||
let testSeconds = TestStats.calculateTestSeconds(performance.now());
|
||||
let afkseconds = TestStats.calculateAfkSeconds(testSeconds);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import * as TestLogic from "./test-logic";
|
||||
import Config from "../config";
|
||||
import * as Misc from "../misc";
|
||||
import * as TestInput from "./test-input";
|
||||
import * as TestWords from "./test-words";
|
||||
|
||||
export let invalid = false;
|
||||
export let start, end;
|
||||
|
|
@ -9,43 +11,7 @@ export let wpmHistory = [];
|
|||
export let rawHistory = [];
|
||||
export let burstHistory = [];
|
||||
|
||||
export let keypressPerSecond = [];
|
||||
export let currentKeypress = {
|
||||
count: 0,
|
||||
errors: 0,
|
||||
words: [],
|
||||
afk: true,
|
||||
};
|
||||
export let lastKeypress;
|
||||
export let currentBurstStart = 0;
|
||||
|
||||
// export let errorsPerSecond = [];
|
||||
// export let currentError = {
|
||||
// count: 0,
|
||||
// words: [],
|
||||
// };
|
||||
export let lastSecondNotRound = false;
|
||||
export let missedWords = {};
|
||||
export let accuracy = {
|
||||
correct: 0,
|
||||
incorrect: 0,
|
||||
};
|
||||
export let keypressTimings = {
|
||||
spacing: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
duration: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
};
|
||||
|
||||
export let spacingDebug = false;
|
||||
export function enableSpacingDebug() {
|
||||
spacingDebug = true;
|
||||
console.clear();
|
||||
}
|
||||
|
||||
export function getStats() {
|
||||
let ret = {
|
||||
|
|
@ -54,23 +20,23 @@ export function getStats() {
|
|||
wpmHistory,
|
||||
rawHistory,
|
||||
burstHistory,
|
||||
keypressPerSecond,
|
||||
currentKeypress,
|
||||
lastKeypress,
|
||||
currentBurstStart,
|
||||
keypressPerSecond: TestInput.keypressPerSecond,
|
||||
currentKeypress: TestInput.currentKeypress,
|
||||
lastKeypress: TestInput.lastKeypress,
|
||||
currentBurstStart: TestInput.currentBurstStart,
|
||||
lastSecondNotRound,
|
||||
missedWords,
|
||||
accuracy,
|
||||
keypressTimings,
|
||||
missedWords: TestInput.missedWords,
|
||||
accuracy: TestInput.accuracy,
|
||||
keypressTimings: TestInput.keypressTimings,
|
||||
};
|
||||
|
||||
try {
|
||||
ret.keySpacingStats = {
|
||||
average:
|
||||
keypressTimings.spacing.array.reduce(
|
||||
TestInput.keypressTimings.spacing.array.reduce(
|
||||
(previous, current) => (current += previous)
|
||||
) / keypressTimings.spacing.array.length,
|
||||
sd: Misc.stdDev(keypressTimings.spacing.array),
|
||||
) / TestInput.keypressTimings.spacing.array.length,
|
||||
sd: Misc.stdDev(TestInput.keypressTimings.spacing.array),
|
||||
};
|
||||
} catch (e) {
|
||||
//
|
||||
|
|
@ -78,10 +44,10 @@ export function getStats() {
|
|||
try {
|
||||
ret.keyDurationStats = {
|
||||
average:
|
||||
keypressTimings.duration.array.reduce(
|
||||
TestInput.keypressTimings.duration.array.reduce(
|
||||
(previous, current) => (current += previous)
|
||||
) / keypressTimings.duration.array.length,
|
||||
sd: Misc.stdDev(keypressTimings.duration.array),
|
||||
) / TestInput.keypressTimings.duration.array.length,
|
||||
sd: Misc.stdDev(TestInput.keypressTimings.duration.array),
|
||||
};
|
||||
} catch (e) {
|
||||
//
|
||||
|
|
@ -97,35 +63,7 @@ export function restart() {
|
|||
wpmHistory = [];
|
||||
rawHistory = [];
|
||||
burstHistory = [];
|
||||
keypressPerSecond = [];
|
||||
currentKeypress = {
|
||||
count: 0,
|
||||
errors: 0,
|
||||
words: [],
|
||||
afk: true,
|
||||
};
|
||||
currentBurstStart = 0;
|
||||
// errorsPerSecond = [];
|
||||
// currentError = {
|
||||
// count: 0,
|
||||
// words: [],
|
||||
// };
|
||||
lastSecondNotRound = false;
|
||||
missedWords = {};
|
||||
accuracy = {
|
||||
correct: 0,
|
||||
incorrect: 0,
|
||||
};
|
||||
keypressTimings = {
|
||||
spacing: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
duration: {
|
||||
current: -1,
|
||||
array: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export let restartCount = 0;
|
||||
|
|
@ -150,9 +88,9 @@ export function setInvalid() {
|
|||
|
||||
export function calculateTestSeconds(now) {
|
||||
if (now === undefined) {
|
||||
let endAfkSeconds = (end - lastKeypress) / 1000;
|
||||
let endAfkSeconds = (end - TestInput.lastKeypress) / 1000;
|
||||
if ((Config.mode == "zen" || TestLogic.bailout) && endAfkSeconds < 7) {
|
||||
return (lastKeypress - start) / 1000;
|
||||
return (TestInput.lastKeypress - start) / 1000;
|
||||
} else {
|
||||
return (end - start) / 1000;
|
||||
}
|
||||
|
|
@ -171,10 +109,6 @@ export function setStart(s) {
|
|||
start2 = Date.now();
|
||||
}
|
||||
|
||||
export function updateLastKeypress() {
|
||||
lastKeypress = performance.now();
|
||||
}
|
||||
|
||||
export function pushToWpmHistory(word) {
|
||||
wpmHistory.push(word);
|
||||
}
|
||||
|
|
@ -183,39 +117,13 @@ export function pushToRawHistory(word) {
|
|||
rawHistory.push(word);
|
||||
}
|
||||
|
||||
export function incrementKeypressCount() {
|
||||
currentKeypress.count++;
|
||||
}
|
||||
|
||||
export function setKeypressNotAfk() {
|
||||
currentKeypress.afk = false;
|
||||
}
|
||||
|
||||
export function incrementKeypressErrors() {
|
||||
currentKeypress.errors++;
|
||||
}
|
||||
|
||||
export function pushKeypressWord(word) {
|
||||
currentKeypress.words.push(word);
|
||||
}
|
||||
|
||||
export function pushKeypressesToHistory() {
|
||||
keypressPerSecond.push(currentKeypress);
|
||||
currentKeypress = {
|
||||
count: 0,
|
||||
errors: 0,
|
||||
words: [],
|
||||
afk: true,
|
||||
};
|
||||
}
|
||||
|
||||
export function calculateAfkSeconds(testSeconds) {
|
||||
let extraAfk = 0;
|
||||
if (testSeconds !== undefined) {
|
||||
if (Config.mode === "time") {
|
||||
extraAfk = Math.round(testSeconds) - keypressPerSecond.length;
|
||||
extraAfk = Math.round(testSeconds) - TestInput.keypressPerSecond.length;
|
||||
} else {
|
||||
extraAfk = Math.ceil(testSeconds) - keypressPerSecond.length;
|
||||
extraAfk = Math.ceil(testSeconds) - TestInput.keypressPerSecond.length;
|
||||
}
|
||||
if (extraAfk < 0) extraAfk = 0;
|
||||
// console.log("-- extra afk debug");
|
||||
|
|
@ -225,7 +133,7 @@ export function calculateAfkSeconds(testSeconds) {
|
|||
// `gonna add extra ${extraAfk} seconds of afk because of no keypress data`
|
||||
// );
|
||||
}
|
||||
let ret = keypressPerSecond.filter((x) => x.afk).length;
|
||||
let ret = TestInput.keypressPerSecond.filter((x) => x.afk).length;
|
||||
return ret + extraAfk;
|
||||
}
|
||||
|
||||
|
|
@ -233,127 +141,43 @@ export function setLastSecondNotRound() {
|
|||
lastSecondNotRound = true;
|
||||
}
|
||||
|
||||
export function setBurstStart(time) {
|
||||
currentBurstStart = time;
|
||||
}
|
||||
|
||||
export function calculateBurst() {
|
||||
let timeToWrite = (performance.now() - currentBurstStart) / 1000;
|
||||
let timeToWrite = (performance.now() - TestInput.currentBurstStart) / 1000;
|
||||
let wordLength;
|
||||
if (Config.mode === "zen") {
|
||||
wordLength = TestLogic.input.current.length;
|
||||
wordLength = TestInput.input.current.length;
|
||||
if (wordLength == 0) {
|
||||
wordLength = TestLogic.input.getHistoryLast().length;
|
||||
wordLength = TestInput.input.getHistoryLast().length;
|
||||
}
|
||||
} else {
|
||||
wordLength = TestLogic.words.getCurrent().length;
|
||||
wordLength = TestWords.words.getCurrent().length;
|
||||
}
|
||||
let speed = Misc.roundTo2((wordLength * (60 / timeToWrite)) / 5);
|
||||
return Math.round(speed);
|
||||
}
|
||||
|
||||
export function pushBurstToHistory(speed) {
|
||||
if (burstHistory[TestLogic.words.currentIndex] === undefined) {
|
||||
if (burstHistory[TestWords.words.currentIndex] === undefined) {
|
||||
burstHistory.push(speed);
|
||||
} else {
|
||||
//repeated word - override
|
||||
burstHistory[TestLogic.words.currentIndex] = speed;
|
||||
burstHistory[TestWords.words.currentIndex] = speed;
|
||||
}
|
||||
}
|
||||
|
||||
export function calculateAccuracy() {
|
||||
let acc = (accuracy.correct / (accuracy.correct + accuracy.incorrect)) * 100;
|
||||
let acc =
|
||||
(TestInput.accuracy.correct /
|
||||
(TestInput.accuracy.correct + TestInput.accuracy.incorrect)) *
|
||||
100;
|
||||
return isNaN(acc) ? 100 : acc;
|
||||
}
|
||||
|
||||
export function incrementAccuracy(correctincorrect) {
|
||||
if (correctincorrect) {
|
||||
accuracy.correct++;
|
||||
} else {
|
||||
accuracy.incorrect++;
|
||||
}
|
||||
}
|
||||
|
||||
export function setKeypressTimingsTooLong() {
|
||||
keypressTimings.spacing.array = "toolong";
|
||||
keypressTimings.duration.array = "toolong";
|
||||
}
|
||||
|
||||
export function pushKeypressDuration(val) {
|
||||
keypressTimings.duration.array.push(val);
|
||||
}
|
||||
|
||||
export function setKeypressDuration(val) {
|
||||
keypressTimings.duration.current = val;
|
||||
}
|
||||
|
||||
export function pushKeypressSpacing(val) {
|
||||
keypressTimings.spacing.array.push(val);
|
||||
}
|
||||
|
||||
export function setKeypressSpacing(val) {
|
||||
keypressTimings.spacing.current = val;
|
||||
}
|
||||
|
||||
export function recordKeypressSpacing() {
|
||||
let now = performance.now();
|
||||
let diff = Math.abs(keypressTimings.spacing.current - now);
|
||||
if (keypressTimings.spacing.current !== -1) {
|
||||
pushKeypressSpacing(diff);
|
||||
if (spacingDebug)
|
||||
console.log(
|
||||
"spacing debug",
|
||||
"push",
|
||||
diff,
|
||||
"length",
|
||||
keypressTimings.spacing.array.length
|
||||
);
|
||||
}
|
||||
setKeypressSpacing(now);
|
||||
if (spacingDebug)
|
||||
console.log(
|
||||
"spacing debug",
|
||||
"set",
|
||||
now,
|
||||
"length",
|
||||
keypressTimings.spacing.array.length
|
||||
);
|
||||
if (spacingDebug)
|
||||
console.log(
|
||||
"spacing debug",
|
||||
"recorded",
|
||||
"length",
|
||||
keypressTimings.spacing.array.length
|
||||
);
|
||||
}
|
||||
|
||||
export function resetKeypressTimings() {
|
||||
keypressTimings = {
|
||||
spacing: {
|
||||
current: performance.now(),
|
||||
array: [],
|
||||
},
|
||||
duration: {
|
||||
current: performance.now(),
|
||||
array: [],
|
||||
},
|
||||
};
|
||||
if (spacingDebug) console.clear();
|
||||
}
|
||||
|
||||
export function pushMissedWord(word) {
|
||||
if (!Object.keys(missedWords).includes(word)) {
|
||||
missedWords[word] = 1;
|
||||
} else {
|
||||
missedWords[word]++;
|
||||
}
|
||||
}
|
||||
|
||||
export function removeAfkData() {
|
||||
let testSeconds = calculateTestSeconds();
|
||||
keypressPerSecond.splice(testSeconds);
|
||||
keypressTimings.duration.array.splice(testSeconds);
|
||||
keypressTimings.spacing.array.splice(testSeconds);
|
||||
TestInput.keypressPerSecond.splice(testSeconds);
|
||||
TestInput.keypressTimings.duration.array.splice(testSeconds);
|
||||
TestInput.keypressTimings.spacing.array.splice(testSeconds);
|
||||
wpmHistory.splice(testSeconds);
|
||||
}
|
||||
|
||||
|
|
@ -365,31 +189,31 @@ function countChars() {
|
|||
let missedChars = 0;
|
||||
let spaces = 0;
|
||||
let correctspaces = 0;
|
||||
for (let i = 0; i < TestLogic.input.history.length; i++) {
|
||||
for (let i = 0; i < TestInput.input.history.length; i++) {
|
||||
let word =
|
||||
Config.mode == "zen"
|
||||
? TestLogic.input.getHistory(i)
|
||||
: TestLogic.words.get(i);
|
||||
if (TestLogic.input.getHistory(i) === "") {
|
||||
? TestInput.input.getHistory(i)
|
||||
: TestWords.words.get(i);
|
||||
if (TestInput.input.getHistory(i) === "") {
|
||||
//last word that was not started
|
||||
continue;
|
||||
}
|
||||
if (TestLogic.input.getHistory(i) == word) {
|
||||
if (TestInput.input.getHistory(i) == word) {
|
||||
//the word is correct
|
||||
correctWordChars += word.length;
|
||||
correctChars += word.length;
|
||||
if (
|
||||
i < TestLogic.input.history.length - 1 &&
|
||||
Misc.getLastChar(TestLogic.input.getHistory(i)) !== "\n"
|
||||
i < TestInput.input.history.length - 1 &&
|
||||
Misc.getLastChar(TestInput.input.getHistory(i)) !== "\n"
|
||||
) {
|
||||
correctspaces++;
|
||||
}
|
||||
} else if (TestLogic.input.getHistory(i).length >= word.length) {
|
||||
} else if (TestInput.input.getHistory(i).length >= word.length) {
|
||||
//too many chars
|
||||
for (let c = 0; c < TestLogic.input.getHistory(i).length; c++) {
|
||||
for (let c = 0; c < TestInput.input.getHistory(i).length; c++) {
|
||||
if (c < word.length) {
|
||||
//on char that still has a word list pair
|
||||
if (TestLogic.input.getHistory(i)[c] == word[c]) {
|
||||
if (TestInput.input.getHistory(i)[c] == word[c]) {
|
||||
correctChars++;
|
||||
} else {
|
||||
incorrectChars++;
|
||||
|
|
@ -407,9 +231,9 @@ function countChars() {
|
|||
missed: 0,
|
||||
};
|
||||
for (let c = 0; c < word.length; c++) {
|
||||
if (c < TestLogic.input.getHistory(i).length) {
|
||||
if (c < TestInput.input.getHistory(i).length) {
|
||||
//on char that still has a word list pair
|
||||
if (TestLogic.input.getHistory(i)[c] == word[c]) {
|
||||
if (TestInput.input.getHistory(i)[c] == word[c]) {
|
||||
toAdd.correct++;
|
||||
} else {
|
||||
toAdd.incorrect++;
|
||||
|
|
@ -421,14 +245,14 @@ function countChars() {
|
|||
}
|
||||
correctChars += toAdd.correct;
|
||||
incorrectChars += toAdd.incorrect;
|
||||
if (i === TestLogic.input.history.length - 1 && Config.mode == "time") {
|
||||
if (i === TestInput.input.history.length - 1 && Config.mode == "time") {
|
||||
//last word - check if it was all correct - add to correct word chars
|
||||
if (toAdd.incorrect === 0) correctWordChars += toAdd.correct;
|
||||
} else {
|
||||
missedChars += toAdd.missed;
|
||||
}
|
||||
}
|
||||
if (i < TestLogic.input.history.length - 1) {
|
||||
if (i < TestInput.input.history.length - 1) {
|
||||
spaces++;
|
||||
}
|
||||
}
|
||||
|
|
@ -440,7 +264,8 @@ function countChars() {
|
|||
spaces: spaces,
|
||||
correctWordChars: correctWordChars,
|
||||
allCorrectChars: correctChars,
|
||||
incorrectChars: Config.mode == "zen" ? accuracy.incorrect : incorrectChars,
|
||||
incorrectChars:
|
||||
Config.mode == "zen" ? TestInput.accuracy.incorrect : incorrectChars,
|
||||
extraChars: extraChars,
|
||||
missedChars: missedChars,
|
||||
correctSpaces: correctspaces,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ import * as CustomText from "./custom-text";
|
|||
import * as TimerProgress from "./timer-progress";
|
||||
import * as LiveWpm from "./live-wpm";
|
||||
import * as TestStats from "./test-stats";
|
||||
import * as TestInput from "./test-input";
|
||||
import * as TestWords from "./test-words";
|
||||
|
||||
import * as Monkey from "./monkey";
|
||||
import * as Misc from "../misc";
|
||||
import * as Notifications from "../elements/notifications";
|
||||
|
|
@ -116,11 +119,11 @@ function layoutfluid() {
|
|||
|
||||
function checkIfFailed(wpmAndRaw, acc) {
|
||||
if (timerDebug) console.time("fail conditions");
|
||||
TestStats.pushKeypressesToHistory();
|
||||
TestInput.pushKeypressesToHistory();
|
||||
if (
|
||||
Config.minWpm === "custom" &&
|
||||
wpmAndRaw.wpm < parseInt(Config.minWpmCustomSpeed) &&
|
||||
TestLogic.words.currentIndex > 3
|
||||
TestWords.words.currentIndex > 3
|
||||
) {
|
||||
clearTimeout(timer);
|
||||
TestLogic.fail("min wpm");
|
||||
|
|
@ -131,7 +134,7 @@ function checkIfFailed(wpmAndRaw, acc) {
|
|||
if (
|
||||
Config.minAcc === "custom" &&
|
||||
acc < parseInt(Config.minAccCustom) &&
|
||||
TestLogic.words.currentIndex > 3
|
||||
TestWords.words.currentIndex > 3
|
||||
) {
|
||||
clearTimeout(timer);
|
||||
TestLogic.fail("min accuracy");
|
||||
|
|
@ -157,8 +160,8 @@ function checkIfTimeIsUp() {
|
|||
//times up
|
||||
clearTimeout(timer);
|
||||
Caret.hide();
|
||||
TestLogic.input.pushHistory();
|
||||
TestLogic.corrected.pushHistory();
|
||||
TestInput.input.pushHistory();
|
||||
TestInput.corrected.pushHistory();
|
||||
TestLogic.finish();
|
||||
SlowTimer.clear();
|
||||
slowTimerCount = 0;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import * as ThemeColors from "../elements/theme-colors";
|
|||
import Config, * as UpdateConfig from "../config";
|
||||
import * as DB from "../db";
|
||||
import * as TestLogic from "./test-logic";
|
||||
import * as TestWords from "./test-words";
|
||||
import * as TestInput from "./test-input";
|
||||
import * as Funbox from "./funbox";
|
||||
import * as PaceCaret from "./pace-caret";
|
||||
import * as CustomText from "./custom-text";
|
||||
|
|
@ -159,8 +161,8 @@ export function showWords() {
|
|||
|
||||
let wordsHTML = "";
|
||||
if (Config.mode !== "zen") {
|
||||
for (let i = 0; i < TestLogic.words.length; i++) {
|
||||
wordsHTML += getWordHTML(TestLogic.words.get(i));
|
||||
for (let i = 0; i < TestWords.words.length; i++) {
|
||||
wordsHTML += getWordHTML(TestWords.words.get(i));
|
||||
}
|
||||
} else {
|
||||
wordsHTML =
|
||||
|
|
@ -204,11 +206,11 @@ export function showWords() {
|
|||
} else {
|
||||
if (Config.keymapMode === "next") {
|
||||
Keymap.highlightKey(
|
||||
TestLogic.words
|
||||
TestWords.words
|
||||
.getCurrent()
|
||||
.substring(
|
||||
TestLogic.input.current.length,
|
||||
TestLogic.input.current.length + 1
|
||||
TestInput.input.current.length,
|
||||
TestInput.input.current.length + 1
|
||||
)
|
||||
.toString()
|
||||
.toUpperCase()
|
||||
|
|
@ -217,7 +219,7 @@ export function showWords() {
|
|||
}
|
||||
|
||||
updateActiveElement();
|
||||
Funbox.toggleScript(TestLogic.words.getCurrent());
|
||||
Funbox.toggleScript(TestWords.words.getCurrent());
|
||||
|
||||
Caret.updatePosition();
|
||||
}
|
||||
|
|
@ -334,11 +336,11 @@ export async function screenshot() {
|
|||
}
|
||||
|
||||
export function updateWordElement(showError = !Config.blindMode) {
|
||||
let input = TestLogic.input.current;
|
||||
let input = TestInput.input.current;
|
||||
let wordAtIndex;
|
||||
let currentWord;
|
||||
wordAtIndex = document.querySelector("#words .word.active");
|
||||
currentWord = TestLogic.words.getCurrent();
|
||||
currentWord = TestWords.words.getCurrent();
|
||||
if (!currentWord) return;
|
||||
|
||||
let ret = "";
|
||||
|
|
@ -346,14 +348,14 @@ export function updateWordElement(showError = !Config.blindMode) {
|
|||
let newlineafter = false;
|
||||
|
||||
if (Config.mode === "zen") {
|
||||
for (let i = 0; i < TestLogic.input.current.length; i++) {
|
||||
if (TestLogic.input.current[i] === "\t") {
|
||||
for (let i = 0; i < TestInput.input.current.length; i++) {
|
||||
if (TestInput.input.current[i] === "\t") {
|
||||
ret += `<letter class='tabChar correct' style="opacity: 0"><i class="fas fa-long-arrow-alt-right"></i></letter>`;
|
||||
} else if (TestLogic.input.current[i] === "\n") {
|
||||
} else if (TestInput.input.current[i] === "\n") {
|
||||
newlineafter = true;
|
||||
ret += `<letter class='nlChar correct' style="opacity: 0"><i class="fas fa-angle-down"></i></letter>`;
|
||||
} else {
|
||||
ret += `<letter class="correct">${TestLogic.input.current[i]}</letter>`;
|
||||
ret += `<letter class="correct">${TestInput.input.current[i]}</letter>`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -578,7 +580,7 @@ export function updateModesNotice() {
|
|||
);
|
||||
}
|
||||
|
||||
if (TestLogic.hasTab) {
|
||||
if (TestWords.hasTab) {
|
||||
$(".pageTest #testModesNotice").append(
|
||||
`<div class="text-button"><i class="fas fa-long-arrow-alt-right"></i>shift + tab to restart</div>`
|
||||
);
|
||||
|
|
@ -765,19 +767,19 @@ export function arrangeCharactersLeftToRight() {
|
|||
async function loadWordsHistory() {
|
||||
$("#resultWordsHistory .words").empty();
|
||||
let wordsHTML = "";
|
||||
for (let i = 0; i < TestLogic.input.history.length + 2; i++) {
|
||||
let input = TestLogic.input.getHistory(i);
|
||||
let word = TestLogic.words.get(i);
|
||||
for (let i = 0; i < TestInput.input.history.length + 2; i++) {
|
||||
let input = TestInput.input.getHistory(i);
|
||||
let word = TestWords.words.get(i);
|
||||
let wordEl = "";
|
||||
try {
|
||||
if (input === "") throw new Error("empty input word");
|
||||
if (
|
||||
TestLogic.corrected.getHistory(i) !== undefined &&
|
||||
TestLogic.corrected.getHistory(i) !== ""
|
||||
TestInput.corrected.getHistory(i) !== undefined &&
|
||||
TestInput.corrected.getHistory(i) !== ""
|
||||
) {
|
||||
wordEl = `<div class='word' burst="${
|
||||
TestStats.burstHistory[i]
|
||||
}" input="${TestLogic.corrected
|
||||
}" input="${TestInput.corrected
|
||||
.getHistory(i)
|
||||
.replace(/"/g, """)
|
||||
.replace(/ /g, "_")}">`;
|
||||
|
|
@ -786,7 +788,7 @@ async function loadWordsHistory() {
|
|||
TestStats.burstHistory[i]
|
||||
}" input="${input.replace(/"/g, """).replace(/ /g, "_")}">`;
|
||||
}
|
||||
if (i === TestLogic.input.history.length - 1) {
|
||||
if (i === TestInput.input.history.length - 1) {
|
||||
//last word
|
||||
let wordstats = {
|
||||
correct: 0,
|
||||
|
|
@ -834,15 +836,15 @@ async function loadWordsHistory() {
|
|||
for (let c = 0; c < loop; c++) {
|
||||
let correctedChar;
|
||||
try {
|
||||
correctedChar = TestLogic.corrected.getHistory(i)[c];
|
||||
correctedChar = TestInput.corrected.getHistory(i)[c];
|
||||
} catch (e) {
|
||||
correctedChar = undefined;
|
||||
}
|
||||
let extraCorrected = "";
|
||||
if (
|
||||
c + 1 === loop &&
|
||||
TestLogic.corrected.getHistory(i) !== undefined &&
|
||||
TestLogic.corrected.getHistory(i).length > input.length
|
||||
TestInput.corrected.getHistory(i) !== undefined &&
|
||||
TestInput.corrected.getHistory(i).length > input.length
|
||||
) {
|
||||
extraCorrected = "extraCorrected";
|
||||
}
|
||||
|
|
@ -857,7 +859,7 @@ async function loadWordsHistory() {
|
|||
"</letter>";
|
||||
}
|
||||
} else {
|
||||
if (input[c] === TestLogic.input.current) {
|
||||
if (input[c] === TestInput.input.current) {
|
||||
wordEl +=
|
||||
`<letter class='correct ${extraCorrected}'>` +
|
||||
word[c] +
|
||||
|
|
@ -943,8 +945,8 @@ export function applyBurstHeatmap() {
|
|||
burstlist = burstlist.filter((x) => x < 350);
|
||||
|
||||
if (
|
||||
TestLogic.input.getHistory(TestLogic.input.getHistory().length - 1)
|
||||
.length !== TestLogic.words.getCurrent()?.length
|
||||
TestInput.input.getHistory(TestInput.input.getHistory().length - 1)
|
||||
.length !== TestWords.words.getCurrent()?.length
|
||||
) {
|
||||
burstlist = burstlist.splice(0, burstlist.length - 1);
|
||||
}
|
||||
|
|
@ -1016,11 +1018,11 @@ $(".pageTest #copyWordsListButton").click(async (event) => {
|
|||
try {
|
||||
let words;
|
||||
if (Config.mode == "zen") {
|
||||
words = TestLogic.input.history.join(" ");
|
||||
words = TestInput.input.history.join(" ");
|
||||
} else {
|
||||
words = TestLogic.words
|
||||
words = TestWords.words
|
||||
.get()
|
||||
.slice(0, TestLogic.input.history.length)
|
||||
.slice(0, TestInput.input.history.length)
|
||||
.join(" ");
|
||||
}
|
||||
await navigator.clipboard.writeText(words);
|
||||
|
|
@ -1031,12 +1033,12 @@ $(".pageTest #copyWordsListButton").click(async (event) => {
|
|||
});
|
||||
|
||||
$(".pageTest #rateQuoteButton").click(async (event) => {
|
||||
QuoteRatePopup.show(TestLogic.randomQuote);
|
||||
QuoteRatePopup.show(TestWords.randomQuote);
|
||||
});
|
||||
|
||||
$(".pageTest #reportQuoteButton").click(async (event) => {
|
||||
ReportQuotePopup.show({
|
||||
quoteId: parseInt(TestLogic.randomQuote.id),
|
||||
quoteId: parseInt(TestWords.randomQuote.id),
|
||||
noAnim: false,
|
||||
});
|
||||
});
|
||||
|
|
@ -1102,7 +1104,7 @@ $("#wordsInput").on("focus", () => {
|
|||
if (!resultVisible && Config.showOutOfFocusWarning) {
|
||||
OutOfFocus.hide();
|
||||
}
|
||||
Caret.show(TestLogic.input.current);
|
||||
Caret.show(TestInput.input.current);
|
||||
});
|
||||
|
||||
$("#wordsInput").on("focusout", () => {
|
||||
|
|
|
|||
65
frontend/src/js/test/test-words.js
Normal file
65
frontend/src/js/test/test-words.js
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
class Words {
|
||||
constructor() {
|
||||
this.list = [];
|
||||
this.length = 0;
|
||||
this.currentIndex = 0;
|
||||
}
|
||||
get(i, raw = false) {
|
||||
if (i === undefined) {
|
||||
return this.list;
|
||||
} else {
|
||||
if (raw) {
|
||||
return this.list[i]?.replace(/[.?!":\-,]/g, "")?.toLowerCase();
|
||||
} else {
|
||||
return this.list[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
getCurrent() {
|
||||
return this.list[this.currentIndex];
|
||||
}
|
||||
getLast() {
|
||||
return this.list[this.list.length - 1];
|
||||
}
|
||||
push(word) {
|
||||
this.list.push(word);
|
||||
this.length = this.list.length;
|
||||
}
|
||||
reset() {
|
||||
this.list = [];
|
||||
this.currentIndex = 0;
|
||||
this.length = this.list.length;
|
||||
}
|
||||
resetCurrentIndex() {
|
||||
this.currentIndex = 0;
|
||||
}
|
||||
decreaseCurrentIndex() {
|
||||
this.currentIndex--;
|
||||
}
|
||||
increaseCurrentIndex() {
|
||||
this.currentIndex++;
|
||||
}
|
||||
clean() {
|
||||
for (let s of this.list) {
|
||||
if (/ +/.test(s)) {
|
||||
let id = this.list.indexOf(s);
|
||||
let tempList = s.split(" ");
|
||||
this.list.splice(id, 1);
|
||||
for (let i = 0; i < tempList.length; i++) {
|
||||
this.list.splice(id + i, 0, tempList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export let words = new Words();
|
||||
export let hasTab = false;
|
||||
export let randomQuote = null;
|
||||
|
||||
export function setRandomQuote(rq) {
|
||||
randomQuote = rq;
|
||||
}
|
||||
|
||||
export function setHasTab(tf) {
|
||||
hasTab = tf;
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
import Config, * as UpdateConfig from "../config";
|
||||
import * as CustomText from "./custom-text";
|
||||
import * as Misc from "../misc";
|
||||
import * as TestLogic from "./test-logic";
|
||||
import * as TestWords from "./test-words";
|
||||
import * as TestInput from "./test-input";
|
||||
import * as TestTimer from "./test-timer";
|
||||
import * as SlowTimer from "../states/slow-timer";
|
||||
import * as TestActive from "./../states/test-active";
|
||||
|
|
@ -131,7 +132,7 @@ export function update() {
|
|||
Config.mode === "custom" ||
|
||||
Config.mode === "quote"
|
||||
) {
|
||||
let outof = TestLogic.words.length;
|
||||
let outof = TestWords.words.length;
|
||||
if (Config.mode === "words") {
|
||||
outof = Config.words;
|
||||
}
|
||||
|
|
@ -143,11 +144,11 @@ export function update() {
|
|||
}
|
||||
}
|
||||
if (Config.mode === "quote") {
|
||||
outof = TestLogic?.randomQuote?.textSplit?.length ?? 1;
|
||||
outof = TestWords.randomQuote?.textSplit?.length ?? 1;
|
||||
}
|
||||
if (Config.timerStyle === "bar") {
|
||||
let percent = Math.floor(
|
||||
((TestLogic.words.currentIndex + 1) / outof) * 100
|
||||
((TestWords.words.currentIndex + 1) / outof) * 100
|
||||
);
|
||||
$("#timer")
|
||||
.stop(true, true)
|
||||
|
|
@ -160,24 +161,24 @@ export function update() {
|
|||
} else if (Config.timerStyle === "text") {
|
||||
if (outof === 0) {
|
||||
timerNumberElement.innerHTML =
|
||||
"<div>" + `${TestLogic.input.history.length}` + "</div>";
|
||||
"<div>" + `${TestInput.input.history.length}` + "</div>";
|
||||
} else {
|
||||
timerNumberElement.innerHTML =
|
||||
"<div>" + `${TestLogic.input.history.length}/${outof}` + "</div>";
|
||||
"<div>" + `${TestInput.input.history.length}/${outof}` + "</div>";
|
||||
}
|
||||
} else if (Config.timerStyle === "mini") {
|
||||
if (Config.words === 0) {
|
||||
miniTimerNumberElement.innerHTML = `${TestLogic.input.history.length}`;
|
||||
miniTimerNumberElement.innerHTML = `${TestInput.input.history.length}`;
|
||||
} else {
|
||||
miniTimerNumberElement.innerHTML = `${TestLogic.input.history.length}/${outof}`;
|
||||
miniTimerNumberElement.innerHTML = `${TestInput.input.history.length}/${outof}`;
|
||||
}
|
||||
}
|
||||
} else if (Config.mode == "zen") {
|
||||
if (Config.timerStyle === "text") {
|
||||
timerNumberElement.innerHTML =
|
||||
"<div>" + `${TestLogic.input.history.length}` + "</div>";
|
||||
"<div>" + `${TestInput.input.history.length}` + "</div>";
|
||||
} else {
|
||||
miniTimerNumberElement.innerHTML = `${TestLogic.input.history.length}`;
|
||||
miniTimerNumberElement.innerHTML = `${TestInput.input.history.length}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import * as TestStats from "./test-stats";
|
||||
import * as TestInput from "./test-input";
|
||||
|
||||
// Changes how quickly it 'learns' scores - very roughly the score for a char
|
||||
// is based on last perCharCount occurrences. Make it smaller to adjust faster.
|
||||
|
|
@ -30,7 +30,7 @@ class Score {
|
|||
}
|
||||
|
||||
export function updateScore(char, isCorrect) {
|
||||
const timings = TestStats.keypressTimings.spacing.array;
|
||||
const timings = TestInput.keypressTimings.spacing.array;
|
||||
if (timings.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue