update lowpro and selector according to last commit

This commit is contained in:
Reinier Balt 2008-07-23 23:42:39 +02:00
parent 291a364b0d
commit a18fab8bf4
3 changed files with 323 additions and 323 deletions

View file

@ -222,86 +222,86 @@ Behavior = {
}; };
// Original code by Sylvian Zimmer // Original code by Sylvian Zimmer
// http://www.sylvainzimmer.com/index.php/archives/2006/06/25/speeding-up-prototypes-selector/ // http://www.sylvainzimmer.com/index.php/archives/2006/06/25/speeding-up-prototypes-selector/
// Optimises execution speed of the $$ function. Rewritten for readability by Justin Palmer. // Optimises execution speed of the $$ function. Rewritten for readability by Justin Palmer.
// //
// Turn off optimisation with LowPro.optimize$$ = false; // Turn off optimisation with LowPro.optimize$$ = false;
LowPro.SelectorLite = Class.create(); LowPro.SelectorLite = Class.create();
LowPro.SelectorLite.prototype = { LowPro.SelectorLite.prototype = {
initialize: function(selectors) { initialize: function(selectors) {
this.results = []; this.results = [];
this.selectors = []; this.selectors = [];
this.index = 0; this.index = 0;
for(var i = selectors.length -1; i >= 0; i--) { for(var i = selectors.length -1; i >= 0; i--) {
var params = { tag: '*', id: null, classes: [] }; var params = { tag: '*', id: null, classes: [] };
var selector = selectors[i]; var selector = selectors[i];
var needle = selector.length - 1; var needle = selector.length - 1;
do { do {
var id = selector.lastIndexOf("#"); var id = selector.lastIndexOf("#");
var klass = selector.lastIndexOf("."); var klass = selector.lastIndexOf(".");
var cursor = Math.max(id, klass); var cursor = Math.max(id, klass);
if(cursor == -1) params.tag = selector.toUpperCase(); if(cursor == -1) params.tag = selector.toUpperCase();
else if(id == -1 || klass == cursor) params.classes.push(selector.substring(klass + 1)) else if(id == -1 || klass == cursor) params.classes.push(selector.substring(klass + 1))
else if(!params.id) params.id = selector.substring(id + 1); else if(!params.id) params.id = selector.substring(id + 1);
selector = selector.substring(0, cursor); selector = selector.substring(0, cursor);
} while(cursor > 0); } while(cursor > 0);
this.selectors[i] = params; this.selectors[i] = params;
} }
}, },
get: function(root) { get: function(root) {
this.findElements(root || document, this.index == (this.selectors.length - 1)); this.findElements(root || document, this.index == (this.selectors.length - 1));
return this.results; return this.results;
}, },
findElements: function(parent, descendant) { findElements: function(parent, descendant) {
var selector = this.selectors[this.index], results = [], element; var selector = this.selectors[this.index], results = [], element;
if(selector.id) { if(selector.id) {
element = $(selector.id); element = $(selector.id);
if(element && (selector.tag == '*' || element.tagName == selector.tag) && if(element && (selector.tag == '*' || element.tagName == selector.tag) &&
(element.childOf(parent))) { (element.childOf(parent))) {
results = [element]; results = [element];
} }
} else { } else {
results = $A(parent.getElementsByTagName(selector.tag)); results = $A(parent.getElementsByTagName(selector.tag));
} }
if(selector.classes.length == 1) { if(selector.classes.length == 1) {
results = results.select(function(target) { results = results.select(function(target) {
return $(target).hasClassName(selector.classes[0]); return $(target).hasClassName(selector.classes[0]);
}); });
} else if(selector.classes.length > 1) { } else if(selector.classes.length > 1) {
results = results.select(function(target) { results = results.select(function(target) {
var klasses = $(target).classNames(); var klasses = $(target).classNames();
return selector.classes.all(function(klass) { return selector.classes.all(function(klass) {
return klasses.include(klass); return klasses.include(klass);
}); });
}); });
} }
if(descendant) { if(descendant) {
this.results = this.results.concat(results); this.results = this.results.concat(results);
} else { } else {
++this.index; ++this.index;
results.each(function(target) { results.each(function(target) {
this.findElements(target, this.index == (this.selectors.length - 1)); this.findElements(target, this.index == (this.selectors.length - 1));
}.bind(this)); }.bind(this));
} }
} }
} }
LowPro.$$old=$$; LowPro.$$old=$$;
LowPro.optimize$$ = true; LowPro.optimize$$ = true;
function $$(a,b) { function $$(a,b) {
if (LowPro.optimize$$ == false || b || a.indexOf("[")>=0) if (LowPro.optimize$$ == false || b || a.indexOf("[")>=0)
return LowPro.$$old.apply(this, arguments); return LowPro.$$old.apply(this, arguments);
return new LowPro.SelectorLite(a.split(/\s+/)).get(); return new LowPro.SelectorLite(a.split(/\s+/)).get();
} }

