js/Mobilizing/core/util/EventEmitter.js
/**
* EventEmitter is a helper class to handle event emission
*/
export default class EventEmitter {
/**
* @param {Object} params Parameters object, given by the constructor.
* @param {Mixed} [params.scope] The scope to use for callbacks, should usually be set to the class instance using the EventEmitter. Defaults to the EventEmitter instance if not specified
*/
constructor({ scope = undefined } = {}) {
this.scope = scope !== undefined ? scope : this;
this.listeners = {};
}
/**
* Add an event listener
*
* @param {String} type The event type to listen to
* @param {Function} callback The callback to call when the event is captured
* @chainable
*/
on(type, callback) {
if (typeof this.listeners[type] === "undefined") {
this.listeners[type] = [];
}
this.listeners[type].push(callback);
return this;
}
/**
* Remove an event listener
*
* @param {String} type The event type to stop listen to
* @param {Function} [callback] The callback function associated with the listener. If not specified, all listeners will be removed
* @chainable
*/
off(type, callback) {
if (this.listeners[type] instanceof Array) {
if (typeof callback === "undefined") {
this.listeners[type] = [];
}
else {
const listeners = this.listeners[type];
for (let i = 0, len = listeners.length; i < len; i++) {
if (listeners[i] === callback) {
listeners.splice(i, 1);
break;
}
}
}
}
return this;
}
/**
* Trigger an event
*
* @param {String} type The event type
* @param {Mixed} [...data] Data to send along with the event
* @chainable
*/
trigger(type, ...data) {
if (this.listeners[type] instanceof Array) {
const listeners = this.listeners[type];
listeners.forEach((listener) => {
listener.call(this.scope, ...data);
});
}
return this;
}
}