/** * Implemented by all those classes that emit events. */ export default class EventEmitter { /** * Connects to an object event. * * @param {String} eventName The event name * @param {Function} callback The callback function * @param {Object} thisArg The scope for the callback or %null */ on(eventName, callback, thisArg) { if (!this.$events) this.$events = {}; if (!this.$events[eventName]) this.$events[eventName] = []; this.$events[eventName].push({callback, thisArg}); } /** * Disconnects all handlers for callback. * * @param {Function} callback The callback function */ off(callback) { if (!this.$events) return; for (let event in this.$events) { for (let i = 0; i < event.length; i++) { if (event[i].callback === callback) event.splice(i--, 1); } } } /** * Disconnects all instance callbacks. * * @param {Object} thisArg The callbacks instance */ disconnect(thisArg) { if (!this.$events) return; for (let event in this.$events) { for (let i = 0; i < event.length; i++) { if (event[i].thisArg === thisArg) event.splice(i--, 1); } } } /** * Emits an event. * * @param {String} eventName The event name * @param {...*} args Arguments to pass to the callbacks */ emit(eventName) { if (!this.$events || !this.$events[eventName]) return; let args = Array.prototype.slice.call(arguments, 1); let callbacks = this.$events[eventName]; for (let callback of callbacks) callback.callback.apply(callback.thisArg, args); } /** * Links the object with another object events. * * @param {Object} propValue The property and the new value * @param {Object} handlers The event handlers */ linkEvents(propValue, handlers) { for (let prop in propValue) { let value = propValue[prop]; if (this[prop]) this[prop].disconnect(this); this[prop] = value; if (value) { for (let event in handlers) value.on(event, handlers[event], this); } } } } EventEmitter.$inject = ['$element', '$scope'];