Skip to content

Commit

Permalink
Merge pull request #7 from nickdesaulniers/objListener
Browse files Browse the repository at this point in the history
allow obj listeners with handleEvent methods Fixes #6
  • Loading branch information
mysticatea committed Dec 17, 2015
2 parents 58e9619 + 6847d27 commit a08a57f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
21 changes: 17 additions & 4 deletions lib/event-target.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ var EventTarget = module.exports = function EventTarget() {
}
};

function hasHandleEventMethod(obj) {
return typeof obj === "object" && "handleEvent" in obj && typeof
obj.handleEvent === "function";
}

EventTarget.prototype = Object.create(
(HAS_EVENTTARGET_INTERFACE ? window.EventTarget : Object).prototype,
{
Expand All @@ -105,11 +110,12 @@ EventTarget.prototype = Object.create(

addEventListener: {
value: function addEventListener(type, listener, capture) {
if (listener == null) {
if (!listener) {
return false;
}
if (typeof listener !== "function") {
throw new TypeError("listener should be a function.");
var isObjListener = hasHandleEventMethod(listener);
if (typeof listener !== "function" && !isObjListener) {
throw new TypeError("listener should be a function or have a handleEvent method.");
}

var kind = (capture ? CAPTURE : BUBBLE);
Expand Down Expand Up @@ -180,7 +186,14 @@ EventTarget.prototype = Object.create(
// This doesn't process capturing phase and bubbling phase.
// This isn't participating in a tree.
while (node != null) {
node.listener.call(this, wrapped);
var isObjListener = hasHandleEventMethod(node.listener);
if (isObjListener) {
node.listener.handleEvent.bind(node.listener).call(this, wrapped);
}
else {
node.listener.call(this, wrapped);
}

if (wrapped[STOP_IMMEDIATE_PROPAGATION_FLAG]) {
break;
}
Expand Down
35 changes: 34 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,45 @@ describe("EventTarget:", function() {
target.removeEventListener("test");
});

it("should throw a TypeError if the listener is not a function", function() {
it("should throw a TypeError if the listener is not a function or object with a handleEvent method", function() {
assert.throws(
function() { target.addEventListener("test", "listener"); },
TypeError
);
});

it("should allow a listener to be an object with a handleEvent method and have this set correctly", function() {
var listener = {
__proto__: {
handleEvent: function() {
this.complete();
},
complete: function() {
assert(true);
}
}
};
var event = createEvent("test");
target.addEventListener("test", listener);
target.dispatchEvent(event);
});

it("should not call removed object listeners.", function() {
var listener = {
__proto__: {
handleEvent: function() {
this.complete();
},
complete: function() {
assert(false);
}
}
};
var event = createEvent("test");
target.addEventListener("test", listener);
target.removeEventListener("test", listener);
target.dispatchEvent(event);
});
});

describe("EventTarget with attribute listeners:", function() {
Expand Down

0 comments on commit a08a57f

Please sign in to comment.