Don't call keybinding callbacks multiple times, stricter capture/bubble checks

This commit is contained in:
Bryan Housel
2016-05-16 14:20:09 -04:00
parent a18976b0ac
commit 0f17f64eca
2 changed files with 25 additions and 8 deletions

View File

@@ -15,25 +15,29 @@ d3.keybinding = function(namespace) {
if (event[p] != binding.event[p])
return false;
}
return (!binding.capture) === (event.eventPhase !== Event.CAPTURING_PHASE);
return true;
}
function capture() {
function testBindings(isCapturing) {
for (var i = 0; i < bindings.length; i++) {
var binding = bindings[i];
if (matches(binding, d3.event)) {
if (!!binding.capture === isCapturing && matches(binding, d3.event)) {
binding.callback();
}
}
}
function capture() {
testBindings(true);
}
function bubble() {
var tagName = d3.select(d3.event.target).node().tagName;
if (tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA') {
return;
}
capture();
testBindings(false);
}
function keybinding(selection) {

View File

@@ -25,7 +25,7 @@ describe("d3.keybinding", function() {
expect(spy).not.to.have.been.called;
happen.keydown(document, {keyCode: 65});
expect(spy).to.have.been.called;
expect(spy).to.have.been.calledOnce;
});
it("adds a binding for the specified key combination", function () {
@@ -35,7 +35,7 @@ describe("d3.keybinding", function() {
expect(spy).not.to.have.been.called;
happen.keydown(document, {keyCode: 65, metaKey: true});
expect(spy).to.have.been.called;
expect(spy).to.have.been.calledOnce;
});
it("does not dispatch when focus is in input elements by default", function () {
@@ -49,7 +49,20 @@ describe("d3.keybinding", function() {
d3.select(document).call(keybinding.on('A', spy, true));
happen.keydown(input.node(), {keyCode: 65});
expect(spy).to.have.been.called;
expect(spy).to.have.been.calledOnce;
});
it("resets bindings when keybinding.off is called", function () {
d3.select(document).call(keybinding.on('A', spy));
happen.keydown(document, {keyCode: 65});
expect(spy).to.have.been.calledOnce;
spy = sinon.spy();
d3.select(document).call(keybinding.off);
d3.select(document).call(keybinding.on('A', spy));
happen.keydown(document, {keyCode: 65});
expect(spy).to.have.been.calledOnce;
});
});
});