From 8246347b7191e79ed09bf1fc4c4a0a58211cf345 Mon Sep 17 00:00:00 2001 From: timmywil Date: Sun, 13 Mar 2011 21:12:10 -0400 Subject: [PATCH 1/8] Starting with adding the test --- test/unit/traversing.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/unit/traversing.js b/test/unit/traversing.js index f5108bde..9216bb5e 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -13,6 +13,15 @@ test("find(String)", function() { same( jQuery("#main").find("> #foo > p").get(), q("sndp", "en", "sap"), "find child elements" ); }); +test("find(node|jQuery object)", function() { + expect( 2 ); + + var $blog = jQuery('.blogTest'), + blog = $blog[0]; + equals( jQuery('#foo').find( $blog ).text(), 'Yahoo', 'Find with blog jQuery object' ); + equals( jQuery('#foo').find( blog ).text(), 'Yahoo', 'Find with blog node' ); +}); + test("is(String)", function() { expect(26); ok( jQuery('#form').is('form'), 'Check for element: A form must be a form' ); From 7a69e34a5cd4df37762cbee9c9468c96c0ac3017 Mon Sep 17 00:00:00 2001 From: timmywil Date: Wed, 16 Mar 2011 01:16:32 -0400 Subject: [PATCH 2/8] 2773: first pass adding node/jQuery object support to jQuery.fn.find; unit tests added --- src/core.js | 2 +- src/traversing.js | 23 ++++++++++++++++++----- test/unit/traversing.js | 25 ++++++++++++++++++++----- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/core.js b/src/core.js index 9312ee28..812ecde5 100644 --- a/src/core.js +++ b/src/core.js @@ -88,7 +88,7 @@ jQuery.fn = jQuery.prototype = { if ( selector === "body" && !context && document.body ) { this.context = document; this[0] = document.body; - this.selector = "body"; + this.selector = selector; this.length = 1; return this; } diff --git a/src/traversing.js b/src/traversing.js index fe2e33d8..fa6aae2f 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -17,17 +17,30 @@ var runtil = /Until$/, jQuery.fn.extend({ find: function( selector ) { - var ret = this.pushStack( "", "find", selector ), - length = 0; + var self = this, + ret, i, l; - for ( var i = 0, l = this.length; i < l; i++ ) { + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + ret = this.pushStack( "", "find", selector ); + + var length, n, r; + for ( i = 0, l = this.length; i < l; i++ ) { length = ret.length; jQuery.find( selector, this[i], ret ); if ( i > 0 ) { // Make sure that the results are unique - for ( var n = length; n < ret.length; n++ ) { - for ( var r = 0; r < length; r++ ) { + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { if ( ret[r] === ret[n] ) { ret.splice(n--, 1); break; diff --git a/test/unit/traversing.js b/test/unit/traversing.js index 9216bb5e..76b93d84 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -14,12 +14,27 @@ test("find(String)", function() { }); test("find(node|jQuery object)", function() { - expect( 2 ); + expect( 11 ); + + var $foo = jQuery('#foo'), + $blog = jQuery('.blogTest'), + $first = jQuery('#first'), + $two = $blog.add( $first ), + $fooTwo = $foo.add( $blog ); + + equals( $foo.find( $blog ).text(), 'Yahoo', 'Find with blog jQuery object' ); + equals( $foo.find( $blog[0] ).text(), 'Yahoo', 'Find with blog node' ); + equals( $foo.find( $first ).length, 0, '#first is not in #foo' ); + equals( $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)' ); + + equals( $two.find( $foo ).length, 0, 'Foo is not in two elements' ); + equals( $two.find( $foo[0] ).length, 0, 'Foo is not in two elements(node)' ); + equals( $two.find( $first ).length, 0, 'first is in the collection and not within two' ); + equals( $two.find( $first ).length, 0, 'first is in the collection and not within two(node)' ); - var $blog = jQuery('.blogTest'), - blog = $blog[0]; - equals( jQuery('#foo').find( $blog ).text(), 'Yahoo', 'Find with blog jQuery object' ); - equals( jQuery('#foo').find( blog ).text(), 'Yahoo', 'Find with blog node' ); }); test("is(String)", function() { From 929792834f77e075e4b5397fb4b25b1a2dcbd49a Mon Sep 17 00:00:00 2001 From: timmywil Date: Wed, 16 Mar 2011 14:41:26 -0400 Subject: [PATCH 3/8] Organizing vars --- src/traversing.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/traversing.js b/src/traversing.js index fa6aae2f..30d60435 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -18,7 +18,7 @@ var runtil = /Until$/, jQuery.fn.extend({ find: function( selector ) { var self = this, - ret, i, l; + i, l; if ( typeof selector !== "string" ) { return jQuery( selector ).filter(function() { @@ -30,9 +30,8 @@ jQuery.fn.extend({ }); } - ret = this.pushStack( "", "find", selector ); - - var length, n, r; + var ret = this.pushStack( "", "find", selector ), + length, n, r; for ( i = 0, l = this.length; i < l; i++ ) { length = ret.length; jQuery.find( selector, this[i], ret ); From e09d8898d8a8df27bb72ebc64a4cd08c11f21ddd Mon Sep 17 00:00:00 2001 From: timmywil Date: Mon, 21 Mar 2011 20:59:20 -0400 Subject: [PATCH 4/8] Add node and jQuery object support to $.fn.closest --- src/traversing.js | 20 ++++++++++++-------- test/unit/traversing.js | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/traversing.js b/src/traversing.js index 30d60435..49197c1f 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -32,6 +32,7 @@ jQuery.fn.extend({ var ret = this.pushStack( "", "find", selector ), length, n, r; + for ( i = 0, l = this.length; i < l; i++ ) { length = ret.length; jQuery.find( selector, this[i], ret ); @@ -77,7 +78,8 @@ jQuery.fn.extend({ closest: function( selectors, context ) { var ret = [], i, l, cur = this[0]; - + + // Array if ( jQuery.isArray( selectors ) ) { var match, selector, matches = {}, @@ -87,8 +89,8 @@ jQuery.fn.extend({ for ( i = 0, l = selectors.length; i < l; i++ ) { selector = selectors[i]; - if ( !matches[selector] ) { - matches[selector] = jQuery.expr.match.POS.test( selector ) ? + if ( !matches[ selector ] ) { + matches[ selector ] = POS.test( selector ) ? jQuery( selector, context || this.context ) : selector; } @@ -96,9 +98,9 @@ jQuery.fn.extend({ while ( cur && cur.ownerDocument && cur !== context ) { for ( selector in matches ) { - match = matches[selector]; + match = matches[ selector ]; - if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { + if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) { ret.push({ selector: selector, elem: cur, level: level }); } } @@ -110,9 +112,11 @@ jQuery.fn.extend({ return ret; } - - var pos = POS.test( selectors ) ? - jQuery( selectors, context || this.context ) : null; + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; for ( i = 0, l = this.length; i < l; i++ ) { cur = this[i]; diff --git a/test/unit/traversing.js b/test/unit/traversing.js index 76b93d84..bd05f470 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -182,6 +182,20 @@ test("closest(Array)", function() { same( jQuery("body").closest(["span","html"]), [{selector:"html", elem:document.documentElement, level:2}], "closest([body, html])" ); }); +test("closest(jQuery)", function() { + expect(7); + var $child = jQuery("#nothiddendivchild"), + $parent = jQuery("#nothiddendiv"), + $main = jQuery("#main"); + ok( $child.closest( $parent ).is('#nothiddendiv'), "closest( jQuery('#nothiddendiv') )" ); + ok( $child.closest( $parent[0] ).is('#nothiddendiv'), "closest( jQuery('#nothiddendiv') ) :: node" ); + ok( $child.closest( $child ).is('#nothiddendivchild'), "child is included" ); + ok( $child.closest( $child[0] ).is('#nothiddendivchild'), "child is included :: node" ); + equals( $child.closest( document.createElement('div') ).length, 0, "created element is not related" ); + equals( $child.closest( $main ).length, 0, "Main not a parent of child" ); + equals( $child.closest( $main[0] ).length, 0, "Main not a parent of child :: node" ); +}); + test("not(Selector)", function() { expect(7); equals( jQuery("#main > p#ap > a").not("#google").length, 2, "not('selector')" ); From b8013581ced78fb6c2005e76b44211e01fc2e466 Mon Sep 17 00:00:00 2001 From: timmywil Date: Wed, 23 Mar 2011 15:56:05 -0400 Subject: [PATCH 5/8] Closest unit tests: add one for passing a jQuery collection with multiple elements --- test/unit/traversing.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/unit/traversing.js b/test/unit/traversing.js index bd05f470..adca5f40 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -183,10 +183,11 @@ test("closest(Array)", function() { }); test("closest(jQuery)", function() { - expect(7); + expect(8); var $child = jQuery("#nothiddendivchild"), $parent = jQuery("#nothiddendiv"), - $main = jQuery("#main"); + $main = jQuery("#main"), + $body = jQuery("body"); ok( $child.closest( $parent ).is('#nothiddendiv'), "closest( jQuery('#nothiddendiv') )" ); ok( $child.closest( $parent[0] ).is('#nothiddendiv'), "closest( jQuery('#nothiddendiv') ) :: node" ); ok( $child.closest( $child ).is('#nothiddendivchild'), "child is included" ); @@ -194,6 +195,7 @@ test("closest(jQuery)", function() { equals( $child.closest( document.createElement('div') ).length, 0, "created element is not related" ); equals( $child.closest( $main ).length, 0, "Main not a parent of child" ); equals( $child.closest( $main[0] ).length, 0, "Main not a parent of child :: node" ); + ok( $child.closest( $body.add($parent) ).is('#nothiddendiv'), "Closest ancestor retrieved." ); }); test("not(Selector)", function() { From e6da0fa6a96c9b4314303e251fd6efac98813ab8 Mon Sep 17 00:00:00 2001 From: timmywil Date: Fri, 25 Mar 2011 23:46:29 -0400 Subject: [PATCH 6/8] Bug #7369: Add test for disconnected node in closest when passing attribute selector; this was recently fixed in 1.5.2rc --- test/unit/traversing.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/unit/traversing.js b/test/unit/traversing.js index adca5f40..f5cd8aac 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -148,7 +148,7 @@ test("filter(jQuery)", function() { }) test("closest()", function() { - expect(11); + expect(12); same( jQuery("body").closest("body").get(), q("body"), "closest(body)" ); same( jQuery("body").closest("html").get(), q("html"), "closest(html)" ); same( jQuery("body").closest("div").get(), [], "closest(div)" ); @@ -168,6 +168,8 @@ test("closest()", function() { // Test on disconnected node equals( jQuery("

").find("p").closest("table").length, 0, "Make sure disconnected closest work." ); + // Bug #7369 + equals( jQuery('
').closest('[foo]').length, 1, "Disconnected nodes with attribute selector" ); }); test("closest(Array)", function() { From e93ca40aa7ec4337a57fcdbc699d900e01b4c67e Mon Sep 17 00:00:00 2001 From: timmywil Date: Fri, 25 Mar 2011 23:52:36 -0400 Subject: [PATCH 7/8] Bug #7369: Check non-existent attribute as well to be sure --- test/unit/traversing.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/unit/traversing.js b/test/unit/traversing.js index f5cd8aac..43a9f22a 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -148,7 +148,7 @@ test("filter(jQuery)", function() { }) test("closest()", function() { - expect(12); + expect(13); same( jQuery("body").closest("body").get(), q("body"), "closest(body)" ); same( jQuery("body").closest("html").get(), q("html"), "closest(html)" ); same( jQuery("body").closest("div").get(), [], "closest(div)" ); @@ -170,6 +170,7 @@ test("closest()", function() { equals( jQuery("

").find("p").closest("table").length, 0, "Make sure disconnected closest work." ); // Bug #7369 equals( jQuery('
').closest('[foo]').length, 1, "Disconnected nodes with attribute selector" ); + equals( jQuery('
').closest('[lang]').length, 0, "Disconnected nodes with non-existent attribute selector" ); }); test("closest(Array)", function() { From 1a167767305202797cf4c839eb64bd7adfb00182 Mon Sep 17 00:00:00 2001 From: timmywil Date: Wed, 30 Mar 2011 23:23:38 -0400 Subject: [PATCH 8/8] Remove test for bug #7369 to move the fix to a separate branch for a sooner pull --- src/traversing.js | 4 ++-- test/unit/traversing.js | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/traversing.js b/src/traversing.js index 49197c1f..91bc017e 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -112,7 +112,7 @@ jQuery.fn.extend({ return ret; } - + // String var pos = POS.test( selectors ) || typeof selectors !== "string" ? jQuery( selectors, context || this.context ) : @@ -135,7 +135,7 @@ jQuery.fn.extend({ } } - ret = ret.length > 1 ? jQuery.unique(ret) : ret; + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; return this.pushStack( ret, "closest", selectors ); }, diff --git a/test/unit/traversing.js b/test/unit/traversing.js index 43a9f22a..117e4600 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -168,9 +168,6 @@ test("closest()", function() { // Test on disconnected node equals( jQuery("

").find("p").closest("table").length, 0, "Make sure disconnected closest work." ); - // Bug #7369 - equals( jQuery('
').closest('[foo]').length, 1, "Disconnected nodes with attribute selector" ); - equals( jQuery('
').closest('[lang]').length, 0, "Disconnected nodes with non-existent attribute selector" ); }); test("closest(Array)", function() {