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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
// Add events to elements
/*
;[ 'click',
'dblclick',
'mousedown',
'mouseup',
'mouseover',
'mouseout',
'mousemove',
'mouseenter',
'mouseleave',
'touchstart',
'touchmove',
'touchleave',
'touchend',
'touchcancel' ].forEach(function (event) {
// add event to SVG.Element
SVG.Element.prototype[event] = function (f) {
// bind event to element rather than element node
SVG.on(this, event, f)
return this
}
})
*/
SVG.listenerId = 0
// Add event binder in the SVG namespace
SVG.on = function (node, events, listener, binding, options) {
var l = listener.bind(binding || node)
var n = node instanceof SVG.EventTarget ? node.getEventTarget() : node
// events can be an array of events or a string of events
events = Array.isArray(events) ? events : events.split(SVG.regex.delimiter)
// ensure instance object for nodes which are not adopted
n.instance = n.instance || {events: {}}
// pull event handlers from the element
var bag = n.instance.events
// add id to listener
if (!listener._svgjsListenerId) {
listener._svgjsListenerId = ++SVG.listenerId
}
events.forEach(function (event) {
var ev = event.split('.')[0]
var ns = event.split('.')[1] || '*'
// ensure valid object
bag[ev] = bag[ev] || {}
bag[ev][ns] = bag[ev][ns] || {}
// reference listener
bag[ev][ns][listener._svgjsListenerId] = l
// add listener
n.addEventListener(ev, l, options || false)
})
}
// Add event unbinder in the SVG namespace
SVG.off = function (node, events, listener, options) {
var n = node instanceof SVG.EventTarget ? node.getEventTarget() : node
if (!n.instance) return
// listener can be a function or a number
if (typeof listener === 'function') {
listener = listener._svgjsListenerId
if (!listener) return
}
// pull event handlers from the element
var bag = n.instance.events
// events can be an array of events or a string or undefined
events = Array.isArray(events) ? events : (events || '').split(SVG.regex.delimiter)
events.forEach(function (event) {
var ev = event && event.split('.')[0]
var ns = event && event.split('.')[1]
var namespace, l
if (listener) {
// remove listener reference
if (bag[ev] && bag[ev][ns || '*']) {
// removeListener
n.removeEventListener(ev, bag[ev][ns || '*'][listener], options || false)
delete bag[ev][ns || '*'][listener]
}
} else if (ev && ns) {
// remove all listeners for a namespaced event
if (bag[ev] && bag[ev][ns]) {
for (l in bag[ev][ns]) { SVG.off(n, [ev, ns].join('.'), l) }
delete bag[ev][ns]
}
} else if (ns) {
// remove all listeners for a specific namespace
for (event in bag) {
for (namespace in bag[event]) {
if (ns === namespace) { SVG.off(n, [event, ns].join('.')) }
}
}
} else if (ev) {
// remove all listeners for the event
if (bag[ev]) {
for (namespace in bag[ev]) { SVG.off(n, [ev, namespace].join('.')) }
delete bag[ev]
}
} else {
// remove all listeners on a given node
for (event in bag) { SVG.off(n, event) }
n.instance.events = {}
}
})
}
SVG.dispatch = function (node, event, data) {
var n = node instanceof SVG.EventTarget ? node.getEventTarget() : node
// Dispatch event
if (event instanceof window.Event) {
n.dispatchEvent(event)
} else {
event = new window.CustomEvent(event, {detail: data, cancelable: true})
n.dispatchEvent(event)
}
return event
}
SVG.EventTarget = SVG.invent({
create: function () {},
extend: {
// Bind given event to listener
on: function (event, listener, binding, options) {
SVG.on(this, event, listener, binding, options)
return this
},
// Unbind event from listener
off: function (event, listener) {
SVG.off(this, event, listener)
return this
},
dispatch: function (event, data) {
return SVG.dispatch(this, event, data)
},
// Fire given event
fire: function (event, data) {
this.dispatch(event, data)
return this
}
}
})
|