Skip to content

Commit 95d05ce

Browse files
authored
Core: Fill in & warn against $.fn.{push,sort,splice}
Fixes gh-473 Closes gh-529
1 parent 5845951 commit 95d05ce

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

src/jquery/core.js

+16
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import {
88
import "../disablePatches.js";
99

1010
var findProp,
11+
arr = [],
12+
push = arr.push,
13+
sort = arr.sort,
14+
splice = arr.splice,
1115
class2type = {},
1216
oldInit = jQuery.fn.init,
1317
oldFind = jQuery.find,
@@ -177,3 +181,15 @@ if ( jQueryVersionSince( "3.3.0" ) ) {
177181
"jQuery.isWindow() is deprecated"
178182
);
179183
}
184+
185+
if ( jQueryVersionSince( "4.0.0" ) ) {
186+
187+
// `push`, `sort` & `splice` are used internally by jQuery <4, so we only
188+
// warn in jQuery 4+.
189+
migrateWarnProp( jQuery.fn, "push", push, "push",
190+
"jQuery.fn.push() is deprecated and removed; use .add or convert to an array" );
191+
migrateWarnProp( jQuery.fn, "sort", sort, "sort",
192+
"jQuery.fn.sort() is deprecated and removed; convert to an array before sorting" );
193+
migrateWarnProp( jQuery.fn, "splice", splice, "splice",
194+
"jQuery.fn.splice() is deprecated and removed; use .slice or .not with .eq" );
195+
}

test/unit/jquery/core.js

+56
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11

22
QUnit.module( "core" );
33

4+
function getTagNames( elem ) {
5+
return elem.toArray().map( function( node ) {
6+
return node.tagName.toLowerCase();
7+
} );
8+
}
9+
410
QUnit.test( "jQuery(html, props)", function( assert ) {
511
assert.expect( 2 );
612

@@ -449,3 +455,53 @@ TestManager.runIframeTest( "old pre-3.0 jQuery", "core-jquery2.html",
449455

450456
assert.ok( /jQuery 3/.test( log ), "logged: " + log );
451457
} );
458+
459+
QUnit[ jQueryVersionSince( "4.0.0" ) ? "test" : "skip" ]( "jQuery.fn.push", function( assert ) {
460+
assert.expect( 2 );
461+
462+
expectWarning( assert, "jQuery.fn.push", 1, function() {
463+
var node = jQuery( "<div></div>" )[ 0 ],
464+
elem = jQuery( "<p></p><span></span>" );
465+
466+
elem.push( node );
467+
468+
assert.deepEqual( getTagNames( elem ), [ "p", "span", "div" ],
469+
"div added in-place" );
470+
} );
471+
} );
472+
473+
QUnit[ jQueryVersionSince( "4.0.0" ) ? "test" : "skip" ]( "jQuery.fn.sort", function( assert ) {
474+
assert.expect( 2 );
475+
476+
expectWarning( assert, "jQuery.fn.sort", 1, function() {
477+
var elem = jQuery( "<span></span><div></div><p></p>" );
478+
479+
elem.sort( function( node1, node2 ) {
480+
const tag1 = node1.tagName.toLowerCase();
481+
const tag2 = node2.tagName.toLowerCase();
482+
if ( tag1 < tag2 ) {
483+
return -1;
484+
}
485+
if ( tag1 > tag2 ) {
486+
return 1;
487+
}
488+
return 0;
489+
} );
490+
491+
assert.deepEqual( getTagNames( elem ), [ "div", "p", "span" ],
492+
"element sorted in-place" );
493+
} );
494+
} );
495+
496+
QUnit[ jQueryVersionSince( "4.0.0" ) ? "test" : "skip" ]( "jQuery.fn.splice", function( assert ) {
497+
assert.expect( 2 );
498+
499+
expectWarning( assert, "jQuery.fn.splice", 1, function() {
500+
var elem = jQuery( "<span></span><div></div><p></p>" );
501+
502+
elem.splice( 1, 1, jQuery( "<i></i>" )[ 0 ], jQuery( "<b></b>" )[ 0 ] );
503+
504+
assert.deepEqual( getTagNames( elem ), [ "span", "i", "b", "p" ],
505+
"splice removed & added in-place" );
506+
} );
507+
} );

warnings.md

+8
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,14 @@ See jQuery-ui [commit](https://github.com/jquery/jquery-ui/commit/c0093b599fcd58
178178

179179
**Solution**: Review code that uses `jQuery.type()` and use a type check that is appropriate for the situation. For example. if the code expects a plain function, check for `typeof arg === "function"`.
180180

181+
### \[push\] JQMIGRATE: jQuery.fn.push() is deprecated and removed; use .add or convert to an array
182+
### \[sort\] JQMIGRATE: jQuery.fn.sort() is deprecated and removed; convert to an array before sorting
183+
### \[splice\] JQMIGRATE: jQuery.fn.splice() is deprecated and removed; use .slice or .not with .eq
184+
185+
**Cause**: jQuery used to add the Array `push`, `sort` & `splice` methods to the jQuery prototype. They behaved 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.
186+
187+
**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 `$()`.
188+
181189
### \[unique\] JQMIGRATE: jQuery.unique is deprecated; use jQuery.uniqueSort
182190

183191
**Cause**: The fact that `jQuery.unique` sorted its results in DOM order was surprising to many who did not read the documentation carefully. As of jQuery 3.0 this function is being renamed to make it clear.

0 commit comments

Comments
 (0)