From eeb12184efda8327f1aff72531df545615cfe17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Go=C5=82e=CC=A8biowski-Owczarek?= Date: Tue, 8 Apr 2025 14:24:26 +0200 Subject: [PATCH] Core: Patch push, sort & splice in jQuery >=3.7.0 Ref jquery/jquery#5653 --- src/jquery/core.js | 15 ++++++++++- test/unit/jquery/core.js | 57 ++++++++++++++++++++++++++++++++++++++++ warnings.md | 8 ++++++ 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/src/jquery/core.js b/src/jquery/core.js index 26d47a0f..aca64fbf 100644 --- a/src/jquery/core.js +++ b/src/jquery/core.js @@ -2,7 +2,11 @@ import { jQueryVersionSince } from "../compareVersions.js"; import { migratePatchAndWarnFunc } from "../main.js"; import "../disablePatches.js"; -var class2type = {}, +var arr = [], + push = arr.push, + sort = arr.sort, + splice = arr.splice, + class2type = {}, // Require that the "whitespace run" starts from a non-whitespace // to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position. @@ -118,3 +122,12 @@ if ( jQueryVersionSince( "3.3.0" ) ) { "proxy", "DEPRECATED: jQuery.proxy()" ); } + +if ( jQueryVersionSince( "3.7.0" ) ) { + migratePatchAndWarnFunc( jQuery.fn, "push", push, "push", + "jQuery.fn.push() is deprecated; use .add() or convert to an array" ); + migratePatchAndWarnFunc( jQuery.fn, "sort", sort, "sort", + "jQuery.fn.sort() is deprecated; convert to an array before sorting" ); + migratePatchAndWarnFunc( jQuery.fn, "splice", splice, "splice", + "jQuery.fn.splice() is deprecated; use .slice() or .not() with .eq()" ); +} diff --git a/test/unit/jquery/core.js b/test/unit/jquery/core.js index b9c95b48..d980059e 100644 --- a/test/unit/jquery/core.js +++ b/test/unit/jquery/core.js @@ -1,6 +1,12 @@ QUnit.module( "core" ); +function getTagNames( elem ) { + return elem.toArray().map( function( node ) { + return node.tagName.toLowerCase(); + } ); +} + QUnit.test( "jQuery(html, props)", function( assert ) { assert.expect( 2 ); @@ -318,6 +324,57 @@ TestManager.runIframeTest( "old pre-3.0 jQuery", "core-jquery2.html", assert.ok( /jQuery 3/.test( log ), "logged: " + log ); } ); +QUnit[ jQueryVersionSince( "3.7.0" ) ? "test" : "skip" ]( "jQuery.fn.push", function( assert ) { + assert.expect( 2 ); + + expectWarning( assert, "jQuery.fn.push", 1, function() { + var node = jQuery( "
" )[ 0 ], + elem = jQuery( "

" ); + + elem.push( node ); + + assert.deepEqual( getTagNames( elem ), [ "p", "span", "div" ], + "div added in-place" ); + } ); +} ); + +QUnit[ jQueryVersionSince( "3.7.0" ) ? "test" : "skip" ]( "jQuery.fn.sort", function( assert ) { + assert.expect( 2 ); + + expectWarning( assert, "jQuery.fn.sort", 1, function() { + var elem = jQuery( "

" ); + + elem.sort( function( node1, node2 ) { + var tag1 = node1.tagName.toLowerCase(), + tag2 = node2.tagName.toLowerCase(); + if ( tag1 < tag2 ) { + return -1; + } + if ( tag1 > tag2 ) { + return 1; + } + return 0; + } ); + + assert.deepEqual( getTagNames( elem ), [ "div", "p", "span" ], + "element sorted in-place" ); + } ); +} ); + +QUnit[ jQueryVersionSince( "3.7.0" ) ? "test" : "skip" ]( "jQuery.fn.splice", function( assert ) { + assert.expect( 2 ); + + expectWarning( assert, "jQuery.fn.splice", 1, function() { + var elem = jQuery( "

" ); + + elem.splice( 1, 1, jQuery( "" )[ 0 ], jQuery( "" )[ 0 ] ); + + assert.deepEqual( getTagNames( elem ), [ "span", "i", "b", "p" ], + "splice removed & added in-place" ); + } ); +} ); + + QUnit[ jQueryVersionSince( "3.3.0" ) ? "test" : "skip" ]( "jQuery.proxy", function( assert ) { assert.expect( 10 ); diff --git a/warnings.md b/warnings.md index e6979b68..e4a0c5b6 100644 --- a/warnings.md +++ b/warnings.md @@ -46,6 +46,14 @@ This is _not_ a warning, but a console log message the plugin shows when it firs **Solution:** Put a [valid doctype](http://www.w3.org/QA/2002/04/valid-dtd-list.html) in the document and ensure that the document is rendering in standards mode. The simplest valid doctype is the HTML5 one, which we highly recommend: `` . The jQuery Migrate plugin does not attempt to fix issues related to quirks mode. +### \[push\] JQMIGRATE: jQuery.fn.push() is deprecated; use .add or convert to an array +### \[sort\] JQMIGRATE: jQuery.fn.sort() is deprecated; convert to an array before sorting +### \[splice\] JQMIGRATE: jQuery.fn.splice() is deprecated; use .slice() or .not() with .eq() + +**Cause**: jQuery adds the Array `push`, `sort` & `splice` methods to the jQuery prototype. They behave differently to other jQuery APIs - they modify the jQuery collections in place, they don't play nice with APIs like `.end()`, they were also never documented. + +**Solution**: Replace `.push( node )` with `.add( node )`, `.splice( index )` with `.not( elem.eq( index ) )`. In more complex cases, call `.toArray()` first, manipulate the resulting array and convert back to the jQuery object by passing the resulting array to `$()`. + ### \[jqXHR-methods\] JQMIGRATE: jQXHR.success is deprecated and removed ### \[jqXHR-methods\] JQMIGRATE: jQXHR.error is deprecated and removed ### \[jqXHR-methods\] JQMIGRATE: jQXHR.complete is deprecated and removed