From 8c7da22caeae8c2c3f7e9869d5f47414669f106c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Go=C5=82=C4=99biowski-Owczarek?= Date: Tue, 11 Oct 2022 11:55:46 +0200 Subject: [PATCH] Selector: Drop support for legacy pseudos, test custom pseudos This backports custom pseudos tests from Sizzle; they were missed in original test backports. Also, the support for legacy custom pseudos has been dropped. The `jQuery.expr` test cleanup has been wrapped in `try-finally` for cleaner test isolation in case anything goes wrong. Closes gh-5137 --- src/selector.js | 23 ++------------ test/unit/selector.js | 74 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/selector.js b/src/selector.js index 871cf8682..a69e16556 100644 --- a/src/selector.js +++ b/src/selector.js @@ -804,9 +804,8 @@ Expr = jQuery.expr = { // https://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - selectorError( "unsupported pseudo: " + pseudo ); + var fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + selectorError( "unsupported pseudo: " + pseudo ); // The user may use createPseudo to indicate that // arguments are needed to create the filter function @@ -815,24 +814,6 @@ Expr = jQuery.expr = { return fn( argument ); } - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction( function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf.call( seed, matched[ i ] ); - seed[ idx ] = !( matches[ idx ] = matched[ i ] ); - } - } ) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - return fn; } }, diff --git a/test/unit/selector.js b/test/unit/selector.js index b1529175b..12297fae9 100644 --- a/test/unit/selector.js +++ b/test/unit/selector.js @@ -2142,3 +2142,77 @@ QUnit.test( "jQuery.escapeSelector", function( assert ) { assert.equal( jQuery.escapeSelector( "\uDF06" ), "\uDF06", "Doesn't escape lone low surrogate" ); assert.equal( jQuery.escapeSelector( "\uD834" ), "\uD834", "Doesn't escape lone high surrogate" ); } ); + +QUnit.test( "custom pseudos", function( assert ) { + assert.expect( 6 ); + + try { + jQuery.expr.filters.foundation = jQuery.expr.filters.root; + assert.deepEqual( jQuery.find( ":foundation" ), [ document.documentElement ], "Copy element filter with new name" ); + } finally { + delete jQuery.expr.filters.foundation; + } + + try { + jQuery.expr.setFilters.primary = jQuery.expr.setFilters.first; + assert.t( "Copy set filter with new name", "div#qunit-fixture :primary", [ "firstp" ] ); + } finally { + delete jQuery.expr.setFilters.primary; + } + + try { + jQuery.expr.filters.aristotlean = jQuery.expr.createPseudo( function() { + return function( elem ) { + return !!elem.id; + }; + } ); + assert.t( "Custom element filter", "#foo :aristotlean", [ "sndp", "en", "yahoo", "sap", "anchor2", "simon" ] ); + } finally { + delete jQuery.expr.filters.aristotlean; + } + + try { + jQuery.expr.filters.endswith = jQuery.expr.createPseudo( function( text ) { + return function( elem ) { + return jQuery.text( elem ).slice( -text.length ) === text; + }; + } ); + assert.t( "Custom element filter with argument", "a:endswith(ogle)", [ "google" ] ); + } finally { + delete jQuery.expr.filters.endswith; + } + + try { + jQuery.expr.setFilters.second = jQuery.expr.createPseudo( function() { + return jQuery.expr.createPseudo( function( seed, matches ) { + if ( seed[ 1 ] ) { + matches[ 1 ] = seed[ 1 ]; + seed[ 1 ] = false; + } + } ); + } ); + assert.t( "Custom set filter", "#qunit-fixture p:second", [ "ap" ] ); + } finally { + delete jQuery.expr.filters.second; + } + + try { + jQuery.expr.setFilters.slice = jQuery.expr.createPseudo( function( argument ) { + var bounds = argument.split( ":" ); + return jQuery.expr.createPseudo( function( seed, matches ) { + var i = bounds[ 1 ]; + + // Match elements found at the specified indexes + while ( --i >= bounds[ 0 ] ) { + if ( seed[ i ] ) { + matches[ i ] = seed[ i ]; + seed[ i ] = false; + } + } + } ); + } ); + assert.t( "Custom set filter with argument", "#qunit-fixture p:slice(1:3)", [ "ap", "sndp" ] ); + } finally { + delete jQuery.expr.filters.slice; + } +} ); -- 2.39.5