-
Notifications
You must be signed in to change notification settings - Fork 426
/
clicker.js
109 lines (99 loc) · 3.38 KB
/
clicker.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
const getDefaultConfig = (randomizer, window) => {
const document = window.document;
const body = document.body;
const defaultClickTypes = [
'click',
'click',
'click',
'click',
'click',
'click',
'dblclick',
'dblclick',
'mousedown',
'mouseup',
'mouseover',
'mouseover',
'mouseover',
'mousemove',
'mouseout',
];
const defaultPositionSelector = () => {
return [
randomizer.natural({
max: Math.max(0, document.documentElement.clientWidth - 1),
}),
randomizer.natural({
max: Math.max(0, document.documentElement.clientHeight - 1),
}),
];
};
const defaultShowAction = (x, y) => {
const clickSignal = document.createElement('div');
clickSignal.style.zIndex = 2000;
clickSignal.style.border = '3px solid red';
// todo clean chrome/mozilla hack
clickSignal.style['border-radius'] = '50%'; // Chrome
clickSignal.style.borderRadius = '50%'; // Mozilla
clickSignal.style.width = '40px';
clickSignal.style.height = '40px';
clickSignal.style['box-sizing'] = 'border-box';
clickSignal.style.position = 'absolute';
clickSignal.style.webkitTransition = 'opacity 1s ease-out';
clickSignal.style.mozTransition = 'opacity 1s ease-out';
clickSignal.style.transition = 'opacity 1s ease-out';
clickSignal.style.left = x - 20 + 'px';
clickSignal.style.top = y - 20 + 'px';
const element = body.appendChild(clickSignal);
setTimeout(() => {
body.removeChild(element);
}, 1000);
setTimeout(() => {
element.style.opacity = 0;
}, 50);
};
const defaultCanClick = () => {
return true;
};
return {
clickTypes: defaultClickTypes,
positionSelector: defaultPositionSelector,
showAction: defaultShowAction,
canClick: defaultCanClick,
maxNbTries: 10,
log: false,
};
};
export default (userConfig) => ({ logger, randomizer, window }) => {
const document = window.document;
const config = {
...getDefaultConfig(randomizer, window),
...userConfig,
};
return () => {
let position;
let posX;
let posY;
let targetElement;
let nbTries = 0;
do {
position = config.positionSelector();
posX = position[0];
posY = position[1];
targetElement = document.elementFromPoint(posX, posY);
nbTries++;
if (nbTries > config.maxNbTries) return;
} while (!targetElement || !config.canClick(targetElement));
const evt = document.createEvent('MouseEvents');
const clickType = randomizer.pick(config.clickTypes);
// todo remove deprecated https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent
evt.initMouseEvent(clickType, true, true, window, 0, 0, 0, posX, posY, false, false, false, false, 0, null);
targetElement.dispatchEvent(evt);
if (typeof config.showAction === 'function') {
config.showAction(posX, posY, clickType);
}
if (logger && config.log) {
logger.log('gremlin', 'clicker ', clickType, 'at', posX, posY);
}
};
};