UNPKG

qoopido.nucleus

Version:

Lightweight, atomic and modular JavaScript utility library that strongly encourages the creation and usage of small yet flexible, reusable and easily maintainable modules.

171 lines (130 loc) 3.95 kB
/** * @use /demand/weakmap */ (function() { 'use strict'; function definition(Weakmap, iterate) { var regexMatchExcludedMethods = /^(_|((get|has|is)([A-Z]|$))|(on|one|off|emit|constructor)$)/, objectDefineProperty = Object.defineProperty, objectGetOwnPropertyNames = Object.getOwnPropertyNames, objectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, objectGetPrototypeOf = Object.getPrototypeOf, objectPrototype = Object.prototype, storage = new Weakmap(); function getStorage(context) { return storage.get(context) || (storage.set(context, {}) && storage.get(context)); } function getPropertyNames(object) { var prototype = object, keys = [], names, i, name; try { while(prototype !== objectPrototype) { for(names = objectGetOwnPropertyNames(prototype), i = 0; (name = names[i]); i++) { keys.indexOf(name) === -1 && keys.push(name); } prototype = prototype.__proto__; } } catch(error) { // required for IE compatibility } return keys; } function getPropertyDescriptor(object, property) { var prototype = object, descriptor; while(prototype && !(descriptor = objectGetOwnPropertyDescriptor(prototype, property))) { prototype = prototype.__proto__; } return descriptor; } function wrap() { var self = this, prototype = self.constructor.prototype, properties = getPropertyNames(prototype); properties.forEach(function(property) { var descriptor = getPropertyDescriptor(prototype, property), event; if(!descriptor.get && typeof self[property] === 'function' && regexMatchExcludedMethods.test(property) === false) { event = property.charAt(0).toUpperCase() + property.slice(1); descriptor.value = function() { var result; self.emit('pre' + event, arguments); result = prototype[property].apply(self, arguments); self.emit('post' + event, arguments, result); return result; }; objectDefineProperty(self, property, descriptor); } }); } function Emitter() { if(objectGetPrototypeOf(self) !== Emitter.prototype) { wrap.call(this); } return this; } Emitter.prototype = { on: function(events, fn) { var self = this, pointer = getStorage(self), i = 0, event; events = events.split(' '); for(; (event = events[i]) !== undefined; i++) { (pointer[event] = pointer[event] || []).push(fn); } return self; }, one: function(events, fn, each) { var self = this; each = (each !== false); self.on(events, function listener(event) { self.off(((each === true) ? event : events), listener); fn.apply(this, arguments); }); return self; }, off: function(events, fn) { var self = this, pointer = getStorage(self), i = 0, event, j, listener; if(events) { events = events.split(' '); for(; (event = events[i]) !== undefined; i++) { pointer[event] = pointer[event] || []; if(fn) { for(j = 0; (listener = pointer[event][j]) !== undefined; j++) { if(listener === fn) { pointer[event].splice(j, 1); j--; } } } else { pointer[event].length = 0; } } } else { iterate(self.listener, function(event) { pointer[event].length = 0; }); } return self; }, emit: function(event) { var self = this, pointer, temp, i = 0, listener; if(event) { pointer = getStorage(self); pointer[event] = pointer[event] || []; temp = pointer[event].slice(); for(; (listener = temp[i]) !== undefined; i++) { listener.apply(self, arguments); } } return self; } }; return Emitter; } provide([ '/demand/weakmap', '/demand/function/iterate' ], definition); }());