-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathdom-delegator.js
More file actions
131 lines (102 loc) · 3.34 KB
/
Copy pathdom-delegator.js
File metadata and controls
131 lines (102 loc) · 3.34 KB
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
var globalDocument = require("global/document")
var DataSet = require("data-set")
var addEvent = require("./add-event.js")
var removeEvent = require("./remove-event.js")
var ProxyEvent = require("./proxy-event.js")
module.exports = DOMDelegator
function DOMDelegator(document) {
document = document || globalDocument
this.target = document.documentElement
this.events = {}
this.rawEventListeners = {}
this.globalListeners = {}
}
DOMDelegator.prototype.addEventListener = addEvent
DOMDelegator.prototype.removeEventListener = removeEvent
DOMDelegator.prototype.addGlobalEventListener =
function addGlobalEventListener(eventName, fn) {
var listeners = this.globalListeners[eventName]
if (!listeners) {
listeners = this.globalListeners[eventName] = []
}
if (listeners.indexOf(fn) === -1) {
listeners.push(fn)
}
}
DOMDelegator.prototype.removeGlobalEventListener =
function removeGlobalEventListener(eventName, fn) {
var listeners = this.globalListeners[eventName]
if (!listeners) {
return
}
var index = listeners.indexOf(fn)
if (index !== -1) {
listeners.splice(index, 1)
}
}
DOMDelegator.prototype.listenTo = function listenTo(eventName) {
if (this.events[eventName]) {
return
}
this.events[eventName] = true
listen(this, eventName)
}
DOMDelegator.prototype.unlistenTo = function unlistenTo(eventName) {
if (!this.events[eventName]) {
return
}
this.events[eventName] = false
unlisten(this, eventName)
}
function listen(delegator, eventName) {
var listener = delegator.rawEventListeners[eventName]
if (!listener) {
listener = delegator.rawEventListeners[eventName] =
createHandler(eventName, delegator.globalListeners)
}
delegator.target.addEventListener(eventName, listener, true)
}
function unlisten(delegator, eventName) {
var listener = delegator.rawEventListeners[eventName]
if (!listener) {
throw new Error("dom-delegator#unlistenTo: cannot " +
"unlisten to " + eventName)
}
delegator.target.removeEventListener(eventName, listener, true)
}
function createHandler(eventName, globalListeners) {
return handler
function handler(ev) {
var globalHandlers = globalListeners[eventName] || []
var listener = getListener(ev.target, eventName)
var handlers = globalHandlers
.concat(listener ? listener.handlers : [])
if (handlers.length === 0) {
return
}
var arg = new ProxyEvent(ev, listener)
handlers.forEach(function (handler) {
typeof handler === "function" ?
handler(arg) : handler.handleEvent(arg)
})
}
}
function getListener(target, type) {
// terminate recursion if parent is `null`
if (target === null) {
return null
}
var ds = DataSet(target)
// fetch list of handler fns for this event
var handler = ds[type]
var allHandler = ds.event
if (!handler && !allHandler) {
return getListener(target.parentNode, type)
}
var handlers = [].concat(handler || [], allHandler || [])
return new Listener(target, handlers)
}
function Listener(target, handlers) {
this.currentTarget = target
this.handlers = handlers
}