Skip to content

Commit

Permalink
Allow on to return the current listener.
Browse files Browse the repository at this point in the history
Fixes #216.
  • Loading branch information
mbostock committed Aug 23, 2011
1 parent a0fa7a0 commit a4500fc
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 15 deletions.
20 changes: 13 additions & 7 deletions d3.js
Original file line number Diff line number Diff line change
Expand Up @@ -1676,26 +1676,32 @@ d3_selectionPrototype.on = function(type, listener, capture) {
if (arguments.length < 3) capture = false;

// parse the type specifier
var i = type.indexOf("."),
typo = i === -1 ? type : type.substring(0, i),
name = "__on" + type;
var name = "__on" + type, i = type.indexOf(".");
if (i > 0) type = type.substring(0, i);

// if called with only one argument, return the current listener
if (arguments.length < 2) return (i = this.node()[name]) && i._;

// remove the old event listener, and add the new event listener
return this.each(function(d, i) {
if (this[name]) this.removeEventListener(typo, this[name], capture);
if (listener) this.addEventListener(typo, this[name] = l, capture);
var node = this;

if (node[name]) node.removeEventListener(type, node[name], capture);
if (listener) node.addEventListener(type, node[name] = l, capture);

// wrapped event listener that preserves i
var node = this;
function l(e) {
var o = d3.event; // Events can be reentrant (e.g., focus).
d3.event = e;
try {
listener.call(this, node.__data__, i);
listener.call(node, node.__data__, i);
} finally {
d3.event = o;
}
}

// stash the unwrapped listener for retrieval
l._ = listener;
});
};
d3_selectionPrototype.each = function(callback) {
Expand Down
2 changes: 1 addition & 1 deletion d3.min.js

Large diffs are not rendered by default.

20 changes: 13 additions & 7 deletions src/core/selection-on.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,31 @@ d3_selectionPrototype.on = function(type, listener, capture) {
if (arguments.length < 3) capture = false;

// parse the type specifier
var i = type.indexOf("."),
typo = i === -1 ? type : type.substring(0, i),
name = "__on" + type;
var name = "__on" + type, i = type.indexOf(".");
if (i > 0) type = type.substring(0, i);

// if called with only one argument, return the current listener
if (arguments.length < 2) return (i = this.node()[name]) && i._;

// remove the old event listener, and add the new event listener
return this.each(function(d, i) {
if (this[name]) this.removeEventListener(typo, this[name], capture);
if (listener) this.addEventListener(typo, this[name] = l, capture);
var node = this;

if (node[name]) node.removeEventListener(type, node[name], capture);
if (listener) node.addEventListener(type, node[name] = l, capture);

// wrapped event listener that preserves i
var node = this;
function l(e) {
var o = d3.event; // Events can be reentrant (e.g., focus).
d3.event = e;
try {
listener.call(this, node.__data__, i);
listener.call(node, node.__data__, i);
} finally {
d3.event = o;
}
}

// stash the unwrapped listener for retrieval
l._ = listener;
});
};
8 changes: 8 additions & 0 deletions test/core/selection-on-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ suite.addBatch({
},
"returns the current selection": function(body) {
assert.isTrue(body.on("submit", function() {}) === body);
},
"returns the assigned listener if called with one argument": function(body) {
body.on("mouseover", f).on("click.foo", f);
function f() {}
assert.equal(body.on("mouseover"), f);
assert.equal(body.on("click.foo"), f);
assert.isUndefined(body.on("click"));
assert.isUndefined(body.on("mouseover.foo"));
}
}
});
Expand Down

0 comments on commit a4500fc

Please sign in to comment.