Skip to content

Commit

Permalink
ui: Enable creating listeners using an object/hash (#5975)
Browse files Browse the repository at this point in the history
Makes listening to multiple events on one target slightly easier.
Adding events can be rolled up into passing through an object, and the
returned remove function removes all of the handlers in the object

For example:

```
//this.listen...
const remove = listeners.add(
  {
    'message': handler,
    'error': handler
  }
);
remove(); // removes all listeners in the object
```

The entire API for listeners is now becoming slightly overloaded, so
potentially we'd use this API always and remove the ability to use a
string/function pair.
  • Loading branch information
johncowen authored and John Cowen committed Aug 22, 2019
1 parent 41ff2d7 commit a44d362
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 10 deletions.
24 changes: 19 additions & 5 deletions ui-v2/app/utils/dom/create-listeners.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down
36 changes: 31 additions & 5 deletions ui-v2/tests/unit/utils/dom/create-listeners-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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() {},
Expand All @@ -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);
});

0 comments on commit a44d362

Please sign in to comment.