Landed a number of improvements to the selector engine. Results are auto-merged onto...
authorJohn Resig <jeresig@gmail.com>
Wed, 7 Jan 2009 00:13:57 +0000 (00:13 +0000)
committerJohn Resig <jeresig@gmail.com>
Wed, 7 Jan 2009 00:13:57 +0000 (00:13 +0000)
object, class filtering is now done inline, and not filtering is more efficient.

src/core.js
src/selector.js

index e2f1f0b..c4c3867 100644 (file)
@@ -260,9 +260,14 @@ jQuery.fn = jQuery.prototype = {
                return this.prevObject || jQuery( [] );
        },
 
+       push: [].push,
+
        find: function( selector ) {
-               if ( this.length === 1 ) {
-                       return this.pushStack( jQuery.find( selector, this[0] ), "find", selector );
+               if ( this.length === 1 && !/,/.test(selector) ) {
+                       var ret = this.pushStack( [], "find", selector );
+                       ret.length = 0;
+                       jQuery.find( selector, this[0], ret );
+                       return ret;
                } else {
                        var elems = jQuery.map(this, function(elem){
                                return jQuery.find( selector, elem );
index 9cc75fc..8d11237 100644 (file)
@@ -21,7 +21,7 @@ var Sizzle = function(selector, context, results, seed) {
                return results;
        }
 
-       var parts = [], m, set, checkSet, check, mode, extra;
+       var parts = [], m, set, checkSet, check, mode, extra, prune = true;
        
        // Reset the position of the chunker regexp (start from head)
        chunker.lastIndex = 0;
@@ -73,6 +73,8 @@ var Sizzle = function(selector, context, results, seed) {
 
                if ( parts.length > 0 ) {
                        checkSet = makeArray(set);
+               } else {
+                       prune = false;
                }
 
                while ( parts.length ) {
@@ -101,7 +103,9 @@ var Sizzle = function(selector, context, results, seed) {
        }
 
        if ( checkSet instanceof Array ) {
-               if ( context.nodeType === 1 ) {
+               if ( !prune ) {
+                       results.push.apply( results, checkSet );
+               } else if ( context.nodeType === 1 ) {
                        for ( var i = 0; checkSet[i] != null; i++ ) {
                                if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
                                        results.push( set[i] );
@@ -160,7 +164,7 @@ Sizzle.find = function(expr, context){
        return {set: set, expr: expr};
 };
 
-Sizzle.filter = function(expr, set, inplace){
+Sizzle.filter = function(expr, set, inplace, not){
        var old = expr, result = [], curLoop = set, match, anyFound;
 
        while ( expr && set.length ) {
@@ -174,9 +178,11 @@ Sizzle.filter = function(expr, set, inplace){
                                }
 
                                if ( Expr.preFilter[ type ] ) {
-                                       match = Expr.preFilter[ type ]( match, curLoop );
+                                       match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not );
 
-                                       if ( match[0] === true ) {
+                                       if ( !match ) {
+                                               anyFound = found = true;
+                                       } else if ( match[0] === true ) {
                                                goodArray = [];
                                                var last = null, elem;
                                                for ( var i = 0; (elem = curLoop[i]) !== undefined; i++ ) {
@@ -188,21 +194,26 @@ Sizzle.filter = function(expr, set, inplace){
                                        }
                                }
 
-                               for ( var i = 0; (item = curLoop[i]) !== undefined; i++ ) {
-                                       if ( item ) {
-                                               if ( goodArray && item != goodArray[goodPos] ) {
-                                                       goodPos++;
-                                               }
-
-                                               found = filter( item, match, goodPos, goodArray );
-                                               if ( inplace && found != null ) {
-                                                       curLoop[i] = found ? curLoop[i] : false;
-                                                       if ( found ) {
+                               if ( match ) {
+                                       for ( var i = 0; (item = curLoop[i]) !== undefined; i++ ) {
+                                               if ( item ) {
+                                                       if ( goodArray && item != goodArray[goodPos] ) {
+                                                               goodPos++;
+                                                       }
+       
+                                                       found = filter( item, match, goodPos, goodArray );
+                                                       var pass = not ^ !!found;
+
+                                                       if ( inplace && found != null ) {
+                                                               if ( pass ) {
+                                                                       anyFound = true;
+                                                               } else {
+                                                                       curLoop[i] = false;
+                                                               }
+                                                       } else if ( pass ) {
+                                                               result.push( item );
                                                                anyFound = true;
                                                        }
-                                               } else if ( found ) {
-                                                       result.push( item );
-                                                       anyFound = true;
                                                }
                                        }
                                }
@@ -336,8 +347,19 @@ var Expr = Sizzle.selectors = {
                }
        },
        preFilter: {
-               CLASS: function(match){
-                       return new RegExp( "(?:^|\\s)" + match[1] + "(?:\\s|$)" );
+               CLASS: function(match, curLoop, inplace, result, not){
+                       match = " " + match[1].replace(/\\/g, "") + " ";
+
+                       for ( var i = 0; curLoop[i]; i++ ) {
+                               if ( not ^ (" " + curLoop[i].className + " ").indexOf(match) >= 0 ) {
+                                       if ( !inplace )
+                                               result.push( curLoop[i] );
+                               } else if ( inplace ) {
+                                       curLoop[i] = false;
+                               }
+                       }
+
+                       return false;
                },
                ID: function(match){
                        return match[1];
@@ -375,12 +397,18 @@ var Expr = Sizzle.selectors = {
 
                        return match;
                },
-               PSEUDO: function(match, curLoop){
+               PSEUDO: function(match, curLoop, inplace, result, not){
                        if ( match[1] === "not" ) {
                                // If we're dealing with a complex expression, or a simple one
-                               match[3] = match[3].match(chunker).length > 1 ?
-                                       Sizzle(match[3], null, null, curLoop) :
-                                       Sizzle.filter(match[3], curLoop);
+                               if ( match[3].match(chunker).length > 1 ) {
+                                       match[3] = Sizzle(match[3], null, null, curLoop);
+                               } else {
+                                       var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+                                       if ( !inplace ) {
+                                               result.push.apply( result, ret );
+                                       }
+                                       return false;
+                               }
                        }
                        
                        return match;