added missing semicolons
[jquery.git] / src / traversing.js
index d788847..b5a5a2d 100644 (file)
@@ -1,3 +1,27 @@
+var winnow = function( elements, qualifier, keep ) {
+       if(jQuery.isFunction( qualifier )) {
+               return jQuery.grep(elements, function(elem, i) {
+                       return !!qualifier.call( elem, i ) === keep;
+               });
+       } else if( qualifier.nodeType ) {
+               return jQuery.grep(elements, function(elem, i) {
+                       return (elem === qualifier) === keep;
+               });
+       } else if( typeof qualifier === "string" ) {
+               var filtered = jQuery.grep(elements, function(elem) { return elem.nodeType === 1; });
+
+               if(isSimple.test( qualifier )) {
+                       return jQuery.filter(qualifier, filtered, !keep);
+               } else {
+                       qualifier = jQuery.filter( qualifier, elements );
+               }
+       }
+
+       return jQuery.grep(elements, function(elem, i) {
+               return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+       });
+};
+
 jQuery.fn.extend({
        find: function( selector ) {
                var ret = this.pushStack( "", "find", selector ), length = 0;
@@ -22,60 +46,56 @@ jQuery.fn.extend({
                return ret;
        },
 
+       not: function( selector ) {
+               return this.pushStack( winnow(this, selector, false), "not", selector);
+       },
+
        filter: function( selector ) {
-               return this.pushStack(
-                       jQuery.isFunction( selector ) &&
-                       jQuery.grep(this, function(elem, i){
-                               return selector.call( elem, i );
-                       }) ||
-
-                       jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
-                               return elem.nodeType === 1;
-                       }) ), "filter", selector );
+               return this.pushStack( winnow(this, selector, true), "filter", selector );
        },
 
-       closest: function( selector ) {
-               var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
-                       closer = 0;
+       closest: function( selector, context ) {
+               var pos = jQuery.expr.match.POS.test( selector ) ? 
+                       jQuery( selector, context || this.context ) : null;
 
                return this.map(function(){
-                       var cur = this;
-                       while ( cur && cur.ownerDocument ) {
+                       var cur = this, closer = 0;
+                       while ( cur && cur.ownerDocument && cur !== context ) {
                                if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
-                                       jQuery.data(cur, "closest", closer);
+                                       jQuery.lastCloser = closer;
                                        return cur;
                                }
                                cur = cur.parentNode;
                                closer++;
                        }
+                       jQuery.lastCloser = -1;
+                       return null;
                });
        },
 
-       not: function( selector ) {
-               if ( typeof selector === "string" )
-                       // test special case where just one selector is passed in
-                       if ( isSimple.test( selector ) )
-                               return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
-                       else
-                               selector = jQuery.multiFilter( selector, this );
-
-               var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
-               return this.filter(function() {
-                       return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
-               });
-       },
+       add: function( selector, context ) {
+               var set = typeof selector === "string" ?
+                               jQuery( selector, context || this.context ) :
+                               jQuery.makeArray( selector ),
+                       all = jQuery.merge( this.get(), set );
 
-       add: function( selector ) {
-               return this.pushStack( jQuery.unique( jQuery.merge(
-                       this.get(),
-                       typeof selector === "string" ?
-                               jQuery( selector ) :
-                               jQuery.makeArray( selector )
-               )));
+               return this.pushStack( set[0] && (set[0].setInterval || set[0].nodeType === 9 || (set[0].parentNode && set[0].parentNode.nodeType !== 11)) ?
+                       jQuery.unique( all ) :
+                       all );
        },
 
        eq: function( i ) {
-               return this.slice( i, +i + 1 );
+               return i === -1 ?
+                       this.slice( i ) :
+                       this.slice( i, +i + 1 );
+       },
+
+       first: function() {
+               return this.eq( 0 );
+       },
+
+       last: function() {
+               return this.eq( -1 );
        },
 
        slice: function() {
@@ -112,9 +132,62 @@ jQuery.each({
        jQuery.fn[ name ] = function( selector ) {
                var ret = jQuery.map( this, fn );
 
-               if ( selector && typeof selector == "string" )
-                       ret = jQuery.multiFilter( selector, ret );
+               if ( selector && typeof selector === "string" ) {
+                       ret = jQuery.filter( selector, ret );
+               }
+
+               ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+               if ( name === "parents" && this.length > 1 ) {
+                       ret = ret.reverse();
+               }
 
-               return this.pushStack( jQuery.unique( ret ), name, selector );
+               return this.pushStack( ret, name, selector );
        };
-});
\ No newline at end of file
+});
+
+jQuery.extend({
+       filter: function( expr, elems, not ) {
+               if ( not ) {
+                       expr = ":not(" + expr + ")";
+               }
+
+               return jQuery.find.matches(expr, elems);
+       },
+       
+       dir: function( elem, dir ) {
+               var matched = [], cur = elem[dir];
+               while ( cur && cur.nodeType !== 9 ) {
+                       if ( cur.nodeType === 1 ) {
+                               matched.push( cur );
+                       }
+                       cur = cur[dir];
+               }
+               return matched;
+       },
+
+       nth: function( cur, result, dir, elem ) {
+               result = result || 1;
+               var num = 0;
+
+               for ( ; cur; cur = cur[dir] ) {
+                       if ( cur.nodeType === 1 && ++num === result ) {
+                               break;
+                       }
+               }
+
+               return cur;
+       },
+
+       sibling: function( n, elem ) {
+               var r = [];
+
+               for ( ; n; n = n.nextSibling ) {
+                       if ( n.nodeType === 1 && n !== elem ) {
+                               r.push( n );
+                       }
+               }
+
+               return r;
+       }
+});