diff --git a/gulpfile.js b/gulpfile.js
index 89321cc93..377c6184a 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -105,6 +105,7 @@ const refactoredSrc = [
"./src/js/account-controller.js",
"./src/js/simple-popups.js",
"./src/js/settings.js",
+ "./src/js/input-controller.js",
"./src/js/account/all-time-stats.js",
"./src/js/account/pb-tables.js",
diff --git a/src/js/global-dependencies.js b/src/js/global-dependencies.js
index 78a62abef..5ea92ce16 100644
--- a/src/js/global-dependencies.js
+++ b/src/js/global-dependencies.js
@@ -55,3 +55,4 @@ import * as AllTimeStats from "./all-time-stats";
import * as PbTables from "./pb-tables";
import * as Account from "./account";
import * as VerificationController from "./verification-controller";
+import "./input-controller";
diff --git a/src/js/input-controller.js b/src/js/input-controller.js
new file mode 100644
index 000000000..6ad7a1f9b
--- /dev/null
+++ b/src/js/input-controller.js
@@ -0,0 +1,808 @@
+import * as TestLogic from "./test-logic";
+import * as TestUI from "./test-ui";
+import * as TestStats from "./test-stats";
+import * as Monkey from "./monkey";
+import Config, * as UpdateConfig from "./config";
+import * as Keymap from "./keymap";
+import * as Misc from "./misc";
+import * as LiveAcc from "./live-acc";
+import * as Funbox from "./funbox";
+import * as Sound from "./sound";
+import * as Caret from "./caret";
+import * as ManualRestart from "./manual-restart-tracker";
+import * as Notifications from "./notifications";
+import * as CustomText from "./custom-text";
+import * as UI from "./ui";
+import * as Settings from "./settings";
+import * as LayoutEmulator from "./layout-emulator";
+import * as PaceCaret from "./pace-caret";
+import * as TimerProgress from "./timer-progress";
+import * as TestTimer from "./test-timer";
+import * as Focus from "./focus";
+import * as ShiftTracker from "./shift-tracker";
+
+$("#wordsInput").keypress((event) => {
+ event.preventDefault();
+});
+
+let dontInsertSpace = false;
+
+$(document).keyup((event) => {
+ if (!event.originalEvent.isTrusted) return;
+
+ if (TestUI.resultVisible) return;
+ let now = performance.now();
+ let diff = Math.abs(TestStats.keypressTimings.duration.current - now);
+ if (TestStats.keypressTimings.duration.current !== -1) {
+ TestStats.pushKeypressDuration(diff);
+ // keypressStats.duration.array.push(diff);
+ }
+ TestStats.setKeypressDuration(now);
+ // keypressStats.duration.current = now;
+ Monkey.stop();
+});
+
+$(document).keydown(function (event) {
+ if (!(event.key == " ") && !event.originalEvent.isTrusted) return;
+
+ if (!TestUI.resultVisible) {
+ TestStats.recordKeypressSpacing();
+ }
+
+ Monkey.type();
+
+ //autofocus
+ let pageTestActive = !$(".pageTest").hasClass("hidden");
+ let commandLineVisible = !$("#commandLineWrapper").hasClass("hidden");
+ let wordsFocused = $("#wordsInput").is(":focus");
+ let modePopupVisible =
+ !$("#customTextPopupWrapper").hasClass("hidden") ||
+ !$("#customWordAmountPopupWrapper").hasClass("hidden") ||
+ !$("#customTestDurationPopupWrapper").hasClass("hidden") ||
+ !$("#quoteSearchPopupWrapper").hasClass("hidden") ||
+ !$("#wordFilterPopupWrapper").hasClass("hidden");
+ if (
+ pageTestActive &&
+ !commandLineVisible &&
+ !modePopupVisible &&
+ !TestUI.resultVisible &&
+ !wordsFocused &&
+ event.key !== "Enter"
+ ) {
+ TestUI.focusWords();
+ wordsFocused = true;
+ // if (Config.showOutOfFocusWarning) return;
+ }
+
+ //tab
+ if (
+ (event.key == "Tab" && !Config.swapEscAndTab) ||
+ (event.key == "Escape" && Config.swapEscAndTab)
+ ) {
+ handleTab(event);
+ // event.preventDefault();
+ }
+
+ //blocking firefox from going back in history with backspace
+ if (event.key === "Backspace" && wordsFocused) {
+ let t = /INPUT|SELECT|TEXTAREA/i;
+ if (
+ !t.test(event.target.tagName) ||
+ event.target.disabled ||
+ event.target.readOnly
+ ) {
+ event.preventDefault();
+ }
+ }
+
+ // keypressStats.duration.current = performance.now();
+ TestStats.setKeypressDuration(performance.now());
+
+ if (TestUI.testRestarting) {
+ return;
+ }
+
+ //backspace
+ const isBackspace =
+ event.key === "Backspace" ||
+ (Config.capsLockBackspace && event.key === "CapsLock");
+ if (isBackspace && wordsFocused) {
+ handleBackspace(event);
+ }
+
+ if (event.key === "Enter" && Funbox.active === "58008" && wordsFocused) {
+ event.key = " ";
+ }
+
+ //space or enter
+ if (event.key === " " && wordsFocused) {
+ handleSpace(event, false);
+ }
+
+ if (wordsFocused && !commandLineVisible) {
+ handleAlpha(event);
+ }
+
+ let acc = Misc.roundTo2(TestStats.calculateAccuracy());
+ LiveAcc.update(acc);
+});
+
+function handleTab(event) {
+ if (TestUI.resultCalculating) {
+ event.preventDefault();
+ }
+ if ($("#customTextPopup .textarea").is(":focus")) {
+ event.preventDefault();
+
+ let area = $("#customTextPopup .textarea")[0];
+
+ var start = area.selectionStart;
+ var end = area.selectionEnd;
+
+ // set textarea value to: text before caret + tab + text after caret
+ area.value =
+ area.value.substring(0, start) + "\t" + area.value.substring(end);
+
+ // put caret at right position again
+ area.selectionStart = area.selectionEnd = start + 1;
+
+ // event.preventDefault();
+ // $("#customTextPopup .textarea").val(
+ // $("#customTextPopup .textarea").val() + "\t"
+ // );
+ return;
+ } else if (
+ $(".pageTest").hasClass("active") &&
+ !TestUI.resultCalculating &&
+ $("#commandLineWrapper").hasClass("hidden") &&
+ $("#simplePopupWrapper").hasClass("hidden")
+ ) {
+ if (Config.quickTab) {
+ if (Config.mode == "zen" && !event.shiftKey) {
+ //ignore
+ } else {
+ if (event.shiftKey) ManualRestart.set();
+
+ if (
+ TestLogic.active &&
+ Config.repeatQuotes === "typing" &&
+ Config.mode === "quote"
+ ) {
+ TestLogic.restart(true, false, event);
+ } else {
+ TestLogic.restart(false, false, event);
+ }
+ }
+ } else {
+ if (
+ !TestUI.resultVisible &&
+ ((TestLogic.hasTab && event.shiftKey) ||
+ (!TestLogic.hasTab && Config.mode !== "zen") ||
+ (Config.mode === "zen" && event.shiftKey))
+ ) {
+ event.preventDefault();
+ $("#restartTestButton").focus();
+ }
+ }
+ } else if (Config.quickTab) {
+ UI.changePage("test");
+ }
+}
+
+function handleBackspace(event) {
+ event.preventDefault();
+ if (!TestLogic.active) return;
+ if (
+ TestLogic.input.current == "" &&
+ TestLogic.input.history.length > 0 &&
+ TestUI.currentWordElementIndex > 0
+ ) {
+ //if nothing is inputted and its not the first word
+ if (
+ (TestLogic.input.getHistory(TestLogic.words.currentIndex - 1) ==
+ TestLogic.words.get(TestLogic.words.currentIndex - 1) &&
+ !Config.freedomMode) ||
+ $($(".word")[TestLogic.words.currentIndex - 1]).hasClass("hidden")
+ ) {
+ return;
+ } else {
+ if (Config.confidenceMode === "on" || Config.confidenceMode === "max")
+ return;
+ if (event["ctrlKey"] || event["altKey"]) {
+ TestLogic.input.resetCurrent();
+ TestLogic.input.popHistory();
+ TestLogic.corrected.popHistory();
+ } else {
+ TestLogic.input.setCurrent(TestLogic.input.popHistory());
+ TestLogic.corrected.setCurrent(TestLogic.corrected.popHistory());
+ if (Funbox.active === "nospace") {
+ TestLogic.input.setCurrent(
+ TestLogic.input.current.substring(
+ 0,
+ TestLogic.input.current.length - 1
+ )
+ );
+ }
+ }
+ TestLogic.words.decreaseCurrentIndex();
+ TestUI.setCurrentWordElementIndex(TestUI.currentWordElementIndex - 1);
+ TestUI.updateActiveElement(true);
+ Funbox.toggleScript(TestLogic.words.getCurrent());
+ TestUI.updateWordElement(!Config.blindMode);
+ }
+ } else {
+ if (Config.confidenceMode === "max") return;
+ if (event["ctrlKey"] || event["altKey"]) {
+ let limiter = " ";
+ if (
+ TestLogic.input.current.lastIndexOf("-") >
+ TestLogic.input.current.lastIndexOf(" ")
+ )
+ limiter = "-";
+
+ let split = TestLogic.input.current.replace(/ +/g, " ").split(limiter);
+ if (split[split.length - 1] == "") {
+ split.pop();
+ }
+ let addlimiter = false;
+ if (split.length > 1) {
+ addlimiter = true;
+ }
+ split.pop();
+ TestLogic.input.setCurrent(split.join(limiter));
+
+ if (addlimiter) {
+ TestLogic.input.appendCurrent(limiter);
+ }
+ } else if (event.metaKey) {
+ TestLogic.input.resetCurrent();
+ } else {
+ TestLogic.input.setCurrent(
+ TestLogic.input.current.substring(0, TestLogic.input.current.length - 1)
+ );
+ }
+ TestUI.updateWordElement(!Config.blindMode);
+ }
+ Sound.playClick(Config.playSoundOnClick);
+ if (Config.keymapMode === "react") {
+ Keymap.flashKey(event.code, true);
+ } else if (Config.keymapMode === "next" && Config.mode !== "zen") {
+ Keymap.highlightKey(
+ TestLogic.words
+ .getCurrent()
+ .substring(
+ TestLogic.input.current.length,
+ TestLogic.input.current.length + 1
+ )
+ .toString()
+ .toUpperCase()
+ );
+ }
+ Caret.updatePosition();
+}
+
+function handleSpace(event, isEnter) {
+ if (!TestLogic.active) return;
+ if (TestLogic.input.current === "") return;
+ // let nextWord = wordsList[TestLogic.words.currentIndex + 1];
+ // if ((isEnter && nextWord !== "\n") && (isEnter && Funbox.active !== "58008")) return;
+ // if (!isEnter && nextWord === "\n") return;
+ event.preventDefault();
+
+ if (Config.mode == "zen") {
+ $("#words .word.active").removeClass("active");
+ $("#words").append("
");
+ }
+
+ let currentWord = TestLogic.words.getCurrent();
+ if (Funbox.active === "layoutfluid" && Config.mode !== "time") {
+ const layouts = ["qwerty", "dvorak", "colemak"];
+ let index = 0;
+ let outof = TestLogic.words.length;
+ index = Math.floor((TestLogic.input.history.length + 1) / (outof / 3));
+ if (Config.layout !== layouts[index] && layouts[index] !== undefined) {
+ Notifications.add(`--- !!! ${layouts[index]} !!! ---`, 0);
+ }
+ UpdateConfig.setLayout(layouts[index]);
+ UpdateConfig.setKeymapLayout(layouts[index]);
+ Keymap.highlightKey(
+ TestLogic.words
+ .getCurrent()
+ .substring(
+ TestLogic.input.current.length,
+ TestLogic.input.current.length + 1
+ )
+ .toString()
+ .toUpperCase()
+ );
+ Settings.groups.layout.updateButton();
+ }
+ dontInsertSpace = true;
+ if (currentWord == TestLogic.input.current || Config.mode == "zen") {
+ //correct word or in zen mode
+ PaceCaret.handleSpace(true, currentWord);
+ TestStats.incrementAccuracy(true);
+ TestLogic.input.pushHistory();
+ TestLogic.words.increaseCurrentIndex();
+ TestUI.setCurrentWordElementIndex(TestUI.currentWordElementIndex + 1);
+ TestUI.updateActiveElement();
+ Funbox.toggleScript(TestLogic.words.getCurrent());
+ Caret.updatePosition();
+ TestStats.incrementKeypressCount();
+ TestStats.pushKeypressWord(TestLogic.words.currentIndex);
+ // currentKeypress.count++;
+ // currentKeypress.words.push(TestLogic.words.currentIndex);
+ if (Funbox.active !== "nospace") {
+ Sound.playClick(Config.playSoundOnClick);
+ }
+ } else {
+ //incorrect word
+ PaceCaret.handleSpace(false, currentWord);
+ if (Funbox.active !== "nospace") {
+ if (!Config.playSoundOnError || Config.blindMode) {
+ Sound.playClick(Config.playSoundOnClick);
+ } else {
+ Sound.playError(Config.playSoundOnError);
+ }
+ }
+ TestStats.incrementAccuracy(false);
+ TestStats.incrementKeypressErrors();
+ let cil = TestLogic.input.current.length;
+ if (cil <= TestLogic.words.getCurrent().length) {
+ if (cil >= TestLogic.corrected.current.length) {
+ TestLogic.corrected.appendCurrent("_");
+ } else {
+ TestLogic.corrected.setCurrent(
+ TestLogic.corrected.current.substring(0, cil) +
+ "_" +
+ TestLogic.corrected.current.substring(cil + 1)
+ );
+ }
+ }
+ if (Config.stopOnError != "off") {
+ if (Config.difficulty == "expert" || Config.difficulty == "master") {
+ //failed due to diff when pressing space
+ TestLogic.fail();
+ return;
+ }
+ if (Config.stopOnError == "word") {
+ TestLogic.input.appendCurrent(" ");
+ TestUI.updateWordElement(true);
+ Caret.updatePosition();
+ }
+ return;
+ }
+ if (Config.blindMode) $("#words .word.active letter").addClass("correct");
+ TestLogic.input.pushHistory();
+ TestUI.highlightBadWord(TestUI.currentWordElementIndex, !Config.blindMode);
+ TestLogic.words.increaseCurrentIndex();
+ TestUI.setCurrentWordElementIndex(TestUI.currentWordElementIndex + 1);
+ TestUI.updateActiveElement();
+ Funbox.toggleScript(TestLogic.words.getCurrent());
+ Caret.updatePosition();
+ // currentKeypress.count++;
+ // currentKeypress.words.push(TestLogic.words.currentIndex);
+ TestStats.incrementKeypressCount();
+ TestStats.pushKeypressWord(TestLogic.words.currentIndex);
+ if (Config.difficulty == "expert" || Config.difficulty == "master") {
+ TestLogic.fail();
+ return;
+ } else if (TestLogic.words.currentIndex == TestLogic.words.length) {
+ //submitted last word that is incorrect
+ TestStats.setLastSecondNotRound();
+ TestLogic.finish();
+ return;
+ }
+ }
+
+ TestLogic.corrected.pushHistory();
+
+ if (
+ !Config.showAllLines ||
+ Config.mode == "time" ||
+ (CustomText.isWordRandom && CustomText.word == 0) ||
+ CustomText.isTimeRandom
+ ) {
+ let currentTop = Math.floor(
+ document.querySelectorAll("#words .word")[
+ TestUI.currentWordElementIndex - 1
+ ].offsetTop
+ );
+ let nextTop;
+ try {
+ nextTop = Math.floor(
+ document.querySelectorAll("#words .word")[
+ TestUI.currentWordElementIndex
+ ].offsetTop
+ );
+ } catch (e) {
+ nextTop = 0;
+ }
+
+ if (nextTop > currentTop && !TestUI.lineTransition) {
+ TestUI.lineJump(currentTop);
+ }
+ } //end of line wrap
+
+ Caret.updatePosition();
+
+ if (Config.keymapMode === "react") {
+ Keymap.flashKey(event.code, true);
+ } else if (Config.keymapMode === "next" && Config.mode !== "zen") {
+ Keymap.highlightKey(
+ TestLogic.words
+ .getCurrent()
+ .substring(
+ TestLogic.input.current.length,
+ TestLogic.input.current.length + 1
+ )
+ .toString()
+ .toUpperCase()
+ );
+ }
+ if (
+ Config.mode === "words" ||
+ Config.mode === "custom" ||
+ Config.mode === "quote" ||
+ Config.mode === "zen"
+ ) {
+ TimerProgress.update(TestTimer.time);
+ }
+ if (
+ Config.mode == "time" ||
+ Config.mode == "words" ||
+ Config.mode == "custom"
+ ) {
+ TestLogic.addWord();
+ }
+}
+
+function handleAlpha(event) {
+ if (
+ [
+ "ContextMenu",
+ "Escape",
+ "Shift",
+ "Control",
+ "Meta",
+ "Alt",
+ "AltGraph",
+ "CapsLock",
+ "Backspace",
+ "PageUp",
+ "PageDown",
+ "Home",
+ "ArrowUp",
+ "ArrowLeft",
+ "ArrowRight",
+ "ArrowDown",
+ "OS",
+ "Insert",
+ "Home",
+ "Undefined",
+ "Control",
+ "Fn",
+ "FnLock",
+ "Hyper",
+ "NumLock",
+ "ScrollLock",
+ "Symbol",
+ "SymbolLock",
+ "Super",
+ "Unidentified",
+ "Process",
+ "Delete",
+ "KanjiMode",
+ "Pause",
+ "PrintScreen",
+ "Clear",
+ "End",
+ undefined,
+ ].includes(event.key)
+ ) {
+ TestStats.incrementKeypressMod();
+ // currentKeypress.mod++;
+ return;
+ }
+
+ //insert space for expert and master or strict space,
+ //otherwise dont do anything
+ if (event.key === " ") {
+ if (Config.difficulty !== "normal" || Config.strictSpace) {
+ if (dontInsertSpace) {
+ dontInsertSpace = false;
+ return;
+ }
+ } else {
+ return;
+ }
+ }
+
+ if (event.key === "Tab") {
+ if (
+ Config.mode !== "zen" &&
+ (!TestLogic.hasTab || (TestLogic.hasTab && event.shiftKey))
+ ) {
+ return;
+ }
+ event.key = "\t";
+ event.preventDefault();
+ }
+
+ if (event.key === "Enter") {
+ if (event.shiftKey && Config.mode == "zen") {
+ TestLogic.finish();
+ }
+ if (
+ event.shiftKey &&
+ ((Config.mode == "time" && Config.time === 0) ||
+ (Config.mode == "words" && Config.words === 0))
+ ) {
+ TestLogic.setBailout(true);
+ TestLogic.finish();
+ }
+ event.key = "\n";
+ }
+
+ // if (event.key.length > 1) return;
+ if (/F\d+/.test(event.key)) return;
+ if (/Numpad/.test(event.key)) return;
+ if (/Volume/.test(event.key)) return;
+ if (/Media/.test(event.key)) return;
+ if (
+ event.ctrlKey != event.altKey &&
+ (event.ctrlKey || /Linux/.test(window.navigator.platform))
+ )
+ return;
+ if (event.metaKey) return;
+
+ let originalEvent = event;
+
+ event = LayoutEmulator.updateEvent(event);
+
+ //start the test
+ if (
+ TestLogic.input.current == "" &&
+ TestLogic.input.history.length == 0 &&
+ !TestLogic.active
+ ) {
+ if (!TestLogic.startTest()) return;
+ } else {
+ if (!TestLogic.active) return;
+ }
+
+ Focus.set(true);
+ Caret.stopAnimation();
+
+ //show dead keys
+ if (event.key === "Dead") {
+ Sound.playClick(Config.playSoundOnClick);
+ $(
+ document.querySelector("#words .word.active").querySelectorAll("letter")[
+ TestLogic.input.current.length
+ ]
+ ).toggleClass("dead");
+ return;
+ }
+
+ //check if the char typed was correct
+ let thisCharCorrect;
+ let nextCharInWord;
+ if (Config.mode != "zen") {
+ nextCharInWord = TestLogic.words
+ .getCurrent()
+ .substring(
+ TestLogic.input.current.length,
+ TestLogic.input.current.length + 1
+ );
+ }
+
+ if (nextCharInWord == event["key"]) {
+ thisCharCorrect = true;
+ } else {
+ thisCharCorrect = false;
+ }
+
+ if (Config.language.split("_")[0] == "russian") {
+ if ((event.key === "е" || event.key === "e") && nextCharInWord == "ё") {
+ event.key = nextCharInWord;
+ thisCharCorrect = true;
+ }
+ if (
+ event.key === "ё" &&
+ (nextCharInWord == "е" || nextCharInWord === "e")
+ ) {
+ event.key = nextCharInWord;
+ thisCharCorrect = true;
+ }
+ }
+
+ if (Config.mode == "zen") {
+ thisCharCorrect = true;
+ }
+
+ if (event.key === "’" && nextCharInWord == "'") {
+ event.key = "'";
+ thisCharCorrect = true;
+ }
+
+ if (event.key === "'" && nextCharInWord == "’") {
+ event.key = "’";
+ thisCharCorrect = true;
+ }
+
+ if (event.key === "”" && nextCharInWord == '"') {
+ event.key = '"';
+ thisCharCorrect = true;
+ }
+
+ if (event.key === '"' && nextCharInWord == "”") {
+ event.key = "”";
+ thisCharCorrect = true;
+ }
+
+ if ((event.key === "–" || event.key === "—") && nextCharInWord == "-") {
+ event.key = "-";
+ thisCharCorrect = true;
+ }
+
+ if (
+ Config.oppositeShiftMode === "on" &&
+ ShiftTracker.isUsingOppositeShift(originalEvent) === false
+ ) {
+ thisCharCorrect = false;
+ }
+
+ if (!thisCharCorrect) {
+ TestStats.incrementAccuracy(false);
+ TestStats.incrementKeypressErrors();
+ // currentError.count++;
+ // currentError.words.push(TestLogic.words.currentIndex);
+ thisCharCorrect = false;
+ TestStats.pushMissedWord(TestLogic.words.getCurrent());
+ } else {
+ TestStats.incrementAccuracy(true);
+ thisCharCorrect = true;
+ if (Config.mode == "zen") {
+ //making the input visible to the user
+ $("#words .active").append(
+ `${event.key}`
+ );
+ }
+ }
+
+ if (thisCharCorrect) {
+ Sound.playClick(Config.playSoundOnClick);
+ } else {
+ if (!Config.playSoundOnError || Config.blindMode) {
+ Sound.playClick(Config.playSoundOnClick);
+ } else {
+ Sound.playError(Config.playSoundOnError);
+ }
+ }
+
+ if (
+ Config.oppositeShiftMode === "on" &&
+ ShiftTracker.isUsingOppositeShift(originalEvent) === false
+ )
+ return;
+
+ //update current corrected verison. if its empty then add the current key. if its not then replace the last character with the currently pressed one / add it
+ if (TestLogic.corrected.current === "") {
+ TestLogic.corrected.setCurrent(TestLogic.input.current + event["key"]);
+ } else {
+ let cil = TestLogic.input.current.length;
+ if (cil >= TestLogic.corrected.current.length) {
+ TestLogic.corrected.appendCurrent(event["key"]);
+ } else if (!thisCharCorrect) {
+ TestLogic.corrected.setCurrent(
+ TestLogic.corrected.current.substring(0, cil) +
+ event["key"] +
+ TestLogic.corrected.current.substring(cil + 1)
+ );
+ }
+ }
+ TestStats.incrementKeypressCount();
+ TestStats.pushKeypressWord(TestLogic.words.currentIndex);
+ // currentKeypress.count++;
+ // currentKeypress.words.push(TestLogic.words.currentIndex);
+
+ if (Config.stopOnError == "letter" && !thisCharCorrect) {
+ return;
+ }
+
+ //update the active word top, but only once
+ if (
+ TestLogic.input.current.length === 1 &&
+ TestLogic.words.currentIndex === 0
+ ) {
+ TestUI.setActiveWordTop(document.querySelector("#words .active").offsetTop);
+ }
+
+ //max length of the input is 20 unless in zen mode
+ if (
+ Config.mode == "zen" ||
+ TestLogic.input.current.length < TestLogic.words.getCurrent().length + 20
+ ) {
+ TestLogic.input.appendCurrent(event["key"]);
+ }
+
+ if (!thisCharCorrect && Config.difficulty == "master") {
+ TestLogic.fail();
+ return;
+ }
+
+ //keymap
+ if (Config.keymapMode === "react") {
+ Keymap.flashKey(event.key, thisCharCorrect);
+ } else if (Config.keymapMode === "next" && Config.mode !== "zen") {
+ Keymap.highlightKey(
+ TestLogic.words
+ .getCurrent()
+ .substring(
+ TestLogic.input.current.length,
+ TestLogic.input.current.length + 1
+ )
+ .toString()
+ .toUpperCase()
+ );
+ }
+
+ let activeWordTopBeforeJump = TestUI.activeWordTop;
+ TestUI.updateWordElement(!Config.blindMode);
+
+ 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;
+ if (
+ (currentWord == TestLogic.input.current ||
+ (Config.quickEnd &&
+ currentWord.length == TestLogic.input.current.length &&
+ Config.stopOnError == "off")) &&
+ lastindex == TestLogic.words.length - 1
+ ) {
+ TestLogic.input.pushHistory();
+
+ TestLogic.corrected.pushHistory();
+ TestStats.setLastSecondNotRound();
+ TestLogic.finish();
+ }
+ }
+
+ //simulate space press in nospace funbox
+ if (
+ (Funbox.active === "nospace" &&
+ TestLogic.input.current.length === TestLogic.words.getCurrent().length) ||
+ (event.key === "\n" && thisCharCorrect)
+ ) {
+ $.event.trigger({
+ type: "keydown",
+ which: " ".charCodeAt(0),
+ key: " ",
+ });
+ }
+
+ let newActiveTop = document.querySelector("#words .word.active").offsetTop;
+ //stop the word jump by slicing off the last character, update word again
+ if (
+ activeWordTopBeforeJump < newActiveTop &&
+ !TestUI.lineTransition &&
+ TestLogic.input.current.length > 1
+ ) {
+ if (Config.mode == "zen") {
+ let currentTop = Math.floor(
+ document.querySelectorAll("#words .word")[
+ TestUI.currentWordElementIndex - 1
+ ].offsetTop
+ );
+ if (!Config.showAllLines) TestUI.lineJump(currentTop);
+ } else {
+ TestLogic.input.setCurrent(TestLogic.input.current.slice(0, -1));
+ TestUI.updateWordElement(!Config.blindMode);
+ }
+ }
+
+ Caret.updatePosition();
+}
diff --git a/src/js/script.js b/src/js/script.js
index 8a6067da0..fd7792fd1 100644
--- a/src/js/script.js
+++ b/src/js/script.js
@@ -1,13 +1,3 @@
-//test timer
-
-//ui
-
-///
-
-// let CustomText = "The quick brown fox jumps over the lazy dog".split(" ");
-// let CustomText.isWordRandom = false;
-// let CustomText.word = 1;
-
(function (history) {
var pushState = history.pushState;
history.pushState = function (state) {
@@ -35,792 +25,6 @@ $(window).on("popstate", (e) => {
}
});
-$("#wordsInput").keypress((event) => {
- event.preventDefault();
-});
-
-let dontInsertSpace = false;
-
-$(document).keyup((event) => {
- if (!event.originalEvent.isTrusted) return;
-
- if (TestUI.resultVisible) return;
- let now = performance.now();
- let diff = Math.abs(TestStats.keypressTimings.duration.current - now);
- if (TestStats.keypressTimings.duration.current !== -1) {
- TestStats.pushKeypressDuration(diff);
- // keypressStats.duration.array.push(diff);
- }
- TestStats.setKeypressDuration(now);
- // keypressStats.duration.current = now;
- Monkey.stop();
-});
-
-$(document).keydown(function (event) {
- if (!(event.key == " ") && !event.originalEvent.isTrusted) return;
-
- if (!TestUI.resultVisible) {
- TestStats.recordKeypressSpacing();
- }
-
- Monkey.type();
-
- //autofocus
- let pageTestActive = !$(".pageTest").hasClass("hidden");
- let commandLineVisible = !$("#commandLineWrapper").hasClass("hidden");
- let wordsFocused = $("#wordsInput").is(":focus");
- let modePopupVisible =
- !$("#customTextPopupWrapper").hasClass("hidden") ||
- !$("#customWordAmountPopupWrapper").hasClass("hidden") ||
- !$("#customTestDurationPopupWrapper").hasClass("hidden") ||
- !$("#quoteSearchPopupWrapper").hasClass("hidden") ||
- !$("#wordFilterPopupWrapper").hasClass("hidden");
- if (
- pageTestActive &&
- !commandLineVisible &&
- !modePopupVisible &&
- !TestUI.resultVisible &&
- !wordsFocused &&
- event.key !== "Enter"
- ) {
- TestUI.focusWords();
- wordsFocused = true;
- // if (Config.showOutOfFocusWarning) return;
- }
-
- //tab
- if (
- (event.key == "Tab" && !Config.swapEscAndTab) ||
- (event.key == "Escape" && Config.swapEscAndTab)
- ) {
- handleTab(event);
- // event.preventDefault();
- }
-
- //blocking firefox from going back in history with backspace
- if (event.key === "Backspace" && wordsFocused) {
- let t = /INPUT|SELECT|TEXTAREA/i;
- if (
- !t.test(event.target.tagName) ||
- event.target.disabled ||
- event.target.readOnly
- ) {
- event.preventDefault();
- }
- }
-
- // keypressStats.duration.current = performance.now();
- TestStats.setKeypressDuration(performance.now());
-
- if (TestUI.testRestarting) {
- return;
- }
-
- //backspace
- const isBackspace =
- event.key === "Backspace" ||
- (Config.capsLockBackspace && event.key === "CapsLock");
- if (isBackspace && wordsFocused) {
- handleBackspace(event);
- }
-
- if (event.key === "Enter" && Funbox.active === "58008" && wordsFocused) {
- event.key = " ";
- }
-
- //space or enter
- if (event.key === " " && wordsFocused) {
- handleSpace(event, false);
- }
-
- if (wordsFocused && !commandLineVisible) {
- handleAlpha(event);
- }
-
- let acc = Misc.roundTo2(TestStats.calculateAccuracy());
- LiveAcc.update(acc);
-});
-
-function handleTab(event) {
- if (TestUI.resultCalculating) {
- event.preventDefault();
- }
- if ($("#customTextPopup .textarea").is(":focus")) {
- event.preventDefault();
-
- let area = $("#customTextPopup .textarea")[0];
-
- var start = area.selectionStart;
- var end = area.selectionEnd;
-
- // set textarea value to: text before caret + tab + text after caret
- area.value =
- area.value.substring(0, start) + "\t" + area.value.substring(end);
-
- // put caret at right position again
- area.selectionStart = area.selectionEnd = start + 1;
-
- // event.preventDefault();
- // $("#customTextPopup .textarea").val(
- // $("#customTextPopup .textarea").val() + "\t"
- // );
- return;
- } else if (
- $(".pageTest").hasClass("active") &&
- !TestUI.resultCalculating &&
- $("#commandLineWrapper").hasClass("hidden") &&
- $("#simplePopupWrapper").hasClass("hidden")
- ) {
- if (Config.quickTab) {
- if (Config.mode == "zen" && !event.shiftKey) {
- //ignore
- } else {
- if (event.shiftKey) ManualRestart.set();
-
- if (
- TestLogic.active &&
- Config.repeatQuotes === "typing" &&
- Config.mode === "quote"
- ) {
- TestLogic.restart(true, false, event);
- } else {
- TestLogic.restart(false, false, event);
- }
- }
- } else {
- if (
- !TestUI.resultVisible &&
- ((TestLogic.hasTab && event.shiftKey) ||
- (!TestLogic.hasTab && Config.mode !== "zen") ||
- (Config.mode === "zen" && event.shiftKey))
- ) {
- event.preventDefault();
- $("#restartTestButton").focus();
- }
- }
- } else if (Config.quickTab) {
- UI.changePage("test");
- }
-}
-
-function handleBackspace(event) {
- event.preventDefault();
- if (!TestLogic.active) return;
- if (
- TestLogic.input.current == "" &&
- TestLogic.input.history.length > 0 &&
- TestUI.currentWordElementIndex > 0
- ) {
- //if nothing is inputted and its not the first word
- if (
- (TestLogic.input.getHistory(TestLogic.words.currentIndex - 1) ==
- TestLogic.words.get(TestLogic.words.currentIndex - 1) &&
- !Config.freedomMode) ||
- $($(".word")[TestLogic.words.currentIndex - 1]).hasClass("hidden")
- ) {
- return;
- } else {
- if (Config.confidenceMode === "on" || Config.confidenceMode === "max")
- return;
- if (event["ctrlKey"] || event["altKey"]) {
- TestLogic.input.resetCurrent();
- TestLogic.input.popHistory();
- TestLogic.corrected.popHistory();
- } else {
- TestLogic.input.setCurrent(TestLogic.input.popHistory());
- TestLogic.corrected.setCurrent(TestLogic.corrected.popHistory());
- if (Funbox.active === "nospace") {
- TestLogic.input.setCurrent(
- TestLogic.input.current.substring(
- 0,
- TestLogic.input.current.length - 1
- )
- );
- }
- }
- TestLogic.words.decreaseCurrentIndex();
- TestUI.setCurrentWordElementIndex(TestUI.currentWordElementIndex - 1);
- TestUI.updateActiveElement(true);
- Funbox.toggleScript(TestLogic.words.getCurrent());
- TestUI.updateWordElement(!Config.blindMode);
- }
- } else {
- if (Config.confidenceMode === "max") return;
- if (event["ctrlKey"] || event["altKey"]) {
- let limiter = " ";
- if (
- TestLogic.input.current.lastIndexOf("-") >
- TestLogic.input.current.lastIndexOf(" ")
- )
- limiter = "-";
-
- let split = TestLogic.input.current.replace(/ +/g, " ").split(limiter);
- if (split[split.length - 1] == "") {
- split.pop();
- }
- let addlimiter = false;
- if (split.length > 1) {
- addlimiter = true;
- }
- split.pop();
- TestLogic.input.setCurrent(split.join(limiter));
-
- if (addlimiter) {
- TestLogic.input.appendCurrent(limiter);
- }
- } else if (event.metaKey) {
- TestLogic.input.resetCurrent();
- } else {
- TestLogic.input.setCurrent(
- TestLogic.input.current.substring(0, TestLogic.input.current.length - 1)
- );
- }
- TestUI.updateWordElement(!Config.blindMode);
- }
- Sound.playClick(Config.playSoundOnClick);
- if (Config.keymapMode === "react") {
- Keymap.flashKey(event.code, true);
- } else if (Config.keymapMode === "next" && Config.mode !== "zen") {
- Keymap.highlightKey(
- TestLogic.words
- .getCurrent()
- .substring(
- TestLogic.input.current.length,
- TestLogic.input.current.length + 1
- )
- .toString()
- .toUpperCase()
- );
- }
- Caret.updatePosition();
-}
-
-function handleSpace(event, isEnter) {
- if (!TestLogic.active) return;
- if (TestLogic.input.current === "") return;
- // let nextWord = wordsList[TestLogic.words.currentIndex + 1];
- // if ((isEnter && nextWord !== "\n") && (isEnter && Funbox.active !== "58008")) return;
- // if (!isEnter && nextWord === "\n") return;
- event.preventDefault();
-
- if (Config.mode == "zen") {
- $("#words .word.active").removeClass("active");
- $("#words").append("");
- }
-
- let currentWord = TestLogic.words.getCurrent();
- if (Funbox.active === "layoutfluid" && Config.mode !== "time") {
- const layouts = ["qwerty", "dvorak", "colemak"];
- let index = 0;
- let outof = TestLogic.words.length;
- index = Math.floor((TestLogic.input.history.length + 1) / (outof / 3));
- if (Config.layout !== layouts[index] && layouts[index] !== undefined) {
- Notifications.add(`--- !!! ${layouts[index]} !!! ---`, 0);
- }
- UpdateConfig.setLayout(layouts[index]);
- UpdateConfig.setKeymapLayout(layouts[index]);
- Keymap.highlightKey(
- TestLogic.words
- .getCurrent()
- .substring(
- TestLogic.input.current.length,
- TestLogic.input.current.length + 1
- )
- .toString()
- .toUpperCase()
- );
- Settings.groups.layout.updateButton();
- }
- dontInsertSpace = true;
- if (currentWord == TestLogic.input.current || Config.mode == "zen") {
- //correct word or in zen mode
- PaceCaret.handleSpace(true, currentWord);
- TestStats.incrementAccuracy(true);
- TestLogic.input.pushHistory();
- TestLogic.words.increaseCurrentIndex();
- TestUI.setCurrentWordElementIndex(TestUI.currentWordElementIndex + 1);
- TestUI.updateActiveElement();
- Funbox.toggleScript(TestLogic.words.getCurrent());
- Caret.updatePosition();
- TestStats.incrementKeypressCount();
- TestStats.pushKeypressWord(TestLogic.words.currentIndex);
- // currentKeypress.count++;
- // currentKeypress.words.push(TestLogic.words.currentIndex);
- if (Funbox.active !== "nospace") {
- Sound.playClick(Config.playSoundOnClick);
- }
- } else {
- //incorrect word
- PaceCaret.handleSpace(false, currentWord);
- if (Funbox.active !== "nospace") {
- if (!Config.playSoundOnError || Config.blindMode) {
- Sound.playClick(Config.playSoundOnClick);
- } else {
- Sound.playError(Config.playSoundOnError);
- }
- }
- TestStats.incrementAccuracy(false);
- TestStats.incrementKeypressErrors();
- let cil = TestLogic.input.current.length;
- if (cil <= TestLogic.words.getCurrent().length) {
- if (cil >= TestLogic.corrected.current.length) {
- TestLogic.corrected.appendCurrent("_");
- } else {
- TestLogic.corrected.setCurrent(
- TestLogic.corrected.current.substring(0, cil) +
- "_" +
- TestLogic.corrected.current.substring(cil + 1)
- );
- }
- }
- if (Config.stopOnError != "off") {
- if (Config.difficulty == "expert" || Config.difficulty == "master") {
- //failed due to diff when pressing space
- TestLogic.fail();
- return;
- }
- if (Config.stopOnError == "word") {
- TestLogic.input.appendCurrent(" ");
- TestUI.updateWordElement(true);
- Caret.updatePosition();
- }
- return;
- }
- if (Config.blindMode) $("#words .word.active letter").addClass("correct");
- TestLogic.input.pushHistory();
- TestUI.highlightBadWord(TestUI.currentWordElementIndex, !Config.blindMode);
- TestLogic.words.increaseCurrentIndex();
- TestUI.setCurrentWordElementIndex(TestUI.currentWordElementIndex + 1);
- TestUI.updateActiveElement();
- Funbox.toggleScript(TestLogic.words.getCurrent());
- Caret.updatePosition();
- // currentKeypress.count++;
- // currentKeypress.words.push(TestLogic.words.currentIndex);
- TestStats.incrementKeypressCount();
- TestStats.pushKeypressWord(TestLogic.words.currentIndex);
- if (Config.difficulty == "expert" || Config.difficulty == "master") {
- TestLogic.fail();
- return;
- } else if (TestLogic.words.currentIndex == TestLogic.words.length) {
- //submitted last word that is incorrect
- TestStats.setLastSecondNotRound();
- TestLogic.finish();
- return;
- }
- }
-
- TestLogic.corrected.pushHistory();
-
- if (
- !Config.showAllLines ||
- Config.mode == "time" ||
- (CustomText.isWordRandom && CustomText.word == 0) ||
- CustomText.isTimeRandom
- ) {
- let currentTop = Math.floor(
- document.querySelectorAll("#words .word")[
- TestUI.currentWordElementIndex - 1
- ].offsetTop
- );
- let nextTop;
- try {
- nextTop = Math.floor(
- document.querySelectorAll("#words .word")[
- TestUI.currentWordElementIndex
- ].offsetTop
- );
- } catch (e) {
- nextTop = 0;
- }
-
- if (nextTop > currentTop && !TestUI.lineTransition) {
- TestUI.lineJump(currentTop);
- }
- } //end of line wrap
-
- Caret.updatePosition();
-
- if (Config.keymapMode === "react") {
- Keymap.flashKey(event.code, true);
- } else if (Config.keymapMode === "next" && Config.mode !== "zen") {
- Keymap.highlightKey(
- TestLogic.words
- .getCurrent()
- .substring(
- TestLogic.input.current.length,
- TestLogic.input.current.length + 1
- )
- .toString()
- .toUpperCase()
- );
- }
- if (
- Config.mode === "words" ||
- Config.mode === "custom" ||
- Config.mode === "quote" ||
- Config.mode === "zen"
- ) {
- TimerProgress.update(TestTimer.time);
- }
- if (
- Config.mode == "time" ||
- Config.mode == "words" ||
- Config.mode == "custom"
- ) {
- TestLogic.addWord();
- }
-}
-
-function handleAlpha(event) {
- if (
- [
- "ContextMenu",
- "Escape",
- "Shift",
- "Control",
- "Meta",
- "Alt",
- "AltGraph",
- "CapsLock",
- "Backspace",
- "PageUp",
- "PageDown",
- "Home",
- "ArrowUp",
- "ArrowLeft",
- "ArrowRight",
- "ArrowDown",
- "OS",
- "Insert",
- "Home",
- "Undefined",
- "Control",
- "Fn",
- "FnLock",
- "Hyper",
- "NumLock",
- "ScrollLock",
- "Symbol",
- "SymbolLock",
- "Super",
- "Unidentified",
- "Process",
- "Delete",
- "KanjiMode",
- "Pause",
- "PrintScreen",
- "Clear",
- "End",
- undefined,
- ].includes(event.key)
- ) {
- TestStats.incrementKeypressMod();
- // currentKeypress.mod++;
- return;
- }
-
- //insert space for expert and master or strict space,
- //otherwise dont do anything
- if (event.key === " ") {
- if (Config.difficulty !== "normal" || Config.strictSpace) {
- if (dontInsertSpace) {
- dontInsertSpace = false;
- return;
- }
- } else {
- return;
- }
- }
-
- if (event.key === "Tab") {
- if (
- Config.mode !== "zen" &&
- (!TestLogic.hasTab || (TestLogic.hasTab && event.shiftKey))
- ) {
- return;
- }
- event.key = "\t";
- event.preventDefault();
- }
-
- if (event.key === "Enter") {
- if (event.shiftKey && Config.mode == "zen") {
- TestLogic.finish();
- }
- if (
- event.shiftKey &&
- ((Config.mode == "time" && Config.time === 0) ||
- (Config.mode == "words" && Config.words === 0))
- ) {
- TestLogic.setBailout(true);
- TestLogic.finish();
- }
- event.key = "\n";
- }
-
- // if (event.key.length > 1) return;
- if (/F\d+/.test(event.key)) return;
- if (/Numpad/.test(event.key)) return;
- if (/Volume/.test(event.key)) return;
- if (/Media/.test(event.key)) return;
- if (
- event.ctrlKey != event.altKey &&
- (event.ctrlKey || /Linux/.test(window.navigator.platform))
- )
- return;
- if (event.metaKey) return;
-
- let originalEvent = event;
-
- event = LayoutEmulator.updateEvent(event);
-
- //start the test
- if (
- TestLogic.input.current == "" &&
- TestLogic.input.history.length == 0 &&
- !TestLogic.active
- ) {
- if (!TestLogic.startTest()) return;
- } else {
- if (!TestLogic.active) return;
- }
-
- Focus.set(true);
- Caret.stopAnimation();
-
- //show dead keys
- if (event.key === "Dead") {
- Sound.playClick(Config.playSoundOnClick);
- $(
- document.querySelector("#words .word.active").querySelectorAll("letter")[
- TestLogic.input.current.length
- ]
- ).toggleClass("dead");
- return;
- }
-
- //check if the char typed was correct
- let thisCharCorrect;
- let nextCharInWord;
- if (Config.mode != "zen") {
- nextCharInWord = TestLogic.words
- .getCurrent()
- .substring(
- TestLogic.input.current.length,
- TestLogic.input.current.length + 1
- );
- }
-
- if (nextCharInWord == event["key"]) {
- thisCharCorrect = true;
- } else {
- thisCharCorrect = false;
- }
-
- if (Config.language.split("_")[0] == "russian") {
- if ((event.key === "е" || event.key === "e") && nextCharInWord == "ё") {
- event.key = nextCharInWord;
- thisCharCorrect = true;
- }
- if (
- event.key === "ё" &&
- (nextCharInWord == "е" || nextCharInWord === "e")
- ) {
- event.key = nextCharInWord;
- thisCharCorrect = true;
- }
- }
-
- if (Config.mode == "zen") {
- thisCharCorrect = true;
- }
-
- if (event.key === "’" && nextCharInWord == "'") {
- event.key = "'";
- thisCharCorrect = true;
- }
-
- if (event.key === "'" && nextCharInWord == "’") {
- event.key = "’";
- thisCharCorrect = true;
- }
-
- if (event.key === "”" && nextCharInWord == '"') {
- event.key = '"';
- thisCharCorrect = true;
- }
-
- if (event.key === '"' && nextCharInWord == "”") {
- event.key = "”";
- thisCharCorrect = true;
- }
-
- if ((event.key === "–" || event.key === "—") && nextCharInWord == "-") {
- event.key = "-";
- thisCharCorrect = true;
- }
-
- if (
- Config.oppositeShiftMode === "on" &&
- ShiftTracker.isUsingOppositeShift(originalEvent) === false
- ) {
- thisCharCorrect = false;
- }
-
- if (!thisCharCorrect) {
- TestStats.incrementAccuracy(false);
- TestStats.incrementKeypressErrors();
- // currentError.count++;
- // currentError.words.push(TestLogic.words.currentIndex);
- thisCharCorrect = false;
- TestStats.pushMissedWord(TestLogic.words.getCurrent());
- } else {
- TestStats.incrementAccuracy(true);
- thisCharCorrect = true;
- if (Config.mode == "zen") {
- //making the input visible to the user
- $("#words .active").append(
- `${event.key}`
- );
- }
- }
-
- if (thisCharCorrect) {
- Sound.playClick(Config.playSoundOnClick);
- } else {
- if (!Config.playSoundOnError || Config.blindMode) {
- Sound.playClick(Config.playSoundOnClick);
- } else {
- Sound.playError(Config.playSoundOnError);
- }
- }
-
- if (
- Config.oppositeShiftMode === "on" &&
- ShiftTracker.isUsingOppositeShift(originalEvent) === false
- )
- return;
-
- //update current corrected verison. if its empty then add the current key. if its not then replace the last character with the currently pressed one / add it
- if (TestLogic.corrected.current === "") {
- TestLogic.corrected.setCurrent(TestLogic.input.current + event["key"]);
- } else {
- let cil = TestLogic.input.current.length;
- if (cil >= TestLogic.corrected.current.length) {
- TestLogic.corrected.appendCurrent(event["key"]);
- } else if (!thisCharCorrect) {
- TestLogic.corrected.setCurrent(
- TestLogic.corrected.current.substring(0, cil) +
- event["key"] +
- TestLogic.corrected.current.substring(cil + 1)
- );
- }
- }
- TestStats.incrementKeypressCount();
- TestStats.pushKeypressWord(TestLogic.words.currentIndex);
- // currentKeypress.count++;
- // currentKeypress.words.push(TestLogic.words.currentIndex);
-
- if (Config.stopOnError == "letter" && !thisCharCorrect) {
- return;
- }
-
- //update the active word top, but only once
- if (
- TestLogic.input.current.length === 1 &&
- TestLogic.words.currentIndex === 0
- ) {
- TestUI.setActiveWordTop(document.querySelector("#words .active").offsetTop);
- }
-
- //max length of the input is 20 unless in zen mode
- if (
- Config.mode == "zen" ||
- TestLogic.input.current.length < TestLogic.words.getCurrent().length + 20
- ) {
- TestLogic.input.appendCurrent(event["key"]);
- }
-
- if (!thisCharCorrect && Config.difficulty == "master") {
- TestLogic.fail();
- return;
- }
-
- //keymap
- if (Config.keymapMode === "react") {
- Keymap.flashKey(event.key, thisCharCorrect);
- } else if (Config.keymapMode === "next" && Config.mode !== "zen") {
- Keymap.highlightKey(
- TestLogic.words
- .getCurrent()
- .substring(
- TestLogic.input.current.length,
- TestLogic.input.current.length + 1
- )
- .toString()
- .toUpperCase()
- );
- }
-
- let activeWordTopBeforeJump = TestUI.activeWordTop;
- TestUI.updateWordElement(!Config.blindMode);
-
- 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;
- if (
- (currentWord == TestLogic.input.current ||
- (Config.quickEnd &&
- currentWord.length == TestLogic.input.current.length &&
- Config.stopOnError == "off")) &&
- lastindex == TestLogic.words.length - 1
- ) {
- TestLogic.input.pushHistory();
-
- TestLogic.corrected.pushHistory();
- TestStats.setLastSecondNotRound();
- TestLogic.finish();
- }
- }
-
- //simulate space press in nospace funbox
- if (
- (Funbox.active === "nospace" &&
- TestLogic.input.current.length === TestLogic.words.getCurrent().length) ||
- (event.key === "\n" && thisCharCorrect)
- ) {
- $.event.trigger({
- type: "keydown",
- which: " ".charCodeAt(0),
- key: " ",
- });
- }
-
- let newActiveTop = document.querySelector("#words .word.active").offsetTop;
- //stop the word jump by slicing off the last character, update word again
- if (
- activeWordTopBeforeJump < newActiveTop &&
- !TestUI.lineTransition &&
- TestLogic.input.current.length > 1
- ) {
- if (Config.mode == "zen") {
- let currentTop = Math.floor(
- document.querySelectorAll("#words .word")[
- TestUI.currentWordElementIndex - 1
- ].offsetTop
- );
- if (!Config.showAllLines) TestUI.lineJump(currentTop);
- } else {
- TestLogic.input.setCurrent(TestLogic.input.current.slice(0, -1));
- TestUI.updateWordElement(!Config.blindMode);
- }
- }
-
- Caret.updatePosition();
-}
-
ManualRestart.set();
UpdateConfig.loadFromCookie();
Misc.getReleasesFromGitHub();