diff --git a/src/traversing.js b/src/traversing.js index 35a5174e9..fa9462216 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -73,9 +73,14 @@ jQuery.fn.extend({ }, is: function( selector ) { - return !!selector && ( typeof selector === "string" ? - jQuery.filter( selector, this ).length > 0 : - this.filter( selector ).length > 0 ); + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); }, closest: function( selectors, context ) { diff --git a/test/unit/traversing.js b/test/unit/traversing.js index 1c415c02e..a3050672b 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -101,6 +101,46 @@ test("is(jQuery)", function() { ok( !jQuery("#simon").is( jQuery(".blogTest")[0] ), "Check for multiple classes: Expected classes 'blog' and 'link', but not 'blogTest'" ); }); +test("is() with positional selectors", function() { + expect(23); + + var html = jQuery( + '

firsttest

' + ).appendTo( "body" ), + isit = function(sel, match, expect) { + equal( jQuery( sel ).is( match ), expect, "jQuery( " + sel + " ).is( " + match + " )" ); + }; + + isit( "#posp", "#posp:first", true ); + isit( "#posp", "#posp:eq(2)", false ); + isit( "#posp", "#posp a:first", false ); + + isit( "#posp .firsta", "#posp a:first", true ); + isit( "#posp .firsta", "#posp a:last", false ); + isit( "#posp .firsta", "#posp a:even", true ); + isit( "#posp .firsta", "#posp a:odd", false ); + isit( "#posp .firsta", "#posp a:eq(0)", true ); + isit( "#posp .firsta", "#posp a:eq(9)", false ); + isit( "#posp .firsta", "#posp em:eq(0)", false ); + isit( "#posp .firsta", "#posp em:first", false ); + isit( "#posp .firsta", "#posp:first", false ); + + isit( "#posp .seconda", "#posp a:first", false ); + isit( "#posp .seconda", "#posp a:last", true ); + isit( "#posp .seconda", "#posp a:gt(0)", true ); + isit( "#posp .seconda", "#posp a:lt(5)", true ); + isit( "#posp .seconda", "#posp a:lt(1)", false ); + + isit( "#posp em", "#posp a:eq(0) em", true ); + isit( "#posp em", "#posp a:lt(1) em", true ); + isit( "#posp em", "#posp a:gt(1) em", false ); + isit( "#posp em", "#posp a:first em", true ); + isit( "#posp em", "#posp a em:last", true ); + isit( "#posp em", "#posp a em:eq(2)", false ); + + html.remove(); +}); + test("index()", function() { expect( 2 );