/*
@author: cgorbit
@version: 0.0.3
*/
var isTrident = document.attachEvent && !window.opera;
var isIE = isTrident;
var isPresto = !!window.opera;
var isKestrel = false;
var isOpera = isPresto || isKestrel;
var isWebKit = navigator.userAgent.indexOf('AppleWebKit/') > -1;
var isSafari = isWebKit;
var isGecko = !isTrident && !isPresto && !isWebKit;
var isIE6 = navigator.appVersion.indexOf( 'MSIE 6.0' ) != -1;
var _events = [];
/*function $( s )
{
var rule = s.split( /[\s+>]/ );
for (var i in rule )
document.writeln(rule[i]+'
');
}
*/
/*
*
* TODO: XPath
* multiple addEvent()
*
*/
window.debug = !true;
function log( s )
{
if ( window.debug )
{
if ( false )
document.write( s + '
' );
else
document.getElementById('fuckoff').innerHTML += s + '
';
}
}
var _ids = {};
function removeFromIdCache( name )
{
_ids[ name ] = null;
}
function getElementById( id )
{
if ( _ids[ id ] )
log( '#' + id + ' from cache' );
else
log( '#' + id + ' dynamicly' );
if ( _ids[ id ] )
return _ids[ id ];
else
return _ids[ id ] = document.getElementById( id );
}
function $( path, multiple, root )
{
//log( path )
multiple = multiple || false;
path = path.replace( /\s*(>|\+)\s*/g, '$1' )
path = path.replace( /\s{2,}/g, ' ' )
var selector = /^([a-z0-9][_a-z0-9-]*|\*)?(?:#([a-z0-9][_a-z0-9-]*))?((?:.[a-z0-9][_a-z0-9-]*)*)$/i;
var pathPicies = path.split( / |>|\+/g );
var operators = ( ' ' + path ).match( / |\+|>/g );
//for (var zzz = 0; zzz < pathPicies.length; zzz++)
//log('-'+pathPicies[zzz]+'-')
//for (zzz = 0; zzz < operators.length; zzz++)
//log('-'+operators[zzz]+'-')
var i, subpath;
var m, classes, id, tag, set;
var elements = root || document;
elements = [ elements ];
var element;
var result;
var subpath, element;
for ( subpath = pathPicies[0], i = 0, operator = operators[0]; i < pathPicies.length; i++, subpath = pathPicies[i], operator = operators[i] )
{
//log( 'i = ' + i );
// > child, + sibling
m = subpath.match( selector );
tag = m[1];
id = m[2];
classes = m[3];
//log( 'operator = ' + operator[0] );
//log( 'tag = ' + tag );
//log( 'id = ' + id );
//log( 'class = ' + classes );
result = [];
// what about result.unique ?
for ( var j = 0; j < elements.length; j++ )
{
//log( 'j = ' + j );
element = elements[j];
// wrong -- `... > #foo` and `... + #foo`
if ( id )
{
element = getElementById( id );
//log( 'by id #' + id + ' ' + element);
if ( element ) result.push( element );
break;
}
switch ( operator )
{
case ' ':
//log('in desc')
set = element.getElementsByTagName( tag || '*' );
//log('desc.len = ' + set.length)
//log(tag || '*')
for ( var k = 0; k < set.length; k++ )
{
if ( isClass( set[k], classes ) && _isTag( set[k], tag ) ) result.push( set[k] );
//log( 'isTag ' + (_isTag( set[k], tag )) )
//log( 'isClass ' + (isClass( set[k], classes )) )
}
//return
//log('result.len = ' + result.length)
break;
case '+':
//log('in sinbl')
set = getNextSiblingElement( element );
if ( isClass( set, classes ) && _isTag( set, tag ) ) result.push( set );
break;
case '>':
//log('in childs')
set = getChilds( element, tag, classes );
for ( var k = 0; k < set.length; k++ )
result.push( set[k] );
break;
}
}
//log( 'result.length = ' + result.length );
//log( '' );
elements = result;
}
//log( 'return ' + elements )
//log( 'return len ' + elements.length )
if ( elements.length )
{
if ( !multiple ) return elements[0];
else return elements;
}
else
{
if ( !multiple ) return null;
else return [];
}
}
var _onLoadInits = [];
function onLoad( func )
{
_onLoadInits.push( func );
}
function globalInit()
{
for ( var i = 0; i < _onLoadInits.length; i++ )
{
(_onLoadInits[i])();
}
}
function iterate( elements, callback )
{
if ( elements.length )
for ( var i = 0, element = elements[0]; i < elements.length; i++, element = elements[i] )
callback( element, i );
}
function isArray( a )
{
return Object.prototype.toString.apply( a ) == '[object Array]';
}
function _addEvent( el, type, func, dontSave )
{
var new_event = function( e ){
e = prepareEvent( e );
func( e );
};
if ( !dontSave )
{
var el_event = null;
for ( var i = 0; i < _events.length; i++ )
if ( _events[i]['el'] == el )
{
el_event = _events[i];
break;
}
if ( !el_event )
el_event = _events[ _events.length ] = { el: el, types: {} }
if ( el_event['types'][type] == undefined )
el_event['types'][type] = {}
if ( el_event['types'][type][func] ) return;
el_event['types'][type][func] = { foo: 'bar', f: new_event }
}
if ( el.addEventListener )
el.addEventListener( type, new_event, false );
else
el.attachEvent( 'on' + type, new_event );
}
function addEvent( el, type, func, dontSave )
{
if ( typeof el == 'string' )
el = document.getElementById( el );
if ( isArray( el ) )
for ( var i = 0; i < el.length; i++ )
_addEvent( el[i], type, func, dontSave );
else if( el )
_addEvent( el, type, func, dontSave );
}
function _removeEvent( el, type, func )
{
var el_event = null;
for ( var i = 0; i < _events.length; i++ )
if ( _events[i]['el'] == el )
{
el_event = _events[i];
break;
}
if ( el_event && el_event['types'][type][func] )
{
var old_event = el_event['types'][type][func].f;
el_event['types'][type][func] = undefined;
if ( el.removeEventListener )
el.removeEventListener( type, old_event, false );
else
el.detachEvent( 'on' + type, old_event );
}
}
function removeEvent( el, type, func )
{
if ( typeof el == 'string' )
el = document.getElementById( el );
if ( isArray( el ) )
for ( var i = 0; i < el.length; i++ )
_removeEvent( el[i], type, func );
else if ( el )
_removeEvent( el, type, func );
}
function addMouseScrollEvent( el, func )
{
addEvent( el, 'mousewheel', func )
addEvent( el, 'DOMMouseScroll', func )
}
function inArray( arr, item )
{
for ( var i = 0; i < arr.length; i++ )
if ( arr[i] == item ) return true;
return false;
}
function trim( s, charlist )
{
charlist = charlist || '\s';
var p = new RegExp( '^[' + charlist + ']|[' + charlist + ']$', 'g' );
return s.replace( p, '' );
}
function isClass( el, className )
{
if ( !className ) return true;
var classes = trim( className, '.' ).split( '.' );
for ( var i = 0; i < classes.length; i++ )
if ( !inArray( el.className.split( ' ' ), classes[i] ) ) return false;
return true;
}
function is_string( el )
{
return typeof el == 'string';
}
function _prepareElement( el )
{
if ( is_string(el) ) el = $(el);
return el;
}
function addClass( el, classname )
{
el = _prepareElement( el );
if ( !isClass(el, classname) )
{
var classes = el.className.split( ' ' );
classes.push( classname );
el.className = classes.join( ' ' );
}
return el;
}
function removeClass( el, classname )
{
el = _prepareElement( el );
var classes = el.className.split( ' ' );
for ( var i = classes.length - 1; i >= 0; i-- )
if ( classes[i] == classname )
{
classes.splice( i, 1 );
break;
}
el.className = classes.join( ' ' );
}
function invertClass( el, className )
{
el = _prepareElement( el );
if ( isClass(el, className) )
removeClass(el, className);
else
addClass(el, className);
}
function swapClass( el, className1, className2 )
{
el = _prepareElement( el );
if ( isClass( el, className1 ) )
{
removeClass(el, className1 );
addClass(el, className2 );
}
else
{
removeClass( el, className2 );
addClass( el, className1 );
}
}
function falseEvent( e )
{
if ( e.preventDefault ) e.preventDefault();
e.returnValue = false;
return false;
}
function doNothing( e )
{
return falseEvent( e );
}
function prepareEvent( e )
{
e = window.event || e;
if ( e.srcElement && !window.opera )
e.target = e.srcElement;
if ( e )
{
if ( e.wheelDelta )
{
e.mouseWheelDelta = e.wheelDelta / 120;
//if ( window.opera )
//e.mouseWheelDelta *= -1;
}
else if ( e.detail )
{
e.mouseWheelDelta = -e.detail / 3;
}
}
return e;
}
function print_r( el )
{
var s = '';
for ( var i in el )
{
var quotes = typeof el[i] == 'string' ? '"' : '';
s += '
' + i + ' = ' + quotes + el[i] + quotes + ''
}
s = '';
var div = null;
if ( !(div = $('print_r_container')) )
{
div = document.createElement( 'div' );
div.id = 'print_r_container';
document.getElementsByTagName('body')[0].appendChild( div );
div.style['backgroundColor'] = 'white';
div.style['position'] = 'absolute';
div.style['zIndex'] = '10';
}
div.innerHTML = s;
}
function getFullOffsets( el )
{
if ( !el )
{
alert('Bad el in getFullOffsets() == ' + el);
return [0,0];
}
var offsets = getPageOffsets( el );
return [ offsets.x, offsets.y ];
}
function getFullOffsetLeft( el, _dump )
{
var offsets = getPageOffsets( el );
return offset.x;
}
function getFullOffsetTop( el )
{
var offsets = getPageOffsets( el );
return offset.y;
}
function _isTag(el, tagName) {
if ( !tagName || tagName == '*' ) return true;
log( el.tagName + ' vs ' + tagName.toUpperCase() );
return el.tagName == tagName.toUpperCase();
}
function removeNode( el ) { el.parentNode.removeChild( el ) }
//ancestor
//descendant
//
//parent
//child
//
//sibling (prev, next)
//
//preceding
//following
function getAncestor( el, tagName, className )
{
tagName = tagName.toUpperCase();
while (el && (!_isTag(el, tagName) || !isClass(el, className))) el = el.parentNode;
return el;
}
function getPreceding( el, tagname, classname )
{
while ( el && ( !_isTag( el, tagname ) || !isClass( el, classname ) ) )
el = el.previousSibling || el.parentNode;
return el;
}
function getNextSibling( el ){ return getNextSiblingElement( el ); }
function getNextSiblingElement( el )
{
while ( (el = el.nextSibling) && el.nodeType != 1 );
return el || !!el;
}
function getPreviousSibling( el )
{
while ( (el = el.previousSibling) && el.nodeType != 1 );
return el || !!el;
}
function getChilds( el, tagname, classname )
{
var result = [];
for ( var child = el.firstChild; child; child = child.nextSibling )
if ( child.nodeType == 1 && _isTag( child, tagname ) && isClass( child, classname ) )
result.push( child );
return result;
}
function in_subtree( el, tree, steps )
{
steps = steps || -1;
do {
if ( el == tree ) return true;
} while ( el = el.parentNode && --steps)
return false;
}
// TODO:
// 1. Check whether is good to always return computed styles
// 2. Automatically convert EMs into pixels
//
function _getStyle( el, style )
{
//dump( el + ' ' + el.id );
if ( el.style[style] ) return el.style[style];
if ( el.currentStyle ) return el.currentStyle[style]
if ( window.getComputedStyle ) return window.getComputedStyle(el,null)[style]
}
function Coordinate( x, y )
{
this.x = x;
this.y = y;
}
function getPageOffsets(el) {
var doc = document;
// Gecko browsers normally use getBoxObjectFor to calculate the position.
// When invoked for an element with an implicit absolute position though it
// can be off by one. Therefor the recursive implementation is used in those
// (relatively rare) cases.
var BUGGY_GECKO_BOX_OBJECT = isGecko && doc.getBoxObjectFor &&
_getStyle(el, 'position') == 'absolute' &&
(el.style.top == '' || el.style.left == '');
var BUGGY_CAMINO_ = false;
// NOTE: If element is hidden (display none or disconnected or any the
// ancestors are hidden) we get (0,0) by default but we still do the
// accumulation of scroll position.
var pos = new Coordinate(0, 0);
var viewportElement;
if (isIE && doc.compatMode != 'CSS1Compat') {
viewportElement = doc.body;
}
else
viewportElement = doc.documentElement;
if (el == viewportElement) {
// viewport is always at 0,0 as that defined the coordinate system for this
// function - this avoids special case checks in the code below
return pos;
}
var parent = null;
var box;
if (el.getBoundingClientRect && !isOpera ) { // IE
// alert('ie');
box = el.getBoundingClientRect();
var scrollTop = viewportElement.scrollTop;
var scrollLeft = viewportElement.scrollLeft;
pos.x = box.left + scrollLeft;
pos.y = box.top + scrollTop;
} else if (doc.getBoxObjectFor && !BUGGY_GECKO_BOX_OBJECT &&
!BUGGY_CAMINO_) { // gecko
// alert('gecko');
// Gecko ignores the scroll values for ancestors, up to 1.9. See:
// https://bugzilla.mozilla.org/show_bug.cgi?id=328881 and
// https://bugzilla.mozilla.org/show_bug.cgi?id=330619
box = doc.getBoxObjectFor(el);
var vpBox = doc.getBoxObjectFor(viewportElement);
pos.x = box.screenX - vpBox.screenX;
pos.y = box.screenY - vpBox.screenY;
} else { // safari/opera
// alert('opera');
pos.x = el.offsetLeft;
pos.y = el.offsetTop;
//dump(pos.x + ' - ' + pos.y );
parent = el.offsetParent;
if (parent != el) {
while (parent) {
pos.x += parent.offsetLeft;
//dump(parent.offsetLeft + ' - ' + parent.offsetTop);
pos.y += parent.offsetTop;
parent = parent.offsetParent;
}
}
// opera & (safari absolute) incorrectly account for body offsetTop
if (isOpera || (isSafari &&
_getStyle(el, 'position') == 'absolute')) {
pos.y -= doc.body.offsetTop;
}
// accumulate the scroll positions for everything but the body element
parent = el.offsetParent;
while (parent && parent != doc.body) {
pos.x -= parent.scrollLeft;
// see https://bugs.opera.com/show_bug.cgi?id=249965
if (!isOpera || parent.tagName != 'TR') {
pos.y -= parent.scrollTop;
}
parent = parent.offsetParent;
}
}
return pos;
};
function getLayout( el, _dump )
{
el = _prepareElement( el );
var offsets = getPageOffsets( el );
layout = {
left: offsets.x,
top: offsets.y,
width: el.offsetWidth,
height: el.offsetHeight
};
layout.bottom = layout.top + layout.height;
layout.right = layout.left + layout.width;
return layout;
}
function is_in( needle, haystack, width_factor, height_factor )
{
needle = _prepareElement( needle );
haystack = _prepareElement( haystack );
if ( !width_factor ) width_factor = 0;
if ( !height_factor ) height_factor = width_factor;
needle = getLayout( needle );
haystack = getLayout( haystack );
return ( needle.left + needle.width * width_factor > haystack.left &&
needle.top + needle.height * height_factor > haystack.top &&
needle.right - needle.width * width_factor < haystack.right &&
needle.bottom - needle.height * height_factor < haystack.bottom );
}
function is_intersect(a, b)
{
a = _prepareElement(a);
b = _prepareElement(b);
a = getLayout(a);
b = getLayout(b);
_is_intersect( a, b );
}
function _is_intersect( a, b, k )
{
k = k || 1
var total_width = a.width + b.width;
var total_height = a.height + b.height;
var intersect_width = Math.max( a.right, b.right ) - Math.min( a.left, b.left );
var intersect_height = Math.max( a.bottom, b.bottom ) - Math.min( a.top, b.top );
return ( intersect_width < total_width && intersect_height < total_height * k );
}
function body()
{
return document.getElementsByTagName( 'body' )[0];
}
function html()
{
return document.getElementsByTagName( 'html' )[0];
}
function getAbsoluteMouseCoordinates( e ) {
return {
x: getPageXOffset() + e.screenX,
y: getPageYOffset() + e.screenY
};
}
function getPageYOffset() { return window.pageYOffset || document.body.scrollTop || 0 }
function getPageXOffset() { return window.pageXOffset || document.body.scrollLeft || 0 }
function _XMLHttpRequest()
{
var ajax_funcs = [
function() { return new XMLHttpRequest() },
function() { return new ActiveXObject('Microsoft.XMLHTTP') },
function() { return new ActiveXObject('Msxml2.XMLHTTP') }
];
var return_value = false;
for (var i = 0; i < ajax_funcs.length; i++ )
{
try {
return_value = ajax_funcs[i]();
}
catch (e) {}
}
this.obj = return_value;
this.async = true;
this.method = 'GET';
this.onready = function(){};
}
_XMLHttpRequest.prototype = {
setRequestHeader: function( name, value) {
this.obj.setRequestHeader( name, value );
},
open: function( method, url, async ) {
this.method = method;
if ( async == undefined ) async = true;
this.async= async;
this.obj.open( method, url, async );
},
send: function( body ) {
var _this = this;
if ( this.async )
this.obj.onreadystatechange = function() {
if ( _this.obj.readyState == 4 && _this.obj.status == 200 )
{
_this.responseText = _this.obj.responseText;
_this.onready( _this.responseText );
}
}
if ( this.method == 'GET' )
body = null;
this.obj.send( body );
if ( !this.async )
{
_this.responseText = _this.obj.responseText;
_this.onready( _this.responseText );
}
}
}
function getOffsetTop( el )
{
return el.offsetTop + (isIE6 && el.offsetParent ? el.offsetParent.clientTop : 0);
}
function getOffsetLeft( el, _dump )
{
if ( _dump ) dump( el.nodeName + ( el.className ? '.' : '' ) + el.className + ( el.id ? '#' : '' ) + el.id + ' = ' + el.offsetLeft + ' + ' + (isIE6 && el.offsetParent ? el.offsetParent.clientLeft: 0) );
return el.offsetLeft + ( isIE6 && el.offsetParent ? el.offsetParent.clientLeft : 0 );
if ( !isIE6 ) return el.offsetLeft;
var offset = el.offsetLeft;
while ( el = el.offsetParent )
if ( el.offsetLeft )
{
offset -= el.offsetLeft
break;
}
return offset;
}
function _border( el, property, style )
{
style = style || '1px solid red';
property = property || 'border';
el.style[ property ] = style;
}
function border( el, style ) { _border( el, 'border', style ) }
function borderl( el, style ) { _border( el, 'borderLeft', style ) }
function unborder( el ) { el.style['borderWidth'] = '0px' }
function applyCommonProperties( el, styles, callback )
{
if ( !styles ) return;
var parts = [];
styles = styles.split( ';' )
for ( var i = 0; i < styles.length; i++ )
if ( styles[i] )
{
parts = styles[i].split(':')
parts[0] = trim( parts[0], ' ' )
parts[1] = trim( parts[1], ' ' )
callback( parts )
}
}
function applyStyles( el, styles )
{
if ( styles )
applyCommonProperties( el, styles, function( parts ){
parts[0] = parts[0].replace( /-\w/i, function ( foo ){
return foo.substr( 1 ).toUpperCase();
} );
el.style[ parts[0] ] = parts[1];
} )
}
function applyAttributes( el, attrs )
{
if ( attrs )
applyCommonProperties( el, attrs, function( parts ){
el[ parts[0] ] = parts[1];
} )
}
function createElement( nodeName, attr, id, className, styles )
{
var el = document.createElement( nodeName );
el.id = id || '';
applyAttributes( el, attr );
el.className = className || '';
applyStyles( el, styles );
return el;
}
function setOpacity( foo, value )
{
/*var object = el.style;
object.opacity = (value / 100);
object.MozOpacity = (value / 100);
object.KhtmlOpacity = (value / 100);
object.filter = "alpha(opacity=" + value + ")";*/
if ( isIE )
foo.style.filter = 'alpha(opacity='+(value * 100)+')';
else
foo.style['opacity'] = value;
}
/*
*
* Cookies
*
*/
function Cookies()
{
}
Cookies.cookies = null;
Cookies.get = function(){
if ( !Cookies.cookies )
{
Cookies.cookies = {};
var parts = [];
var cookies = document.cookie
cookies = cookies.split( ';' );
if ( cookies.length == 1 && cookies[0] == '' ) cookies = [];
for ( var i = 0; i < cookies.length; i++ )
{
parts = cookies[i].split( '=' );
Cookies.cookies[ parts[0].replace( /\s/, '' ) ] = decodeURIComponent( parts[1].replace( /\s/, '' ) );
}
}
return Cookies.cookies;
}
Cookies.add = function ( name, value )
{
}
function showDump(){ if ( $('#dump-container') ) $('#dump-container').style['display'] = 'block'; }
function hideDump(){ if ( $('#dump-container') ) $('#dump-container').style['display'] = 'none'; }
function clearDump(){ if ( $('#dump-container') ) $('#dump-container').innerHTML = ''; }
function dump( s )
{
if ( !$('#dump-container') )
{
body().appendChild( createElement( 'div', '', 'dump-container', '', '' ) );
applyStyles( $('#dump-container'), 'position: absolute; position: fixed; background-color: white; border: 1px solid gray; width: 45em; height: 45em; right: 1em; top: 1em; opacity: 0.5; filter: alpha(opacity=50); font-size: 0.8em; overflow: auto;' )
}
var cont = $('#dump-container').innerHTML;
if ( cont )
cont += '
'
$('#dump-container').innerHTML = cont + s;
$('#dump-container').scrollTop += 1000;
}