Skip to content

Commit

Permalink
Core: Fix the selector module, make CI green
Browse files Browse the repository at this point in the history
Changes:
1. Support legacy pseudos only in jQuery 3.7.0+.
2. Downgrade sinon to a version working with IE 9+.
3. Skip cross-domain ajax tests in IE 9.
4. Skip tests requiring `jQuery.Deferred.getErrorHook` in <3.7.
5. Don't require warnings for backwards-compatible pseudos if Proxy unsupported.
  • Loading branch information
mgol committed Oct 29, 2024
1 parent 76f8055 commit d526cd8
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 96 deletions.
116 changes: 74 additions & 42 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"qunit": "2.21.0",
"rollup": "4.22.4",
"selenium-webdriver": "4.21.0",
"sinon": "9.2.4",
"sinon": "7.5.0",
"uglify-js": "3.9.4",
"yargs": "17.7.2"
},
Expand Down
104 changes: 56 additions & 48 deletions src/jquery/selector.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { jQueryVersionSince } from "../compareVersions.js";
import { migratePatchFunc, migrateWarnProp, migrateWarn } from "../main.js";

// Now jQuery.expr.pseudos is the standard incantation
Expand All @@ -11,59 +12,66 @@ function markFunction( fn ) {
return fn;
}

migratePatchFunc( jQuery.expr.filter, "PSEUDO", function( pseudo, argument ) {
// jQuery older than 3.7.0 used Sizzle which has its own private expando
// variable that we cannot access. This makes thi patch impossible in those
// jQuery versions.
if ( jQueryVersionSince( "3.7.0" ) ) {
migratePatchFunc( jQuery.expr.filter, "PSEUDO", function( pseudo, argument ) {

// pseudo-class names are case-insensitive
// 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 = jQuery.expr.pseudos[ pseudo ] ||
jQuery.expr.setFilters[ pseudo.toLowerCase() ] ||
jQuery.error( "Syntax error, unrecognized expression: unsupported pseudo: " + pseudo );
// pseudo-class names are case-insensitive
// 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 = jQuery.expr.pseudos[ pseudo ] ||
jQuery.expr.setFilters[ pseudo.toLowerCase() ] ||
jQuery.error(
"Syntax error, unrecognized expression: unsupported pseudo: " +
pseudo );

// The user may use createPseudo to indicate that
// arguments are needed to create the filter function
// just as jQuery does
if ( fn[ jQuery.expando ] ) {
return fn( argument );
}
// The user may use createPseudo to indicate that
// arguments are needed to create the filter function
// just as jQuery does
if ( fn[ jQuery.expando ] ) {
return fn( argument );
}

// But maintain support for old signatures
if ( fn.length > 1 ) {
migrateWarn( "legacy-custom-pseudos",
"Pseudos with multiple arguments are deprecated; " +
"use jQuery.expr.createPseudo()" );
args = [ pseudo, pseudo, "", argument ];
return jQuery.expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
markFunction( function( seed, matches ) {
var idx,
matched = fn( seed, argument ),
i = matched.length;
while ( i-- ) {
idx = Array.prototype.indexOf.call( seed, matched[ i ] );
seed[ idx ] = !( matches[ idx ] = matched[ i ] );
}
} ) :
function( elem ) {
return fn( elem, 0, args );
};
}
// But maintain support for old signatures
if ( fn.length > 1 ) {
migrateWarn( "legacy-custom-pseudos",
"Pseudos with multiple arguments are deprecated; " +
"use jQuery.expr.createPseudo()" );
args = [ pseudo, pseudo, "", argument ];
return jQuery.expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
markFunction( function( seed, matches ) {
var idx,
matched = fn( seed, argument ),
i = matched.length;
while ( i-- ) {
idx = Array.prototype.indexOf.call( seed, matched[ i ] );
seed[ idx ] = !( matches[ idx ] = matched[ i ] );
}
} ) :
function( elem ) {
return fn( elem, 0, args );
};
}

return fn;
}, "legacy-custom-pseudos" );
return fn;
}, "legacy-custom-pseudos" );

if ( typeof Proxy !== "undefined" ) {
jQuery.each( [ "pseudos", "setFilters" ], function( _, api ) {
jQuery.expr[ api ] = new Proxy( jQuery.expr[ api ], {
set: function( _target, _prop, fn ) {
if ( typeof fn === "function" && !fn[ jQuery.expando ] && fn.length > 1 ) {
migrateWarn( "legacy-custom-pseudos",
"Pseudos with multiple arguments are deprecated; " +
"use jQuery.expr.createPseudo()" );
if ( typeof Proxy !== "undefined" ) {
jQuery.each( [ "pseudos", "setFilters" ], function( _, api ) {
jQuery.expr[ api ] = new Proxy( jQuery.expr[ api ], {
set: function( _target, _prop, fn ) {
if ( typeof fn === "function" && !fn[ jQuery.expando ] && fn.length > 1 ) {
migrateWarn( "legacy-custom-pseudos",
"Pseudos with multiple arguments are deprecated; " +
"use jQuery.expr.createPseudo()" );
}
return Reflect.set.apply( this, arguments );
}
return Reflect.set.apply( this, arguments );
}
} );
} );
} );
}
}
6 changes: 5 additions & 1 deletion test/unit/jquery/ajax.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ QUnit.test( "jQuery.ajax() deprecations on jqXHR", function( assert ) {
function runTests( options ) {
var forceEnablePatch = ( options || {} ).forceEnablePatch || false;

QUnit.test( "jQuery.ajax() JSON-to-JSONP auto-promotion" + label + (
// Support: IE <10 only
// IE 9 doesn't support CORS, skip cross-domain tests there.
QUnit[
document.documentMode < 10 && crossDomain ? "skip" : "test"
]( "jQuery.ajax() JSON-to-JSONP auto-promotion" + label + (
forceEnablePatch ? ", patch force-enabled" : ""
), function( assert ) {

Expand Down
6 changes: 5 additions & 1 deletion test/unit/jquery/deferred.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,11 @@ QUnit.test( "jQuery.Deferred.getStackHook - setter", function( assert ) {
} );
} );

QUnit.test( "jQuery.Deferred.getStackHook - disabled patch, getter", function( assert ) {
// jQuery.Deferred.getErrorHook was introduced in jQuery 3.7.0 and this test
// depends on it.
QUnit[
jQueryVersionSince( "3.7.0" ) ? "test" : "skip"
]( "jQuery.Deferred.getStackHook - disabled patch, getter", function( assert ) {
assert.expect( 5 );

var exceptionHookSpy,
Expand Down
15 changes: 12 additions & 3 deletions test/unit/jquery/selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,20 @@ QUnit.test( "custom pseudos", function( assert ) {
} );
} );

QUnit.test( "backwards-compatible custom pseudos", function( assert ) {
QUnit[
jQueryVersionSince( "3.7.0" ) ? "test" : "skip"
]( "backwards-compatible custom pseudos", function( assert ) {
assert.expect( 7 );

var expectWarningWithProxy = typeof Proxy !== "undefined" ?
expectWarning :
function( _assert, _title, fn ) {
fn();
assert.ok( true, "No Proxy => warnings not expected" );
};

try {
expectWarning( assert, "Custom element filter with argument - setter", function() {
expectWarningWithProxy( assert, "Custom element filter with argument - setter", function() {
jQuery.expr.pseudos.icontains = function( elem, i, match ) {
return jQuery
.text( elem )
Expand All @@ -214,7 +223,7 @@ QUnit.test( "backwards-compatible custom pseudos", function( assert ) {
}

try {
expectWarning( assert, "Custom setFilter pseudo - setter", function() {
expectWarningWithProxy( assert, "Custom setFilter pseudo - setter", function() {
jQuery.expr.setFilters.podium = function( elements, argument ) {
var count = argument == null || argument === "" ? 3 : +argument;
return elements.slice( 0, count );
Expand Down

0 comments on commit d526cd8

Please sign in to comment.