You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
3.1 KiB
105 lines
3.1 KiB
'use strict'; |
|
var $ = require('../internals/export'); |
|
var uncurryThis = require('../internals/function-uncurry-this'); |
|
var aCallable = require('../internals/a-callable'); |
|
var toObject = require('../internals/to-object'); |
|
var lengthOfArrayLike = require('../internals/length-of-array-like'); |
|
var toString = require('../internals/to-string'); |
|
var fails = require('../internals/fails'); |
|
var internalSort = require('../internals/array-sort'); |
|
var arrayMethodIsStrict = require('../internals/array-method-is-strict'); |
|
var FF = require('../internals/engine-ff-version'); |
|
var IE_OR_EDGE = require('../internals/engine-is-ie-or-edge'); |
|
var V8 = require('../internals/engine-v8-version'); |
|
var WEBKIT = require('../internals/engine-webkit-version'); |
|
|
|
var test = []; |
|
var un$Sort = uncurryThis(test.sort); |
|
var push = uncurryThis(test.push); |
|
|
|
// IE8- |
|
var FAILS_ON_UNDEFINED = fails(function () { |
|
test.sort(undefined); |
|
}); |
|
// V8 bug |
|
var FAILS_ON_NULL = fails(function () { |
|
test.sort(null); |
|
}); |
|
// Old WebKit |
|
var STRICT_METHOD = arrayMethodIsStrict('sort'); |
|
|
|
var STABLE_SORT = !fails(function () { |
|
// feature detection can be too slow, so check engines versions |
|
if (V8) return V8 < 70; |
|
if (FF && FF > 3) return; |
|
if (IE_OR_EDGE) return true; |
|
if (WEBKIT) return WEBKIT < 603; |
|
|
|
var result = ''; |
|
var code, chr, value, index; |
|
|
|
// generate an array with more 512 elements (Chakra and old V8 fails only in this case) |
|
for (code = 65; code < 76; code++) { |
|
chr = String.fromCharCode(code); |
|
|
|
switch (code) { |
|
case 66: case 69: case 70: case 72: value = 3; break; |
|
case 68: case 71: value = 4; break; |
|
default: value = 2; |
|
} |
|
|
|
for (index = 0; index < 47; index++) { |
|
test.push({ k: chr + index, v: value }); |
|
} |
|
} |
|
|
|
test.sort(function (a, b) { return b.v - a.v; }); |
|
|
|
for (index = 0; index < test.length; index++) { |
|
chr = test[index].k.charAt(0); |
|
if (result.charAt(result.length - 1) !== chr) result += chr; |
|
} |
|
|
|
return result !== 'DGBEFHACIJK'; |
|
}); |
|
|
|
var FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT; |
|
|
|
var getSortCompare = function (comparefn) { |
|
return function (x, y) { |
|
if (y === undefined) return -1; |
|
if (x === undefined) return 1; |
|
if (comparefn !== undefined) return +comparefn(x, y) || 0; |
|
return toString(x) > toString(y) ? 1 : -1; |
|
}; |
|
}; |
|
|
|
// `Array.prototype.sort` method |
|
// https://tc39.es/ecma262/#sec-array.prototype.sort |
|
$({ target: 'Array', proto: true, forced: FORCED }, { |
|
sort: function sort(comparefn) { |
|
if (comparefn !== undefined) aCallable(comparefn); |
|
|
|
var array = toObject(this); |
|
|
|
if (STABLE_SORT) return comparefn === undefined ? un$Sort(array) : un$Sort(array, comparefn); |
|
|
|
var items = []; |
|
var arrayLength = lengthOfArrayLike(array); |
|
var itemsLength, index; |
|
|
|
for (index = 0; index < arrayLength; index++) { |
|
if (index in array) push(items, array[index]); |
|
} |
|
|
|
internalSort(items, getSortCompare(comparefn)); |
|
|
|
itemsLength = items.length; |
|
index = 0; |
|
|
|
while (index < itemsLength) array[index] = items[index++]; |
|
while (index < arrayLength) delete array[index++]; |
|
|
|
return array; |
|
} |
|
});
|
|
|