UNPKG

ampersand-events

Version:

Module that can be mixed into any object to provide eventing. Heavily based on Backbone Events.

67 lines (60 loc) 2.61 kB
var uniqueId = require('lodash/uniqueId'); var eventSplitter = /\s+/; // A difficult-to-believe, but optimized internal dispatch function for // triggering events. Tries to keep the usual cases speedy. exports.triggerEvents = function triggerEvents(events, args) { var ev; var i = -1; var l = events.length; var a1 = args[0]; var a2 = args[1]; var a3 = args[2]; switch (args.length) { case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return; case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return; case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return; case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return; default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return; } }; // Implement fancy features of the Events API such as multiple event // names `"change blur"` and jQuery-style event maps `{change: action}` // in terms of the existing API. exports.eventsApi = function eventsApi(obj, action, name, rest) { if (!name) return true; // Handle event maps. if (typeof name === 'object') { for (var key in name) { obj[action].apply(obj, [key, name[key]].concat(rest)); } return false; } // Handle space separated event names. if (eventSplitter.test(name)) { var names = name.split(eventSplitter); for (var i = 0, l = names.length; i < l; i++) { obj[action].apply(obj, [names[i]].concat(rest)); } return false; } return true; }; // Inversion-of-control versions of `on` and `once`. Tell *this* object to // listen to an event in another object ... keeping track of what it's // listening to. exports.createListenMethod = function createListenMethod(implementation) { return function listenMethod(obj, name, callback) { if (!obj) { throw new Error('Trying to listenTo event: \'' + name + '\' but the target object is undefined'); } var listeningTo = this._listeningTo || (this._listeningTo = {}); var id = obj._listenId || (obj._listenId = uniqueId('l')); listeningTo[id] = obj; if (!callback && typeof name === 'object') callback = this; if (typeof obj[implementation] !== 'function') { throw new Error('Trying to listenTo event: \'' + name + '\' on object: ' + obj.toString() + ' but it does not have an \'on\' method so is unbindable'); } obj[implementation](name, callback, this); return this; }; };