/* «js-core» — JavaScript framework, version 2.5.9 © Dmitry Korobkin, 2008 http://www.js-core.ru/ */ Object.prototype.each = function(fn, arg) { if(this.length != undefined) { var i, length = this.length; for(i = 0; i < length; i++) if(fn.apply(this[i], arg || []) === false) break; } else for(var key in this) if(this.hasOwnProperty(key)) if(fn.apply(key, arg || []) === false) break; 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]) return 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)) return !(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]) return !(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) { 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();