Skip to content

Instantly share code, notes, and snippets.

@tatat
Last active September 30, 2015 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tatat/1838843 to your computer and use it in GitHub Desktop.
Save tatat/1838843 to your computer and use it in GitHub Desktop.
(function(g, undefined) {
var __index_of = !Array.prototype.indexOf ? function (array, search) {
var len = array.length
, from = Number(arguments[1]) || 0;
from = from < 0 ? Math.ceil(from) : Math.floor(from);
if (from < 0) from += len;
for (; from < len; from ++) {
if(from in array && array[from] === search)
return from;
}
return -1;
} : function (array, search) {
return array.indexOf(search);
};
var __slice = Array.prototype.slice;
/**
* Ev
* */
var Ev = function(E) {
this.__events = {};
this.__emitted = {};
if (!this.Event)
this.Event = E || Ev.Event;
};
Ev.prototype.on = function(event, listener, once, at) {
var __evts = this.__events
, evts = __evts[event]
, evt = {
type: event
, listener: listener
, once: !! once
};
if(!evts) {
evts = __evts[event] = evt;
at = 0;
} else if (evts.constructor === Object) {
if (at === 0) {
evts = __evts[event] = [evt, evts];
} else {
evts = __evts[event] = [evts, evt];
at = 1;
}
} else {
if (at != null && typeof at === 'number') {
evts.splice(at, 0, evt);
} else {
at = evts.length;
evts.push(evt);
}
}
return this.emit('newlistener', event, listener, once, at);
};
Ev.prototype.once = function (event, listener, at) {
return this.on(event, listener, true, at);
};
Ev.prototype.at = function(at, event, listener, once) {
var evts = this.__events[event];
if (at === 'first') {
at = 0;
} else if (at === 'last') {
at = null;
} else {
at = parseInt(at);
if (isNaN(at)) at = null;
}
return this.on(event, listener, once, at);
};
Ev.prototype.off = function(event, listener) {
var __evts = this.__events
, evts = __evts[event]
, index
, ec;
if (!evts)
return this;
if (listener == null) {
delete __evts[event];
return this;
}
ec = evts.constructor;
if (listener.constructor === Object) {
if (ec === Object && evts === listener) {
delete __evts[event];
} else if (evts.length === 1 && evts[0] === listener) {
delete __evts[event];
} else {
index = __index_of(evts, listener);
index !== -1 && evts.splice(index, 1);
if (evts.length === 0)
delete __evts[event];
}
} else if (ec === Object && evts.listener === listener) {
delete __evts[event];
} else if (evts.length === 1 && evts[0].listener === listener) {
delete __evts[event];
} else {
for (var i = 0, j = evts.length; i < j; i ++) {
if (evts[i].listener === listener) {
evts.splice(i, 1);
break;
}
if (evts.length === 0)
delete __evts[event];
}
}
return this;
};
Ev.prototype.size = function(event) {
return this.listeners(event, true).length;
};
Ev.prototype.ever = function(event) {
return this.__emitted[event] || 0;
};
Ev.prototype.listeners = function (event, with_params) {
var evts = this.__events[event];
if (evts) {
if (evts.constructor === Object) {
return [with_params ? evts : evts.listener];
} else {
if (with_params) {
return evts.slice(0);
} else {
for (var result = [], i = 0, j = evts.length; i < j; i ++)
result.push(evts[i].listener);
return result;
}
}
} else {
return [];
}
};
Ev.prototype.emit = function (event /* [, args] ...*/) {
var event_type;
if (typeof event === 'string') {
event_type = event;
event = null;
} else {
event_type = event.type;
}
var a = arguments
, emitted = this.__emitted
, evts = this.__events[event_type]
, j;
if (emitted[event_type] == null)
emitted[event_type] = 0;
emitted[event_type] ++;
if (!evts) {
if (event_type === 'error') {
if (a[1]) {
if (a[1] instanceof Error) {
throw a[1];
} else {
throw new Error(a[1]);
}
} else {
throw new Error("Uncaught, unspecified 'error' event.");
}
}
return this;
}
if (evts.constructor === Object) {
j = 1;
evts = [evts];
} else {
j = evts.length;
evts = j > 1 ? evts.slice(0) : evts;
}
var i = 0
, args = a.length === 1 ? [] : __slice.call(a, 1)
, e = event || new this.Event(event_type);
args.unshift(e);
for (var __e; i < j && !e.stopped; i ++) {
__e = evts[i];
__e.listener.apply(this, args);
__e.once && this.off(event_type, __e);
}
return this;
};
Ev.prototype.Event = null;
Ev.Event = function(type) {
this.type = type;
this.stopped = false;
};
Ev.Event.prototype.stop = function() {
this.stopped = true;
};
g.Ev = Ev;
})(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment