Repository

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;
    }
}