Last active
September 30, 2015 17:57
-
-
Save tatat/1838843 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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