minitech
Apr 10th, 2011, 08:16 PM
Finally, I've implemented the relationship selectors :rolleyes: It was much easier than expected, actually. I've rebuilt my whole system from the ground up... and I minified it as I was writing it! :D That's right - the whitespace, the variable names, everything :D So enjoy! I'm working on giving it a better structure and actually finishing the selector system, then attaching my other JS library, but I don't have time today. See you then.
You can copy the most recent and compressed version right here (5.77KB), or download the full (readable) version:
Newest release is Sprint 2.0, which improves performance and general code structure. It doesn't support nth-xxx selectors yet (I didn't have time) but I'm working on it. Minified (6.89KB) is available below the link.
Sprint 2.0 Dev Download, 05/09/2011 (http://dl.dropbox.com/u/2463964/sprint-2.0.js) [11.2KB]
if(![].indexOf)Array.prototype.indexOf=function(b,a){for(a=a||0;a<this.length;)if(this[a++]===b)return a-1;return-1};String.prototype.startsWith=function(b){return this.length>=b.length&&this.substring(0,b.length)===b};String.prototype.endsWith=function(b){return this.length>=b.length&&this.substring(this.length-b.length)===b};
var Sprint={Error:function(b){this.message=b;this.toString=function(){return this.message}},getAllElementsIn:function(b){var a=[];(function d(a,b){from(a).each(function(a,g){g.nodeType===1&&(b.push(g),d(g,b))})})(b,a);return a},getAllElements:function(){return Sprint.getAllElementsIn(document.documentElement)},getSiblings:function(b){return b.parentNode?from(b.parentNode).where(function(a,b){return b.nodeType===1}).toArray():[b]},getInfo:function(b){for(var a={ATTR:{},CLASS:[],PSEUDO:[]},c=!1,d=!1,
g=null,e=[],h=/^[^a-zA-Z0-9_\-]$/,j=null,l=-1,i,f="";++l<b.length;){i=b.charAt(l);if(d)d=!1;else if(i==="\\"){d=!0;continue}else if(g)g===i&&(g=null);else if("'\"".indexOf(i)>-1)g=i;else if(e.length)"(){}".indexOf(e[e.length-1])+1==="(){}".indexOf(i)&&e.pop();else if("(){}".indexOf(i)>-1)e.push(i);else if(h.test(i)){if(j)switch(j){case "#":a.ID=f;break;case ".":a.CLASS.push(f);break;case "[":case ",":if(c){var k;(k=f.indexOf("="))>-1?a.ATTR[f.substring(0,k)]=f.substring(k+1):a.ATTR[f]=!0}break;case ":":a.PSEUDO.push(f)}else a.TAG=
f;i==="]"?c=!1:i==="["&&(c=!0);j=i;f="";continue}f+=i}if(j)switch(j){case "#":a.ID=f;break;case ".":a.CLASS.push(f);break;case "[":case ",":c&&((k=f.indexOf("="))>-1?a.ATTR[f.substring(0,k)]=f.substring(k+1):a.ATTR[f]=!0);break;case ":":a.PSEUDO.push(f)}else a.TAG=f;return a},compileSingle:function(b){var a='var t=l.nodeName?l.nodeName.toLowerCase():"",i=l.id?l.id.toLowerCase():"",c=l.className?" "+l.className.toLowerCase()+" ":"",s=Sprint.getSiblings(l),ss=from(s).where(function(k,v){return v.nodeName?v.nodeName.toLowerCase()===t:false;}).toArray(),si=s.indexOf(l),ssi=ss.indexOf(l);return ';
b.TAG&&b.TAG!=="*"&&(a+="t==='"+b.TAG.toLowerCase().replace(/[\\']/g,function(a){return"\\"+a})+"'&&");b.ID&&(a+="i==='"+b.ID.toLowerCase().replace(/[\\']/g,function(a){return"\\"+a})+"'&&");if(b.CLASS)for(var c=0;c<b.CLASS.length;c++)a+="c.indexOf(' "+b.CLASS[c].toLowerCase()+" ')>-1&&";if(b.PSEUDO)for(c=0;c<b.PSEUDO.length;c++){var d=b.PSEUDO[c],g,e="";if((g=d.indexOf("("))>-1)e=d.substring(g+1,d.length-1),d=d.substring(0,g);switch(d){case "first-child":a+="!si";break;case "first-of-type":a+="!ssi";
break;case "nth-child":break;case "nth-of-type":break;case "last-child":a+="si===s.length-1";break;case "last-of-type":a+="ssi===ss.length-1";break;case "nth-last-child":break;case "nth-last-of-type":break;case "only-child":a+="s.length===1";break;case "only-of-type":a+="ss.length===1";break;case "disabled":a+="l.disabled";break;case "enabled":a+="!l.disabled";break;case "checked":a+="l.checked";break;case "empty":a+="!l.childNodes.length";break;case "not":a+="!Sprint.isMatch('"+e.replace(/\\'/g,
function(a){return"\\"+a})+"')(0,l)";break;default:throw new Sprint.Error('Unrecognized pseudo-class "'+d+'".');}a+="&&"}b.ATTR&&from(b.ATTR).each(function(b,d){var e=b.charAt(b.length-1);a+="l.getAttribute('"+("$^*~|".indexOf(e)>-1?b.substring(0,b.length-1):b).replace(/\\'/g,function(a){return"\\"+a})+"')";if(typeof d==="string")switch(d=d.replace(/\\'/g,function(a){return"\\"+a}),e){case "$":a+=".endsWith('"+d+"')";break;case "^":a+=".startsWith('"+d+"')";break;case "*":a+=".indexOf('"+d+"')+1";
break;case "~":a+=".split(' ').indexOf('"+d+"')+1";break;case "|":a+=".split('-').indexOf('"+d+"')+1";break;default:a+="==='"+d+"'"}a+="&&"});a.substring(a.length-2)!=="&&"&&(a="return true ");return new Function(["l"],a.substring(0,a.length-2)+";")},compileTree:function(b){for(var b=Sprint.tokenizeSelector(b),a=-1,c;++a<b.length;)if(", >~+".indexOf(b[a])>-1){for(c=a;--c>=0&&b[c]===" ";)b[c]=null;for(c=a;++c<b.length&&b[c]===" ";)b[c]=null}return from(b).where().select(function(a,b){return a%2?b:
Sprint.compileSingle(Sprint.getInfo(b))}).toArray()},matchSingleTree:function(b,a){if(!a.length)retu rn!0;if(!a[a.length-1](b))return!1;for(var c=a.length-3;c>=0;c-=2)switch(a[c+1]||" "){case " ":for(;;){if(!(b=b.parentNode))return!1;if(a[c](b))break}break;case ">":if(!(b=b.parentNode)||!a[c](b))return!1;break;case "+":for(;;){if(!(b=b.previousSibling))return!1;if(b.nodeType===1)if(a[c](b))break;else return!1}break;case "~":for(;;){if(!(b=b.previousSibling))return!1;if(a[c](b))break}}return!0},matchTree:function(b,
a){for(var c=[],d=0;d<a.length;d++)if(a[d]===","){if(Sprint.matchSingleTree(b,c))return!0;c=[]}else c.push(a[d]);return Sprint.matchSingleTree(b,c)},tokenizeSelector:function(b){for(var a=!1,c=null,d=[],g=[],e=-1,h,j="";++e<b.length;){h=b.charAt(e);if(a)a=!1;else if(h==="\\"){a=!0;continue}else if(c)c===h&&(c=null);else if("'\"".indexOf(h)>-1)c=h;else if(d.length)"(){}[]".indexOf(d[d.length-1])+1==="(){}[]".indexOf(h)&&d.pop();else if("(){}[]".indexOf(h)>-1)d.push(h);else if(", >~+".indexOf(h)>-1){g.push(j);
g.push(h);j="";continue}j+=h}g.push(j);return g},isMatch:function(b){var a=Sprint.compileTree(b);return function(b,d){return Sprint.matchTree(d,a)}},select:function(b){return from(Sprint.getAllElements()).where(Sprint.isMatch(b)).toArray()},selectIn:function(b,a){return from(Sprint.getAllElementsIn(a)).where(Sprint.isMatch(b)).toArray()}};
function from(b){if(!b)throw new Sprint.Error("null or undefined passed to Sprint:from().");var a={keys:[],values:[]};if(b.length)for(var c=0;c<b.length;c++)a.keys.push(c),a.values.push(b[c]);else if(b.childNodes)return from(b.childNodes);else for(c in b)b.hasOwnProperty(c)&&(a.keys.push(c),a.values.push(b[c]));a.length=a.keys.length;a.where=function(a){if(a){if(typeof a==="string")return this.where(new Function(["k","v"],"return "+a+";"));for(var b={},e=0;e<this.length;e++)a(this.keys[e],this.values[e])&&
(b[this.keys[e]]=this.values[e]);return from(b)}else return this.where(function(a,b){return b})};a.select=function(a){for(var b={},e=0;e<this.length;e++)b[this.keys[e]]=a(this.keys[e],this.values[e]);return from(b)};a.each=function(a){for(var b=0;b<this.length;b++)a(this.keys[b],this.values[b])};a.first=function(){return this.values[0]};a.last=function(){return this.values[this.length-1]};a.splitBy=function(a){if(typeof a==="function"){for(var b=[],e={},c=0;c<this.length;c++)a(this.keys[c],this.values[c])?
(b.push(e),e={}):e[this.keys[c]]=this.values[c];b.push(e);return from(b)}else return this.splitBy(function(b){return b===a})};a.limit=function(a){var b={},c=-1;if(typeof a==="function")for(;++c<this.length&&a(this.keys[c],this.values[c]);)b[this.keys[c]]=this.values[c];else for(;++c<Math.min(this.length,a);)b[this.keys[c]]=this.values[c];return from(b)};a.after=function(a){var b={},c=-1;if(typeof a==="function"){for(;++c<this.length&&!a(this.keys[c],this.values[c]););for(;++c<this.length;)b[this.keys[c]]=
this.values[c]}else if(a<this.length)for(c=a-1;++c<this.length;)b[this.keys[c]]=this.values[c];return from(b)};a.toArray=function(){return this.values};return a};
Sprint 1.1 Dev Download, 04/11/2011 (http://dl.dropbox.com/u/2463964/sprint-1.1.js) [8.64KB]
Version 0.2: Fixed some pseudo-class problems, gave things better names, reorganized code, added whitespace, removed whitespace with Closure Compiler.
Version 0.2 Minified removed.
Version 0.1 removed.
You can copy the most recent and compressed version right here (5.77KB), or download the full (readable) version:
Newest release is Sprint 2.0, which improves performance and general code structure. It doesn't support nth-xxx selectors yet (I didn't have time) but I'm working on it. Minified (6.89KB) is available below the link.
Sprint 2.0 Dev Download, 05/09/2011 (http://dl.dropbox.com/u/2463964/sprint-2.0.js) [11.2KB]
if(![].indexOf)Array.prototype.indexOf=function(b,a){for(a=a||0;a<this.length;)if(this[a++]===b)return a-1;return-1};String.prototype.startsWith=function(b){return this.length>=b.length&&this.substring(0,b.length)===b};String.prototype.endsWith=function(b){return this.length>=b.length&&this.substring(this.length-b.length)===b};
var Sprint={Error:function(b){this.message=b;this.toString=function(){return this.message}},getAllElementsIn:function(b){var a=[];(function d(a,b){from(a).each(function(a,g){g.nodeType===1&&(b.push(g),d(g,b))})})(b,a);return a},getAllElements:function(){return Sprint.getAllElementsIn(document.documentElement)},getSiblings:function(b){return b.parentNode?from(b.parentNode).where(function(a,b){return b.nodeType===1}).toArray():[b]},getInfo:function(b){for(var a={ATTR:{},CLASS:[],PSEUDO:[]},c=!1,d=!1,
g=null,e=[],h=/^[^a-zA-Z0-9_\-]$/,j=null,l=-1,i,f="";++l<b.length;){i=b.charAt(l);if(d)d=!1;else if(i==="\\"){d=!0;continue}else if(g)g===i&&(g=null);else if("'\"".indexOf(i)>-1)g=i;else if(e.length)"(){}".indexOf(e[e.length-1])+1==="(){}".indexOf(i)&&e.pop();else if("(){}".indexOf(i)>-1)e.push(i);else if(h.test(i)){if(j)switch(j){case "#":a.ID=f;break;case ".":a.CLASS.push(f);break;case "[":case ",":if(c){var k;(k=f.indexOf("="))>-1?a.ATTR[f.substring(0,k)]=f.substring(k+1):a.ATTR[f]=!0}break;case ":":a.PSEUDO.push(f)}else a.TAG=
f;i==="]"?c=!1:i==="["&&(c=!0);j=i;f="";continue}f+=i}if(j)switch(j){case "#":a.ID=f;break;case ".":a.CLASS.push(f);break;case "[":case ",":c&&((k=f.indexOf("="))>-1?a.ATTR[f.substring(0,k)]=f.substring(k+1):a.ATTR[f]=!0);break;case ":":a.PSEUDO.push(f)}else a.TAG=f;return a},compileSingle:function(b){var a='var t=l.nodeName?l.nodeName.toLowerCase():"",i=l.id?l.id.toLowerCase():"",c=l.className?" "+l.className.toLowerCase()+" ":"",s=Sprint.getSiblings(l),ss=from(s).where(function(k,v){return v.nodeName?v.nodeName.toLowerCase()===t:false;}).toArray(),si=s.indexOf(l),ssi=ss.indexOf(l);return ';
b.TAG&&b.TAG!=="*"&&(a+="t==='"+b.TAG.toLowerCase().replace(/[\\']/g,function(a){return"\\"+a})+"'&&");b.ID&&(a+="i==='"+b.ID.toLowerCase().replace(/[\\']/g,function(a){return"\\"+a})+"'&&");if(b.CLASS)for(var c=0;c<b.CLASS.length;c++)a+="c.indexOf(' "+b.CLASS[c].toLowerCase()+" ')>-1&&";if(b.PSEUDO)for(c=0;c<b.PSEUDO.length;c++){var d=b.PSEUDO[c],g,e="";if((g=d.indexOf("("))>-1)e=d.substring(g+1,d.length-1),d=d.substring(0,g);switch(d){case "first-child":a+="!si";break;case "first-of-type":a+="!ssi";
break;case "nth-child":break;case "nth-of-type":break;case "last-child":a+="si===s.length-1";break;case "last-of-type":a+="ssi===ss.length-1";break;case "nth-last-child":break;case "nth-last-of-type":break;case "only-child":a+="s.length===1";break;case "only-of-type":a+="ss.length===1";break;case "disabled":a+="l.disabled";break;case "enabled":a+="!l.disabled";break;case "checked":a+="l.checked";break;case "empty":a+="!l.childNodes.length";break;case "not":a+="!Sprint.isMatch('"+e.replace(/\\'/g,
function(a){return"\\"+a})+"')(0,l)";break;default:throw new Sprint.Error('Unrecognized pseudo-class "'+d+'".');}a+="&&"}b.ATTR&&from(b.ATTR).each(function(b,d){var e=b.charAt(b.length-1);a+="l.getAttribute('"+("$^*~|".indexOf(e)>-1?b.substring(0,b.length-1):b).replace(/\\'/g,function(a){return"\\"+a})+"')";if(typeof d==="string")switch(d=d.replace(/\\'/g,function(a){return"\\"+a}),e){case "$":a+=".endsWith('"+d+"')";break;case "^":a+=".startsWith('"+d+"')";break;case "*":a+=".indexOf('"+d+"')+1";
break;case "~":a+=".split(' ').indexOf('"+d+"')+1";break;case "|":a+=".split('-').indexOf('"+d+"')+1";break;default:a+="==='"+d+"'"}a+="&&"});a.substring(a.length-2)!=="&&"&&(a="return true ");return new Function(["l"],a.substring(0,a.length-2)+";")},compileTree:function(b){for(var b=Sprint.tokenizeSelector(b),a=-1,c;++a<b.length;)if(", >~+".indexOf(b[a])>-1){for(c=a;--c>=0&&b[c]===" ";)b[c]=null;for(c=a;++c<b.length&&b[c]===" ";)b[c]=null}return from(b).where().select(function(a,b){return a%2?b:
Sprint.compileSingle(Sprint.getInfo(b))}).toArray()},matchSingleTree:function(b,a){if(!a.length)retu rn!0;if(!a[a.length-1](b))return!1;for(var c=a.length-3;c>=0;c-=2)switch(a[c+1]||" "){case " ":for(;;){if(!(b=b.parentNode))return!1;if(a[c](b))break}break;case ">":if(!(b=b.parentNode)||!a[c](b))return!1;break;case "+":for(;;){if(!(b=b.previousSibling))return!1;if(b.nodeType===1)if(a[c](b))break;else return!1}break;case "~":for(;;){if(!(b=b.previousSibling))return!1;if(a[c](b))break}}return!0},matchTree:function(b,
a){for(var c=[],d=0;d<a.length;d++)if(a[d]===","){if(Sprint.matchSingleTree(b,c))return!0;c=[]}else c.push(a[d]);return Sprint.matchSingleTree(b,c)},tokenizeSelector:function(b){for(var a=!1,c=null,d=[],g=[],e=-1,h,j="";++e<b.length;){h=b.charAt(e);if(a)a=!1;else if(h==="\\"){a=!0;continue}else if(c)c===h&&(c=null);else if("'\"".indexOf(h)>-1)c=h;else if(d.length)"(){}[]".indexOf(d[d.length-1])+1==="(){}[]".indexOf(h)&&d.pop();else if("(){}[]".indexOf(h)>-1)d.push(h);else if(", >~+".indexOf(h)>-1){g.push(j);
g.push(h);j="";continue}j+=h}g.push(j);return g},isMatch:function(b){var a=Sprint.compileTree(b);return function(b,d){return Sprint.matchTree(d,a)}},select:function(b){return from(Sprint.getAllElements()).where(Sprint.isMatch(b)).toArray()},selectIn:function(b,a){return from(Sprint.getAllElementsIn(a)).where(Sprint.isMatch(b)).toArray()}};
function from(b){if(!b)throw new Sprint.Error("null or undefined passed to Sprint:from().");var a={keys:[],values:[]};if(b.length)for(var c=0;c<b.length;c++)a.keys.push(c),a.values.push(b[c]);else if(b.childNodes)return from(b.childNodes);else for(c in b)b.hasOwnProperty(c)&&(a.keys.push(c),a.values.push(b[c]));a.length=a.keys.length;a.where=function(a){if(a){if(typeof a==="string")return this.where(new Function(["k","v"],"return "+a+";"));for(var b={},e=0;e<this.length;e++)a(this.keys[e],this.values[e])&&
(b[this.keys[e]]=this.values[e]);return from(b)}else return this.where(function(a,b){return b})};a.select=function(a){for(var b={},e=0;e<this.length;e++)b[this.keys[e]]=a(this.keys[e],this.values[e]);return from(b)};a.each=function(a){for(var b=0;b<this.length;b++)a(this.keys[b],this.values[b])};a.first=function(){return this.values[0]};a.last=function(){return this.values[this.length-1]};a.splitBy=function(a){if(typeof a==="function"){for(var b=[],e={},c=0;c<this.length;c++)a(this.keys[c],this.values[c])?
(b.push(e),e={}):e[this.keys[c]]=this.values[c];b.push(e);return from(b)}else return this.splitBy(function(b){return b===a})};a.limit=function(a){var b={},c=-1;if(typeof a==="function")for(;++c<this.length&&a(this.keys[c],this.values[c]);)b[this.keys[c]]=this.values[c];else for(;++c<Math.min(this.length,a);)b[this.keys[c]]=this.values[c];return from(b)};a.after=function(a){var b={},c=-1;if(typeof a==="function"){for(;++c<this.length&&!a(this.keys[c],this.values[c]););for(;++c<this.length;)b[this.keys[c]]=
this.values[c]}else if(a<this.length)for(c=a-1;++c<this.length;)b[this.keys[c]]=this.values[c];return from(b)};a.toArray=function(){return this.values};return a};
Sprint 1.1 Dev Download, 04/11/2011 (http://dl.dropbox.com/u/2463964/sprint-1.1.js) [8.64KB]
Version 0.2: Fixed some pseudo-class problems, gave things better names, reorganized code, added whitespace, removed whitespace with Closure Compiler.
Version 0.2 Minified removed.
Version 0.1 removed.