Skip to content

Commit

Permalink
Selector: Patch & warn against legacy selector pseudos
Browse files Browse the repository at this point in the history
Also:
1. Create the selector module in Migrate.
2. Migrate some selector patches from `core` to `selector`.

Fixes gh-544
Closes gh-546
  • Loading branch information
mgol authored Oct 28, 2024
1 parent a4889b6 commit 9ebcb61
Show file tree
Hide file tree
Showing 7 changed files with 321 additions and 39 deletions.
6 changes: 0 additions & 6 deletions src/jquery/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,6 @@ migratePatchAndWarnFunc( jQuery, "holdReady", jQuery.holdReady,
migratePatchAndWarnFunc( jQuery, "unique", jQuery.uniqueSort,
"unique", "jQuery.unique is deprecated; use jQuery.uniqueSort" );

// Now jQuery.expr.pseudos is the standard incantation
migrateWarnProp( jQuery.expr, "filters", jQuery.expr.pseudos, "expr-pre-pseudos",
"jQuery.expr.filters is deprecated; use jQuery.expr.pseudos" );
migrateWarnProp( jQuery.expr, ":", jQuery.expr.pseudos, "expr-pre-pseudos",
"jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos" );

// Prior to jQuery 3.1.1 there were internal refs so we don't warn there
if ( jQueryVersionSince( "3.1.1" ) ) {
migratePatchAndWarnFunc( jQuery, "trim", function( text ) {
Expand Down
69 changes: 69 additions & 0 deletions src/jquery/selector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { migratePatchFunc, migrateWarnProp, migrateWarn } from "../main.js";

// Now jQuery.expr.pseudos is the standard incantation
migrateWarnProp( jQuery.expr, "filters", jQuery.expr.pseudos, "expr-pre-pseudos",
"jQuery.expr.filters is deprecated; use jQuery.expr.pseudos" );
migrateWarnProp( jQuery.expr, ":", jQuery.expr.pseudos, "expr-pre-pseudos",
"jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos" );

function markFunction( fn ) {
fn[ jQuery.expando ] = true;
return fn;
}

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 );

// 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 );
};
}

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()" );
}
return Reflect.set.apply( this, arguments );
}
} );
} );
}
1 change: 1 addition & 0 deletions src/migrate.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import "./version.js";
import "./compareVersions.js";
import "./main.js";
import "./jquery/core.js";
import "./jquery/selector.js";
import "./jquery/ajax.js";
import "./jquery/attributes.js";
import "./jquery/css.js";
Expand Down
5 changes: 3 additions & 2 deletions test/data/testinit.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,14 @@
"unit/jquery/attributes.js",
"unit/jquery/css.js",
"unit/jquery/data.js",
"unit/jquery/deferred.js",
"unit/jquery/effects.js",
"unit/jquery/event.js",
"unit/jquery/manipulation.js",
"unit/jquery/offset.js",
"unit/jquery/selector.js",
"unit/jquery/serialize.js",
"unit/jquery/traversing.js",
"unit/jquery/deferred.js"
"unit/jquery/traversing.js"
];

testFiles.forEach( function( testFile ) {
Expand Down
5 changes: 3 additions & 2 deletions test/runner/flags/modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ export const modules = [
"attributes",
"css",
"data",
"deferred",
"effects",
"event",
"manipulation",
"offset",
"selector",
"serialize",
"traversing",
"deferred"
"traversing"
];
29 changes: 0 additions & 29 deletions test/unit/jquery/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,35 +315,6 @@ QUnit.test( "jQuery.unique", function( assert ) {
} );
} );

QUnit.test( "jQuery.expr.pseudos aliases", function( assert ) {
assert.expect( 7 );

expectWarning( assert, "jQuery.expr.filters", function() {
jQuery.expr.filters.mazda = function( elem ) {
return elem.style.zoom === "3";
};
} );

expectWarning( assert, "jQuery.expr[':']", function() {
jQuery.expr[ ":" ].marginal = function( elem ) {
return parseInt( elem.style.marginLeftWidth ) > 20;
};
} );

expectNoWarning( assert, "jQuery.expr.pseudos", function() {
var fixture = jQuery( "#qunit-fixture" ).prepend( "<p>hello</p>" );

assert.ok( jQuery.expr.pseudos.mazda, "filters assigned" );
assert.ok( jQuery.expr.pseudos.marginal, "[':'] assigned" );
fixture.find( "p" ).first().css( "marginLeftWidth", "40px" );
assert.equal( fixture.find( "p:marginal" ).length, 1, "One marginal element" );
assert.equal( fixture.find( "div:mazda" ).length, 0, "No mazda elements" );
delete jQuery.expr.pseudos.mazda;
delete jQuery.expr.pseudos.marginal;
} );

} );

QUnit.test( "jQuery.holdReady (warn only)", function( assert ) {
assert.expect( 1 );

Expand Down
Loading

0 comments on commit 9ebcb61

Please # to comment.