UNPKG

riot-observable

Version:

Simple script to send and receive events

140 lines (120 loc) 3.69 kB
;(function(window, undefined) {var observable = function(el) { /** * Extend the original object or create a new empty one * @type { Object } */ el = el || {} /** * Private variables and methods */ var callbacks = {}, slice = Array.prototype.slice, onEachEvent = function(e, fn) { e.replace(/\S+/g, fn) } // extend the object adding the observable methods Object.defineProperties(el, { /** * Listen to the given space separated list of `events` and execute the `callback` each time an event is triggered. * @param { String } events - events ids * @param { Function } fn - callback function * @returns { Object } el */ on: { value: function(events, fn) { if (typeof fn != 'function') return el onEachEvent(events, function(name, pos) { (callbacks[name] = callbacks[name] || []).push(fn) fn.typed = pos > 0 }) return el }, enumerable: false, writable: false, configurable: false }, /** * Removes the given space separated list of `events` listeners * @param { String } events - events ids * @param { Function } fn - callback function * @returns { Object } el */ off: { value: function(events, fn) { if (events == '*' && !fn) callbacks = {} else { onEachEvent(events, function(name) { if (fn) { var arr = callbacks[name] for (var i = 0, cb; cb = arr && arr[i]; ++i) { if (cb == fn) arr.splice(i--, 1) } } else delete callbacks[name] }) } return el }, enumerable: false, writable: false, configurable: false }, /** * Listen to the given space separated list of `events` and execute the `callback` at most once * @param { String } events - events ids * @param { Function } fn - callback function * @returns { Object } el */ one: { value: function(events, fn) { function on() { el.off(events, on) fn.apply(el, arguments) } return el.on(events, on) }, enumerable: false, writable: false, configurable: false }, /** * Execute all callback functions that listen to the given space separated list of `events` * @param { String } events - events ids * @returns { Object } el */ trigger: { value: function(events) { // getting the arguments var arglen = arguments.length - 1, args = new Array(arglen), fns for (var i = 0; i < arglen; i++) { args[i] = arguments[i + 1] // skip first argument } onEachEvent(events, function(name) { fns = slice.call(callbacks[name] || [], 0) for (var i = 0, fn; fn = fns[i]; ++i) { if (fn.busy) return fn.busy = 1 fn.apply(el, fn.typed ? [name].concat(args) : args) if (fns[i] !== fn) { i-- } fn.busy = 0 } if (callbacks['*'] && name != '*') el.trigger.apply(el, ['*', name].concat(args)) }) return el }, enumerable: false, writable: false, configurable: false } }) return el } /* istanbul ignore next */ // support CommonJS, AMD & browser if (typeof exports === 'object') module.exports = observable else if (typeof define === 'function' && define.amd) define(function() { return observable }) else window.observable = observable })(typeof window != 'undefined' ? window : undefined);