UNPKG

rizzo-next

Version:

The next generation of Lonely Planet's style guide and pattern library.

193 lines (174 loc) 6.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var each = require("lodash/each"), _once = require("lodash/once"), keys = require("lodash/keys"), isEmpty = require("lodash/isEmpty"), uniqueId = require("lodash/uniqueId"), slice = Array.prototype.slice; // Regular expression used to split event strings. var eventSplitter = /\s+/; // 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. function eventsApi(obj, action, name, rest) { if (!name) return true; // Handle event maps. if ((typeof name === "undefined" ? "undefined" : _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; } // A difficult-to-believe, but optimized internal dispatch function for // triggering events. Tries to keep the usual cases speedy (most internal // Backbone events have 3 arguments). function triggerEvents(events, args) { var ev = void 0, i = -1, l = events.length, a1 = args[0], a2 = args[1], 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; } } var Events = { // Bind an event to a `callback` function. Passing `"all"` will bind // the callback to all events fired. on: function on(name, callback, context) { if (!eventsApi(this, "on", name, [callback, context]) || !callback) return this; this._events || (this._events = {}); var events = this._events[name] || (this._events[name] = []); events.push({ callback: callback, context: context, ctx: context || this }); return this; }, // Bind an event to only be triggered a single time. After the first time // the callback is invoked, it will be removed. once: function once(name, callback, context) { if (!eventsApi(this, "once", name, [callback, context]) || !callback) return this; var self = this; var onced = _once(function () { self.off(name, _once); callback.apply(this, arguments); }); onced._callback = callback; return this.on(name, onced, context); }, // Remove one or many callbacks. If `context` is null, removes all // callbacks with that function. If `callback` is null, removes all // callbacks for the event. If `name` is null, removes all bound // callbacks for all events. off: function off(name, callback, context) { var retain = void 0, ev = void 0, events = void 0, names = void 0, i = void 0, l = void 0, j = void 0, k = void 0; if (!this._events || !eventsApi(this, "off", name, [callback, context])) return this; if (!name && !callback && !context) { this._events = void 0; return this; } names = name ? [name] : keys(this._events); for (i = 0, l = names.length; i < l; i++) { name = names[i]; if (events = this._events[name]) { this._events[name] = retain = []; if (callback || context) { for (j = 0, k = events.length; j < k; j++) { ev = events[j]; if (callback && callback !== ev.callback && callback !== ev.callback._callback || context && context !== ev.context) { retain.push(ev); } } } if (!retain.length) delete this._events[name]; } } return this; }, // Trigger one or many events, firing all bound callbacks. Callbacks are // passed the same arguments as `trigger` is, apart from the event name // (unless you're listening on `"all"`, which will cause your callback to // receive the true name of the event as the first argument). trigger: function trigger(name) { if (!this._events) return this; var args = slice.call(arguments, 1); if (!eventsApi(this, "trigger", name, args)) return this; var events = this._events[name]; var allEvents = this._events.all; if (events) triggerEvents(events, args); if (allEvents) triggerEvents(allEvents, arguments); return this; }, // Tell this object to stop listening to either specific events ... or // to every object it's currently listening to. stopListening: function stopListening(obj, name, callback) { var listeningTo = this._listeningTo; if (!listeningTo) return this; var remove = !name && !callback; if (!callback && (typeof name === "undefined" ? "undefined" : _typeof(name)) === "object") callback = this; if (obj) (listeningTo = {})[obj._listenId] = obj; for (var id in listeningTo) { obj = listeningTo[id]; obj.off(name, callback, this); if (remove || isEmpty(obj._events)) delete this._listeningTo[id]; } return this; } }; var listenMethods = { listenTo: "on", listenToOnce: "once" }; // 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. each(listenMethods, function (implementation, method) { Events[method] = function (obj, name, callback) { var listeningTo = this._listeningTo || (this._listeningTo = {}); var id = obj._listenId || (obj._listenId = uniqueId("l")); listeningTo[id] = obj; if (!callback && (typeof name === "undefined" ? "undefined" : _typeof(name)) === "object") callback = this; obj[implementation](name, callback, this); return this; }; }); // Aliases for backwards compatibility. Events.bind = Events.on; Events.unbind = Events.off; exports.default = Events;