|
function contextListener(listener) { |
|
return function(event) { |
|
listener.call(this, event, this.__data__); |
|
}; |
|
} |
|
|
|
function parseTypenames(typenames) { |
|
return typenames.trim().split(/^|\s+/).map(function(t) { |
|
var name = "", i = t.indexOf("."); |
|
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); |
|
return {type: t, name: name}; |
|
}); |
|
} |
|
|
|
function onRemove(typename) { |
|
return function() { |
|
var on = this.__on; |
|
if (!on) return; |
|
for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { |
|
if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { |
|
this.removeEventListener(o.type, o.listener, o.options); |
|
} else { |
|
on[++i] = o; |
|
} |
|
} |
|
if (++i) on.length = i; |
|
else delete this.__on; |
|
}; |
|
} |
|
|
|
function onAdd(typename, value, options) { |
|
return function() { |
|
var on = this.__on, o, listener = contextListener(value); |
|
if (on) for (var j = 0, m = on.length; j < m; ++j) { |
|
if ((o = on[j]).type === typename.type && o.name === typename.name) { |
|
this.removeEventListener(o.type, o.listener, o.options); |
|
this.addEventListener(o.type, o.listener = listener, o.options = options); |
|
o.value = value; |
|
return; |
|
} |
|
} |
|
this.addEventListener(typename.type, listener, options); |
|
o = {type: typename.type, name: typename.name, value: value, listener: listener, options: options}; |
|
if (!on) this.__on = [o]; |
|
else on.push(o); |
|
}; |
|
} |
|
|
|
export default function(typename, value, options) { |
|
var typenames = parseTypenames(typename + ""), i, n = typenames.length, t; |
|
|
|
if (arguments.length < 2) { |
|
var on = this.node().__on; |
|
if (on) for (var j = 0, m = on.length, o; j < m; ++j) { |
|
for (i = 0, o = on[j]; i < n; ++i) { |
|
if ((t = typenames[i]).type === o.type && t.name === o.name) { |
|
return o.value; |
|
} |
|
} |
|
} |
|
return; |
|
} |
|
|
|
on = value ? onAdd : onRemove; |
|
for (i = 0; i < n; ++i) this.each(on(typenames[i], value, options)); |
|
return this; |
|
} |
|
|