diff --git a/ui-v2/app/utils/dom/create-listeners.js b/ui-v2/app/utils/dom/create-listeners.js index d317a773fc29..c8ffe26c41c0 100644 --- a/ui-v2/app/utils/dom/create-listeners.js +++ b/ui-v2/app/utils/dom/create-listeners.js @@ -15,11 +15,25 @@ class Listeners { addEventListener = 'on'; removeEventListener = 'off'; } - target[addEventListener](event, handler); - remove = function() { - target[removeEventListener](event, handler); - return handler; - }; + let obj = event; + if (typeof obj === 'string') { + obj = { + [event]: handler, + }; + } + const removers = Object.keys(obj).map(function(key) { + return (function(event, handler) { + target[addEventListener](event, handler); + return function() { + target[removeEventListener](event, handler); + return handler; + }; + })(key, obj[key]); + }); + // TODO: if event was a string only return the first + // although the problem remains that it could sometimes return + // a function, sometimes an array, so this needs some more thought + remove = () => removers.map(item => item()); } this.listeners.push(remove); return () => { diff --git a/ui-v2/tests/unit/utils/dom/create-listeners-test.js b/ui-v2/tests/unit/utils/dom/create-listeners-test.js index afe2f618167e..ec8d9634ae2d 100644 --- a/ui-v2/tests/unit/utils/dom/create-listeners-test.js +++ b/ui-v2/tests/unit/utils/dom/create-listeners-test.js @@ -11,9 +11,12 @@ test('it has add and remove methods', function(assert) { }); test('add returns a remove function', function(assert) { const listeners = createListeners(); - const remove = listeners.add({ - addEventListener: function() {}, - }); + const remove = listeners.add( + { + addEventListener: function() {}, + }, + 'click' + ); assert.ok(typeof remove === 'function'); }); test('remove returns an array of removed handlers (the return of a saved remove)', function(assert) { @@ -50,6 +53,29 @@ test('listeners are added on add', function(assert) { assert.ok(stub.calledOnce); assert.ok(stub.calledWith(name, handler)); }); +test('listeners as objects are added on add and removed on remove', function(assert) { + const listeners = createListeners(); + const addStub = this.stub(); + const removeStub = this.stub(); + const target = { + addEventListener: addStub, + removeEventListener: removeStub, + }; + const handler = function(e) {}; + const remove = listeners.add(target, { + message: handler, + error: handler, + }); + assert.ok(addStub.calledTwice); + assert.ok(addStub.calledWith('message', handler)); + assert.ok(addStub.calledWith('error', handler)); + + remove(); + + assert.ok(removeStub.calledTwice); + assert.ok(removeStub.calledWith('message', handler)); + assert.ok(removeStub.calledWith('error', handler)); +}); test('listeners are removed on remove', function(assert) { const listeners = createListeners(); const stub = this.stub(); @@ -88,7 +114,7 @@ test('listeners as functions of other listeners are removed on remove', function remove(); assert.ok(stub.calledOnce); }); -test('remove returns the original handler', function(assert) { +test('remove returns an array containing the original handler', function(assert) { const listeners = createListeners(); const target = { addEventListener: function() {}, @@ -98,6 +124,6 @@ test('remove returns the original handler', function(assert) { const expected = this.stub(); const remove = listeners.add(target, name, expected); const actual = remove(); - actual(); + actual[0](); assert.ok(expected.calledOnce); });