aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmed.S.ElAfifi <ahmed.s.elafifi@gmail.com>2019-08-19 10:04:01 +0200
committerMichał Gołębiowski-Owczarek <m.goleb@gmail.com>2019-09-25 01:38:21 +0200
commit9df4f1de12728b44a4b0f91748f12421008d9079 (patch)
treea8864c22790c5045db115c789af5dfecebeb6a02
parentaa6344baf87145ffc807a527d9c1fb03c96b1948 (diff)
downloadjquery-9df4f1de12728b44a4b0f91748f12421008d9079.tar.gz
jquery-9df4f1de12728b44a4b0f91748f12421008d9079.zip
Core: Use Array.prototype.flat where supported
Calling `Array.prototype.concat.apply( [], inputArray )` to flatten `inputArray` crashes for large arrays; using `Array.prototype.flat` avoids these issues in browsers that support it. In case it's necessary to support these large arrays even in older browsers, a polyfill for `Array.prototype.flat` can be loaded. This is already being done by many applications. Fixes gh-4320 Closes gh-4459
-rw-r--r--src/core.js6
-rw-r--r--src/manipulation.js6
-rw-r--r--src/var/concat.js7
-rw-r--r--src/var/flat.js15
-rw-r--r--test/unit/core.js19
5 files changed, 39 insertions, 14 deletions
diff --git a/src/core.js b/src/core.js
index 0999da9f5..af5d44214 100644
--- a/src/core.js
+++ b/src/core.js
@@ -6,7 +6,7 @@ define( [
"./var/arr",
"./var/getProto",
"./var/slice",
- "./var/concat",
+ "./var/flat",
"./var/push",
"./var/indexOf",
"./var/class2type",
@@ -18,7 +18,7 @@ define( [
"./var/isWindow",
"./core/DOMEval",
"./core/toType"
-], function( arr, getProto, slice, concat, push, indexOf,
+], function( arr, getProto, slice, flat, push, indexOf,
class2type, toString, hasOwn, fnToString, ObjectFunctionString,
support, isWindow, DOMEval, toType ) {
@@ -397,7 +397,7 @@ jQuery.extend( {
}
// Flatten any nested arrays
- return concat.apply( [], ret );
+ return flat( ret );
},
// A global GUID counter for objects
diff --git a/src/manipulation.js b/src/manipulation.js
index fc4c659fd..11bd5b079 100644
--- a/src/manipulation.js
+++ b/src/manipulation.js
@@ -1,7 +1,7 @@
define( [
"./core",
"./core/isAttached",
- "./var/concat",
+ "./var/flat",
"./var/isIE",
"./var/push",
"./core/access",
@@ -22,7 +22,7 @@ define( [
"./traversing",
"./selector",
"./event"
-], function( jQuery, isAttached, concat, isIE, push, access, rtagName,
+], function( jQuery, isAttached, flat, isIE, push, access, rtagName,
rscriptType, wrapMap, getAll, setGlobalEval, buildFragment,
dataPriv, dataUser, acceptData, DOMEval, nodeName ) {
@@ -103,7 +103,7 @@ function cloneCopyEvent( src, dest ) {
function domManip( collection, args, callback, ignored ) {
// Flatten any nested arrays
- args = concat.apply( [], args );
+ args = flat( args );
var fragment, first, scripts, hasScripts, node, doc,
i = 0,
diff --git a/src/var/concat.js b/src/var/concat.js
deleted file mode 100644
index e47c19d75..000000000
--- a/src/var/concat.js
+++ /dev/null
@@ -1,7 +0,0 @@
-define( [
- "./arr"
-], function( arr ) {
- "use strict";
-
- return arr.concat;
-} );
diff --git a/src/var/flat.js b/src/var/flat.js
new file mode 100644
index 000000000..6c7a27169
--- /dev/null
+++ b/src/var/flat.js
@@ -0,0 +1,15 @@
+define( [
+ "./arr"
+], function( arr ) {
+
+"use strict";
+
+// Support: IE 11+, Edge 18+
+// Provide fallback for browsers without Array#flat.
+return arr.flat ? function( array ) {
+ return arr.flat.call( array );
+} : function( array ) {
+ return arr.concat.apply( [], array );
+};
+
+} );
diff --git a/test/unit/core.js b/test/unit/core.js
index be09163ac..bc5d2fc25 100644
--- a/test/unit/core.js
+++ b/test/unit/core.js
@@ -681,7 +681,7 @@ QUnit.test( "map()", function( assert ) {
} );
QUnit.test( "jQuery.map", function( assert ) {
- assert.expect( 25 );
+ assert.expect( 28 );
var i, label, result, callback;
@@ -781,6 +781,23 @@ QUnit.test( "jQuery.map", function( assert ) {
return k % 2 ? k : [ k, k, k ];
} );
assert.equal( result.join( "" ), "00012223", "Array results flattened (#2616)" );
+
+ result = jQuery.map( [ [ [ 1, 2 ], 3 ], 4 ], function( v, k ) {
+ return v;
+ } );
+ assert.equal( result.length, 3, "Array flatten only one level down" );
+ assert.ok( Array.isArray( result[ 0 ] ), "Array flatten only one level down" );
+
+ // Support: IE 11+, Edge 18+
+ // Skip the test in browsers without Array#flat.
+ if ( Array.prototype.flat ) {
+ result = jQuery.map( Array( 300000 ), function( v, k ) {
+ return k;
+ } );
+ assert.equal( result.length, 300000, "Able to map 300000 records without any problems (#4320)" );
+ } else {
+ assert.ok( "skip", "Array#flat doesn't supported on all browsers" );
+ }
} );
QUnit.test( "jQuery.merge()", function( assert ) {