View file

@ -1,163 +1,163 @@
/************************************ /************************************
* *
* An add-on to Prototype 1.5 to speed up the $$ function in usual cases. * An add-on to Prototype 1.5 to speed up the $$ function in usual cases.
* *
* http://www.sylvainzimmer.com/index.php/archives/2006/06/25/speeding-up-prototypes-selector/ * http://www.sylvainzimmer.com/index.php/archives/2006/06/25/speeding-up-prototypes-selector/
* *
* Authors: * Authors:
* - Sylvain ZIMMER <sylvain _at_ jamendo.com> * - Sylvain ZIMMER <sylvain _at_ jamendo.com>
* *
* Changelog: * Changelog:
* v1 (2006/06/25) * v1 (2006/06/25)
* - Initial release * - Initial release
* *
* License: AS-IS * License: AS-IS
* *
* Trivia: Check out www.jamendo.com for some great Creative Commons music ;-) * Trivia: Check out www.jamendo.com for some great Creative Commons music ;-)
* *
************************************/ ************************************/
// We don't extend the Selector class because we want // We don't extend the Selector class because we want
// to be able to use it if the expression is too complicated. // to be able to use it if the expression is too complicated.
var SelectorLiteAddon=Class.create(); var SelectorLiteAddon=Class.create();
SelectorLiteAddon.prototype = { SelectorLiteAddon.prototype = {
// This is the constructor. It parses the stack of selectors. // This is the constructor. It parses the stack of selectors.
initialize: function(stack) { initialize: function(stack) {
this.r=[]; //results this.r=[]; //results
this.s=[]; //stack of selectors this.s=[]; //stack of selectors
this.i=0; //stack pointer this.i=0; //stack pointer
//Parse the selectors //Parse the selectors
for (var i=stack.length-1;i>=0;i--) { for (var i=stack.length-1;i>=0;i--) {
//This is the parsed selector. Format is : [tagname, id, classnames] //This is the parsed selector. Format is : [tagname, id, classnames]
var s=["*","",[]]; var s=["*","",[]];
//The unparsed current selector //The unparsed current selector
var t=stack[i]; var t=stack[i];
//Parse the selector backwards //Parse the selector backwards
var cursor=t.length-1; var cursor=t.length-1;
do { do {
var d=t.lastIndexOf("#"); var d=t.lastIndexOf("#");
var p=t.lastIndexOf("."); var p=t.lastIndexOf(".");
cursor=Math.max(d,p); cursor=Math.max(d,p);
//Found a tagName //Found a tagName
if (cursor==-1) { if (cursor==-1) {
s[0]=t.toUpperCase(); s[0]=t.toUpperCase();
//Found a className //Found a className
} else if (d==-1 || p==cursor) { } else if (d==-1 || p==cursor) {
s[2].push(t.substring(p+1)); s[2].push(t.substring(p+1));
//Found an ID //Found an ID
} else if (!s[1]) { } else if (!s[1]) {
s[1]=t.substring(d+1); s[1]=t.substring(d+1);
} }
t=t.substring(0,cursor); t=t.substring(0,cursor);
} while (cursor>0); } while (cursor>0);
this.s[i]=s; this.s[i]=s;
} }
}, },
//Returns a list of matched elements below a given root. //Returns a list of matched elements below a given root.
get:function(root) { get:function(root) {
this.explore(root || document,this.i==(this.s.length-1)); this.explore(root || document,this.i==(this.s.length-1));
return this.r; return this.r;
}, },
//Recursive function where the actual search is being done. //Recursive function where the actual search is being done.
// elt: current root element // elt: current root element
// leaf: boolean, are we in a leaf of the search tree? // leaf: boolean, are we in a leaf of the search tree?
explore:function(elt,leaf) { explore:function(elt,leaf) {
//Parsed selector //Parsed selector
var s=this.s[this.i]; var s=this.s[this.i];
//Results //Results
var r=[]; var r=[];
//Selector has an ID, use it! //Selector has an ID, use it!
if (s[1]) { if (s[1]) {
e=$(s[1]); e=$(s[1]);
if (e && (s[0]=="*" || e.tagName==s[0]) && e.childOf(elt)) { if (e && (s[0]=="*" || e.tagName==s[0]) && e.childOf(elt)) {
r=[e]; r=[e];
} }
//Selector has no ID, search by tagname. //Selector has no ID, search by tagname.
} else { } else {
r=$A(elt.getElementsByTagName(s[0])); r=$A(elt.getElementsByTagName(s[0]));
} }
//Filter the results by classnames. //Filter the results by classnames.
//Todo: by attributes too? //Todo: by attributes too?
//Sidenote: The performance hit is often here. //Sidenote: The performance hit is often here.
//Single className : that's fast! //Single className : that's fast!
if (s[2].length==1) { //single classname if (s[2].length==1) { //single classname
r=r.findAll(function(o) { r=r.findAll(function(o) {
//If the element has only one classname too, the test is simple! //If the element has only one classname too, the test is simple!
if (o.className.indexOf(" ")==-1) { if (o.className.indexOf(" ")==-1) {
return o.className==s[2][0]; return o.className==s[2][0];
} else { } else {
return o.className.split(/\s+/).include(s[2][0]); return o.className.split(/\s+/).include(s[2][0]);
} }
}); });
//Multipe classNames, a bit slower. //Multipe classNames, a bit slower.
} else if (s[2].length>0) { } else if (s[2].length>0) {
r=r.findAll(function(o) { r=r.findAll(function(o) {
//If the elemtn has only one classname, we can drop it. //If the elemtn has only one classname, we can drop it.
if (o.className.indexOf(" ")==-1) { if (o.className.indexOf(" ")==-1) {
return false; return false;
} else { } else {
//Check that all required classnames are present. //Check that all required classnames are present.
var q=o.className.split(/\s+/); var q=o.className.split(/\s+/);
return s[2].all(function(c) { return s[2].all(function(c) {
return q.include(c); return q.include(c);
}); });
} }
}); });
} }
//Append the results if we're in a leaf //Append the results if we're in a leaf
if (leaf) { if (leaf) {
this.r=this.r.concat(r); this.r=this.r.concat(r);
//Continue exploring the tree otherwise //Continue exploring the tree otherwise
} else { } else {
++this.i; ++this.i;
r.each(function(o) { r.each(function(o) {
this.explore(o,this.i==(this.s.length-1)); this.explore(o,this.i==(this.s.length-1));
}.bind(this)); }.bind(this));
} }
} }
}
//Overwrite the $$ function.
var $$old=$$;
var $$=function(a,b) {
//expression is too complicated, forward the call to prototype's function!
if (b || a.indexOf("[")>=0) return $$old.apply(this,arguments);
//Otherwise use our addon!
return new SelectorLiteAddon(a.split(/\s+/)).get();
} }
//Overwrite the $$ function.
var $$old=$$;
var $$=function(a,b) {
//expression is too complicated, forward the call to prototype's function!
if (b || a.indexOf("[")>=0) return $$old.apply(this,arguments);
//Otherwise use our addon!
return new SelectorLiteAddon(a.split(/\s+/)).get();
}

