// Global variables var interval; var remainingTime; var startTime, countUpStartTime; //var countUpStartTime; var countUpElapsedTime = 0; var isPaused = false; var isCountUpPaused = false; var incorrectWords = 0; var remainingWords = 0; var correctWords = 0; var currentWordIndex = 0; // Variable to track the index of the current word to highlight // Populate dropdown with 500 options const dropdown = document.getElementById('testType'); for (let i = 01; i <= 01; i++) { const option = document.createElement('option'); option.value = `Trial-Paragraph-${i}`; option.textContent = `Trial-Paragraph-${i}`; dropdown.appendChild(option); } // Submitting form // Elements const submitButton = document.getElementById("submitButton"); const startButton = document.getElementById("startButton"); const pauseResume = document.getElementById("pauseResume"); const pauseResumeIcon = document.getElementById('pauseResumeIcon'); // Initialize button as disabled when user click on submit the form to start test submitButton.disabled = true; reloadButton.disabled = true; pauseResume.disabled = true; // Submit Form Function function submitForm() { const name = document.getElementById("name").value; const time = document.getElementById("time").value; const testType = document.getElementById("testType").value; // Alert if (!name || !time || !testType) { //alert("Please fill in all fields"); //return; // Trigger the Bootstrap modal let alertModal = new bootstrap.Modal(document.getElementById('alertModal')); alertModal.show(); return; } // Labels // document.getElementById("label1").innerText = "Name: " + name; // document.getElementById("label2").innerText = "Test Type: " + testType; // document.getElementById("label3").innerText = "Time: " + (time === "noLimit" ? "No Limit" : time + " Minutes"); document.getElementById("label1").innerText = name; document.getElementById("label2").innerText = testType; document.getElementById("label3").innerText = (time === "noLimit" ? "No Limit" : time + " Min."); if (time !== "noLimit") { const formattedTime = formatTime(parseInt(time) * 60); document.getElementById("timerLabel").innerText = formattedTime; } else { document.getElementById("timerLabel").innerText = "No Limit"; } fetchTextFile(testType); // Containter show or hide document.getElementById("formContainer").style.display = "none"; document.getElementById("titleDiv").style.display = "none"; document.getElementById("textareaContainer").style.display = "block"; } let totalWords = 0; // Variable to store total words in the paragraph let totalKeystrokes = 0; // Variable to store total keystrokes in the paragraph including space // Fetch Text File Function function fetchTextFile(testType) { const fileName = `typingtest/english-paragraph/${testType}.txt?timestamp=${new Date().getTime()}`; // Show the loader document.getElementById('loader').style.display = 'block'; startButton.disabled = true; fetch(fileName) .then(response => { if (!response.ok) { throw new Error('Network issue, please check your internet connection!!!'); } return response.text(); // Extract text from the response }) .then(text => { // Hide the loader document.getElementById('loader').style.display = 'none'; startButton.disabled = false; // Display the text in the textarea document.getElementById("readonlyTextarea").innerHTML = text; totalWords = text.trim().split(/\s+/).length; // Count total words totalKeystrokes = text.replace(/\s+/g, '').length; // Count the keystrokes without spaces }) .catch(error => { // Hide the loader in case of an error startButton.disabled = true; document.getElementById('loader').style.display = 'none'; // Show the error message in an alert alert("Error loading the selected paragraph:\n" + error.message); // After the user clicks OK on the alert, reload the page location.reload(); // You can also handle the error further as needed console.error("Error loading the selected paragraph:", error); }); } //---------------------------------------------------------------------// //---------------------------------------------------------------------// // Variables for timer //let interval; //let remainingTime; //let startTime; //let countUpStartTime; //let countUpElapsedTime = 0; //let isPaused = false; //let isCountUpPaused = false; // Start Timer Function when click on Start button function startTimer() { const time = document.getElementById("time").value; const inputTextarea = document.getElementById("inputTextarea"); if (time === "noLimit") { startTime = Date.now(); countUpStartTime = Date.now(); countUpElapsedTime = 0; // Reset count-up elapsed time startButton.disabled = true; submitButton.disabled = false; // Enable submit button when timer starts reloadButton.disabled = false; // Enable reload button when timer starts inputTextarea.disabled = false; // Ensure the input textarea is enabled inputTextarea.focus(); // Focus the textarea when enabled return; } if (!isPaused) { remainingTime = parseInt(time) * 60; // Convert minutes to seconds } updateTimerLabel(remainingTime); // Initialize the countdown timer label interval = setInterval(() => { if (remainingTime <= 0) { clearInterval(interval); endTest(); return; } remainingTime--; updateTimerLabel(remainingTime); if (!isCountUpPaused) { // Update count-up timer only if not paused updateCountUpLabel(); } }, 1000); startTime = Date.now(); countUpStartTime = Date.now(); // Initialize count-up start time countUpElapsedTime = 0; // Reset count-up elapsed time startButton.disabled = true; submitButton.disabled = false; // Enable submit button when timer starts reloadButton.disabled = false; // Enable reload button when timer starts inputTextarea.disabled = false; // Ensure the input textarea is enabled inputTextarea.focus(); // Focus the textarea when enabled } // Format Time Function function formatTime(totalTime) { const minutes = Math.floor(totalTime / 60); const seconds = totalTime % 60; return `${minutes}:${seconds < 10 ? "0" + seconds : seconds}`; } // Update Count-down Timer Label Function function updateTimerLabel(totalTime) { const formattedTime = formatTime(totalTime); document.getElementById("timerLabel").innerText = formattedTime; } // Update Count-Up Timer Label Function function updateCountUpLabel() { const elapsedTime = Math.floor((Date.now() - countUpStartTime + countUpElapsedTime) / 1000); document.getElementById("countUpLabel").innerText = elapsedTime; // Display total seconds } // Pause Resume timer document.getElementById('pauseResume').addEventListener('click', () => { if (interval) { clearInterval(interval); interval = null; isPaused = true; isCountUpPaused = true; // Pause count-up timer countUpElapsedTime += Date.now() - countUpStartTime; // Add elapsed time to the count-up elapsed time //document.getElementById('pauseResume').textContent = 'Resume'; pauseResumeIcon.classList.remove('fa-pause'); // remove pause icon pauseResumeIcon.classList.add('fa-play'); // change to play icon inputTextarea.disabled = true; // Ensure the input textarea is disabled } else if (isPaused) { interval = setInterval(() => { if (remainingTime <= 0) { clearInterval(interval); endTest(); return; } remainingTime--; updateTimerLabel(remainingTime); if (!isCountUpPaused) { // Update count-up timer only if not paused updateCountUpLabel(); } }, 1000); isPaused = false; isCountUpPaused = false; // Resume count-up timer countUpStartTime = Date.now(); // Reset count-up start time for resumed period //document.getElementById('pauseResume').textContent = 'Pause'; pauseResumeIcon.classList.remove('fa-play'); // remove play icon pauseResumeIcon.classList.add('fa-pause'); // change to pause icon inputTextarea.disabled = false; // Ensure the input textarea is enabled inputTextarea.focus(); // Focus the textarea when enabled } }); //---------------------------------------------------------------------// //---------------------------------------------------------------------// // Reload Test Function function reloadTest() { // Clear the interval if (interval) { clearInterval(interval); } // Reset global variables incorrectWords = 0; remainingWords = 0; correctWords = 0; startTime = null; //countUpStartTime = null; //countUpElapsedTime = 0; currentWordIndex = 0; backspaceCounter = 0; isPaused = false; // Reset the UI elements document.getElementById("inputTextarea").value = ""; document.getElementById("correctWordCount").textContent = "0"; document.getElementById("incorrectWordCount").textContent = "0"; document.getElementById("correctLetterCount").textContent = "0"; document.getElementById("incorrectLetterCount").textContent = "0"; document.getElementById("backspaceCounterBadge").textContent = "0"; document.getElementById("countUpLabel").textContent = "0"; // Re-enable disable buttons startButton.disabled = false; submitButton.disabled = true; reloadButton.disabled = true; pauseResume.disabled = true; // Reset the scroll position readonlyTextarea.scrollTop = 0; // Reset timer based on user selection const time = document.getElementById("time").value; if (time !== "noLimit") { const totalTimeInSeconds = parseInt(time) * 60; updateTimerLabel(totalTimeInSeconds); } else { document.getElementById("timerLabel").innerText = "No Limit"; } // Reset form visibility document.getElementById("formContainer").style.display = "none"; document.getElementById("textareaContainer").style.display = "block"; document.getElementById("resultContainer").style.display = "none"; } // Event listener for the reload button document.getElementById("reloadButton").addEventListener("click", function() { inputTextarea.disabled = true; reloadTest(); // Call the function to reload or reset the test highlightWords(); // Call the function to apply highlighting //document.getElementById('pauseResume').textContent = 'Pause'; pauseResumeIcon.classList.remove('fa-play'); // remove play icon pauseResumeIcon.classList.add('fa-pause'); // change to pause icon }); //---------------------------------------------------------------------// //---------------------------------------------------------------------// // Backspace counter in inputTextarea and show them on badge and result page let backspaceCounter = 0; const backspaceBadge = document.getElementById('backspaceCounterBadge'); document.getElementById('inputTextarea').addEventListener('keydown', function(event) { if (event.key === 'Backspace') { backspaceCounter++; backspaceBadge.textContent = backspaceCounter; } }); //---------------------------------------------------------------------// //----------------------------END TEST-----------------------------------------// // ***Result displayed when the time end or user click on submit button*** function endTest() { clearInterval(interval); // Clear any running intervals startButton.disabled = false; // Enable start button for the next test // If the timer was never started, handle it gracefully if (!startTime) { document.getElementById("timeTakenResult").innerText = "0:00:00"; document.getElementById("gwpmWordsResult").innerText = "0.00"; document.getElementById("nwpmWordsResult").innerText = "0.00"; document.getElementById("accuracyWordsResult").innerText = "0.00%"; //document.getElementById("typedKeystrokeResult").innerText = "0"; return; } // Total time taken const totalTime = document.getElementById("countUpLabel").innerText; // if count in seconds elapsedTime const totalMinutes = totalTime / 60; // Convert total time to minutes for wpm speed const formattedElapsedTime = formatElapsedTime(totalTime); // Check if totalTime is less than or equal to zero if (totalTime <= 0) { document.getElementById("timeTakenResult").innerText = "0:00:00"; document.getElementById("gwpmWordsResult").innerText = "0.00"; document.getElementById("nwpmWordsResult").innerText = "0.00"; document.getElementById("accuracyWordsResult").innerText = "0.00%"; return; } // Count words only if inputText is not empty const inputText = document.getElementById("inputTextarea").value.trim(); const wordsTyped = inputText.length > 0 ? inputText.split(/\s+/).filter(word => word.length > 0).length : 0; const gwpm = wordsTyped / totalMinutes; // Gross Words Per Minute const readonlyText = document.getElementById("readonlyTextarea").innerText; const wordsArray = readonlyText.trim().split(/\s+/); const inputWords = inputText.split(/\s+/).filter(word => word.length > 0); // Filter out empty words const incorrectWords = calculateIncorrectWords(wordsArray, inputWords); remainingWords = wordsArray.length - inputWords.length; correctWords = wordsArray.length - incorrectWords - remainingWords; const totalTypedWords = correctWords + incorrectWords; //const typedKeystrokes = inputText.length; // count the keystrokes with space //const typedKeystrokes = inputText.replace(/\s+/g, '').length; // count the keystrokes without space // Get the text content from the elements with IDs const correctLetterCount = Number(document.getElementById('correctLetterCount').textContent); const incorrectLetterCount = Number(document.getElementById('incorrectLetterCount').textContent); // Sum the values for total typed keystrokes const typedKeystrokes = correctLetterCount + incorrectLetterCount; const remainingKeystrokes = totalKeystrokes - typedKeystrokes; const correctKeystrokes = letterCountCorrect.textContent; const incorrectKeystrokes = letterCountIncorrect.textContent; // Check if there are no typed words to avoid division by zero const nwpm = wordsTyped > 0 ? correctWords / totalMinutes : 0; // Net Word Per Minute // Calculate accuracy with floating-point precision const accuracyWords = totalTypedWords > 0 ? (100 - (incorrectWords / totalTypedWords * 100)) : 0; const accuracyKeystrokes = typedKeystrokes > 0 ? (100 - (incorrectKeystrokes / typedKeystrokes * 100)) : 0; const gkpmKeystrokes = (typedKeystrokes / 5) / totalMinutes; // Gross Keystrokes Per Minute const nkpmKeystrokes = ((typedKeystrokes - incorrectKeystrokes) / 5) / totalMinutes; // Net Keystrokes Per Minute // Format values to 2 decimal places document.getElementById("nameResult").innerText = document.getElementById("name").value; document.getElementById("testTypeResult").innerText = document.getElementById("testType").value; document.getElementById("timeResult").innerText = document.getElementById("time").value + (document.getElementById("time").value === "noLimit" ? "" : " minutes"); document.getElementById("timeTakenResult").innerText = formattedElapsedTime; document.getElementById('backspaceCount').innerText = backspaceCounter; //document.getElementById("gwpmWordsResult").innerText = gwpm.toFixed(2); // Gross Words Per Minute document.getElementById("gwpmWordsResult").innerHTML = gwpm.toFixed(2) + ''; // Gross Words Per Minute //document.getElementById("nwpmWordsResult").innerText = nwpm.toFixed(2); // Net Words Per Minute document.getElementById("nwpmWordsResult").innerHTML = nwpm.toFixed(2) + ''; document.getElementById("totalTypedWordsResult").innerText = totalTypedWords; document.getElementById("totalWordsResult").innerText = totalWords; document.getElementById("totalKeystrokeResult").innerText = totalKeystrokes; document.getElementById("typedKeystrokesResult").innerText = typedKeystrokes; document.getElementById("remainingKeystrokesResult").innerText = remainingKeystrokes; document.getElementById("correctWordsResult").innerText = correctWords; document.getElementById("incorrectWordsResult").innerText = incorrectWords; document.getElementById("correctKeystrokesResult").innerText = correctKeystrokes; document.getElementById("incorrectKeystrokesResult").innerText = incorrectKeystrokes; document.getElementById("remainingWordsResult").innerText = remainingWords; //document.getElementById("accuracyWordsResult").innerText = accuracyWords.toFixed(2) + "%"; document.getElementById("accuracyWordsResult").innerHTML = accuracyWords.toFixed(2) + "%" + ''; // Accuracy in percentage with 2 decimal places //document.getElementById("accuracyKeystrokesResult").innerText = accuracyKeystrokes.toFixed(2) + "%"; // Accuracy in percentage with 2 decimal places document.getElementById("accuracyKeystrokesResult").innerHTML = accuracyKeystrokes.toFixed(2) + "%" + ''; //document.getElementById("gkpmKeystrokesResult").innerText = gkpmKeystrokes.toFixed(2); document.getElementById("gkpmKeystrokesResult").innerHTML = gkpmKeystrokes.toFixed(2) + ''; //document.getElementById("nkpmKeystrokesResult").innerText = nkpmKeystrokes.toFixed(2); document.getElementById("nkpmKeystrokesResult").innerHTML = nkpmKeystrokes.toFixed(2) + ''; // Elemetns hide or show when click on Go Back button document.getElementById("textareaContainer").style.display = "none"; document.getElementById("titleDiv").style.display = "block"; document.getElementById("resultContainer").style.display = "block"; } // ***Result displayed code ended here*** //---------------------------------------------------------------------// //---------------------------------------------------------------------// // Format Elapsed Time Function on result page function formatElapsedTime(totalTime) { const hours = Math.floor(totalTime / 3600); const minutes = Math.floor((totalTime % 3600) / 60); const seconds = Math.floor(totalTime % 60); return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; } //---------------------------------------------------------------------// //---------------------------------------------------------------------// // Calculate Incorrect Words Function giving value on our result page function calculateIncorrectWords(originalWords, typedWords) { let incorrectWords = 0; for (let i = 0; i < typedWords.length; i++) { if (originalWords[i] !== typedWords[i]) { incorrectWords++; } } return incorrectWords; } //---------------------------------------------------------------------// //---------------------------------------------------------------------// // Function to update the correct incorrect word and letters (keystrokes) counts in each label in the text area containter (change it carefully) const userInput = document.getElementById('inputTextarea'); const referenceText = document.getElementById('readonlyTextarea'); const wordCountCorrect = document.getElementById('correctWordCount'); const wordCountIncorrect = document.getElementById('incorrectWordCount'); const letterCountCorrect = document.getElementById('correctLetterCount'); const letterCountIncorrect = document.getElementById('incorrectLetterCount'); function updateWordCounts() { const referenceContent = referenceText.textContent.trim(); const userContent = userInput.value.trim(); if (userContent === '') { // If the input is empty, there are no correct or incorrect words wordCountCorrect.textContent = 0; wordCountIncorrect.textContent = 0; return; } const referenceWords = referenceContent.split(/\s+/); const userWords = userContent.split(/\s+/); let totalCorrectWords = 0; let totalIncorrectWords = 0; const minWordCount = Math.min(referenceWords.length, userWords.length); // Counting correct and incorrect words for (let i = 0; i < minWordCount; i++) { if (referenceWords[i] === userWords[i]) { totalCorrectWords++; } else { totalIncorrectWords++; } } // Update the labels with the counts wordCountIncorrect.textContent = totalIncorrectWords; wordCountCorrect.textContent = totalCorrectWords; } function countCorrectLetters(refWord, usrWord) { let correctLetters = 0; const minCharCount = Math.min(refWord.length, usrWord.length); for (let i = 0; i < minCharCount; i++) { if (refWord[i] === usrWord[i]) { correctLetters++; } } return correctLetters; } function countIncorrectLetters(refWord, usrWord) { let incorrectLetters = 0; const minCharCount = Math.min(refWord.length, usrWord.length); for (let i = 0; i < minCharCount; i++) { if (refWord[i] !== usrWord[i]) { incorrectLetters++; } } // Remaining characters in the longer word are incorrect incorrectLetters += Math.abs(refWord.length - usrWord.length); return incorrectLetters; } function updateLetterCounts() { const referenceContent = referenceText.textContent.trim(); const userContent = userInput.value.trim(); if (userContent === '') { // If the input is empty, there are no correct or incorrect letters letterCountCorrect.textContent = 0; letterCountIncorrect.textContent = 0; return; } const referenceWords = referenceContent.split(/\s+/); const userWords = userContent.split(/\s+/); let totalCorrectLetters = 0; let totalIncorrectLetters = 0; const minWordCount = Math.min(referenceWords.length, userWords.length); // Counting correct and incorrect letters for (let i = 0; i < minWordCount; i++) { totalCorrectLetters += countCorrectLetters(referenceWords[i], userWords[i]); totalIncorrectLetters += countIncorrectLetters(referenceWords[i], userWords[i]); } // Update the labels with the counts // letterCountCorrect.textContent = `K:${totalCorrectLetters}`; // letterCountIncorrect.textContent = `K:${totalIncorrectLetters}`; letterCountCorrect.textContent = totalCorrectLetters; letterCountIncorrect.textContent = totalIncorrectLetters; } // Event listener for space and backspace to update word counts userInput.addEventListener('keydown', function(event) { if (event.key === ' ' || event.key === 'Backspace') { setTimeout(updateWordCounts, 0); // Ensure textarea value is updated } }); // Event listener for any key to update letter counts userInput.addEventListener('keydown', function() { setTimeout(updateLetterCounts, 0); // Ensure textarea value is updated }); //---------------------------------------------------------------------// //---------------------------------------------------------------------// // Highlight Word Function // let currentWordIndex = 0; // Variable to track the index of the current word to highlight function getCursorWordIndex() { return currentWordIndex; } function highlightWords() { const inputTextarea = document.getElementById("inputTextarea"); const readonlyTextarea = document.getElementById("readonlyTextarea"); const wordsArray = readonlyTextarea.innerText.trim().split(/\s+/); const cursorWordIndex = getCursorWordIndex(); const autoscrollEnabled = document.getElementById("noAutoscroll").checked; const highlightEnabled = document.getElementById("noHighlighter").checked; const colorsEnabled = document.getElementById("noColor").checked; readonlyTextarea.innerHTML = wordsArray.map((word, index) => { let className = ''; if (index === cursorWordIndex && highlightEnabled) { className = 'highlight-background'; } else if (index < cursorWordIndex && colorsEnabled) { // Determine if the word is correct or incorrect const inputWords = inputTextarea.value.trim().split(/\s+/); if (inputWords[index] === word) { className = 'correct-word'; } else { className = 'incorrect-word'; } } return className ? `${word}` : word; }).join(" "); // Scroll to the current highlight if autoscroll is enabled if (autoscrollEnabled) { const highlightedElement = readonlyTextarea.querySelector('.highlight-background'); if (highlightedElement) { const rect = highlightedElement.getBoundingClientRect(); const containerRect = readonlyTextarea.getBoundingClientRect(); const scrollPadding = 40; // Space from the bottom in pixel value // Adjust scroll position if the highlighted word is near the bottom if (rect.bottom > containerRect.bottom - scrollPadding) { readonlyTextarea.scrollTop += rect.bottom - containerRect.bottom + scrollPadding; inputTextarea.scrollTop += rect.bottom - containerRect.bottom + scrollPadding; } } } } function handleKeyEvent(event) { const inputTextarea = document.getElementById("inputTextarea"); const cursorPosition = inputTextarea.selectionStart; const textBeforeCursor = inputTextarea.value.substring(0, cursorPosition).trim(); const backspaceEnabled = document.getElementById("disableBackspace").checked; if (event.key === " " && cursorPosition > 0) { currentWordIndex++; } else if (event.key === "Backspace" && backspaceEnabled) { const wordsBeforeCursor = textBeforeCursor.split(/\s+/); if (wordsBeforeCursor.length < currentWordIndex + 1) { currentWordIndex--; } } else if (event.key === "Backspace" && !backspaceEnabled) { event.preventDefault(); // Disable Backspace key } setTimeout(highlightWords, 1); // Ensure this runs after default key behavior } document.getElementById("inputTextarea").addEventListener("input", handleKeyEvent); document.getElementById("inputTextarea").addEventListener("keydown", function(event) { if (event.key === " " || event.key === "Backspace") { handleKeyEvent(event); // Call handleKeyEvent to update highlights after key press } }); // Event listener to enable inputTextarea on start button click document.getElementById("startButton").addEventListener("click", function() { const inputTextarea = document.getElementById("inputTextarea"); inputTextarea.disabled = false; inputTextarea.focus(); // Focus the textarea when enabled highlightWords(); // Initial highlight update pauseResume.disabled = false; }); // Add event listeners to update highlights, colors and autoscroll based on the checkboxes document.getElementById("noHighlighter").addEventListener("change", highlightWords); document.getElementById("noColor").addEventListener("change", highlightWords); document.getElementById("noAutoscroll").addEventListener("change", highlightWords); //---------------------------------------------------------------------// //---------------------------------------------------------------------// //////////Zoom function in-out code start here ////////// // Zoom In Function function zoomIn() { adjustFontSize(1); // Increase font size by 1px } // Zoom Out Function function zoomOut() { adjustFontSize(-1); // Decrease font size by 1px } // Function to adjust font size function adjustFontSize(change) { const inputTextarea = document.getElementById("inputTextarea"); const readonlyTextarea = document.getElementById("readonlyTextarea"); // Helper function to parse current font size function parseFontSize(fontSize) { return parseFloat(fontSize) || 20; // Default to 20px if not set } // Get current font sizes const inputSize = parseFontSize(window.getComputedStyle(inputTextarea).fontSize); const readonlySize = parseFontSize(window.getComputedStyle(readonlyTextarea).fontSize); // Set new font sizes inputTextarea.style.fontSize = (inputSize + change) + 'px'; readonlyTextarea.style.fontSize = (readonlySize + change) + 'px'; } //////////Zoom function in-out code ended here ////////// //---------------------------------------------------------------------// //---------------------------------------------------------------------// // Toggle Fullscreen const fullscreenToggle = document.getElementById('fullscreenToggle'); fullscreenToggle.addEventListener('change', function() { if (fullscreenToggle.checked) { document.documentElement.requestFullscreen(); } else { document.exitFullscreen(); } }); // Show or Hide Menu document.getElementById('toggleNavbar').addEventListener('change', function(event) { const navbar = document.getElementById('navbar'); if (event.target.checked) { navbar.classList.remove('hide'); } else { navbar.classList.add('hide'); } }); //---------------------------------------------------------------------// //---------------------------------------------------------------------// // Go To Form Function function goToForm() { //document.getElementById("formContainer").style.display = "block"; //document.getElementById("textareaContainer").style.display = "none"; //document.getElementById("resultContainer").style.display = "none"; //startButton.disabled = false; //submitButton.disabled = true; // Disable submit button when going back to form //clearInterval(interval); // Clear any running intervals //document.getElementById("testForm").reset(); //document.getElementById("inputTextarea").value = ""; window.location.href = window.location.href; } //---------------------------------------------------------------------// //---------------------------------------------------------------------// // Start Button Event Listener startButton.addEventListener("click", startTimer); // Submit Button Event Listener submitButton.addEventListener("click", endTest); //---------------------------------------------------------------------// //---------------------------------------------------------------------// //////////// Disable mouse click and other special key ... //////////// // Get the inputTextarea and readonlyTextarea elements const inputTextarea = document.getElementById("inputTextarea"); const readonlyTextarea = document.getElementById("readonlyTextarea"); // Set the cursor to default (arrow pointer) for both text areas inputTextarea.style.cursor = "default"; readonlyTextarea.style.cursor = "default"; // Disable mouse clicks and text selection inside the inputTextarea and readonlyTextarea inputTextarea.addEventListener('mousedown', function(event) { event.preventDefault(); // Prevents default mouse click behavior inputTextarea.focus(); // Forces focus on the inputTextarea }); readonlyTextarea.addEventListener('mousedown', function(event) { event.preventDefault(); // Prevents default mouse click behavior inputTextarea.focus(); // Forces focus on the inputTextarea }); // Prevent text selection inside the inputTextarea and readonlyTextarea inputTextarea.addEventListener('selectstart', function(event) { event.preventDefault(); // Prevents text selection }); readonlyTextarea.addEventListener('selectstart', function(event) { event.preventDefault(); // Prevents text selection }); // Disable context menu to prevent copying text via right-click on both textarea //inputTextarea.addEventListener('contextmenu', function(event) { //event.preventDefault(); // Prevents context menu from appearing //}); // Ensure inputTextarea remains focused when clicking outside document.addEventListener('click', function(event) { const isTextInput = event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA'; if (startTime && !isTextInput && !inputTextarea.contains(event.target)) { inputTextarea.focus(); } }); // Disable context menu to prevent left and right-click on entire page /////// document.addEventListener('contextmenu', function(event) { event.preventDefault(); // Prevents right click context menu from appearing inputTextarea.focus(); // Forces focus on the inputTextarea }); // Disable control key on entire page /////// document.addEventListener('keydown', function(event) { if (event.ctrlKey) { event.preventDefault(); } }); // Disable special key press and text selection in inputTextarea document.getElementById('inputTextarea').addEventListener('keydown', function(event) { // Disable Enter, Home, and End keys if (event.key === 'Enter' || event.key === 'Home' || event.key === 'End') { event.preventDefault(); } // Disable Shift + Arrow key combinations to select the text if (event.shiftKey && (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'ArrowLeft' || event.key === 'ArrowRight')) { event.preventDefault(); } // Disable Control key in inputTextarea if (event.ctrlKey) { event.preventDefault(); } }); //---------------------------------------------------------------------// //---------------------------------------------------------------------// // Bootstrap and MathJax for Tooltip Initialization // NWPM Render document.addEventListener('DOMContentLoaded', function () { var button = document.getElementById('nwpmWordsResult'); // Create and insert tooltip content var tooltipContent = `
\\[ NWPM = \\frac{\\text{Correct Words}}{\\text{Time Taken}} \\]
`; // Initialize Bootstrap tooltip with custom content var tooltip = new bootstrap.Tooltip(button, { title: tooltipContent, html: true, trigger: 'hover' }); // Re-render MathJax inside tooltips when they are shown button.addEventListener('shown.bs.tooltip', function () { MathJax.typeset(); }); }); // GWPM Render document.addEventListener('DOMContentLoaded', function () { var button = document.getElementById('gwpmWordsResult'); // Create and insert tooltip content var tooltipContent = `
\\[ GWPM = \\frac{\\text{Typed Word}}{\\text{Time Taken}} \\]
`; // Initialize Bootstrap tooltip with custom content var tooltip = new bootstrap.Tooltip(button, { title: tooltipContent, html: true, trigger: 'hover' }); // Re-render MathJax inside tooltips when they are shown button.addEventListener('shown.bs.tooltip', function () { MathJax.typeset(); }); }); // Accuracy Words document.addEventListener('DOMContentLoaded', function () { var button = document.getElementById('accuracyWordsResult'); // Create and insert tooltip content var tooltipContent = `
\\[ Accuracy = \\frac{\\text{Typed Words} - \\text{Incorrect Words}}{\\text{Typed Words }} \\times 100 \\]
`; // Initialize Bootstrap tooltip with custom content var tooltip = new bootstrap.Tooltip(button, { title: tooltipContent, html: true, trigger: 'hover' }); // Re-render MathJax inside tooltips when they are shown button.addEventListener('shown.bs.tooltip', function () { MathJax.typeset(); }); }); // NKPM Render document.addEventListener('DOMContentLoaded', function () { var button = document.getElementById('nkpmKeystrokesResult'); // Create and insert tooltip content var tooltipContent = `
\\[ NKPM = \\frac{\\left(\\text{Typed Keystrokes} - \\text{Incorrect Keystrokes}\\right) / 5}{\\text{Time Taken}} \\] Where 5 = 5 Keystrokes per Word
`; // Initialize Bootstrap tooltip with custom content var tooltip = new bootstrap.Tooltip(button, { title: tooltipContent, html: true, trigger: 'hover' }); // Re-render MathJax inside tooltips when they are shown button.addEventListener('shown.bs.tooltip', function () { MathJax.typeset(); }); }); // GKPM Render document.addEventListener('DOMContentLoaded', function () { var button = document.getElementById('gkpmKeystrokesResult'); // Create and insert tooltip content var tooltipContent = `
\\[ GKPM = \\frac{\\frac{\\text{Typed Keystrokes}}{5}}{\\text{Time Taken}} \\] Where 5 = 5 Keystrokes per Word
`; // Initialize Bootstrap tooltip with custom content var tooltip = new bootstrap.Tooltip(button, { title: tooltipContent, html: true, trigger: 'hover' }); // Re-render MathJax inside tooltips when they are shown button.addEventListener('shown.bs.tooltip', function () { MathJax.typeset(); }); }); // Keystrokes Accuracy document.addEventListener('DOMContentLoaded', function () { var button = document.getElementById('accuracyKeystrokesResult'); // Create and insert tooltip content var tooltipContent = `
\\[ Accuracy = \\frac{\\text{Typed Keystrokes} - \\text{Incorrect Keystrokes}}{\\text{Typed Keystrokes }} \\times 100 \\]
`; // Initialize Bootstrap tooltip with custom content var tooltip = new bootstrap.Tooltip(button, { title: tooltipContent, html: true, trigger: 'hover' }); // Re-render MathJax inside tooltips when they are shown button.addEventListener('shown.bs.tooltip', function () { MathJax.typeset(); }); }); //---------------------------------------------------------------------//