Created
June 17, 2010 10:53
-
-
Save antimatter15/441966 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//eLite | |
(function(){ | |
var core = function(e){ //this is the constructor behind the library | |
var _this = this, i = _this[_length] = e[_length]; | |
//* | |
if(i===_undefined){ | |
//if no length value, set it to be that thingy | |
_this[0] = e; | |
_this[_length] = 1; | |
} | |
//i===_undefined&&(t[_length] = (t[0] = e, 1)); | |
for(;i--;)_this[i]=e[i]; //count backwards and set the properties | |
}, | |
proto = core.prototype, | |
ie = /msie/i.test(navigator.userAgent), //better check? | |
_length = 'length', | |
_undefined = undefined, | |
I = proto.I = function(callback){ //magical | |
//THIS IS THE SINGLE MOST IMPORTANT PART OF CODE IN THE WHOLE APP | |
//~230 bytes in size | |
var _fn = function(){ | |
for(var r, //r stores the return of the function | |
w = [], //stores the new array | |
i = -1, //this increments! | |
_this = this, //a shortenable reference to this | |
len = _this[_length], //length to be faster? | |
arg = _this.a(arguments); //finally, a copy of argumetns | |
++i<len;){ //while its not done looping, loop. | |
r = callback.apply(_this,[i, _this[i]].concat(arg)) | |
w = w.concat(_this.a( //append an array to the array | |
r===_undefined? //undefined, make it return default | |
[_this[i]]: //return the original element | |
(typeof(r)<'c'?( //'boolean'<'c' | |
//its a boolean, so now what | |
r?[_this[i]]:[] //add original if true, do nothing if false | |
):r) //if it's not a boolean or undefined, make it an array | |
)); | |
} | |
return _this.g(w); | |
} | |
_fn.orig = callback; | |
return _fn; | |
}; | |
proto.get = proto.g = function(list, no_select){ //exposed core | |
//this is the magical function that acutally gets exposed! | |
if(list.substr) | |
return /^</.test(list)||no_select?this.make(list):this.find(list); //if its a string, either .make() it or .find() it | |
return list.fn?list:(new core(list)); //if the list is already magical, don't re-magicalize | |
} | |
//Miscallaneous definitions | |
proto.fn = proto; | |
proto.core = core; | |
proto.v = 0.1337; | |
//{{{ Enumerables | |
proto.array = proto.a = function(list){ | |
return [].slice.call(list||this) | |
} | |
proto.filter = I(function(index, item, filter){ | |
return !!filter(item) | |
}) | |
proto.map = I(function(index, item, callback){ | |
return [callback(item)] | |
}) | |
proto.each = I(function(index, item, fn){ | |
//fn(index, item); | |
fn.call(item, index, item) | |
}) | |
proto.is = I(function(index, item, check){ | |
return [item==check]; | |
}) | |
proto.not = I(function(index, item){ | |
return [!item]; | |
}) | |
proto.defined = I(function(index, item){ | |
//remove the false/undefined/0 stuff | |
return !!item; | |
}) | |
proto.first = function(){ | |
return this.eq(0); | |
} | |
proto.last = function(){ | |
//negative index | |
return this.eq(-1); | |
} | |
proto.eq = function(index){ | |
//expanded from the original version, supports negative indexes | |
return this.g(this[index<0?(this.length+index):index]); | |
} | |
proto.toString = proto.tj = function(delimiter){ | |
return this.a().join(delimiter||''); | |
} | |
proto.add = function(item){ | |
//current object -> array -> add the item -> new object -> return | |
return this.g(this.a().concat(this.g(item).array())); | |
} | |
proto.del = I(function(index, item, check){ | |
//create a new list with all except the ones that match | |
return check==item?[]:[item]; | |
}) | |
proto.count = function(item){ | |
return this.is(item).defined().length; | |
} | |
proto.has = function(item){ | |
//return !!this.count(item); | |
for(var i = 0, _this=this; //redefine _this to shorten it | |
_this[i]!=item && ++i < _this[_length]; //loop/increment until element is found | |
){}; //closure gets rid of {} | |
return i<_this[_length]?i:-1 //if not found, it's a huge number | |
} | |
proto.unique = I(function(index, item){ | |
return this.has(item) == index; | |
}) | |
proto.slice = function(begin, end){ | |
return this.get([].slice.apply(this,arguments)); | |
} | |
//}}} | |
//{{{ Utilities | |
proto.no = function(){}; | |
proto.trim = function(str){ | |
return (str||this+'').replace(/^\s+|\s+$/g,''); | |
} | |
proto.now = function(){ | |
return +new Date; | |
} | |
proto.set = proto.extend = function(old, properties){ | |
if (!properties) { | |
properties = old; | |
old = this; | |
} | |
for(var i in properties) | |
old[i] = properties[i]; | |
return old; //== this; | |
} | |
proto.rand = function(range){ | |
return ~~(Math.random()*range); | |
} | |
proto._xdecode = function(str){ | |
return eval('('+str+')'); | |
} | |
proto._xencode = function(obj){ | |
var x, t=[], N=proto.encode; //arguments.callee | |
if(obj.split) //string | |
return "'"+obj.replace(/(['\n\\])/g,"\\$1")+"'"; | |
if(typeof obj < 'o') //number/boolean | |
return obj+''; | |
for(x in obj) t.push( //object/array | |
(obj.pop?'':(N(x)+':'))+N(obj[x])); | |
obj = t.join(); | |
return obj.pop?('{'+obj+'}'):('['+obj+']') | |
} | |
proto.decode = window.JSON?JSON.parse:proto._xdecode; | |
proto.encode = window.JSON?JSON.stringify:proto._xencode; | |
proto.ajax = function(url, callback, post){ | |
var x = new(window.XMLHttpRequest||ActiveXObject)('Microsoft.XMLHTTP') | |
x.open(post?'POST':'GET',url||'.',1); | |
post&&x.setRequestHeader('Content-type','application/x-www-form-urlencoded'); | |
x.onreadystatechange=function(){ | |
x.readyState>3&&callback&&callback(x.responseText,x) | |
}; | |
x.send(post) | |
return x | |
} | |
//}}} | |
//{{{ Animation | |
proto.fxrate = 10; //10ms per iteration | |
proto.fxdefault = 400; //default animation is 400ms | |
proto.ease = proto.esine = function(v){return (1-Math.cos(v*Math.PI))/2}; | |
//proto.eline = function(v){return v}; | |
proto.fx = I(function(index, | |
element, //the affected element | |
duration, //duration in milliseconds | |
callback //callback for each iteration args: (post-easing val 0-1, pre-easing val 0-1) | |
){ | |
var _this = this, | |
now = _this.now, //assign a shortuct to this.now(), which is +new Date | |
begin = now(), //store the startup time | |
amount, //here is the amount, its from 0-1 and pre-easing | |
loop //this stores the main animation looper | |
if(element.R) //if it's running | |
return (element.Q=(element.Q||[]).concat([arguments]),[element]); //add to Q(ueue) | |
element.R = 1; //set thta the animation is running | |
;(loop = function(){ //set the main recursive looper | |
if( | |
(amount = (now()-begin)/duration) < 1 //terminate if amount is > 1 | |
&& element.R | |
&& callback(_this.ease(amount),element) != 9 //9 terminates execution, it's a random number | |
) setTimeout(loop, _this.fxrate); else{ | |
amount>1&&callback(1,element); //the last value must be greater than 1 for the loop to terminate | |
//or else it has been cancelled in the middle, in which case, it shouldn't be called again | |
//and because of that you dont call it again. | |
element.R = 0; //animation is no longer running | |
element.Q && element.Q.length && | |
_this.g(element).fx.apply(_this.g(element), _this.a(element.Q.shift()).slice(2)); | |
} | |
})() //start off the looper | |
}); | |
proto.fade = function(d, r){ | |
var t = this; | |
t.fx(d || t.fxdefault, function(a,e){ | |
if(!a && t.get(e).hidden()[0]==r)return 9; | |
if(a==1) t.css('opacity','').css('filter', '').show(!r); | |
else{ | |
r&&(a=1-a); | |
t.show().css('opacity', a+''); | |
ie && | |
t.css('filter', 'alpha(opacity='+100*a+')'); | |
} | |
}) | |
return t; | |
} | |
proto.slide = function(d, r){ | |
var t = this, _height = 'height'; | |
return t.fx(d || t.fxdefault, function(a, e){ | |
if(!a && t.get(e).hidden()[0]==r) return 9; | |
a==1? | |
t.get(e).css(_height, e.p + 'px').show(!r,e.p=0): | |
t.get(e).css(_height, (e.p ? ((r?(1-a):a)*e.p):( | |
(e.p=t.get(e).show().pos()[0].h)*(+r) | |
)) + 'px'); | |
}) | |
} | |
proto.show = I(function(index, item, state){ | |
this.g(item).css('display',(state||state===_undefined)?'':'none') | |
}) | |
proto.hide = function(){ | |
return this.show(0); | |
} | |
proto.hidden = I(function(index, item){ | |
return [item.style.display == 'none'] | |
}) | |
proto.fadeIn = function(duration){ | |
return this.fade(duration,0) | |
} | |
proto.fadeOut = function(duration){ | |
return this.fade(duration,1) | |
} | |
proto.slideDown = function(duration){ | |
return this.slide(duration,0) //weird how i cant get rid of the zero without breaking it | |
//issue: using it without the zero prevents hidden() from working properly | |
//cuz undefined!=false | |
} | |
proto.slideUp = function(duration){ | |
return this.slide(duration,1) | |
} | |
proto.delay = function(duration){ | |
return this.fx(duration,this.no); | |
} | |
proto.queue = function(callback){ | |
var _this = this; | |
//it cant be zero because division by zero equals infinity which is > 1.0 | |
//but if its negative, i cant see any negative side effects | |
_this.fx(-1, function(u, element){ | |
callback(); | |
return 9 //SIGKILL, read: http://en.wikipedia.org/wiki/SIGKILL | |
}) | |
return _this; | |
} | |
//}}} | |
//{{{ CSS Selectors/DOM Traversal | |
proto._nfind = I(function(index, item, selector){ | |
return item.querySelectorAll(selector) | |
}); | |
proto._xfind = function(selector){ | |
//parse it and search manually yay yay yay | |
var item = this; | |
(' '+this.trim(selector)) | |
.replace(/ *([>\+]) */g,'$1;%') | |
.replace(/ ([\.#:])/g, ' *$1') | |
.replace(/([ %\.#:>\+\[]|^)(;% .+?\]|;|[^\[\.#:>\+% ]*)/g, function(all, op, arg){ | |
item = item[op](arg).nodeType(1); | |
}) | |
return item; | |
}; | |
proto.find = document.querySelectorAll?proto._nfind:proto._xfind; | |
proto[' '] = proto.tag = I(function(index, item, tag){ | |
return item.getElementsByTagName(tag||'*'); | |
}) | |
proto.id = function(id){ | |
return this.g(this.d().getElementById(id)); | |
} | |
proto.cls = function(cls){ | |
return this.find('.'+cls); | |
} | |
proto['%'] = proto.filterTag = I(function(index, item, tag){ | |
return item.tagName.toLowerCase() == tag.toLowerCase() | |
}) | |
proto['#'] = proto.filterId = I(function(index, item, id){ | |
return item.id == id | |
}) | |
proto['.'] = proto.filterClass = I(function(index, item, cls){ | |
return this.g(item).hasClass(cls)[0] | |
}) | |
proto.children = function(){ | |
return this.contents().nodeType(1) | |
} | |
proto['>'] = proto.contents = I(function(index, item){ | |
return item.childNodes | |
}); | |
proto['+'] = proto.next = I(function(index, item){ | |
return item.nextSibling; | |
}) | |
proto.prev = I(function(item){ | |
return item.previousSibling; | |
}) | |
proto.nodeType = I(function(index, item, type){ | |
return item.nodeType == type | |
}) | |
proto.parent = I(function(index, item){ | |
return [item.parentNode]; | |
}) | |
//}}} | |
//{{{ Dom Manipulation | |
proto.d = function(){ | |
return this[0].ownerDocument||document; | |
} | |
proto.make = function(str){ | |
return this.create().html(str).contents(); //maybe .contents() at the end? | |
} | |
proto.create = function(tag){ | |
return this.g(this.d().createElement(tag||'div')) | |
} | |
proto.remove = I(function(index, item){ | |
item.parentNode.removeChild(item); | |
}) | |
proto.append = function(el){ | |
this.g(el,1).appendTo(this); | |
return this; | |
} | |
proto.prepend = function(el){ | |
this.g(el,1).prependTo(this); | |
return this; | |
} | |
proto.appendTo = I(function(index, item, target){ | |
this.g(target)[0].appendChild(item); | |
}) | |
proto.prependTo = I(function(index, item, target){ | |
target = this.g(target)[0]; | |
target.insertBefore(item, target.firstChild); | |
}) | |
proto.insertAfter = I(function(index, item, target){ | |
//this.insertBefore(target.nextSibling); | |
target = this.g(target)[0]; | |
target.parentNode.insertBefore(item, target.nextSibling); | |
}) | |
proto.insertBefore = I(function(index, item, target){ | |
target = this.g(target)[0]; | |
target.parentNode.insertBefore(item, target); | |
}) | |
proto.before = function(el){ | |
this.g(el).insertBefore(this); | |
return this; | |
} | |
proto.after = function(el){ | |
this.g(el).insertAfter(this); | |
return this; | |
} | |
//}}} | |
//{{{ Attributes | |
proto.html = function(val){ | |
return this.prop('innerHTML',val) | |
} | |
proto.val = function(val){ | |
return this.prop('value', val) | |
} | |
proto.text = function(val){ | |
return this.prop(document.body.innerText?'innerText':'contentText', val) | |
} | |
proto.attr = I(function(index, item, name, val){ | |
if(val===_undefined) return [item.getAttribute(name)]; | |
item.setAttribute(name, val); | |
}) | |
proto.removeAttr = I(function(index, item, name){ | |
item.removeAttribute(name) | |
}) | |
proto.toggleClass = I(function(index, item, name){ | |
item = this.g(item); | |
item.hasClass(name)[0]?item.removeClass(name):item.addClass(name); | |
}) | |
proto.prop = I(function(index, item, name, val){ | |
if(val===_undefined) return [item[name]]; | |
item[name] = val; | |
}) | |
proto.hasClass = I(function(index, item, cls){ | |
return [this.g(item.className.split(' ')).has(cls)>-1] | |
}) | |
proto.addClass = I(function(index, item, cls){ | |
this.g(item).hasClass(cls)||(item.className+=' '+cls); | |
}) | |
proto.removeClass = I(function(index, item, cls){ | |
item.className = this.g(item).del(cls).tj(' '); | |
}) | |
proto.css = I(function(index, item, name, val){ | |
name = name.replace(/-(.)/,function(all, match){return match.toUpperCase()}); | |
if(val===_undefined) | |
return [item.style[name]]; | |
item.style[name] = val; | |
}) | |
proto.pos = I(function(index, item){ | |
var pos = {l:0, t:0, w:item.offsetWidth, h:item.offsetHeight}; | |
do{ | |
pos.l += item.offsetLeft; | |
pos.t += item.offsetTop | |
}while(item = item.offsetParent) | |
return [pos] | |
}) | |
//}}} | |
//{{{ Events | |
//should this be unbound for all elements immediately | |
//when its first triggered for one element or after each? | |
proto.one = function(t, f){ | |
var j = this, g = function(a){ | |
j.un(t, g) | |
f.call(this, a) | |
} | |
return j.on(t, g) | |
} | |
proto.on = I(function(index, item, type, callback){ | |
if(item.attachEvent || item.addEventListener(type,callback,0)){ | |
item['e'+type+callback] = callback; | |
item[type+callback] = function(){ | |
item['e'+type+callback].call(event.srcElement, event) | |
}; | |
item.attachEvent('on'+type,item[type+callback]) | |
} | |
}) | |
proto.un = I(function(index, item, type, callback){ | |
item.attachEvent? | |
item.detachEvent('on'+type,item[type+callback]): | |
item.removeEventListener(type,callback,0); | |
}) | |
proto.fire = I(function(index, item, type){ | |
if (item.fireEvent) { | |
item.fireEvent('on' + type) | |
} else { | |
var event = this.d().createEvent('Events'); | |
event.initEvent(type); | |
item.dispatchEvent(event); | |
} | |
}) | |
proto.ready = function(f){ | |
ie? //if unhappy browser | |
setTimeout(f,0): //do ugly hack for ie | |
this.g(this.d()).on('DOMContentLoaded', f) | |
} | |
//or should it be .proxy? | |
proto.bind = function(callback, scope){ | |
return function(){ | |
return callback.apply(scope, arguments) | |
} | |
} | |
//}}} | |
var methods = proto.get(document.documentElement), | |
exposed = proto.bind(methods.get, methods), | |
property; | |
for(property in proto) | |
exposed[property] = methods[property].apply? //basic function-ity test | |
proto.bind(methods[property], methods): | |
methods[property]; | |
proto._old$ = window.$; | |
window.eLite = window.$ = exposed; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment