var evt = (function(w){
"use strict";
// (C) Andrea Giammarchi - Mit Style License
// ordered event prototype V 0.0.9 beta
// TODO: test possible leaks
// [X] TODO: add fucking native fire event rather than call events like a monkey
// [X] TODO: implement just the classic "ready" case
// [X] TODO: normalize the event shadow
// TODO: documentation + credits
// TODO: enormeous number of tests
/* demo
evt.on(document, "ready", function(){
var div = evt
.on(
document.body.appendChild(
document.createElement("div")
)
.appendChild(
document.createTextNode("click me!")
)
.parentNode,
"mousedown",
function(e){
this.appendChild(
document.createTextNode("the mouse is down: " + e.clientX + ", " + e.event.clientY)
);
this.appendChild(
document.createElement("br")
);
}
)
.on(evt.target, "customMouseUp", function(e){
this.appendChild(
document.createTextNode("the mouse is custom up")
);
this.appendChild(
document.createElement("br")
);
})
.target
;
div.style.background = "#EEE";
evt
.fire(div, "mousedown", {clientX:32, clientY:14})
.go(div, "customMouseUp")
;
});
*/
function add(
target,
type,
callback
){
var
i = target[$],
o = i ? a[i] : (a[target[$] = new Number(length++)] = {})
;
if(i = !o.hasOwnProperty(type))
o[type] = []
;
if(indexOf.call(o = o[type], callback) < 0)
o.push(callback)
;
return i && o
};
function defaultView(target){
return (target.ownerDocument || target).defaultView || w
};
function event(o){
var e;
if(o){
if(o.event){
event.e(o);
o.stop = stop;
o.preventDefault = preventDefault;
o.stopPropagation = stopPropagation;
}
o.timeStamp = +new Date;
}
return o
};
event.e = (function(e){
for(var event = ["var e=o.event"], i = 0, length = e.length; i < length; ++i)
event[i + 1] = "o." + e[i] + "=e." + e[i]
;
event[i++] = "if(!o.target)o.target=e.srcElement||document";
event[i++] = "if(o.target.nodeType===3)o.target=o.target.parentNode";
event[i++] = "if(!o.relatedTarget&&o.fromElement)o.relatedTarget=o.fromElement===o.target?o.toElement:o.fromElement";
event[i++] = "if(o.pageX==null&&o.clientX!=null){var d=o.target.ownerDocument||o.target,w=d.documentElement;d=d.body;o.pageX=o.clientX+(w&&w.scrollLeft||d&&d.scrollLeft||0)-(w&&w.clientLeft||d&&d.clientLeft||0);o.pageY=o.clientY+(w&&w.scrollTop||d&&d.scrollTop||0)-(w&&w.clientTop||d&&d.clientTop||0)}";
event[i++] = "if(!o.which&&((o.charCode||o.charCode===0)?o.charCode:o.keyCode))o.which=o.charCode||o.keyCode";
event[i++] = "if(!o.metaKey&&o.ctrlKey)o.metaKey=o.ctrlKey";
event[i++] = "if(!o.which&&o.button!=null)o.which=(o.button&1?1:(o.button&2?3:(o.button&4?2:0)))";
return Function("o", event.join(";"))
})("altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "));
function e(
target,
type,
o
){
return (o.e = function event(
event
){
var
e = evt.event({type:type, target:target, event:event || defaultView(target).event})
;
for(var a = o.slice(), i = 0, length = a.length; i < length; ++i){
if(a[i].call(target, e) === false)
break
;
}
})
};
function off(
target,
type,
callback
){
var
o = remove(target, type, callback)
;
if(o)
evt.detach(target, type, o.e)
;
this.target = target;
return this
};
function on(
target,
type,
callback
){
var
o = add(target, type, callback)
;
if(o)
evt.attach(target, type, e(target, type, o))
;
this.target = target;
return this
};
function go(
target,
type,
event
){
var
i = target[$],
o
;
if(i && (o = a[i]).hasOwnProperty(type))
o[type].e(event)
;
return this
};
function preventDefault(){
var e = this.event;
if(e.preventDefault)
e.preventDefault()
;
e.returnValue = false;
};
function remove(
target,
type,
callback
){
var
i = target[$],
d,
o
;
if(i && (o = a[i]).hasOwnProperty(type)){
d = indexOf.call(o = o[type], callback);
if(-1 < d){
o.splice(d, 1);
if(!o.length){
d = true;
delete a[i];
target[$] = null;
if(target.removeAttribute)
target.removeAttribute($)
;
}
}
}
return d === true && o
};
function stop(){
this.preventDefault();
this.stopPropagation();
return false;
};
function stopPropagation(){
var e = this.event;
if(e.stopPropagation)
e.stopPropagation()
;
e.cancelBubble = true;
};
var
a = [], indexOf = a.indexOf || function indexOf(
target
){
for(var i = 0; i < length; ++i){
if(this[i] === target)
return i
;
}
return -1
},
d = w.document,
$ = "_evt." + Math.random() * new Date,
length = 0,
load = false,
attach,
detach,
evt,
fire,
off,
on
;
if(d.addEventListener){
attach = function attach(
target,
type,
callback
){
var
d = type == "ready"
;
if(d && (load || target.readyState == "complete"))
callback()
; else if(d){
function ready(){
load = true;
evt.detach(target, "ready", callback);
callback()
};
callback[$] = ready;
target.addEventListener("DOMContentLoaded", ready, false);
defaultView(target).addEventListener("load", ready, false);
} else
target.addEventListener(type, callback, false)
;
}
} else {
attach = function attach(
target,
type,
callback
){
var
w = defaultView(target),
i = type == "ready",
ready
;
if(i && (load || target.readyState == "complete"))
callback()
; else if(i){
ready = (function(){
function change(){
if(!load){
try{
d.doScroll("left")
} catch(e) {
return setTimeout(change, 0)
};
ready()
}
};
function ready(){
load = true;
evt.detach(target, "ready", callback);
callback()
};
var
d = target.documentElement
;
if(d.doScroll){
try {
if(w.frameElement == null)
setTimeout(change, 0)
;
} catch(e) {
}
};
target.attachEvent("on" + "readystatechange", ready[$] = function(){
if(target.readyState === "complete")
ready()
;
});
return ready
})();
callback[$] = ready;
w.attachEvent("on" + "load", ready)
} else
target.attachEvent("on" + type, callback)
;
}
};
detach = (function(d, o){
function detach(
target,
type,
callback
){
if(type == "ready"){
if(o = a[target[$]])
delete o[type]
;
callback = callback[$] || callback;
d ?
target.removeEventListener("DOMContentLoaded", callback, false) :
target.detachEvent("on" + "readystatechange", callback[$] || callback)
;
type = "load";
target = defaultView(target)
}
d ? target.removeEventListener(type, callback, false) : target.detachEvent("on" + type, callback)
};
return detach
})(!!d.removeEventListener, null);
if(d.readyState == null && d.addEventListener)(function(){
d.addEventListener("DOMContentLoaded", function DOMContentLoaded(){
d.removeEventListener("DOMContentLoaded", DOMContentLoaded, false);
d.readyState = "complete";
}, false);
d.readyState = "loading";
})();
if(d.dispatchEvent && d.createEvent){
fire = function fire(
target,
type,
o
){
var
d = target.ownerDocument,
w = defaultView(target),
e
;
if(type === "focus"){
target.focus()
return this;
};
if(!o)
o = {}
;
switch(true){
case type == "blur":
case type == "focus":
target[type]();
break;
case /^(?:click|contextmenu|dblclick|mousedown|mousenter|mouseleave|mousemove|mouseout|mouseup|mouseover)$/.test(type):
//(e = d.createEvent("MouseEvents")).initMouseEvent(type, !0, !0, w, (type == "dblclick") ? 2 : 1, 0, 0, 0, 0, !0, !0, !0, !0, 0, null);
//* TODO: be sure it is consistent across IE as well
(e = d.createEvent("MouseEvents")).initMouseEvent(
type,
o.canBubble || true,
o.cancelable || true,
w,
o.detail || ((type == "dblclick") ? 2 : 1),
o.screenX || 0,
o.screenY || 0,
o.clientX || 0,
o.clientY || 0,
o.ctrlKey || false,
o.altKey || false,
o.shiftKey || false,
o.metaKey || false,
o.button || 0,
o.relatedTarget || null
)
//*/
break;
case /^(?:change|keydown|keypress|keyup|reset|select)$/.test(type):
(e = d.createEvent("UIEvents")).initUIEvent(type, o.canBubble || true, o.cancelable || true, w, o.detail || 1);
break;
case /^(?:abort|error|load|offline|online|resize|scroll|unload)$/.test(type):
(e = d.createEvent("HTMLEvents")).initEvent(type, o.canBubble || true, o.cancelable || true);
break;
}
if(e){
for(var i in o){
if(o.hasOwnProperty(i))
e[i] = o[i]
;
};
target.dispatchEvent(e);
};
return this
}
} else {
fire = function fire(
target,
type,
o
){
switch(type){
case "blur":
case "focus":
target[type]();
break;
default:
var e = target.ownerDocument.createEventObject();
for(var i in (o || (o = {}))){
if(o.hasOwnProperty(i))
e[i] = o[i]
;
};
target.fireEvent("on" + type, e);
break;
}
return this
}
};
return evt = {
$:function(){return $},
attach:attach,
detach:detach,
event:event,
go:go,
off:off,
on:on,
fire:fire
}
})(this);