monkeytype/src/js/input-controller.js

931 lines
26 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 LiveBurst from "./live-burst";
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";
import * as Replay from "./replay.js";
import * as MonkeyPower from "./monkey-power";
import * as WeakSpot from "./weak-spot";
$("#wordsInput").keypress((event) => {
event.preventDefault();
});
let dontInsertSpace = false;
function handleTab(event) {
if (TestUI.resultCalculating) {
event.preventDefault();
}
if (
!$("#presetWrapper").hasClass("hidden") ||
!$("#tagsWrapper").hasClass("hidden")
) {
event.preventDefault();
return;
}
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 (
!TestUI.resultCalculating &&
$("#commandLineWrapper").hasClass("hidden") &&
$("#simplePopupWrapper").hasClass("hidden") &&
!$(".page.pageLogin").hasClass("active")
) {
if ($(".pageTest").hasClass("active")) {
if (Config.quickTab) {
if (
(Config.mode == "zen" && !event.shiftKey) ||
(TestLogic.hasTab && !event.shiftKey)
) {
//ignore
} else {
if (event.shiftKey) {
ManualRestart.set();
} else {
ManualRestart.reset();
}
event.preventDefault();
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 (Config.funbox === "nospace") {
TestLogic.input.setCurrent(
TestLogic.input.current.substring(
0,
TestLogic.input.current.length - 1
)
);
}
}
TestLogic.words.decreaseCurrentIndex();
Replay.addReplayEvent("backWord");
TestUI.setCurrentWordElementIndex(TestUI.currentWordElementIndex - 1);
TestUI.updateActiveElement(true);
Funbox.toggleScript(TestLogic.words.getCurrent());
TestUI.updateWordElement(!Config.blindMode);
}
} else if (TestLogic.input.current !== "") {
if (Config.confidenceMode === "max") return;
if (event["ctrlKey"] || event["altKey"] || event.metaKey) {
Replay.addReplayEvent("clearWord");
// 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);
// }
if (
/^[ £§`~!@#$%^&*()_+\\\-=[\]{};':"|,./<>?]*$/g.test(
TestLogic.input.getCurrent()
)
) {
//pop current and previous
TestLogic.input.resetCurrent();
TestLogic.input.popHistory();
TestLogic.corrected.popHistory();
TestUI.updateWordElement(!Config.blindMode);
TestLogic.words.decreaseCurrentIndex();
Replay.addReplayEvent("backWord");
TestUI.setCurrentWordElementIndex(TestUI.currentWordElementIndex - 1);
TestUI.updateActiveElement(true);
Funbox.toggleScript(TestLogic.words.getCurrent());
TestUI.updateWordElement(!Config.blindMode);
TestLogic.input.resetCurrent();
} else {
const regex = new RegExp(
/[ £§`~!@#$%^&*()_+\\\-=[\]{};':"|,./<>?]/,
"g"
);
let input = TestLogic.input.getCurrent();
regex.test(input);
// let puncIndex = regex.lastIndex;
let puncIndex = input.lastIndexOfRegex(
/[ £§`~!@#$%^&*()_+\\\-=[\]{};':"|,./<>?]/g
);
while (
/[ £§`~!@#$%^&*()_+\\\-=[\]{};':"|,./<>?]/g.test(input.slice(-1))
) {
input = input.substring(0, input.length - 1);
}
puncIndex = input.lastIndexOfRegex(
/[ £§`~!@#$%^&*()_+\\\-=[\]{};':"|,./<>?]/g
);
TestLogic.input.setCurrent(
input.substring(0, puncIndex == 0 ? 0 : puncIndex + 1)
);
}
} else {
TestLogic.input.setCurrent(
TestLogic.input.current.substring(0, TestLogic.input.current.length - 1)
);
Replay.addReplayEvent("deleteLetter");
}
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 && Config.funbox !== "58008")) return;
// if (!isEnter && nextWord === "\n") return;
event.preventDefault();
if (Config.mode == "zen") {
$("#words .word.active").removeClass("active");
$("#words").append("<div class='word active'></div>");
}
let currentWord = TestLogic.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;
index = Math.floor(
(TestLogic.input.history.length + 1) / (outof / layouts.length)
);
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;
let burst = TestStats.calculateBurst();
LiveBurst.update(Math.round(burst));
TestStats.pushBurstToHistory(burst);
if (currentWord == TestLogic.input.current || Config.mode == "zen") {
//correct word or in zen mode
MonkeyPower.addPower(true, true);
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 (Config.funbox !== "nospace") {
Sound.playClick(Config.playSoundOnClick);
}
Replay.addReplayEvent("submitCorrectWord");
} else {
//incorrect word
MonkeyPower.addPower(false, true);
if (Config.funbox !== "nospace") {
if (!Config.playSoundOnError || Config.blindMode) {
Sound.playClick(Config.playSoundOnClick);
} else {
Sound.playError(Config.playSoundOnError);
}
}
TestStats.pushMissedWord(TestLogic.words.getCurrent());
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("difficulty");
return;
}
if (Config.stopOnError == "word") {
TestLogic.input.appendCurrent(" ");
Replay.addReplayEvent("incorrectLetter", "_");
TestUI.updateWordElement(true);
Caret.updatePosition();
}
return;
}
PaceCaret.handleSpace(false, currentWord);
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);
TestStats.updateLastKeypress();
if (Config.difficulty == "expert" || Config.difficulty == "master") {
TestLogic.fail("difficulty");
return;
} else if (TestLogic.words.currentIndex == TestLogic.words.length) {
//submitted last word that is incorrect
TestLogic.finish();
return;
}
Replay.addReplayEvent("submitErrorWord");
}
let wordLength;
if (Config.mode === "zen") {
wordLength = TestLogic.input.getCurrent().length;
} else {
wordLength = TestLogic.words.getCurrent().length;
}
let flex = Misc.whorf(Config.minBurstCustomSpeed, wordLength);
if (
(Config.minBurst === "fixed" && burst < Config.minBurstCustomSpeed) ||
(Config.minBurst === "flex" && burst < flex)
) {
TestLogic.fail("min burst");
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",
"GroupPrevious",
"GroupNext",
"WakeUp",
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 = {
code: event.code,
};
event = LayoutEmulator.updateEvent(event);
//start the test
if (
TestLogic.input.current == "" &&
TestLogic.input.history.length == 0 &&
!TestLogic.active
) {
if (!TestLogic.startTest()) return;
MonkeyPower.addPower();
} else {
if (!TestLogic.active) return;
}
if (TestLogic.input.current == "") {
TestStats.setBurstStart(performance.now());
}
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 === `` || event.key === `` || event.key === "'") &&
(nextCharInWord == `` || nextCharInWord === `` || nextCharInWord === "'")
) {
event.key = nextCharInWord;
thisCharCorrect = true;
}
if (
(event.key === `"` ||
event.key === "”" ||
event.key == "“" ||
event.key === "„") &&
(nextCharInWord == `"` ||
nextCharInWord === "”" ||
nextCharInWord === "“" ||
nextCharInWord === "„")
) {
event.key = nextCharInWord;
thisCharCorrect = true;
}
if (
(event.key === "" || event.key === "—" || event.key == "-") &&
(nextCharInWord == "-" || nextCharInWord === "" || nextCharInWord === "—")
) {
event.key = nextCharInWord;
thisCharCorrect = true;
}
if (
Config.oppositeShiftMode === "on" &&
ShiftTracker.isUsingOppositeShift(originalEvent) === false
) {
thisCharCorrect = false;
}
MonkeyPower.addPower(thisCharCorrect);
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(
`<letter class="correct">${event.key}</letter>`
);
}
}
WeakSpot.updateScore(nextCharInWord, thisCharCorrect);
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.updateLastKeypress();
TestStats.pushKeypressWord(TestLogic.words.currentIndex);
// currentKeypress.count++;
// currentKeypress.words.push(TestLogic.words.currentIndex);
if (Config.stopOnError == "letter" && !thisCharCorrect) {
return;
}
Replay.addReplayEvent(
thisCharCorrect ? "correctLetter" : "incorrectLetter",
event.key
);
//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 then its 30
if (
(Config.mode == "zen" && TestLogic.input.current.length < 30) ||
(Config.mode !== "zen" &&
TestLogic.input.current.length < TestLogic.words.getCurrent().length + 20)
) {
TestLogic.input.appendCurrent(event["key"]);
}
if (!thisCharCorrect && Config.difficulty == "master") {
TestLogic.input.pushHistory();
TestLogic.corrected.pushHistory();
TestLogic.fail("difficulty");
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();
TestLogic.finish();
}
}
//simulate space press in nospace funbox
if (
(Config.funbox === "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);
}
}
if (originalEvent.code !== "Enter") Caret.updatePosition();
}
$(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 leaderboardsVisible = !$("#leaderboardsWrapper").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 &&
!leaderboardsVisible &&
!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" && Config.funbox === "58008" && wordsFocused) {
event.key = " ";
}
//space or enter
if (event.key === " " && wordsFocused) {
handleSpace(event, false);
}
if (wordsFocused && !commandLineVisible && !leaderboardsVisible) {
handleAlpha(event);
}
let acc = Misc.roundTo2(TestStats.calculateAccuracy());
LiveAcc.update(acc);
});