/** * The `evented` mixin provides methods allowing an object to trigger events, * running externally registered event handlers. */ export default { /** * Arrays of registered event handlers, grouped by the event name. * * @type {Object} * @protected */ handlers: null, /** * Get all of the registered handlers for an event. * * @param {String} event The name of the event. * @return {Array} * @protected */ getHandlers(event) { this.handlers = this.handlers || {}; this.handlers[event] = this.handlers[event] || []; return this.handlers[event]; }, /** * Trigger an event. * * @param {String} event The name of the event. * @param {...*} args Arguments to pass to event handlers. * @public */ trigger(event, ...args) { this.getHandlers(event).forEach(handler => handler.apply(this, args)); }, /** * Register an event handler. * * @param {String} event The name of the event. * @param {function} handler The function to handle the event. */ on(event, handler) { this.getHandlers(event).push(handler); }, /** * Register an event handler so that it will run only once, and then * unregister itself. * * @param {String} event The name of the event. * @param {function} handler The function to handle the event. */ one(event, handler) { const wrapper = function() { handler.apply(this, arguments); this.off(event, wrapper); }; this.getHandlers(event).push(wrapper); }, /** * Unregister an event handler. * * @param {String} event The name of the event. * @param {function} handler The function that handles the event. */ off(event, handler) { const handlers = this.getHandlers(event); const index = handlers.indexOf(handler); if (index !== -1) { handlers.splice(index, 1); } } }