if ('undefined' === typeof JSLib) {
window.JSLib = {};
}
if ('undefined' === typeof JSLib.util) {
window.JSLib.util = {};
}
JSLib.util.getEl = function(el) {
if ('string' === typeof el) {
if ('undefined' !== typeof window.Sizzle) {
//TODO: check allowed syntax of CSS ID
if (el.match(/^\s*[a-z][a-z\d-_]*\s*/i)) {
el = '#' + el.replace(/(^\s+)|(\s+$)/g, '');
}
var els = window.Sizzle(el);
el = els.length ? els.shift() : false;
} else {
el = document.getElementById(el);
}
}
if (!el || 'object' !== typeof el) {
return false;
}
return el;
};
JSLib.util.addListener = function(el, eventName, fn, capture) {
el = JSLib.util.getEl(el);
if (!el) {
return;
}
if (window.addEventListener) {
el.addEventListener(eventName, fn, (capture));
} else if (window.attachEvent) {
el.attachEvent('on' + eventName, fn);
} else {
var old_handler = el['on' + eventName];
el['on' + eventName] = function(e) { 
if ('function' === typeof old_handler) {
old_handler.apply(el, [e]);
}
fn.apply(el, [e]);
};
}
};
JSLib.util.removeListener = function(el, eventName, fn, capture) {
el = JSLib.util.getEl(el);
if (!el) {
return;
}
if (window.removeEventListener) {
el.removeEventListener(eventName, fn, (capture));
} else if (window.detachEvent) {
el.detachEvent('on' + eventName, fn);
}
};
JSLib.Event = {
listeners: [],
addListener: function(el, eventName, fn, scope, options) {
//provide several events handling
if ('object' === typeof eventName && 'undefined' === typeof eventName.nodeName) {
for (var event in eventName) {
this.addListener(el, event, eventName[event]);
}
return;
}
el = JSLib.util.getEl(el);
if (!el || !fn) {
return false;
}
options = options || {};
var stack = [];
var wrappedFn = function(e) {
return function() {
e = new JSLib.EventObject(e);
//process multiple event triggering
//todo: refactor and optimize
if ((e.type == 'mouseover' && !e.checkMouseEnter(el, e.browserEvent)) ||
(e.type == 'mouseout' && !e.checkMouseLeave(el, e.browserEvent))) {
return;
}
if (options.delay) {
var timeout = setTimeout(function() {
fn.createDelegate(scope)(e, el);
}, options.delay || 10);
if (e.type == 'mouseover') {
JSLib.Event.addListener(el, 'mouseout', function() {
clearTimeout(timeout);
});
} else if (e.type == 'mouseout') {
JSLib.Event.addListener(el, 'mouseover', function() {
clearTimeout(timeout);
});
}
} else {
fn.createDelegate(scope)(e, el);
}
}();
};
this.listeners.push({
el: el,
eventName: eventName,
fn: fn,
wrappedFn: wrappedFn,
scope: scope,
stack: []
});
JSLib.util.addListener(el, eventName, wrappedFn, false);
},
removeListener: function(el, eventName, fn, scope) {
el = JSLib.util.getEl(el);
if (!el) {
return false;
}
var removed_listeners_count = 0;
for (var i = 0, len = this.listeners.length; i < len; ++i) {
var li = this.listeners[i];
if (li && li.fn === fn && li.el === el && li.eventName === eventName && li.scope === scope) {
JSLib.util.removeListener(el, eventName, li.wrappedFn, false);
// delete this.listeners[i].wrappedFn;
// delete this.listeners[i].fn;
this.listeners.splice(i, 1);
len = len - 1;
removed_listeners_count++;
}
}
//TODO: test removing several equal listeners
return removed_listeners_count;
},
unload: function(e) {
var i, j, l, index;
if (this.listeners && this.listeners.length > 0) {
j = this.listeners.length;
while (j) {
index = j - 1;
l = this.listeners[index];
if (l) {
JSLib.Event.removeListener(l[0], l[1], l[2], index);
}
j = j - 1;
}
l = null;
}
JSLib.Event.removeListener(window, 'unload', JSLib.Event.unload);
}
};
JSLib.EventObject = function() {
construct = function(e) {
if (!e) {
return;
}
this.setEvent(e.browserEvent || e);
};
construct.prototype = {
browserEvent : null,
x: function() {
return typeof this.browserEvent.clientX === 'undefined' ? false : this.browserEvent.clientX;
},
y: function() {
return typeof this.browserEvent.clientY === 'undefined' ? false : this.browserEvent.clientY;
},
setEvent : function(e){
if(e && e.browserEvent) {
return e;
}
this.browserEvent = e;
if (this.browserEvent) {
this.type = e.type;
this.target = this.browserEvent.target || this.browserEvent.srcElement;
isSafari = (/webkit|khtml/).test(navigator.userAgent.toLowerCase());
if (isSafari && this.target && 3 == this.target.nodeType) {
this.target = this.target.parentNode;
}
} else {
this.target = null;
}
return this;
},
stop: function() {
this.stopPropagation();
this.preventDefault();
},
preventDefault: function() {
if (this.browserEvent.preventDefault) {
this.browserEvent.preventDefault();
} else {
this.browserEvent.returnValue = false;
}
},
stopPropagation: function(){
if (this.browserEvent.stopPropagation) {
this.browserEvent.stopPropagation();
} else {
this.browserEvent.cancelBubble = true;
}
},
getTarget: function(){
var t = this.browserEvent.target || this.browserEvent.srcElement;
if (3 == t.nodeType) {
return t.parentNode;
}
return t;
},
getRelatedTarget : function(){
},
containsDOM: function(container, containee){
var isParent = false;
do {
if (isParent = (container === containee)) {
break;
}
containee = containee.parentNode;
} while (containee !== null);
return isParent;
},
getKey: function() {
var k = this.browserEvent.which || this.browserEvent.keyCode;
return (/webkit|khtml/i).test(navigator.userAgent) ? (this.safariKeys[k] || k) : k;
},
checkMouseLeave: function(el, e){
e = e || window.event;
if (el.contains && e.toElement) {
return !el.contains(e.toElement);
} else if (e.relatedTarget) {
return !this.containsDOM(el, e.relatedTarget);
}
},
checkMouseEnter: function(el, e){
e = e || window.event;
if (el.contains && e.fromElement) {
return !el.contains(e.fromElement);
} else if (e.relatedTarget) {
return !this.containsDOM(el, e.relatedTarget);
}
}
};
return construct;
}();
ContentLoaded(window, function() {
JSLib.Event.addListener(window, 'unload', JSLib.Event.unload, false);
});
