app/assets/javascripts/ext/src/ext-core/src/adapter/ext-base-event.js
/*!
* Ext JS Library 3.3.0
* Copyright(c) 2006-2010 Ext JS, Inc.
* licensing@extjs.com
* http://www.extjs.com/license
*/
Ext.lib.Event = function() {
var loadComplete = false,
unloadListeners = {},
retryCount = 0,
onAvailStack = [],
_interval,
locked = false,
win = window,
doc = document,
// constants
POLL_RETRYS = 200,
POLL_INTERVAL = 20,
TYPE = 0,
FN = 1,
OBJ = 2,
ADJ_SCOPE = 3,
SCROLLLEFT = 'scrollLeft',
SCROLLTOP = 'scrollTop',
UNLOAD = 'unload',
MOUSEOVER = 'mouseover',
MOUSEOUT = 'mouseout',
// private
doAdd = function() {
var ret;
if (win.addEventListener) {
ret = function(el, eventName, fn, capture) {
if (eventName == 'mouseenter') {
fn = fn.createInterceptor(checkRelatedTarget);
el.addEventListener(MOUSEOVER, fn, (capture));
} else if (eventName == 'mouseleave') {
fn = fn.createInterceptor(checkRelatedTarget);
el.addEventListener(MOUSEOUT, fn, (capture));
} else {
el.addEventListener(eventName, fn, (capture));
}
return fn;
};
} else if (win.attachEvent) {
ret = function(el, eventName, fn, capture) {
el.attachEvent("on" + eventName, fn);
return fn;
};
} else {
ret = function(){};
}
return ret;
}(),
// private
doRemove = function(){
var ret;
if (win.removeEventListener) {
ret = function (el, eventName, fn, capture) {
if (eventName == 'mouseenter') {
eventName = MOUSEOVER;
} else if (eventName == 'mouseleave') {
eventName = MOUSEOUT;
}
el.removeEventListener(eventName, fn, (capture));
};
} else if (win.detachEvent) {
ret = function (el, eventName, fn) {
el.detachEvent("on" + eventName, fn);
};
} else {
ret = function(){};
}
return ret;
}();
function checkRelatedTarget(e) {
return !elContains(e.currentTarget, pub.getRelatedTarget(e));
}
function elContains(parent, child) {
if(parent && parent.firstChild){
while(child) {
if(child === parent) {
return true;
}
child = child.parentNode;
if(child && (child.nodeType != 1)) {
child = null;
}
}
}
return false;
}
// private
function _tryPreloadAttach() {
var ret = false,
notAvail = [],
element, i, v, override,
tryAgain = !loadComplete || (retryCount > 0);
if(!locked){
locked = true;
for(i = 0; i < onAvailStack.length; ++i){
v = onAvailStack[i];
if(v && (element = doc.getElementById(v.id))){
if(!v.checkReady || loadComplete || element.nextSibling || (doc && doc.body)) {
override = v.override;
element = override ? (override === true ? v.obj : override) : element;
v.fn.call(element, v.obj);
onAvailStack.remove(v);
--i;
}else{
notAvail.push(v);
}
}
}
retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
if (tryAgain) {
startInterval();
} else {
clearInterval(_interval);
_interval = null;
}
ret = !(locked = false);
}
return ret;
}
// private
function startInterval() {
if(!_interval){
var callback = function() {
_tryPreloadAttach();
};
_interval = setInterval(callback, POLL_INTERVAL);
}
}
// private
function getScroll() {
var dd = doc.documentElement,
db = doc.body;
if(dd && (dd[SCROLLTOP] || dd[SCROLLLEFT])){
return [dd[SCROLLLEFT], dd[SCROLLTOP]];
}else if(db){
return [db[SCROLLLEFT], db[SCROLLTOP]];
}else{
return [0, 0];
}
}
// private
function getPageCoord (ev, xy) {
ev = ev.browserEvent || ev;
var coord = ev['page' + xy];
if (!coord && coord !== 0) {
coord = ev['client' + xy] || 0;
if (Ext.isIE) {
coord += getScroll()[xy == "X" ? 0 : 1];
}
}
return coord;
}
var pub = {
extAdapter: true,
onAvailable : function(p_id, p_fn, p_obj, p_override) {
onAvailStack.push({
id: p_id,
fn: p_fn,
obj: p_obj,
override: p_override,
checkReady: false });
retryCount = POLL_RETRYS;
startInterval();
},
// This function should ALWAYS be called from Ext.EventManager
addListener: function(el, eventName, fn) {
el = Ext.getDom(el);
if (el && fn) {
if (eventName == UNLOAD) {
if (unloadListeners[el.id] === undefined) {
unloadListeners[el.id] = [];
}
unloadListeners[el.id].push([eventName, fn]);
return fn;
}
return doAdd(el, eventName, fn, false);
}
return false;
},
// This function should ALWAYS be called from Ext.EventManager
removeListener: function(el, eventName, fn) {
el = Ext.getDom(el);
var i, len, li, lis;
if (el && fn) {
if(eventName == UNLOAD){
if((lis = unloadListeners[el.id]) !== undefined){
for(i = 0, len = lis.length; i < len; i++){
if((li = lis[i]) && li[TYPE] == eventName && li[FN] == fn){
unloadListeners[el.id].splice(i, 1);
}
}
}
return;
}
doRemove(el, eventName, fn, false);
}
},
getTarget : function(ev) {
ev = ev.browserEvent || ev;
return this.resolveTextNode(ev.target || ev.srcElement);
},
resolveTextNode : Ext.isGecko ? function(node){
if(!node){
return;
}
// work around firefox bug, https://bugzilla.mozilla.org/show_bug.cgi?id=101197
var s = HTMLElement.prototype.toString.call(node);
if(s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]'){
return;
}
return node.nodeType == 3 ? node.parentNode : node;
} : function(node){
return node && node.nodeType == 3 ? node.parentNode : node;
},
getRelatedTarget : function(ev) {
ev = ev.browserEvent || ev;
return this.resolveTextNode(ev.relatedTarget ||
(/(mouseout|mouseleave)/.test(ev.type) ? ev.toElement :
/(mouseover|mouseenter)/.test(ev.type) ? ev.fromElement : null));
},
getPageX : function(ev) {
return getPageCoord(ev, "X");
},
getPageY : function(ev) {
return getPageCoord(ev, "Y");
},
getXY : function(ev) {
return [this.getPageX(ev), this.getPageY(ev)];
},
stopEvent : function(ev) {
this.stopPropagation(ev);
this.preventDefault(ev);
},
stopPropagation : function(ev) {
ev = ev.browserEvent || ev;
if (ev.stopPropagation) {
ev.stopPropagation();
} else {
ev.cancelBubble = true;
}
},
preventDefault : function(ev) {
ev = ev.browserEvent || ev;
if (ev.preventDefault) {
ev.preventDefault();
} else {
ev.returnValue = false;
}
},
getEvent : function(e) {
e = e || win.event;
if (!e) {
var c = this.getEvent.caller;
while (c) {
e = c.arguments[0];
if (e && Event == e.constructor) {
break;
}
c = c.caller;
}
}
return e;
},
getCharCode : function(ev) {
ev = ev.browserEvent || ev;
return ev.charCode || ev.keyCode || 0;
},
//clearCache: function() {},
// deprecated, call from EventManager
getListeners : function(el, eventName) {
Ext.EventManager.getListeners(el, eventName);
},
// deprecated, call from EventManager
purgeElement : function(el, recurse, eventName) {
Ext.EventManager.purgeElement(el, recurse, eventName);
},
_load : function(e) {
loadComplete = true;
if (Ext.isIE && e !== true) {
// IE8 complains that _load is null or not an object
// so lets remove self via arguments.callee
doRemove(win, "load", arguments.callee);
}
},
_unload : function(e) {
var EU = Ext.lib.Event,
i, v, ul, id, len, scope;
for (id in unloadListeners) {
ul = unloadListeners[id];
for (i = 0, len = ul.length; i < len; i++) {
v = ul[i];
if (v) {
try{
scope = v[ADJ_SCOPE] ? (v[ADJ_SCOPE] === true ? v[OBJ] : v[ADJ_SCOPE]) : win;
v[FN].call(scope, EU.getEvent(e), v[OBJ]);
}catch(ex){}
}
}
};
Ext.EventManager._unload();
doRemove(win, UNLOAD, EU._unload);
}
};
// Initialize stuff.
pub.on = pub.addListener;
pub.un = pub.removeListener;
if (doc && doc.body) {
pub._load(true);
} else {
doAdd(win, "load", pub._load);
}
doAdd(win, UNLOAD, pub._unload);
_tryPreloadAttach();
return pub;
}();