-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
127 lines (108 loc) · 2.88 KB
/
index.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
var ever = require('ever')
, vkey = require('vkey')
, max = Math.max
, EventEmitter = require('events').EventEmitter
module.exports = function(el, bindings, state, opts) {
var root = null
if(bindings === undefined || !el.ownerDocument) {
state = bindings
bindings = el
el = this.document.body
try {
root = window.top.document.body
} catch(e){}
}
var ee = ever(el)
, re = root ? ever(root) : ee
, measured = {}
, enabled = true
opts = opts || {}
opts.preventDefaults = (opts.preventDefaults === undefined) ? true : opts.preventDefaults
state = state || {}
state.down = new EventEmitter()
state.up = new EventEmitter()
state.changed = new EventEmitter()
state.bindings = bindings
// always initialize the state.
for(var key in bindings) {
if(bindings[key] === 'enabled' ||
bindings[key] === 'enable' ||
bindings[key] === 'disable' ||
bindings[key] === 'destroy' ||
bindings[key] === 'down' ||
bindings[key] === 'up' ||
bindings[key] === 'changed' ||
bindings[key] === 'bindings') {
throw new Error(bindings[key]+' is reserved')
}
state[bindings[key]] = 0
measured[key] = 1
}
re.on('keyup', wrapped(onoff(kb, false)))
re.on('keydown', wrapped(onoff(kb, true)))
ee.on('mouseup', wrapped(onoff(mouse, false)))
ee.on('mousedown', wrapped(onoff(mouse, true)))
ee.on('contextmenu', function(ev) {
if (opts.preventDefaults) ev.preventDefault()
})
state.enabled = function() {
return enabled
}
state.enable = enable_disable(true)
state.disable = enable_disable(false)
state.destroy = function() {
re.removeAllListeners()
ee.removeAllListeners()
}
return state
function clear() {
// always initialize the state.
for(var key in bindings) {
state[bindings[key]] = 0
measured[key] = 1
}
}
function enable_disable(on_or_off) {
return function() {
clear()
enabled = on_or_off
return this
}
}
function wrapped(fn) {
return function(ev) {
if(enabled) {
if (opts.preventDefaults) ev.preventDefault()
fn(ev)
} else {
return
}
}
}
function onoff(find, on_or_off) {
return function(ev) {
var key = find(ev)
, binding = bindings[key]
if(binding) {
var previous_state = state[binding];
state[binding] += on_or_off ? max(measured[key]--, 0) : -(measured[key] = 1)
if(!on_or_off && state[binding] < 0) {
state[binding] = 0
}
if (previous_state !== state[binding]) {
if (on_or_off)
state.down.emit(binding)
else
state.up.emit(binding)
state.changed.emit(binding, on_or_off)
}
}
}
}
function mouse(ev) {
return '<mouse '+ev.which+'>'
}
function kb(ev) {
return vkey[ev.keyCode] || ev.char
}
}