]> source.dussan.org Git - jquery.git/commitdiff
Traversing: Never let .closest() match positional selectors
authorRichard Gibson <richard.gibson@gmail.com>
Tue, 12 Jan 2016 05:56:29 +0000 (00:56 -0500)
committerTimmy Willison <timmywillisn@gmail.com>
Wed, 13 Jan 2016 18:37:11 +0000 (13:37 -0500)
Fixes gh-2796
Close gh-2818

src/traversing.js
test/unit/traversing.js

index 0d4c1c4c36cb47f1988f5812b7bb740c73974148..8525c0a5dff6e192c0ed9e8fa95ef741d5fc46b1 100644 (file)
@@ -39,23 +39,24 @@ jQuery.fn.extend( {
                        i = 0,
                        l = this.length,
                        matched = [],
-                       pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
-                               jQuery( selectors, context || this.context ) :
-                               0;
+                       targets = typeof selectors !== "string" && jQuery( selectors );
 
-               for ( ; i < l; i++ ) {
-                       for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
+               // Positional selectors never match, since there's no _selection_ context
+               if ( !rneedsContext.test( selectors ) ) {
+                       for ( ; i < l; i++ ) {
+                               for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
 
-                               // Always skip document fragments
-                               if ( cur.nodeType < 11 && ( pos ?
-                                       pos.index( cur ) > -1 :
+                                       // Always skip document fragments
+                                       if ( cur.nodeType < 11 && ( targets ?
+                                               targets.index( cur ) > -1 :
 
-                                       // Don't pass non-elements to Sizzle
-                                       cur.nodeType === 1 &&
-                                               jQuery.find.matchesSelector( cur, selectors ) ) ) {
+                                               // Don't pass non-elements to Sizzle
+                                               cur.nodeType === 1 &&
+                                                       jQuery.find.matchesSelector( cur, selectors ) ) ) {
 
-                                       matched.push( cur );
-                                       break;
+                                               matched.push( cur );
+                                               break;
+                                       }
                                }
                        }
                }
index d38d40be5f73406073ddc4ac26c8112c539aa9e3..3e0c3765b71a356c72313eb440747f0533735837 100644 (file)
@@ -323,7 +323,7 @@ QUnit[ jQuery.find.compile ? "test" : "skip" ]( "filter() with positional select
 } );
 
 QUnit.test( "closest()", function( assert ) {
-       assert.expect( 13 );
+       assert.expect( 14 );
 
        var jq;
 
@@ -344,6 +344,12 @@ QUnit.test( "closest()", function( assert ) {
        // Test on disconnected node
        assert.equal( jQuery( "<div><p></p></div>" ).find( "p" ).closest( "table" ).length, 0, "Make sure disconnected closest work." );
 
+       assert.deepEqual(
+               jQuery( "#firstp" ).closest( q( "qunit-fixture" ) ).get(),
+               q( "qunit-fixture" ),
+               "Non-string match target"
+       );
+
        // Bug #7369
        assert.equal( jQuery( "<div foo='bar'></div>" ).closest( "[foo]" ).length, 1, "Disconnected nodes with attribute selector" );
        assert.equal( jQuery( "<div>text</div>" ).closest( "[lang]" ).length, 0, "Disconnected nodes with text and non-existent attribute selector" );
@@ -355,10 +361,17 @@ QUnit.test( "closest()", function( assert ) {
 } );
 
 QUnit[ jQuery.find.compile ? "test" : "skip" ]( "closest() with positional selectors", function( assert ) {
-       assert.expect( 2 );
+       assert.expect( 3 );
 
-       assert.deepEqual( jQuery( "#qunit-fixture" ).closest( "div:first" ).get(), [], "closest(div:first)" );
-       assert.deepEqual( jQuery( "#qunit-fixture div" ).closest( "body:first div:last" ).get(), q( "fx-tests" ), "closest(body:first div:last)" );
+       assert.deepEqual( jQuery( "#qunit-fixture" ).closest( "div:first" ).get(), [],
+               "closest(div:first)" );
+       assert.deepEqual( jQuery( "#qunit-fixture div" ).closest( "body:first div:last" ).get(), [],
+               "closest(body:first div:last)" );
+       assert.deepEqual(
+               jQuery( "#qunit-fixture div" ).closest( "body:first div:last", document ).get(),
+               [],
+               "closest(body:first div:last, document)"
+       );
 } );
 
 QUnit.test( "closest(jQuery)", function( assert ) {