View file

@ -222,86 +222,86 @@ Behavior = {
}; };
// Original code by Sylvian Zimmer // Original code by Sylvian Zimmer
// http://www.sylvainzimmer.com/index.php/archives/2006/06/25/speeding-up-prototypes-selector/ // http://www.sylvainzimmer.com/index.php/archives/2006/06/25/speeding-up-prototypes-selector/
// Optimises execution speed of the $$ function. Rewritten for readability by Justin Palmer. // Optimises execution speed of the $$ function. Rewritten for readability by Justin Palmer.
// //
// Turn off optimisation with LowPro.optimize$$ = false; // Turn off optimisation with LowPro.optimize$$ = false;
LowPro.SelectorLite = Class.create(); LowPro.SelectorLite = Class.create();
LowPro.SelectorLite.prototype = { LowPro.SelectorLite.prototype = {
initialize: function(selectors) { initialize: function(selectors) {
this.results = []; this.results = [];
this.selectors = []; this.selectors = [];
this.index = 0; this.index = 0;
for(var i = selectors.length -1; i >= 0; i--) { for(var i = selectors.length -1; i >= 0; i--) {
var params = { tag: '*', id: null, classes: [] }; var params = { tag: '*', id: null, classes: [] };
var selector = selectors[i]; var selector = selectors[i];
var needle = selector.length - 1; var needle = selector.length - 1;
do { do {
var id = selector.lastIndexOf("#"); var id = selector.lastIndexOf("#");
var klass = selector.lastIndexOf("."); var klass = selector.lastIndexOf(".");
var cursor = Math.max(id, klass); var cursor = Math.max(id, klass);
if(cursor == -1) params.tag = selector.toUpperCase(); if(cursor == -1) params.tag = selector.toUpperCase();
else if(id == -1 || klass == cursor) params.classes.push(selector.substring(klass + 1)) else if(id == -1 || klass == cursor) params.classes.push(selector.substring(klass + 1))
else if(!params.id) params.id = selector.substring(id + 1); else if(!params.id) params.id = selector.substring(id + 1);
selector = selector.substring(0, cursor); selector = selector.substring(0, cursor);
} while(cursor > 0); } while(cursor > 0);
this.selectors[i] = params; this.selectors[i] = params;
} }
}, },
get: function(root) { get: function(root) {
this.findElements(root || document, this.index == (this.selectors.length - 1)); this.findElements(root || document, this.index == (this.selectors.length - 1));
return this.results; return this.results;
}, },
findElements: function(parent, descendant) { findElements: function(parent, descendant) {
var selector = this.selectors[this.index], results = [], element; var selector = this.selectors[this.index], results = [], element;
if(selector.id) { if(selector.id) {
element = $(selector.id); element = $(selector.id);
if(element && (selector.tag == '*' || element.tagName == selector.tag) && if(element && (selector.tag == '*' || element.tagName == selector.tag) &&
(element.childOf(parent))) { (element.childOf(parent))) {
results = [element]; results = [element];
} }
} else { } else {
results = $A(parent.getElementsByTagName(selector.tag)); results = $A(parent.getElementsByTagName(selector.tag));
} }
if(selector.classes.length == 1) { if(selector.classes.length == 1) {
results = results.select(function(target) { results = results.select(function(target) {
return $(target).hasClassName(selector.classes[0]); return $(target).hasClassName(selector.classes[0]);
}); });
} else if(selector.classes.length > 1) { } else if(selector.classes.length > 1) {
results = results.select(function(target) { results = results.select(function(target) {
var klasses = $(target).classNames(); var klasses = $(target).classNames();
return selector.classes.all(function(klass) { return selector.classes.all(function(klass) {
return klasses.include(klass); return klasses.include(klass);
}); });
}); });
} }
if(descendant) { if(descendant) {
this.results = this.results.concat(results); this.results = this.results.concat(results);
} else { } else {
++this.index; ++this.index;
results.each(function(target) { results.each(function(target) {
this.findElements(target, this.index == (this.selectors.length - 1)); this.findElements(target, this.index == (this.selectors.length - 1));
}.bind(this)); }.bind(this));
} }
} }
} }
LowPro.$$old=$$; LowPro.$$old=$$;
LowPro.optimize$$ = true; LowPro.optimize$$ = true;
function $$(a,b) { function $$(a,b) {
if (LowPro.optimize$$ == false || b || a.indexOf("[")>=0) if (LowPro.optimize$$ == false || b || a.indexOf("[")>=0)
return LowPro.$$old.apply(this, arguments); return LowPro.$$old.apply(this, arguments);
return new LowPro.SelectorLite(a.split(/\s+/)).get(); return new LowPro.SelectorLite(a.split(/\s+/)).get();
} }