From ec2b688920cf38f5bb2487b8a1897f7eb7557248 Mon Sep 17 00:00:00 2001 From: John Resig Date: Sat, 24 Mar 2007 21:55:03 +0000 Subject: [PATCH] Merged my speed improvements into the jQuery core (is actually 200b smaller now!). Additionally, added in some better reporting to the test suite, and fixed a bug with how selector tests were performmed. --- build/test/data/testrunner.js | 22 +++++++++++++++--- src/jquery/jquery.js | 39 +++++++++++++++----------------- src/selector/selector.js | 42 +++++++---------------------------- 3 files changed, 45 insertions(+), 58 deletions(-) diff --git a/build/test/data/testrunner.js b/build/test/data/testrunner.js index 78395aad..72238e31 100644 --- a/build/test/data/testrunner.js +++ b/build/test/data/testrunner.js @@ -172,17 +172,33 @@ function ok(a, msg) { function isSet(a, b, msg) { var ret = true; if ( a && b && a.length == b.length ) { - for ( var i in a ) + for ( var i = 0; i < a.length; i++ ) if ( a[i] != b[i] ) ret = false; } else ret = false; if ( !ret ) - _config.Test.push( [ ret, msg + " expected: " + b + " result: " + a ] ); + _config.Test.push( [ ret, msg + " expected: " + serialArray(b) + " result: " + serialArray(a) ] ); else _config.Test.push( [ ret, msg ] ); } +function serialArray( a ) { + var r = []; + for ( var i = 0; i < a.length; i++ ) { + var str = a[i].nodeName; + if ( str ) { + str = str.toLowerCase(); + if ( a[i].id ) + str += "#" + a[i].id; + } else + str = a[i]; + r.push( str ); + } + + return "[ " + r.join(", ") + " ]" +} + /** * Returns an array of elements with the given IDs, eg. * @example q("main", "foo", "bar") @@ -201,7 +217,7 @@ function q() { * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baar' */ function t(a,b,c) { - var f = jQuery.find(b); + var f = jQuery(b); var s = ""; for ( var i = 0; i < f.length; i++ ) s += (s && ",") + '"' + f[i].id + '"'; diff --git a/src/jquery/jquery.js b/src/jquery/jquery.js index 489522f6..a8872dfb 100644 --- a/src/jquery/jquery.js +++ b/src/jquery/jquery.js @@ -817,9 +817,9 @@ jQuery.fn = jQuery.prototype = { * @cat DOM/Traversing */ find: function(t) { - return this.pushStack( jQuery.map( this, function(a){ + return this.pushStack( jQuery.unique( jQuery.map( this, function(a){ return jQuery.find(t,a); - }), t ); + }) ), t ); }, /** @@ -1629,19 +1629,26 @@ jQuery.extend({ * @cat JavaScript */ merge: function(first, second) { - var r = [].slice.call( first, 0 ); - - // Now check for duplicates between the two arrays - // and only add the unique items for ( var i = 0, sl = second.length; i < sl; i++ ) - // Check for duplicates - if ( jQuery.inArray( second[i], r ) == -1 ) - // The item is unique, add it - first.push( second[i] ); + first.push(second[i]); return first; }, + unique: function(first) { + var r = [], num = jQuery.mergeNum++; + + for ( var i = 0, fl = first.length; i < fl; i++ ) + if ( first[i].mergeNum != num ) { + first[i].mergeNum = num; + r.push(first[i]); + } + + return r; + }, + + mergeNum: 0, + /** * Filter items out of an array, by using a filter function. * @@ -1735,17 +1742,7 @@ jQuery.extend({ } } - var r = result.length ? [ result[0] ] : []; - - check: for ( var i = 1, rl = result.length; i < rl; i++ ) { - for ( var j = 0; j < i; j++ ) - if ( result[i] == r[j] ) - continue check; - - r.push( result[i] ); - } - - return r; + return result; } }); diff --git a/src/selector/selector.js b/src/selector/selector.js index 856e0f59..3bd6b343 100644 --- a/src/selector/selector.js +++ b/src/selector/selector.js @@ -195,7 +195,7 @@ jQuery.extend({ if ( ret[0] == context ) ret.shift(); // Merge the result sets - jQuery.merge( done, ret ); + done = jQuery.merge( done, ret ); // Reset the context r = ret = [context]; @@ -243,29 +243,25 @@ jQuery.extend({ // We need to find all descendant elements, it is more // efficient to use getAll() when we are already further down // the tree - we try to recognize that here - jQuery.each( ret, function(){ + for ( var i = 0, rl = ret.length; i < rl; i++ ) { // Grab the tag name being searched for var tag = m[1] != "" || m[0] == "" ? "*" : m[2]; // Handle IE7 being really dumb about s - if ( jQuery.nodeName(this, "object") && tag == "*" ) + if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" ) tag = "param"; - jQuery.merge( r, - m[1] != "" && ret.length != 1 ? - jQuery.getAll( this, [], m[1], m[2], rec ) : - this.getElementsByTagName( tag ) - ); - }); + r = jQuery.merge( r, ret[i].getElementsByTagName( tag )); + } // It's faster to filter by class and be done with it - if ( m[1] == "." && ret.length == 1 ) + if ( m[1] == "." ) r = jQuery.grep( r, function(e) { return rec.test(e.className); }); // Same with ID filtering - if ( m[1] == "#" && ret.length == 1 ) { + if ( m[1] == "#" ) { // Remember, then wipe out, the result set var tmp = r; r = []; @@ -300,7 +296,7 @@ jQuery.extend({ if ( ret && ret[0] == context ) ret.shift(); // And combine the results - jQuery.merge( done, ret ); + done = jQuery.merge( done, ret ); return done; }, @@ -363,28 +359,6 @@ jQuery.extend({ // and the modified expression string (t) return { r: r, t: t }; }, - - getAll: function( o, r, token, name, re ) { - for ( var s = o.firstChild; s; s = s.nextSibling ) - if ( s.nodeType == 1 ) { - var add = true; - - if ( token == "." ) - add = s.className && re.test(s.className); - else if ( token == "#" ) - add = s.getAttribute("id") == name; - - if ( add ) - r.push( s ); - - if ( token == "#" && r.length ) break; - - if ( s.firstChild ) - jQuery.getAll( s, r, token, name, re ); - } - - return r; - }, /** * All ancestors of a given element.