diff --git a/src/traversing.js b/src/traversing.js index 1f38d68cd..0d76038ca 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -12,39 +12,46 @@ var runtil = /Until$/, jQuery.fn.extend({ find: function( selector ) { - var i, l, length, n, r, ret, - self = this; + var prevLength, n, r, ret, + i = 0, + self = this, + selfLength = this.length; if ( typeof selector !== "string" ) { - return jQuery( selector ).filter(function() { - for ( i = 0, l = self.length; i < l; i++ ) { + + ret = jQuery( selector ).filter(function() { + for ( ; i < selfLength; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } }); - } - ret = this.pushStack( [] ); + } else { - for ( i = 0, l = this.length; i < l; i++ ) { - length = ret.length; - jQuery.find( selector, this[i], ret ); + ret = []; + for ( ; i < selfLength; i++ ) { + prevLength = ret.length; + jQuery.find( selector, this[ i ], ret ); - if ( i > 0 ) { - // Make sure that the results are unique - for ( n = length; n < ret.length; n++ ) { - for ( r = 0; r < length; r++ ) { - if ( ret[r] === ret[n] ) { - ret.splice(n--, 1); + if ( i > 0 ) { + // Make sure that the results are unique + // by comparing the newly added elements on the ith + // iteration to the elements added by the previous iterations + for ( n = prevLength; n < ret.length; n++ ) { + for ( r = 0; r < prevLength; r++ ) { + if ( ret[ r ] === ret[ n ] ) { + ret.splice( n--, 1 ); break; + } } } } } } - // Needed because $( "selector", context ) becomes $( context ).find( "selector" ) + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( ret ); ret.selector = ( this.selector ? this.selector + " " : "" ) + selector; return ret; }, diff --git a/test/unit/traversing.js b/test/unit/traversing.js index 0facd2e6e..f374f53c2 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -1,20 +1,21 @@ module("traversing", { teardown: moduleTeardown }); -test("find(String)", function() { - expect(5); +test( "find(String)", function() { + expect( 6 ); equal( "Yahoo", jQuery("#foo").find(".blogTest").text(), "Check for find" ); // using contents will get comments regular, text, and comment nodes var j = jQuery("#nonnodes").contents(); equal( j.find("div").length, 0, "Check node,textnode,comment to find zero divs" ); + equal( j.find("div").andSelf().length, 3, "Check node,textnode,comment to find zero divs, but preserves pushStack" ); - deepEqual( jQuery("#qunit-fixture").find("> div").get(), q("foo", "moretests", "tabindex-tests", "liveHandlerOrder", "siblingTest", "fx-test-group"), "find child elements" ); - deepEqual( jQuery("#qunit-fixture").find("> #foo, > #moretests").get(), q("foo", "moretests"), "find child elements" ); - deepEqual( jQuery("#qunit-fixture").find("> #foo > p").get(), q("sndp", "en", "sap"), "find child elements" ); + deepEqual( jQuery("#qunit-fixture").find("> div").get(), q( "foo", "moretests", "tabindex-tests", "liveHandlerOrder", "siblingTest", "fx-test-group" ), "find child elements" ); + deepEqual( jQuery("#qunit-fixture").find("> #foo, > #moretests").get(), q( "foo", "moretests" ), "find child elements" ); + deepEqual( jQuery("#qunit-fixture").find("> #foo > p").get(), q( "sndp", "en", "sap" ), "find child elements" ); }); -test("find(node|jQuery object)", function() { - expect( 11 ); +test( "find(node|jQuery object)", function() { + expect( 12 ); var $foo = jQuery("#foo"), $blog = jQuery(".blogTest"), @@ -23,18 +24,19 @@ test("find(node|jQuery object)", function() { $fooTwo = $foo.add( $blog ); equal( $foo.find( $blog ).text(), "Yahoo", "Find with blog jQuery object" ); - equal( $foo.find( $blog[0] ).text(), "Yahoo", "Find with blog node" ); + equal( $foo.find( $blog[ 0 ] ).text(), "Yahoo", "Find with blog node" ); equal( $foo.find( $first ).length, 0, "#first is not in #foo" ); - equal( $foo.find( $first[0]).length, 0, "#first not in #foo (node)" ); + equal( $foo.find( $first[ 0 ]).length, 0, "#first not in #foo (node)" ); ok( $foo.find( $two ).is(".blogTest"), "Find returns only nodes within #foo" ); ok( $fooTwo.find( $blog ).is(".blogTest"), "Blog is part of the collection, but also within foo" ); - ok( $fooTwo.find( $blog[0] ).is(".blogTest"), "Blog is part of the collection, but also within foo(node)" ); + ok( $fooTwo.find( $blog[ 0 ] ).is(".blogTest"), "Blog is part of the collection, but also within foo(node)" ); equal( $two.find( $foo ).length, 0, "Foo is not in two elements" ); - equal( $two.find( $foo[0] ).length, 0, "Foo is not in two elements(node)" ); + equal( $two.find( $foo[ 0 ] ).length, 0, "Foo is not in two elements(node)" ); equal( $two.find( $first ).length, 0, "first is in the collection and not within two" ); equal( $two.find( $first ).length, 0, "first is in the collection and not within two(node)" ); + equal( $two.find( $foo[ 0 ] ).andSelf().length, 2, "find preserves the pushStack, see #12009" ); }); test("is(String|undefined)", function() {