Simulate human typing in Google Docs and Google Slides with customizable options.
目前為
// ==UserScript==
// @name Human-Typer for Google Docs/Slides
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Simulate human typing in Google Docs and Google Slides with customizable options.
// @author Your Name
// @match https://docs.google.com/*
// @match https://slides.google.com/*
// @grant none
// @require https://code.jquery.com/jquery-3.6.0.min.js
// ==/UserScript==
(function() {
'use strict';
// Constants
const TYPING_SPEEDS = {
fast: [50, 100],
medium: [100, 200],
normal: [200, 300],
slow: [300, 500]
};
let settings = {
text: "",
speed: "normal",
errorRate: 0,
breakTime: 1, // minutes
breakCount: 1
};
function addButton() {
const toolbar = document.querySelector('.docs-titlebar');
if (toolbar && !document.querySelector('#human-typer-button')) {
const button = document.createElement('button');
button.id = 'human-typer-button';
button.textContent = 'Human-Typer';
button.style.margin = '0 10px';
button.onclick = openSettingsOverlay;
toolbar.appendChild(button);
}
}
function openSettingsOverlay() {
if (document.querySelector('#human-typer-overlay')) return;
const overlay = document.createElement('div');
overlay.id = 'human-typer-overlay';
overlay.style.position = 'fixed';
overlay.style.top = '50px';
overlay.style.right = '50px';
overlay.style.backgroundColor = '#fff';
overlay.style.border = '1px solid #ccc';
overlay.style.padding = '20px';
overlay.style.zIndex = 1000;
overlay.innerHTML = `
<h3>Human-Typer Settings</h3>
<label for="ht-text">Text:</label><br>
<textarea id="ht-text" rows="4" cols="30"></textarea><br><br>
<label for="ht-speed">Typing Speed:</label><br>
<select id="ht-speed">
<option value="fast">Fast</option>
<option value="medium">Medium</option>
<option value="normal" selected>Normal</option>
<option value="slow">Slow</option>
</select><br><br>
<label for="ht-error-rate">Error Rate (%):</label><br>
<input type="number" id="ht-error-rate" min="0" max="20" value="0"><br><br>
<label for="ht-break-time">Break Time (minutes):</label><br>
<input type="number" id="ht-break-time" min="0" value="1"><br><br>
<label for="ht-break-count">Break Count:</label><br>
<input type="number" id="ht-break-count" min="0" value="1"><br><br>
<button id="ht-start-typing">Start Typing</button>
<button id="ht-close">Close</button>
`;
document.body.appendChild(overlay);
document.getElementById('ht-text').value = settings.text;
document.getElementById('ht-speed').value = settings.speed;
document.getElementById('ht-error-rate').value = settings.errorRate;
document.getElementById('ht-break-time').value = settings.breakTime;
document.getElementById('ht-break-count').value = settings.breakCount;
document.getElementById('ht-start-typing').onclick = startTyping;
document.getElementById('ht-close').onclick = () => overlay.remove();
}
function startTyping() {
settings.text = document.getElementById('ht-text').value;
settings.speed = document.getElementById('ht-speed').value;
settings.errorRate = parseInt(document.getElementById('ht-error-rate').value, 10);
settings.breakTime = parseInt(document.getElementById('ht-break-time').value, 10) * 60000; // convert to ms
settings.breakCount = parseInt(document.getElementById('ht-break-count').value, 10);
document.getElementById('human-typer-overlay').remove();
typeText();
}
function typeText() {
const typingArea = document.activeElement;
const text = settings.text.split('');
const [minDelay, maxDelay] = TYPING_SPEEDS[settings.speed];
const totalBreaks = settings.breakCount;
let breakInterval = settings.breakTime / totalBreaks;
let currentBreak = 0;
function typeNextChar() {
if (text.length === 0) return;
let char = text.shift();
if (Math.random() * 100 < settings.errorRate) {
char = String.fromCharCode(Math.random() * (126 - 33) + 33); // Random char
}
typingArea.focus();
typingArea.dispatchEvent(new KeyboardEvent('keydown', { key: char }));
typingArea.dispatchEvent(new KeyboardEvent('keypress', { key: char }));
typingArea.dispatchEvent(new KeyboardEvent('keyup', { key: char }));
typingArea.textContent += char;
let delay = Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
setTimeout(() => {
if (text.length === 0 && currentBreak < totalBreaks) {
currentBreak++;
setTimeout(typeNextChar, breakInterval);
} else {
typeNextChar();
}
}, delay);
}
typeNextChar();
}
window.addEventListener('load', addButton);
})();