133 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
var d        = require('d')
 | 
						|
  , callable = require('es5-ext/object/valid-callable')
 | 
						|
 | 
						|
  , apply = Function.prototype.apply, call = Function.prototype.call
 | 
						|
  , create = Object.create, defineProperty = Object.defineProperty
 | 
						|
  , defineProperties = Object.defineProperties
 | 
						|
  , hasOwnProperty = Object.prototype.hasOwnProperty
 | 
						|
  , descriptor = { configurable: true, enumerable: false, writable: true }
 | 
						|
 | 
						|
  , on, once, off, emit, methods, descriptors, base;
 | 
						|
 | 
						|
on = function (type, listener) {
 | 
						|
	var data;
 | 
						|
 | 
						|
	callable(listener);
 | 
						|
 | 
						|
	if (!hasOwnProperty.call(this, '__ee__')) {
 | 
						|
		data = descriptor.value = create(null);
 | 
						|
		defineProperty(this, '__ee__', descriptor);
 | 
						|
		descriptor.value = null;
 | 
						|
	} else {
 | 
						|
		data = this.__ee__;
 | 
						|
	}
 | 
						|
	if (!data[type]) data[type] = listener;
 | 
						|
	else if (typeof data[type] === 'object') data[type].push(listener);
 | 
						|
	else data[type] = [data[type], listener];
 | 
						|
 | 
						|
	return this;
 | 
						|
};
 | 
						|
 | 
						|
once = function (type, listener) {
 | 
						|
	var once, self;
 | 
						|
 | 
						|
	callable(listener);
 | 
						|
	self = this;
 | 
						|
	on.call(this, type, once = function () {
 | 
						|
		off.call(self, type, once);
 | 
						|
		apply.call(listener, this, arguments);
 | 
						|
	});
 | 
						|
 | 
						|
	once.__eeOnceListener__ = listener;
 | 
						|
	return this;
 | 
						|
};
 | 
						|
 | 
						|
off = function (type, listener) {
 | 
						|
	var data, listeners, candidate, i;
 | 
						|
 | 
						|
	callable(listener);
 | 
						|
 | 
						|
	if (!hasOwnProperty.call(this, '__ee__')) return this;
 | 
						|
	data = this.__ee__;
 | 
						|
	if (!data[type]) return this;
 | 
						|
	listeners = data[type];
 | 
						|
 | 
						|
	if (typeof listeners === 'object') {
 | 
						|
		for (i = 0; (candidate = listeners[i]); ++i) {
 | 
						|
			if ((candidate === listener) ||
 | 
						|
					(candidate.__eeOnceListener__ === listener)) {
 | 
						|
				if (listeners.length === 2) data[type] = listeners[i ? 0 : 1];
 | 
						|
				else listeners.splice(i, 1);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		if ((listeners === listener) ||
 | 
						|
				(listeners.__eeOnceListener__ === listener)) {
 | 
						|
			delete data[type];
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return this;
 | 
						|
};
 | 
						|
 | 
						|
emit = function (type) {
 | 
						|
	var i, l, listener, listeners, args;
 | 
						|
 | 
						|
	if (!hasOwnProperty.call(this, '__ee__')) return;
 | 
						|
	listeners = this.__ee__[type];
 | 
						|
	if (!listeners) return;
 | 
						|
 | 
						|
	if (typeof listeners === 'object') {
 | 
						|
		l = arguments.length;
 | 
						|
		args = new Array(l - 1);
 | 
						|
		for (i = 1; i < l; ++i) args[i - 1] = arguments[i];
 | 
						|
 | 
						|
		listeners = listeners.slice();
 | 
						|
		for (i = 0; (listener = listeners[i]); ++i) {
 | 
						|
			apply.call(listener, this, args);
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		switch (arguments.length) {
 | 
						|
		case 1:
 | 
						|
			call.call(listeners, this);
 | 
						|
			break;
 | 
						|
		case 2:
 | 
						|
			call.call(listeners, this, arguments[1]);
 | 
						|
			break;
 | 
						|
		case 3:
 | 
						|
			call.call(listeners, this, arguments[1], arguments[2]);
 | 
						|
			break;
 | 
						|
		default:
 | 
						|
			l = arguments.length;
 | 
						|
			args = new Array(l - 1);
 | 
						|
			for (i = 1; i < l; ++i) {
 | 
						|
				args[i - 1] = arguments[i];
 | 
						|
			}
 | 
						|
			apply.call(listeners, this, args);
 | 
						|
		}
 | 
						|
	}
 | 
						|
};
 | 
						|
 | 
						|
methods = {
 | 
						|
	on: on,
 | 
						|
	once: once,
 | 
						|
	off: off,
 | 
						|
	emit: emit
 | 
						|
};
 | 
						|
 | 
						|
descriptors = {
 | 
						|
	on: d(on),
 | 
						|
	once: d(once),
 | 
						|
	off: d(off),
 | 
						|
	emit: d(emit)
 | 
						|
};
 | 
						|
 | 
						|
base = defineProperties({}, descriptors);
 | 
						|
 | 
						|
module.exports = exports = function (o) {
 | 
						|
	return (o == null) ? create(base) : defineProperties(Object(o), descriptors);
 | 
						|
};
 | 
						|
exports.methods = methods;
 |