ui: Enable creating listeners using an object/hash (#5975)
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.
This commit is contained in:
parent
e66a1b3874
commit
011fb8a559
|
@ -15,11 +15,25 @@ class Listeners {
|
|||
addEventListener = 'on';
|
||||
removeEventListener = 'off';
|
||||
}
|
||||
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);
|
||||
remove = function() {
|
||||
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 () => {
|
||||
|
|
|
@ -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({
|
||||
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);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue