forked from marmelab/gremlins.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
typer.js
132 lines (114 loc) · 4.73 KB
/
typer.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
* The typer gremlin types keys on the keyboard
*
* Note that keyboard events must be localized somewhere on screen, so this
* gremlins picks a random screen location first.
*
* By default, the typer gremlin activity is showed by a letter surrounded by
* a orange circle with a keyname on it.
*
* var typerGremlin = gremlins.species.typer();
* horde.gremlin(typerGremlin);
*
* The typerGremlin gremlin can be customized as follows:
*
* typerGremlin.eventTypes(['keypress', 'keyup', 'keydown']); // types of events to trigger
* typerGremlin.showAction(function(element) { // show the gremlin activity on screen });
* typerGremlin.logger(loggerObject); // inject a logger
* typerGremlin.randomizer(randomizerObject); // inject a randomizer
*
*/
define(function(require) {
"use strict";
var configurable = require('../utils/configurable');
var Chance = require('../vendor/chance');
var RandomizerRequiredException = require('../exceptions/randomizerRequired');
return function() {
var document = window.document,
documentElement = document.documentElement,
body = document.body;
var defaultEventTypes = ['keypress', 'keyup', 'keydown'];
function defaultKeyGenerator() {
return config.randomizer.natural({ min: 3, max: 254});
}
function defaultTargetElement(x, y) {
return document.elementFromPoint(x, y);
}
function defaultShowAction(targetElement, x, y, key) {
var typeSignal = document.createElement('div');
typeSignal.style.zIndex = 2000;
typeSignal.style.border = "3px solid orange";
typeSignal.style['border-radius'] = '50%'; // Chrome
typeSignal.style.borderRadius = '50%'; // Mozilla
typeSignal.style.width = "40px";
typeSignal.style.height = "40px";
typeSignal.style['box-sizing'] = 'border-box';
typeSignal.style.position = "absolute";
typeSignal.style.webkitTransition = 'opacity 1s ease-out';
typeSignal.style.mozTransition = 'opacity 1s ease-out';
typeSignal.style.transition = 'opacity 1s ease-out';
typeSignal.style.left = x + 'px';
typeSignal.style.top = y + 'px';
typeSignal.style.textAlign = 'center';
typeSignal.style.paddingTop = '7px';
typeSignal.innerHTML = String.fromCharCode(key);
var element = body.appendChild(typeSignal);
setTimeout(function () {
body.removeChild(element);
}, 1000);
setTimeout(function () {
element.style.opacity = 0;
}, 50);
}
/**
* @mixin
*/
var config = {
eventTypes: defaultEventTypes,
showAction: defaultShowAction,
keyGenerator: defaultKeyGenerator,
targetElement: defaultTargetElement,
logger: null,
randomizer: null
};
/**
* @mixes config
*/
function typerGremlin() {
if (!config.randomizer) {
throw new RandomizerRequiredException();
}
var keyboardEvent = document.createEventObject ? document.createEventObject() : document.createEvent("Events"),
eventType = config.randomizer.pick(config.eventTypes),
key = config.keyGenerator(),
posX = config.randomizer.natural({ max: documentElement.clientWidth - 1 }),
posY = config.randomizer.natural({ max: documentElement.clientHeight - 1 }),
targetElement = config.targetElement(posX, posY);
if(keyboardEvent.initEvent){
keyboardEvent.initEvent(eventType, true, true);
}
keyboardEvent.keyCode = key;
keyboardEvent.which = key;
keyboardEvent.keyCodeVal = key;
targetElement.dispatchEvent ? targetElement.dispatchEvent(keyboardEvent) : targetElement.fireEvent("on" + eventType, keyboardEvent);
if (typeof config.showAction === 'function') {
config.showAction(targetElement, posX, posY, key);
}
if (config.logger && typeof config.logger.log == 'function') {
var event = {
species: 'gremlin',
type: 'typer',
action: 'key',
value: String.fromCharCode(key),
element: targetElement,
posX: posX,
posY: posY,
timestamp: new Date().getTime()
};
config.logger.log(event);
}
}
configurable(typerGremlin, config);
return typerGremlin;
};
});