-
Notifications
You must be signed in to change notification settings - Fork 0
/
background.js
93 lines (75 loc) · 2.32 KB
/
background.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
const State = {
Start: "0",
Stop: "1",
};
// Important: use "all" context as this also allows to write
// on "special" elements, such as google docs
chrome.contextMenus.create({
id: State.Start,
title: "Start typing",
contexts: ["all"],
});
chrome.contextMenus.create({
id: State.Stop,
title: "Stop typing",
contexts: ["all"],
});
chrome.contextMenus.onClicked.addListener(({ menuItemId }, tab) => {
if (menuItemId == State.Start) {
startTyping(tab.id);
} else {
stopTyping(tab.id);
}
});
// Track current task for each tab to prevent running multiple
// tasks on the same tab. New tasks will end previous ones.
let tasks = {};
const startTyping = async (tabId) => {
const taskId = Math.random();
tasks[tabId] = taskId;
await chrome.debugger.attach({ tabId }, "1.3").catch(() => {});
const text = [...(await readClipboard(tabId))];
let i = 0;
while (tasks[tabId] === taskId && i < text.length) {
await typeCharacter(tabId, text[i]);
// Random delay from 50ms to 200ms
// Source: https://sa.rochester.edu/jur/issues/fall2005/ordal.pdf
await wait(randomNumber(50, 200));
i++;
}
// cleanup
stopTyping(tabId);
};
const stopTyping = (tabId) => {
delete tasks[tabId];
};
const typeCharacter = async (tabId, character) => {
await chrome.debugger.sendCommand({ tabId }, "Input.insertText", { text: character });
/*
As there isn't a reliable way of sending certain characters like \n without
adding additional logic and the method below doesn't support emojis, the above
solution was just simpler. Might consider the one below if the current method
gets detected or blocked.
*/
//await chrome.debugger.sendCommand({ tabId }, "Input.dispatchKeyEvent", {
// type: "keyDown",
// code: character,
//});
//await wait(randomNumber(70, 150));
//await chrome.debugger.sendCommand({ tabId }, "Input.dispatchKeyEvent", {
// type: "keyUp",
// code: character,
//});
};
const readClipboard = async (tabId) => {
return chrome.scripting
.executeScript({
target: { tabId },
func: () => navigator.clipboard.readText(),
})
.then(([{ result }]) => result);
};
const wait = (milliseconds) =>
new Promise((resolve) => setTimeout(resolve, milliseconds));
const randomNumber = (min, max) =>
Math.floor(Math.random() * (max - min + 1)) + min;