-
Notifications
You must be signed in to change notification settings - Fork 0
/
dispatch.js
69 lines (55 loc) · 1.61 KB
/
dispatch.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
var d3_Map = require('./map');
module.exports = function() {
var dispatch = new d3_dispatch,
i = -1,
n = arguments.length;
while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
return dispatch;
};
function d3_dispatch() {}
d3_dispatch.prototype.on = function(type, listener) {
var i = type.indexOf("."),
name = "";
// Extract optional namespace, e.g., "click.foo"
if (i >= 0) {
name = type.substring(i + 1);
type = type.substring(0, i);
}
if (type) return arguments.length < 2
? this[type].on(name)
: this[type].on(name, listener);
if (arguments.length === 2) {
if (listener == null) for (type in this) {
if (this.hasOwnProperty(type)) this[type].on(name, null);
}
return this;
}
};
function d3_dispatch_event(dispatch) {
var listeners = [],
listenerByName = new d3_Map;
function event() {
var z = listeners, // defensive reference
i = -1,
n = z.length,
l;
while (++i < n) if (l = z[i].on) l.apply(this, arguments);
return dispatch;
}
event.on = function(name, listener) {
var l = listenerByName.get(name),
i;
// return the current listener, if any
if (arguments.length < 2) return l && l.on;
// remove the old listener, if any (with copy-on-write)
if (l) {
l.on = null;
listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1));
listenerByName.remove(name);
}
// add the new listener, if any
if (listener) listeners.push(listenerByName.set(name, {on: listener}));
return dispatch;
};
return event;
}