diff --git a/README.md b/README.md index 031d471..60ee01d 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ available modes: - `wordcount` - `time` +- `custom` ## punctuation @@ -100,4 +101,4 @@ acc: total number of characters (including spaces) of words you got right divide ## support -- PayPal \ No newline at end of file +- PayPal diff --git a/index.html b/index.html index effbf72..108061d 100644 --- a/index.html +++ b/index.html @@ -47,6 +47,9 @@ / 240 + + custom +
WPM: XX / ACC: XX
diff --git a/main.js b/main.js index e8f7db5..c4b0eb3 100644 --- a/main.js +++ b/main.js @@ -6,6 +6,7 @@ const inputField = document.querySelector('#input-field'); let typingMode = 'wordcount'; let wordCount; let timeCount; +let customText = ''; // Initialize dynamic variables let randomWords = []; @@ -17,7 +18,11 @@ let timer; let timerActive = false; let punctuation = false; +// Initialize global constants +const PUNCREGEX = /!:;'",.\/?!@#$%^&*()_}{\[\]\-s\+\=/; + // Get cookies +customText = getCookie('customText'); getCookie('theme') === '' ? setTheme('light') : setTheme(getCookie('theme')); getCookie('language') === '' ? setLanguage('english') : setLanguage(getCookie('language')); getCookie('wordCount') === '' ? setWordCount(50) : setWordCount(getCookie('wordCount')); @@ -36,14 +41,26 @@ function setText(e) { } currentWord = 0; correctKeys = 0; - inputField.value = ''; timerActive = false; clearTimeout(timer); textDisplay.style.display = 'block'; inputField.className = ''; switch (typingMode) { + case 'custom': + if (inputField.value === 'custom') { + customText = prompt('enter custom text:'); + setCookie('customText', customText, 90); + } + wordList = betterSplit(customText); + punctuation = false; + textDisplay.style.height = 'auto'; + textDisplay.innerHTML = ''; + inputField.value=''; + break; + case 'wordcount': + inputField.value = ''; textDisplay.style.height = 'auto'; textDisplay.innerHTML = ''; if (!keepWordList) { @@ -58,6 +75,7 @@ function setText(e) { break; case 'time': + inputField.value = ''; textDisplay.style.height = '3.2rem'; document.querySelector(`#tc-${timeCount}`).innerHTML = timeCount; textDisplay.innerHTML = ''; @@ -69,7 +87,6 @@ function setText(e) { } } } - if (punctuation) addPunctuations(); showText(); inputField.focus(); @@ -120,18 +137,20 @@ function showText() { inputField.addEventListener('keydown', e => { // Add wrong class to input field switch (typingMode) { + case 'custom': case 'wordcount': if (currentWord < wordList.length) inputFieldClass(); case 'time': if (timerActive) inputFieldClass(); } function inputFieldClass() { - if (e.key >= 'a' && e.key <= 'z' || (e.key === `'` || e.key === ',' || e.key === '.' || e.key === ';')) { - let inputWordSlice = inputField.value + e.key; + var puncRegex = new RegExp('[' + PUNCREGEX.source + ']'); + if (e.key === 'Backspace') { + let inputWordSlice = e.ctrlKey ? '' : inputField.value.slice(0, inputField.value.length - 1); let currentWordSlice = wordList[currentWord].slice(0, inputWordSlice.length); inputField.className = inputWordSlice === currentWordSlice ? '' : 'wrong'; - } else if (e.key === 'Backspace') { - let inputWordSlice = e.ctrlKey ? '' : inputField.value.slice(0, inputField.value.length - 1); + } else if (e.key >= 'a' && e.key <= 'z' || puncRegex.test(e.key)) { + let inputWordSlice = inputField.value + e.key; let currentWordSlice = wordList[currentWord].slice(0, inputWordSlice.length); inputField.className = inputWordSlice === currentWordSlice ? '' : 'wrong'; } else if (e.key === ' ') { @@ -142,6 +161,7 @@ inputField.addEventListener('keydown', e => { // If it is the first character entered if (currentWord === 0 && inputField.value === '') { switch (typingMode) { + case 'custom': case 'wordcount': startDate = Date.now(); break; @@ -216,6 +236,7 @@ inputField.addEventListener('keydown', e => { function showResult() { let words, minute, acc; switch (typingMode) { + case 'custom': case 'wordcount': words = correctKeys / 5; minute = (Date.now() - startDate) / 1000 / 60; @@ -322,6 +343,7 @@ function setTypingMode(_mode) { setCookie('typingMode', mode, 90); document.querySelector('#word-count').style.display = 'inline'; document.querySelector('#time-count').style.display = 'none'; + document.querySelector('#custom').style.display = 'none'; setText(); break; case 'time': @@ -329,6 +351,15 @@ function setTypingMode(_mode) { setCookie('typingMode', mode, 90); document.querySelector('#word-count').style.display = 'none'; document.querySelector('#time-count').style.display = 'inline'; + document.querySelector('#custom').style.display = 'none'; + setText(); + break; + case 'custom': + typingMode = mode; + setCookie('typingMode', mode, 90); + document.querySelector('#word-count').style.display = 'none'; + document.querySelector('#time-count').style.display = 'none'; + document.querySelector('#custom').style.display = 'inline'; setText(); break; default: @@ -456,4 +487,19 @@ function hideThemeCenter() { document.getElementById('command-center').classList.remove('hidden'); } - +function betterSplit(str) { + // Regex tester for: + // Normal a-z, A-Z + // punjabi, + // CJK, + // Russian + // TODO: Add support for remaining European languages + // Cleaner way to do this??? + const regex1 = "[\u0A00-\u0A7F\u3040-\u30ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff\uff66-\uff9f\u3131-\uD79D]+|[\u0400-\u04FFa-zA-Z0-9"; + const regex2 = "]+\'*[a-z]*"; + + + const regex = new RegExp(regex1 + PUNCREGEX.source + regex2, "g"); + let array = [...str.match(regex)]; + return array; +}