diff --git a/src/event/target.js b/src/event/target.js index 1d363d24..4f802117 100644 --- a/src/event/target.js +++ b/src/event/target.js @@ -29,6 +29,15 @@ class EventTarget { if (filter(this.listeners[type], item => item === listener).length === 0) { this.listeners[type].push(listener); } + } else if (typeof listener === 'object' && Object.prototype.hasOwnProperty.call(listener, 'handleEvent')) { + if (!Array.isArray(this.listeners[type])) { + this.listeners[type] = []; + } + + // Only add the same function once + if (filter(this.listeners[type], item => item === listener.handleEvent).length === 0) { + this.listeners[type].push(listener.handleEvent); + } } } diff --git a/tests/unit/event-target.test.js b/tests/unit/event-target.test.js index 1a5122f6..d87ab946 100644 --- a/tests/unit/event-target.test.js +++ b/tests/unit/event-target.test.js @@ -37,6 +37,35 @@ test('adding/removing "message" event listeners works', t => { mock.dispatchEvent(eventObject); }); +test('adding/removing "message" for objects with handleEvent function works', t => { + const mock = new Mock(); + const eventObject = createEvent({ + type: 'message' + }); + + const fooListener = { + handleEvent: event => { + t.is(event.type, 'message'); + } + }; + + const barListener = { + handleEvent: event => { + t.is(event.type, 'message'); + } + }; + + mock.addEventListener('message', fooListener); + mock.addEventListener('message', barListener); + mock.dispatchEvent(eventObject); + + mock.removeEventListener('message', fooListener); + mock.dispatchEvent(eventObject); + + mock.removeEventListener('message', barListener); + mock.dispatchEvent(eventObject); +}); + test('events to different object should not share events', t => { const mock = new Mock(); const mockFoo = new MockFoo(); @@ -65,6 +94,38 @@ test('events to different object should not share events', t => { mockFoo.dispatchEvent(eventObject); }); +test('events to different object should not share events', t => { + const mock = new Mock(); + const mockFoo = new MockFoo(); + const eventObject = createEvent({ + type: 'message' + }); + + const fooListener = { + handleEvent: event => { + t.is(event.type, 'message'); + } + }; + const barListener = { + handleEvent: event => { + t.is(event.type, 'message'); + } + }; + + mock.addEventListener('message', fooListener); + mockFoo.addEventListener('message', barListener); + mock.dispatchEvent(eventObject); + mockFoo.dispatchEvent(eventObject); + + mock.removeEventListener('message', fooListener); + mock.dispatchEvent(eventObject); + mockFoo.dispatchEvent(eventObject); + + mockFoo.removeEventListener('message', barListener); + mock.dispatchEvent(eventObject); + mockFoo.dispatchEvent(eventObject); +}); + test('that adding the same function twice for the same event type is only added once', t => { const mock = new Mock(); const fooListener = event => { @@ -81,6 +142,26 @@ test('that adding the same function twice for the same event type is only added t.is(mock.listeners.message.length, 2); }); +test('that adding the same function twice for the same event type is only added once', t => { + const mock = new Mock(); + const fooListener = { + handleEvent: event => { + t.is(event.type, 'message'); + } + }; + const barListener = { + handleEvent: event => { + t.is(event.type, 'message'); + } + }; + + mock.addEventListener('message', fooListener); + mock.addEventListener('message', fooListener); + mock.addEventListener('message', barListener); + + t.is(mock.listeners.message.length, 2); +}); + test('that dispatching an event with multiple data arguments works correctly', t => { const mock = new Mock(); const eventObject = createEvent({ @@ -97,3 +178,22 @@ test('that dispatching an event with multiple data arguments works correctly', t mock.addEventListener('message', fooListener); mock.dispatchEvent(eventObject, 'foo', 'bar', 'baz'); }); + +test('that dispatching an event with multiple data arguments works correctly', t => { + const mock = new Mock(); + const eventObject = createEvent({ + type: 'message' + }); + + const fooListener = { + handleEvent: (...data) => { + t.is(data.length, 3); + t.is(data[0], 'foo'); + t.is(data[1], 'bar'); + t.is(data[2], 'baz'); + } + }; + + mock.addEventListener('message', fooListener); + mock.dispatchEvent(eventObject, 'foo', 'bar', 'baz'); +});