/*
«js-core» — JavaScript framework, version 2.5.7
© Dmitry Korobkin, 2008
http://code.google.com/p/js-core/
*/
Object.prototype.each = function(fn, arg) {
if(this.length != undefined) {
var i, length = this.length;
for(i = 0; i < length; i++) fn.apply(this[i], arg || []);
}
else for(var key in this) if(this.hasOwnProperty(key)) fn.apply(key, arg || []);
return this;
};
Object.prototype.extend = function(hash) {
if(hash) hash.each(function(obj) {
obj[this] = hash[this];
}, [this]);
return this;
};
Function.prototype.extend(function(ie) {
return {
context: function(obj) {
var fn = this;
return function _fn() {
return fn.call(obj, arguments[0]);
};
},
event: function() {
return ie ? function() {
return window.event;
} : function() {
return this.arguments[0];
};
}(),
preventDefault: function() {
return ie ? function() {
this.event().returnValue = false;
} : function() {
this.event().preventDefault();
};
}(),
stopPropagation: function() {
return ie ? function() {
this.event().cancelBubble = true;
} : function() {
this.event().stopPropagation();
};
}(),
handler: function(target) {
return function() {
return this.event()[target];
};
}(ie ? 'srcElement' : 'target')
};
}(/*@cc_on 1 @*/));
if(!Array.prototype.forEach) Array.prototype.forEach = function(fn, context) {
var i, length = this.length;
for(i = 0; i < length; i++) fn.call(context, this[i], i, this);
};
String.prototype.extend({
trimLeft: function() {
return this.replace(/^\s+/, '');
},
trimRight: function() {
return this.replace(/\s+$/, '');
},
trimSpaces: function() {
return this.replace(/\s{2,}/g, ' ');
},
trim: function(arg) {
if(arg) {
var str = this;
core.array(arg).each(function() {
str = core.trim[this](str);
});
return str;
}
else return core.trim['both'](this);
}
});
var core = {
ie: 0 /*@cc_on + ScriptEngineMinorVersion() @*/,
trim: {
left: function(str) {
return str.trimLeft();
},
right: function(str) {
return str.trimRight();
},
spaces: function(str) {
return str.trimSpaces();
},
both: function(str) {
return str.trimLeft().trimRight();
},
all: function(str) {
return str.trimSpaces().trimLeft().trimRight();
}
},
cache: {},
clear: function(node) {
node.hasChildNodes() ? this.cache = {} : delete this.cache[node.id];
return node;
},
incache: function(id) {
return this.cache[id] || (this.cache[id] = document.getElementById(id));
},
isstr: function(arg) {
return typeof arg == 'string';
},
id: function(arg) {
return this.isstr(arg) ? this.incache(arg) : arg;
},
tag: function(ie) {
return ie ? function(hash) {
var node = hash.node || document, array = [];
Array.prototype.forEach.call(hash.tag ? node.getElementsByTagName(hash.tag) : (this.ie == 5 ? node.all : node.getElementsByTagName('*')), function(el) {
array.push(el);
});
return array;
} : function(hash) {
return (hash.node || document).getElementsByTagName(hash.tag || '*');
};
}(/*@cc_on 1 @*/),
create: function(arg) {
return this.isstr(arg) ? document.createElement(arg) : arg;
},
insert: function(node, arg, before) {
return node.insertBefore(this.create(arg), before);
},
sibling: function(node, dir, tag) {
while(node = node[dir]) if(node.nodeType == 1 && (tag ? node.tagName == tag.toUpperCase() : true)) return node;
},
bind: function() {
return window.addEventListener ? function(node, type, listener) {
node.addEventListener(type, listener, false);
} : function(expr) {
return function(node, type, listener) {
node.attachEvent('on' + type, expr.test(listener) ? listener.context(node) : listener);
};
}(/^function\s*\(/);
}(),
unbind: function() {
return window.removeEventListener ? function(node, type, listener) {
node.removeEventListener(type, listener, false);
} : function(node, type, listener) {
node.detachEvent('on' + type, listener);
};
}(),
instr: function(str, search) {
return str.search('\\b' + search + '\\b') + 1;
},
replace: function(str, search, replace) {
return str.replace(new RegExp('\\b' + search + '\\b'), replace || '').trim(['all']);
},
array: function(arg) {
return arg.split ? this.trim['all'](arg).split(/\s+/) : arg;
},
attr: function(hash) {
if(hash.attr.length) {
var array = [];
this.tag({node: hash.node, tag: hash.tag}).each(function() {
var key = true;
core.array(hash.attr).each(function(node) {
if(!node[this]) return key = false;
}, [this]);
if(key) array.push(this);
});
return array;
}
else if(hash.node) hash.attr.each(function() {
hash.node[this] = hash.attr[this];
});
},
value: function(hash) {
var array = [];
this.tag({node: hash.node, tag: hash.tag}).each(function() {
var key = true;
hash.attr.each(function(node) {
if(node[this] != hash.attr[this]) key = false;
}, [this]);
if(key) array.push(this);
});
return array;
},
child: function(node, tags) {
var i, children = node.childNodes, length = children.length, array = [];
if(tags) {
if(tags.join) tags = tags.join(' ');
tags = tags.toUpperCase();
}
for(i = 0; i < length; i++) if(children[i].nodeType == 1) if(tags ? this.instr(tags, children[i].tagName) : true) array.push(children[i]);
return array;
},
tags: function(hash) {
if(hash.tag) {
var array = [];
this.array(hash.tag).each(function() {
core.tag({node: hash.node, tag: this}).each(function() {
array.push(this);
});
});
return array;
}
else return this.tag({node: hash.node});
},
values: function(hash) {
var array = [], val = this.isstr(hash.value) ? hash.value : hash.value.join(' ');
core.attr({node: hash.node, tag: hash.tag, attr: hash.attr}).each(function() {
var key = false;
core.array(this[hash.attr]).each(function() {
if(core.instr(val, this)) key = true;
});
if(key) array.push(this);
});
return array;
},
props: {
'float': 'styleFloat'
},
prop: function(str) {
if(this.props[str]) return this.props[str];
if(/-/.test(str)) {
var array = [];
str.split('-').forEach(function(el, index) {
array.push((index ? el.charAt(0).toUpperCase() : el.charAt(0)) + el.substr(1));
});
return array.join('');
}
return str;
},
css: function(ie) {
return ie ? function(node, property) {
return node.currentStyle[this.prop(property)];
} : function(node, property) {
return document.defaultView.getComputedStyle(node, null).getPropertyValue(property);
};
}(/*@cc_on 1 @*/),
dom: {
init: [],
ready: function() {
if(!arguments.callee.done) {
arguments.callee.done = true;
if(core.dom.timer) clearInterval(core.dom.timer);
this.init.each(function() { this(); });
this.init = [];
}
},
check: function() {
var listener = this.ready.context(this);
if(document.addEventListener) document.addEventListener('DOMContentLoaded', listener, false);
if(/KHTML|WebKit/i.test(navigator.userAgent)) core.dom.timer = setInterval(function() {
if(/loaded|complete/.test(document.readyState)) core.dom.ready();
}, 10);
/*@cc_on document.write(unescape('%3CSCRIPT onreadystatechange="if(this.readyState==\'complete\') core.dom.ready()" defer=defer src=\/\/:%3E%3C/SCRIPT%3E')); @*/
core.bind(window, 'load', listener);
}
}
};
function preventDefault() {
arguments.callee.preventDefault();
}
function stopPropagation() {
arguments.callee.stopPropagation();
}
function _$(arg) {
this.node = core.id(arg);
}
_$.prototype = {
child: function(tag, bool) {
if(tag) return typeof tag == 'boolean' ? core.tags({node: this.node}) : (bool ? core.tags({node: this.node, tag: tag}) : core.child(this.node, tag));
else return core.child(this.node);
},
parent: function() {
return new _$(this.node.parentNode);
},
append: function(arg) {
return new _$(this.node.appendChild(core.create(arg)));
},
prepend: function(arg) {
return new _$(core.insert(this.node, arg, this.node.firstChild));
},
after: function(arg) {
return new _$(core.insert(this.node.parentNode, arg, this.node.nextSibling));
},
before: function(arg) {
return new _$(core.insert(this.node.parentNode, arg, this.node));
},
appendTo: function(arg) {
core.id(arg).appendChild(this.node);
return new _$(arg);
},
prependTo: function(arg) {
var node = core.id(arg);
core.insert(node, this.node, node.firstChild);
return new _$(arg);
},
insertAfter: function(arg) {
var node = core.id(arg);
return new _$(core.insert(node.parentNode, this.node, node.nextSibling));
},
insertBefore: function(arg) {
var node = core.id(arg);
return new _$(core.insert(node.parentNode, this.node, node));
},
next: function(tag) {
return new _$(core.sibling(this.node, 'nextSibling', tag));
},
prev: function(tag) {
return new _$(core.sibling(this.node, 'previousSibling', tag));
},
clone: function(bool) {
return new _$(this.node.cloneNode(bool !== false));
},
replace: function(arg) {
try {
return this.before(core.create(arg));
}
catch(e) {}
finally {
this.remove();
}
},
wrap: function(arg) {
return this.before(arg).append(this.node);
},
el: function(arg) {
return arg ? this.replace(core.id(arg)) : this.node;
},
empty: function() {
core.clear(this.node);
while(this.node.firstChild) this.node.removeChild(this.node.firstChild);
return this;
},
remove: function() {
core.clear(this.node).parentNode.removeChild(this.node);
return null;
},
html: function(str) {
if(str != undefined) {
this.node.innerHTML = str;
return this;
}
else return this.node.innerHTML;
},
text: function(str) {
if(str != undefined) {
this.empty().node.appendChild(document.createTextNode(str));
return this;
}
else return this.node.innerText || this.node.textContent;
},
useDefault: function(type, def) {
var prefix = 'preventDefaultOn';
if(def) {
this.node[prefix + type] = false;
core.unbind(this.node, type, preventDefault);
}
else if(!this.node[prefix + type]) {
this.node[prefix + type] = true;
core.bind(this.node, type, preventDefault);
}
return this;
},
bind: function(type, listener, def) {
core.bind(this.node, type, listener);
if(typeof def == 'boolean') this.useDefault(type, def);
return this;
},
unbind: function(type, listener, def) {
core.unbind(this.node, type, listener);
if(typeof def == 'boolean') this.useDefault(type, def);
return this;
},
exist: function(exist, die) {
if(exist && this.node) exist.call(this.node);
else if(die && !this.node) die();
return !!this.node;
},
hasClass: function(arg) {
if(arg) {
var key = false;
core.array(arg).each(function(str) {
if(!core.instr(str, this)) return key = true;
}, [this.node.className]);
return !key;
}
else return !!this.node.className;
},
addClass: function(arg) {
core.array(arg).each(function(node) {
if(!core.instr(node.className, this)) node.className += ' ' + this;
}, [this.node]);
return this;
},
removeClass: function(arg) {
arg ? core.array(arg).each(function(node) {
node.className = core.replace(node.className, this);
}, [this.node]) : this.node.className = '';
return this;
},
toggleClass: function(arg1, arg2) {
if(arg2) {
var i, array1 = core.array(arg1), array2 = core.array(arg2), length = array1.length;
for(i = 0; i < length; i++) this.node.className = core.replace(this.node.className, array1[i], array2[i]);
}
else if(arg1) core.array(arg1).each(function(obj) {
obj.hasClass(this) ? obj.removeClass(this) : obj.addClass(this);
}, [this]);
else this.removeClass();
return this;
},
attr: function(arg) {
if(arg.join || arg.split) {
var array = [];
core.array(arg).each(function(node) {
array.push(node[this]);
}, [this.node]);
return array.length == 1 ? array[0] : array;
}
else {
core.attr({node: this.node, attr: arg});
return this;
}
},
removeAttr: function(arg) {
core.array(arg).each(function(node) {
node[this] = null;
}, [this.node]);
return this;
},
val: function(str) {
return str != undefined ? this.attr({value: str}): this.attr('value');
},
find: function(arg, tag) {
return arg.join || arg.split ? core.attr({node: this.node, tag: tag, attr: arg}) : core.value({node: this.node, tag: tag, attr: arg});
},
findAttr: function(attr, value, tag) {
return core.values({node: this.node, tag: tag, attr: attr, value: value});
},
is: function(arg, tag) {
if(arg) {
if(!arg.join && !arg.split) {
var key = false;
arg.each(function(node) {
if(node[this] != arg[this]) key = true;
}, [this.node]);
if(tag && !key) key = this.node.tagName != tag.toUpperCase();
return !key;
}
else return this.node.tagName == arg.toUpperCase();
}
else return this.exist();
},
findClass: function(arg, tag) {
return core.values({node: this.node, tag: tag, attr: 'className', value: arg});
},
css: function(arg) {
if(arg.join || arg.split) {
var array = [];
core.array(arg).each(function(node) {
array.push(core.css(node, this));
}, [this.node]);
return array.length == 1 ? array[0] : array;
}
else {
core.attr({node: this.node.style, attr: arg});
return this;
}
},
hide: function() {
return this.css({display: 'none', visibility: 'hidden'});
},
show: function(type) {
return this.css({display: type || 'block', visibility: 'visible'});
},
visible: function() {
return this.css(['display']) != 'none' && this.css(['visibility']) != 'hidden';
},
toggle: function(type) {
return this.visible() ? this.hide() : this.show(type);
},
enabled: function(bool) {
return typeof bool == 'boolean' ? (bool ? this.removeAttr('disabled') : this.attr({disabled: 'disabled'})) : !this.attr(['disabled']);
},
id: function(str) {
if(str) {
if(core.cache[this.node.id]) delete core.cache[this.node.id];
this.node.id = str;
return this;
}
else return this.node.id;
},
run: function(fn, arg) {
fn.apply(this.node, arg || []);
return this;
},
serialize: function() {
return this.node.outerHTML || new XMLSerializer().serializeToString(this.node);
}
};
function $(arg) {
return new _$(arg);
}
$.extend({
t: function(tag) {
return core.tags({tag: tag});
},
n: function(tag) {
return new _$(document.createElement(tag));
},
c: function(arg, tag) {
return _$.prototype.findClass(arg, tag);
},
a: function(arg, tag) {
return _$.prototype.find(arg, tag);
},
f: function(attr, value, tag) {
return _$.prototype.findAttr(attr, value, tag);
},
ready: function(fn) {
core.dom.init.push(fn);
},
foreach: function(obj, fn) {
return (obj || {}).each(function() {
fn.call(obj, this, obj[this]);
});
},
makeArray: function() {
return core.ie ? function(list) {
var array = [];
Array.prototype.forEach.call(list, function(el) {
array.push(el);
});
return array;
} : function(list) {
return Array.prototype.slice.call(list);
};
}()
});
function Timer(time, fn, arg) {
this.extend({time: time, fn: fn, arg: arg, enabled: false});
}
Timer.prototype = {
start: function() {
if (!this.enabled) {
var timer = this;
this.interval = setInterval(function(){
timer.fn.apply(timer, timer.arg || []);
}, this.time);
this.enabled = true;
}
return this;
},
stop: function() {
clearInterval(this.interval);
this.enabled = false;
return this;
},
repeat: function(amount, fn, arg) {
if(fn) this.extend({callback: {fn: fn, arg: arg}});
var timer = this;
if(amount) setTimeout(function() {
timer.fn.apply(timer, timer.arg || []);
timer.repeat(--amount);
if(!amount && timer.callback) timer.callback.fn.apply(timer, timer.callback.arg || []);
}, this.time);
return this;
}
};
core.dom.check();