Human-Typer by Warrior

Simulate human typing in Google Docs and Slides with customizable settings such as typing speed, errors, and breaks.

目前為 2024-04-27 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Human-Typer by Warrior
  3. // @description Simulate human typing in Google Docs and Slides with customizable settings such as typing speed, errors, and breaks.
  4. // @version 1.3
  5. // @namespace http://yournamespace.com/human-typer
  6. // @match *://docs.google.com/document/*
  7. // @match *://docs.google.com/presentation/*
  8. // @include *://docs.google.com/document/*
  9. // @include *://docs.google.com/presentation/*
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. // Function to create a button on the Google Docs/Slides toolbar
  17. function createButton() {
  18. const toolbar = document.querySelector('.docs-titlebar-right');
  19. if (!toolbar) {
  20. return;
  21. }
  22.  
  23. const button = document.createElement("button");
  24. button.textContent = "Human-Typer";
  25. button.style.marginLeft = "10px";
  26. button.style.backgroundColor = "#000";
  27. button.style.color = "#fff";
  28. button.style.border = "none";
  29. button.style.padding = "8px 12px";
  30. button.style.borderRadius = "4px";
  31. button.style.cursor = "pointer";
  32. button.id = "human-typer-button";
  33.  
  34. // Add event listener to show UI overlay when button is clicked
  35. button.addEventListener("click", showUIOverlay);
  36. toolbar.appendChild(button);
  37. }
  38.  
  39. // Function to create and display the UI overlay for user customization
  40. function showUIOverlay() {
  41. // Check if an overlay already exists; if so, remove it
  42. const existingOverlay = document.getElementById("human-typer-overlay");
  43. if (existingOverlay) {
  44. document.body.removeChild(existingOverlay);
  45. return;
  46. }
  47.  
  48. // Create an overlay div for user input and customization options
  49. const overlay = document.createElement("div");
  50. overlay.id = "human-typer-overlay";
  51. overlay.style.position = "fixed";
  52. overlay.style.bottom = "10px";
  53. overlay.style.right = "10px";
  54. overlay.style.backgroundColor = "rgba(255, 255, 255, 0.9)";
  55. overlay.style.padding = "20px";
  56. overlay.style.border = "1px solid #ccc";
  57. overlay.style.borderRadius = "8px";
  58. overlay.style.boxShadow = "0px 2px 8px rgba(0, 0, 0, 0.1)";
  59. overlay.style.zIndex = "10000";
  60.  
  61. // Create input field for text input
  62. const textInput = document.createElement("textarea");
  63. textInput.rows = "4";
  64. textInput.placeholder = "Enter text to type...";
  65. textInput.style.width = "100%";
  66. textInput.style.marginBottom = "10px";
  67. textInput.style.padding = "8px";
  68. textInput.style.border = "1px solid #ccc";
  69. textInput.style.borderRadius = "4px";
  70.  
  71. // Create dropdown for typing speed selection
  72. const speedLabel = document.createElement("p");
  73. speedLabel.textContent = "Typing Speed:";
  74. const speedSelect = document.createElement("select");
  75. speedSelect.options.add(new Option("Fast", "fast"));
  76. speedSelect.options.add(new Option("Medium", "medium"));
  77. speedSelect.options.add(new Option("Normal", "normal"));
  78. speedSelect.options.add(new Option("Slow", "slow"));
  79. speedSelect.style.marginBottom = "10px";
  80.  
  81. // Create input for number of typing errors
  82. const errorLabel = document.createElement("p");
  83. errorLabel.textContent = "Number of Typing Errors:";
  84. const errorInput = document.createElement("input");
  85. errorInput.type = "number";
  86. errorInput.min = "0";
  87. errorInput.value = "0";
  88. errorInput.style.width = "100%";
  89. errorInput.style.marginBottom = "10px";
  90. errorInput.style.padding = "8px";
  91. errorInput.style.border = "1px solid #ccc";
  92. errorInput.style.borderRadius = "4px";
  93.  
  94. // Create input for the number of breaks
  95. const breakLabel = document.createElement("p");
  96. breakLabel.textContent = "Number of Breaks:";
  97. const breakInput = document.createElement("input");
  98. breakInput.type = "number";
  99. breakInput.min = "0";
  100. breakInput.value = "0";
  101. breakInput.style.width = "100%";
  102. breakInput.style.marginBottom = "10px";
  103. breakInput.style.padding = "8px";
  104. breakInput.style.border = "1px solid #ccc";
  105. breakInput.style.borderRadius = "4px";
  106.  
  107. // Create input for the duration of each break in minutes
  108. const breakDurationLabel = document.createElement("p");
  109. breakDurationLabel.textContent = "Duration of Each Break (minutes):";
  110. const breakDurationInput = document.createElement("input");
  111. breakDurationInput.type = "number";
  112. breakDurationInput.min = "0";
  113. breakDurationInput.value = "0";
  114. breakDurationInput.style.width = "100%";
  115. breakDurationInput.style.marginBottom = "10px";
  116. breakDurationInput.style.padding = "8px";
  117. breakDurationInput.style.border = "1px solid #ccc";
  118. breakDurationInput.style.borderRadius = "4px";
  119.  
  120. // Create a button to start typing
  121. const startButton = document.createElement("button");
  122. startButton.textContent = "Start Typing";
  123. startButton.style.padding = "8px 16px";
  124. startButton.style.backgroundColor = "#1a73e8";
  125. startButton.style.color = "#fff";
  126. startButton.style.border = "none";
  127. startButton.style.borderRadius = "4px";
  128. startButton.style.cursor = "pointer";
  129.  
  130. // Append elements to the overlay
  131. overlay.appendChild(textInput);
  132. overlay.appendChild(speedLabel);
  133. overlay.appendChild(speedSelect);
  134. overlay.appendChild(errorLabel);
  135. overlay.appendChild(errorInput);
  136. overlay.appendChild(breakLabel);
  137. overlay.appendChild(breakInput);
  138. overlay.appendChild(breakDurationLabel);
  139. overlay.appendChild(breakDurationInput);
  140. overlay.appendChild(startButton);
  141.  
  142. // Append the overlay to the body
  143. document.body.appendChild(overlay);
  144.  
  145. // Add an event listener to the start button
  146. startButton.addEventListener("click", () => {
  147. // Get user input values from the overlay
  148. const text = textInput.value.trim();
  149. const speed = speedSelect.value;
  150. const numErrors = parseInt(errorInput.value);
  151. const numBreaks = parseInt(breakInput.value);
  152. const breakDuration = parseInt(breakDurationInput.value);
  153.  
  154. // Remove the overlay from the page
  155. document.body.removeChild(overlay);
  156.  
  157. // Call function to start typing with user-defined options
  158. startTyping(text, speed, numErrors, numBreaks, breakDuration);
  159. });
  160. }
  161.  
  162. // Function to simulate typing with errors and breaks
  163. function startTyping(text, speed, numErrors, numBreaks, breakDuration) {
  164. // Select the active element in the iframe to simulate typing
  165. const inputElement = document.querySelector(".docs-texteventtarget-iframe").contentDocument.activeElement;
  166.  
  167. // Define speed settings based on user choice
  168. const speedSettings = {
  169. fast: { lowerBound: 50, upperBound: 150 },
  170. medium: { lowerBound: 60, upperBound: 220 },
  171. normal: { lowerBound: 70, upperBound: 200 },
  172. slow: { lowerBound: 80, upperBound: 250 }
  173. };
  174.  
  175. // Get the lower and upper bounds for the chosen typing speed
  176. const lowerBound = speedSettings[speed].lowerBound;
  177. const upperBound = speedSettings[speed].upperBound;
  178.  
  179. let currentErrorCount = 0; // Track current error count
  180. let currentBreakCount = 0; // Track current break count
  181.  
  182. // Calculate interval for breaks based on the number of breaks
  183. let breakInterval = numBreaks > 0 ? Math.floor(text.length / numBreaks) : text.length;
  184.  
  185. // Convert break duration from minutes to milliseconds
  186. let breakTime = breakDuration * 60 * 1000;
  187.  
  188. // Function to type a character with optional errors and delay
  189. async function typeCharacter(character, delay) {
  190. return new Promise((resolve) => {
  191. if (currentErrorCount < numErrors && Math.random() < 0.05) {
  192. // Introduce a random typing error
  193. inputElement.value += character;
  194. inputElement.value = inputElement.value.slice(0, -2);
  195. currentErrorCount++;
  196. } else {
  197. inputElement.value += character;
  198. }
  199.  
  200. setTimeout(resolve, delay);
  201. });
  202. }
  203.  
  204. // Function to type the text with the defined speed, errors, and breaks
  205. async function typeText(text) {
  206. for (let i = 0; i < text.length; i++) {
  207. // Generate a random delay based on the chosen speed
  208. const delay = Math.floor(Math.random() * (upperBound - lowerBound + 1)) + lowerBound;
  209.  
  210. // Check if it's time to take a break
  211. if (currentBreakCount < numBreaks && i > 0 && i % breakInterval === 0) {
  212. // Take a break
  213. await new Promise((resolve) => setTimeout(resolve, breakTime));
  214. currentBreakCount++;
  215. }
  216.  
  217. // Type the current character with a delay
  218. await typeCharacter(text[i], delay);
  219. }
  220. }
  221.  
  222. // Start typing the text
  223. typeText(text);
  224. }
  225.  
  226. // Create the button on the toolbar
  227. createButton();
  228. })();