es6-shim
Version:
ECMAScript 6 (Harmony) compatibility shims for legacy JavaScript engines
1,411 lines (1,304 loc) • 139 kB
JavaScript
/*!
* https://github.com/paulmillr/es6-shim
* @license es6-shim Copyright 2013-2016 by Paul Miller (http://paulmillr.com)
* and contributors, MIT License
* es6-shim: v0.35.4
* see https://github.com/paulmillr/es6-shim/blob/0.35.3/LICENSE
* Details and documentation:
* https://github.com/paulmillr/es6-shim/
*/
// UMD (Universal Module Definition)
// see https://github.com/umdjs/umd/blob/master/returnExports.js
(function (root, factory) {
/*global define */
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(factory);
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
// Browser globals (root is window)
root.returnExports = factory();
}
}(this, function () {
'use strict';
var _apply = Function.call.bind(Function.apply);
var _call = Function.call.bind(Function.call);
var isArray = Array.isArray;
var keys = Object.keys;
var not = function notThunker(func) {
return function notThunk() {
return !_apply(func, this, arguments);
};
};
var throwsError = function (func) {
try {
func();
return false;
} catch (e) {
return true;
}
};
var valueOrFalseIfThrows = function valueOrFalseIfThrows(func) {
try {
return func();
} catch (e) {
return false;
}
};
var isCallableWithoutNew = not(throwsError);
var arePropertyDescriptorsSupported = function () {
// if Object.defineProperty exists but throws, it's IE 8
return !throwsError(function () {
return Object.defineProperty({}, 'x', { get: function () { } }); // eslint-disable-line getter-return
});
};
var supportsDescriptors = !!Object.defineProperty && arePropertyDescriptorsSupported();
var functionsHaveNames = (function foo() {}).name === 'foo';
var _forEach = Function.call.bind(Array.prototype.forEach);
var _reduce = Function.call.bind(Array.prototype.reduce);
var _filter = Function.call.bind(Array.prototype.filter);
var _some = Function.call.bind(Array.prototype.some);
var defineProperty = function (object, name, value, force) {
if (!force && name in object) { return; }
if (supportsDescriptors) {
Object.defineProperty(object, name, {
configurable: true,
enumerable: false,
writable: true,
value: value
});
} else {
object[name] = value;
}
};
// Define configurable, writable and non-enumerable props
// if they don’t exist.
var defineProperties = function (object, map, forceOverride) {
_forEach(keys(map), function (name) {
var method = map[name];
defineProperty(object, name, method, !!forceOverride);
});
};
var _toString = Function.call.bind(Object.prototype.toString);
var isCallable = typeof /abc/ === 'function' ? function IsCallableSlow(x) {
// Some old browsers (IE, FF) say that typeof /abc/ === 'function'
return typeof x === 'function' && _toString(x) === '[object Function]';
} : function IsCallableFast(x) { return typeof x === 'function'; };
var Value = {
getter: function (object, name, getter) {
if (!supportsDescriptors) {
throw new TypeError('getters require true ES5 support');
}
Object.defineProperty(object, name, {
configurable: true,
enumerable: false,
get: getter
});
},
proxy: function (originalObject, key, targetObject) {
if (!supportsDescriptors) {
throw new TypeError('getters require true ES5 support');
}
var originalDescriptor = Object.getOwnPropertyDescriptor(originalObject, key);
Object.defineProperty(targetObject, key, {
configurable: originalDescriptor.configurable,
enumerable: originalDescriptor.enumerable,
get: function getKey() { return originalObject[key]; },
set: function setKey(value) { originalObject[key] = value; }
});
},
redefine: function (object, property, newValue) {
if (supportsDescriptors) {
var descriptor = Object.getOwnPropertyDescriptor(object, property);
descriptor.value = newValue;
Object.defineProperty(object, property, descriptor);
} else {
object[property] = newValue;
}
},
defineByDescriptor: function (object, property, descriptor) {
if (supportsDescriptors) {
Object.defineProperty(object, property, descriptor);
} else if ('value' in descriptor) {
object[property] = descriptor.value;
}
},
preserveToString: function (target, source) {
if (source && isCallable(source.toString)) {
defineProperty(target, 'toString', source.toString.bind(source), true);
}
}
};
// Simple shim for Object.create on ES3 browsers
// (unlike real shim, no attempt to support `prototype === null`)
var create = Object.create || function (prototype, properties) {
var Prototype = function Prototype() {};
Prototype.prototype = prototype;
var object = new Prototype();
if (typeof properties !== 'undefined') {
keys(properties).forEach(function (key) {
Value.defineByDescriptor(object, key, properties[key]);
});
}
return object;
};
var supportsSubclassing = function (C, f) {
if (!Object.setPrototypeOf) { return false; /* skip test on IE < 11 */ }
return valueOrFalseIfThrows(function () {
var Sub = function Subclass(arg) {
var o = new C(arg);
Object.setPrototypeOf(o, Subclass.prototype);
return o;
};
Object.setPrototypeOf(Sub, C);
Sub.prototype = create(C.prototype, {
constructor: { value: Sub }
});
return f(Sub);
});
};
var getGlobal = function () {
/* global self, window */
// the only reliable means to get the global object is
// `Function('return this')()`
// However, this causes CSP violations in Chrome apps.
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};
var globals = getGlobal();
var globalIsFinite = globals.isFinite;
var _indexOf = Function.call.bind(String.prototype.indexOf);
var _arrayIndexOfApply = Function.apply.bind(Array.prototype.indexOf);
var _concat = Function.call.bind(Array.prototype.concat);
// var _sort = Function.call.bind(Array.prototype.sort);
var _strSlice = Function.call.bind(String.prototype.slice);
var _push = Function.call.bind(Array.prototype.push);
var _pushApply = Function.apply.bind(Array.prototype.push);
var _join = Function.call.bind(Array.prototype.join);
var _shift = Function.call.bind(Array.prototype.shift);
var _max = Math.max;
var _min = Math.min;
var _floor = Math.floor;
var _abs = Math.abs;
var _exp = Math.exp;
var _log = Math.log;
var _sqrt = Math.sqrt;
var _hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);
var ArrayIterator; // make our implementation private
var noop = function () {};
var OrigMap = globals.Map;
var origMapDelete = OrigMap && OrigMap.prototype['delete'];
var origMapGet = OrigMap && OrigMap.prototype.get;
var origMapHas = OrigMap && OrigMap.prototype.has;
var origMapSet = OrigMap && OrigMap.prototype.set;
var Symbol = globals.Symbol || {};
var symbolSpecies = Symbol.species || '@@species';
var numberIsNaN = Number.isNaN || function isNaN(value) {
// NaN !== NaN, but they are identical.
// NaNs are the only non-reflexive value, i.e., if x !== x,
// then x is NaN.
// isNaN is broken: it converts its argument to number, so
// isNaN('foo') => true
return value !== value;
};
var numberIsFinite = Number.isFinite || function isFinite(value) {
return typeof value === 'number' && globalIsFinite(value);
};
var _sign = isCallable(Math.sign) ? Math.sign : function sign(value) {
var number = Number(value);
if (number === 0) { return number; }
if (numberIsNaN(number)) { return number; }
return number < 0 ? -1 : 1;
};
var _log1p = function log1p(value) {
var x = Number(value);
if (x < -1 || numberIsNaN(x)) { return NaN; }
if (x === 0 || x === Infinity) { return x; }
if (x === -1) { return -Infinity; }
return (1 + x) - 1 === 0 ? x : x * (_log(1 + x) / ((1 + x) - 1));
};
// taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
// can be replaced with require('is-arguments') if we ever use a build process instead
var isStandardArguments = function isArguments(value) {
return _toString(value) === '[object Arguments]';
};
var isLegacyArguments = function isArguments(value) {
return value !== null
&& typeof value === 'object'
&& typeof value.length === 'number'
&& value.length >= 0
&& _toString(value) !== '[object Array]'
&& _toString(value.callee) === '[object Function]';
};
var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;
var Type = {
primitive: function (x) { return x === null || (typeof x !== 'function' && typeof x !== 'object'); },
string: function (x) { return _toString(x) === '[object String]'; },
regex: function (x) { return _toString(x) === '[object RegExp]'; },
symbol: function (x) {
return typeof globals.Symbol === 'function' && typeof x === 'symbol';
}
};
var overrideNative = function overrideNative(object, property, replacement) {
var original = object[property];
defineProperty(object, property, replacement, true);
Value.preserveToString(object[property], original);
};
// eslint-disable-next-line no-restricted-properties
var hasSymbols = typeof Symbol === 'function' && typeof Symbol['for'] === 'function' && Type.symbol(Symbol());
// This is a private name in the es6 spec, equal to '[Symbol.iterator]'
// we're going to use an arbitrary _-prefixed name to make our shims
// work properly with each other, even though we don't have full Iterator
// support. That is, `Array.from(map.keys())` will work, but we don't
// pretend to export a "real" Iterator interface.
var $iterator$ = Type.symbol(Symbol.iterator) ? Symbol.iterator : '_es6-shim iterator_';
// Firefox ships a partial implementation using the name @@iterator.
// https://bugzilla.mozilla.org/show_bug.cgi?id=907077#c14
// So use that name if we detect it.
if (globals.Set && typeof new globals.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
// Reflect
if (!globals.Reflect) {
defineProperty(globals, 'Reflect', {}, true);
}
var Reflect = globals.Reflect;
var $String = String;
/* global document */
var domAll = (typeof document === 'undefined' || !document) ? null : document.all;
var isNullOrUndefined = domAll == null ? function isNullOrUndefined(x) {
return x == null;
} : function isNullOrUndefinedAndNotDocumentAll(x) {
return x == null && x !== domAll;
};
var ES = {
// http://www.ecma-international.org/ecma-262/6.0/#sec-call
Call: function Call(F, V) {
var args = arguments.length > 2 ? arguments[2] : [];
if (!ES.IsCallable(F)) {
throw new TypeError(F + ' is not a function');
}
return _apply(F, V, args);
},
RequireObjectCoercible: function (x, optMessage) {
if (isNullOrUndefined(x)) {
throw new TypeError(optMessage || 'Cannot call method on ' + x);
}
return x;
},
// This might miss the "(non-standard exotic and does not implement
// [[Call]])" case from
// http://www.ecma-international.org/ecma-262/6.0/#sec-typeof-operator-runtime-semantics-evaluation
// but we can't find any evidence these objects exist in practice.
// If we find some in the future, you could test `Object(x) === x`,
// which is reliable according to
// http://www.ecma-international.org/ecma-262/6.0/#sec-toobject
// but is not well optimized by runtimes and creates an object
// whenever it returns false, and thus is very slow.
TypeIsObject: function (x) {
if (x === void 0 || x === null || x === true || x === false) {
return false;
}
return typeof x === 'function' || typeof x === 'object' || x === domAll;
},
ToObject: function (o, optMessage) {
return Object(ES.RequireObjectCoercible(o, optMessage));
},
IsCallable: isCallable,
IsConstructor: function (x) {
// We can't tell callables from constructors in ES5
return ES.IsCallable(x);
},
ToInt32: function (x) {
return ES.ToNumber(x) >> 0;
},
ToUint32: function (x) {
return ES.ToNumber(x) >>> 0;
},
ToNumber: function (value) {
if (hasSymbols && _toString(value) === '[object Symbol]') {
throw new TypeError('Cannot convert a Symbol value to a number');
}
return +value;
},
ToInteger: function (value) {
var number = ES.ToNumber(value);
if (numberIsNaN(number)) { return 0; }
if (number === 0 || !numberIsFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * _floor(_abs(number));
},
ToLength: function (value) {
var len = ES.ToInteger(value);
if (len <= 0) { return 0; } // includes converting -0 to +0
if (len > Number.MAX_SAFE_INTEGER) { return Number.MAX_SAFE_INTEGER; }
return len;
},
SameValue: function (a, b) {
if (a === b) {
// 0 === -0, but they are not identical.
if (a === 0) { return 1 / a === 1 / b; }
return true;
}
return numberIsNaN(a) && numberIsNaN(b);
},
SameValueZero: function (a, b) {
// same as SameValue except for SameValueZero(+0, -0) == true
return (a === b) || (numberIsNaN(a) && numberIsNaN(b));
},
GetIterator: function (o) {
if (isArguments(o)) {
// special case support for `arguments`
return new ArrayIterator(o, 'value');
}
var itFn = ES.GetMethod(o, $iterator$);
if (!ES.IsCallable(itFn)) {
// Better diagnostics if itFn is null or undefined
throw new TypeError('value is not an iterable');
}
var it = ES.Call(itFn, o);
if (!ES.TypeIsObject(it)) {
throw new TypeError('bad iterator');
}
return it;
},
GetMethod: function (o, p) {
var func = ES.ToObject(o)[p];
if (isNullOrUndefined(func)) {
return void 0;
}
if (!ES.IsCallable(func)) {
throw new TypeError('Method not callable: ' + p);
}
return func;
},
IteratorComplete: function (iterResult) {
return !!iterResult.done;
},
IteratorClose: function (iterator, completionIsThrow) {
var returnMethod = ES.GetMethod(iterator, 'return');
if (returnMethod === void 0) {
return;
}
var innerResult, innerException;
try {
innerResult = ES.Call(returnMethod, iterator);
} catch (e) {
innerException = e;
}
if (completionIsThrow) {
return;
}
if (innerException) {
throw innerException;
}
if (!ES.TypeIsObject(innerResult)) {
throw new TypeError("Iterator's return method returned a non-object.");
}
},
IteratorNext: function (it) {
var result = arguments.length > 1 ? it.next(arguments[1]) : it.next();
if (!ES.TypeIsObject(result)) {
throw new TypeError('bad iterator');
}
return result;
},
IteratorStep: function (it) {
var result = ES.IteratorNext(it);
var done = ES.IteratorComplete(result);
return done ? false : result;
},
Construct: function (C, args, newTarget, isES6internal) {
var target = typeof newTarget === 'undefined' ? C : newTarget;
if (!isES6internal && Reflect.construct) {
// Try to use Reflect.construct if available
return Reflect.construct(C, args, target);
}
// OK, we have to fake it. This will only work if the
// C.[[ConstructorKind]] == "base" -- but that's the only
// kind we can make in ES5 code anyway.
// OrdinaryCreateFromConstructor(target, "%ObjectPrototype%")
var proto = target.prototype;
if (!ES.TypeIsObject(proto)) {
proto = Object.prototype;
}
var obj = create(proto);
// Call the constructor.
var result = ES.Call(C, obj, args);
return ES.TypeIsObject(result) ? result : obj;
},
SpeciesConstructor: function (O, defaultConstructor) {
var C = O.constructor;
if (C === void 0) {
return defaultConstructor;
}
if (!ES.TypeIsObject(C)) {
throw new TypeError('Bad constructor');
}
var S = C[symbolSpecies];
if (isNullOrUndefined(S)) {
return defaultConstructor;
}
if (!ES.IsConstructor(S)) {
throw new TypeError('Bad @@species');
}
return S;
},
CreateHTML: function (string, tag, attribute, value) {
var S = ES.ToString(string);
var p1 = '<' + tag;
if (attribute !== '') {
var V = ES.ToString(value);
var escapedV = V.replace(/"/g, '"');
p1 += ' ' + attribute + '="' + escapedV + '"';
}
var p2 = p1 + '>';
var p3 = p2 + S;
return p3 + '</' + tag + '>';
},
IsRegExp: function IsRegExp(argument) {
if (!ES.TypeIsObject(argument)) {
return false;
}
var isRegExp = argument[Symbol.match];
if (typeof isRegExp !== 'undefined') {
return !!isRegExp;
}
return Type.regex(argument);
},
ToString: function ToString(string) {
if (hasSymbols && _toString(string) === '[object Symbol]') {
throw new TypeError('Cannot convert a Symbol value to a number');
}
return $String(string);
}
};
// Well-known Symbol shims
if (supportsDescriptors && hasSymbols) {
var defineWellKnownSymbol = function defineWellKnownSymbol(name) {
if (Type.symbol(Symbol[name])) {
return Symbol[name];
}
// eslint-disable-next-line no-restricted-properties
var sym = Symbol['for']('Symbol.' + name);
Object.defineProperty(Symbol, name, {
configurable: false,
enumerable: false,
writable: false,
value: sym
});
return sym;
};
if (!Type.symbol(Symbol.search)) {
var symbolSearch = defineWellKnownSymbol('search');
var originalSearch = String.prototype.search;
defineProperty(RegExp.prototype, symbolSearch, function search(string) {
return ES.Call(originalSearch, string, [this]);
});
var searchShim = function search(regexp) {
var O = ES.RequireObjectCoercible(this);
if (!isNullOrUndefined(regexp)) {
var searcher = ES.GetMethod(regexp, symbolSearch);
if (typeof searcher !== 'undefined') {
return ES.Call(searcher, regexp, [O]);
}
}
return ES.Call(originalSearch, O, [ES.ToString(regexp)]);
};
overrideNative(String.prototype, 'search', searchShim);
}
if (!Type.symbol(Symbol.replace)) {
var symbolReplace = defineWellKnownSymbol('replace');
var originalReplace = String.prototype.replace;
defineProperty(RegExp.prototype, symbolReplace, function replace(string, replaceValue) {
return ES.Call(originalReplace, string, [this, replaceValue]);
});
var replaceShim = function replace(searchValue, replaceValue) {
var O = ES.RequireObjectCoercible(this);
if (!isNullOrUndefined(searchValue)) {
var replacer = ES.GetMethod(searchValue, symbolReplace);
if (typeof replacer !== 'undefined') {
return ES.Call(replacer, searchValue, [O, replaceValue]);
}
}
return ES.Call(originalReplace, O, [ES.ToString(searchValue), replaceValue]);
};
overrideNative(String.prototype, 'replace', replaceShim);
}
if (!Type.symbol(Symbol.split)) {
var symbolSplit = defineWellKnownSymbol('split');
var originalSplit = String.prototype.split;
defineProperty(RegExp.prototype, symbolSplit, function split(string, limit) {
return ES.Call(originalSplit, string, [this, limit]);
});
var splitShim = function split(separator, limit) {
var O = ES.RequireObjectCoercible(this);
if (!isNullOrUndefined(separator)) {
var splitter = ES.GetMethod(separator, symbolSplit);
if (typeof splitter !== 'undefined') {
return ES.Call(splitter, separator, [O, limit]);
}
}
return ES.Call(originalSplit, O, [ES.ToString(separator), limit]);
};
overrideNative(String.prototype, 'split', splitShim);
}
var symbolMatchExists = Type.symbol(Symbol.match);
var stringMatchIgnoresSymbolMatch = symbolMatchExists && (function () {
// Firefox 41, through Nightly 45 has Symbol.match, but String#match ignores it.
// Firefox 40 and below have Symbol.match but String#match works fine.
var o = {};
o[Symbol.match] = function () { return 42; };
return 'a'.match(o) !== 42;
}());
if (!symbolMatchExists || stringMatchIgnoresSymbolMatch) {
var symbolMatch = defineWellKnownSymbol('match');
var originalMatch = String.prototype.match;
defineProperty(RegExp.prototype, symbolMatch, function match(string) {
return ES.Call(originalMatch, string, [this]);
});
var matchShim = function match(regexp) {
var O = ES.RequireObjectCoercible(this);
if (!isNullOrUndefined(regexp)) {
var matcher = ES.GetMethod(regexp, symbolMatch);
if (typeof matcher !== 'undefined') {
return ES.Call(matcher, regexp, [O]);
}
}
return ES.Call(originalMatch, O, [ES.ToString(regexp)]);
};
overrideNative(String.prototype, 'match', matchShim);
}
}
var wrapConstructor = function wrapConstructor(original, replacement, keysToSkip) {
Value.preserveToString(replacement, original);
if (Object.setPrototypeOf) {
// sets up proper prototype chain where possible
Object.setPrototypeOf(original, replacement);
}
if (supportsDescriptors) {
_forEach(Object.getOwnPropertyNames(original), function (key) {
if (key in noop || keysToSkip[key]) { return; }
Value.proxy(original, key, replacement);
});
} else {
_forEach(Object.keys(original), function (key) {
if (key in noop || keysToSkip[key]) { return; }
replacement[key] = original[key];
});
}
replacement.prototype = original.prototype;
Value.redefine(original.prototype, 'constructor', replacement);
};
var defaultSpeciesGetter = function () { return this; };
var addDefaultSpecies = function (C) {
if (supportsDescriptors && !_hasOwnProperty(C, symbolSpecies)) {
Value.getter(C, symbolSpecies, defaultSpeciesGetter);
}
};
var addIterator = function (prototype, impl) {
var implementation = impl || function iterator() { return this; };
defineProperty(prototype, $iterator$, implementation);
if (!prototype[$iterator$] && Type.symbol($iterator$)) {
// implementations are buggy when $iterator$ is a Symbol
prototype[$iterator$] = implementation;
}
};
var createDataProperty = function createDataProperty(object, name, value) {
if (supportsDescriptors) {
Object.defineProperty(object, name, {
configurable: true,
enumerable: true,
writable: true,
value: value
});
} else {
object[name] = value;
}
};
var createDataPropertyOrThrow = function createDataPropertyOrThrow(object, name, value) {
createDataProperty(object, name, value);
if (!ES.SameValue(object[name], value)) {
throw new TypeError('property is nonconfigurable');
}
};
var emulateES6construct = function (o, defaultNewTarget, defaultProto, slots) {
// This is an es5 approximation to es6 construct semantics. in es6,
// 'new Foo' invokes Foo.[[Construct]] which (for almost all objects)
// just sets the internal variable NewTarget (in es6 syntax `new.target`)
// to Foo and then returns Foo().
// Many ES6 object then have constructors of the form:
// 1. If NewTarget is undefined, throw a TypeError exception
// 2. Let xxx by OrdinaryCreateFromConstructor(NewTarget, yyy, zzz)
// So we're going to emulate those first two steps.
if (!ES.TypeIsObject(o)) {
throw new TypeError('Constructor requires `new`: ' + defaultNewTarget.name);
}
var proto = defaultNewTarget.prototype;
if (!ES.TypeIsObject(proto)) {
proto = defaultProto;
}
var obj = create(proto);
for (var name in slots) {
if (_hasOwnProperty(slots, name)) {
var value = slots[name];
defineProperty(obj, name, value, true);
}
}
return obj;
};
// Firefox 31 reports this function's length as 0
// https://bugzilla.mozilla.org/show_bug.cgi?id=1062484
if (String.fromCodePoint && String.fromCodePoint.length !== 1) {
var originalFromCodePoint = String.fromCodePoint;
overrideNative(String, 'fromCodePoint', function fromCodePoint(codePoints) {
return ES.Call(originalFromCodePoint, this, arguments);
});
}
var StringShims = {
fromCodePoint: function fromCodePoint(codePoints) {
var result = [];
var next;
for (var i = 0, length = arguments.length; i < length; i++) {
next = Number(arguments[i]);
if (!ES.SameValue(next, ES.ToInteger(next)) || next < 0 || next > 0x10FFFF) {
throw new RangeError('Invalid code point ' + next);
}
if (next < 0x10000) {
_push(result, String.fromCharCode(next));
} else {
next -= 0x10000;
_push(result, String.fromCharCode((next >> 10) + 0xD800));
_push(result, String.fromCharCode((next % 0x400) + 0xDC00));
}
}
return _join(result, '');
},
raw: function raw(template) {
var numberOfSubstitutions = arguments.length - 1;
var cooked = ES.ToObject(template, 'bad template');
var raw = ES.ToObject(cooked.raw, 'bad raw value');
var len = raw.length;
var literalSegments = ES.ToLength(len);
if (literalSegments <= 0) {
return '';
}
var stringElements = [];
var nextIndex = 0;
var nextKey, next, nextSeg, nextSub;
while (nextIndex < literalSegments) {
nextKey = ES.ToString(nextIndex);
nextSeg = ES.ToString(raw[nextKey]);
_push(stringElements, nextSeg);
if (nextIndex + 1 >= literalSegments) {
break;
}
next = nextIndex + 1 < arguments.length ? arguments[nextIndex + 1] : '';
nextSub = ES.ToString(next);
_push(stringElements, nextSub);
nextIndex += 1;
}
return _join(stringElements, '');
}
};
if (String.raw && String.raw({ raw: { 0: 'x', 1: 'y', length: 2 } }) !== 'xy') {
// IE 11 TP has a broken String.raw implementation
overrideNative(String, 'raw', StringShims.raw);
}
defineProperties(String, StringShims);
// Fast repeat, uses the `Exponentiation by squaring` algorithm.
// Perf: http://jsperf.com/string-repeat2/2
var stringRepeat = function repeat(s, times) {
if (times < 1) { return ''; }
if (times % 2) { return repeat(s, times - 1) + s; }
var half = repeat(s, times / 2);
return half + half;
};
var stringMaxLength = Infinity;
var StringPrototypeShims = {
repeat: function repeat(times) {
var thisStr = ES.ToString(ES.RequireObjectCoercible(this));
var numTimes = ES.ToInteger(times);
if (numTimes < 0 || numTimes >= stringMaxLength) {
throw new RangeError('repeat count must be less than infinity and not overflow maximum string size');
}
return stringRepeat(thisStr, numTimes);
},
startsWith: function startsWith(searchString) {
var S = ES.ToString(ES.RequireObjectCoercible(this));
if (ES.IsRegExp(searchString)) {
throw new TypeError('Cannot call method "startsWith" with a regex');
}
var searchStr = ES.ToString(searchString);
var position;
if (arguments.length > 1) {
position = arguments[1];
}
var start = _max(ES.ToInteger(position), 0);
return _strSlice(S, start, start + searchStr.length) === searchStr;
},
endsWith: function endsWith(searchString) {
var S = ES.ToString(ES.RequireObjectCoercible(this));
if (ES.IsRegExp(searchString)) {
throw new TypeError('Cannot call method "endsWith" with a regex');
}
var searchStr = ES.ToString(searchString);
var len = S.length;
var endPosition;
if (arguments.length > 1) {
endPosition = arguments[1];
}
var pos = typeof endPosition === 'undefined' ? len : ES.ToInteger(endPosition);
var end = _min(_max(pos, 0), len);
return _strSlice(S, end - searchStr.length, end) === searchStr;
},
includes: function includes(searchString) {
if (ES.IsRegExp(searchString)) {
throw new TypeError('"includes" does not accept a RegExp');
}
var searchStr = ES.ToString(searchString);
var position;
if (arguments.length > 1) {
position = arguments[1];
}
// Somehow this trick makes method 100% compat with the spec.
return _indexOf(this, searchStr, position) !== -1;
},
codePointAt: function codePointAt(pos) {
var thisStr = ES.ToString(ES.RequireObjectCoercible(this));
var position = ES.ToInteger(pos);
var length = thisStr.length;
if (position >= 0 && position < length) {
var first = thisStr.charCodeAt(position);
var isEnd = position + 1 === length;
if (first < 0xD800 || first > 0xDBFF || isEnd) { return first; }
var second = thisStr.charCodeAt(position + 1);
if (second < 0xDC00 || second > 0xDFFF) { return first; }
return ((first - 0xD800) * 1024) + (second - 0xDC00) + 0x10000;
}
}
};
if (String.prototype.includes && 'a'.includes('a', Infinity) !== false) {
overrideNative(String.prototype, 'includes', StringPrototypeShims.includes);
}
if (String.prototype.startsWith && String.prototype.endsWith) {
var startsWithRejectsRegex = throwsError(function () {
/* throws if spec-compliant */
return '/a/'.startsWith(/a/);
});
var startsWithHandlesInfinity = valueOrFalseIfThrows(function () {
return 'abc'.startsWith('a', Infinity) === false;
});
if (!startsWithRejectsRegex || !startsWithHandlesInfinity) {
// Firefox (< 37?) and IE 11 TP have a noncompliant startsWith implementation
overrideNative(String.prototype, 'startsWith', StringPrototypeShims.startsWith);
overrideNative(String.prototype, 'endsWith', StringPrototypeShims.endsWith);
}
}
if (hasSymbols) {
var startsWithSupportsSymbolMatch = valueOrFalseIfThrows(function () {
var re = /a/;
re[Symbol.match] = false;
return '/a/'.startsWith(re);
});
if (!startsWithSupportsSymbolMatch) {
overrideNative(String.prototype, 'startsWith', StringPrototypeShims.startsWith);
}
var endsWithSupportsSymbolMatch = valueOrFalseIfThrows(function () {
var re = /a/;
re[Symbol.match] = false;
return '/a/'.endsWith(re);
});
if (!endsWithSupportsSymbolMatch) {
overrideNative(String.prototype, 'endsWith', StringPrototypeShims.endsWith);
}
var includesSupportsSymbolMatch = valueOrFalseIfThrows(function () {
var re = /a/;
re[Symbol.match] = false;
return '/a/'.includes(re);
});
if (!includesSupportsSymbolMatch) {
overrideNative(String.prototype, 'includes', StringPrototypeShims.includes);
}
}
defineProperties(String.prototype, StringPrototypeShims);
// whitespace from: http://es5.github.io/#x15.5.4.20
// implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324
var ws = [
'\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003',
'\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028',
'\u2029\uFEFF'
].join('');
var trimRegexp = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');
var trimShim = function trim() {
return ES.ToString(ES.RequireObjectCoercible(this)).replace(trimRegexp, '');
};
var nonWS = ['\u0085', '\u200b', '\ufffe'].join('');
var nonWSregex = new RegExp('[' + nonWS + ']', 'g');
var isBadHexRegex = /^[-+]0x[0-9a-f]+$/i;
var hasStringTrimBug = nonWS.trim().length !== nonWS.length;
defineProperty(String.prototype, 'trim', trimShim, hasStringTrimBug);
// Given an argument x, it will return an IteratorResult object,
// with value set to x and done to false.
// Given no arguments, it will return an iterator completion object.
var iteratorResult = function (x) {
return { value: x, done: arguments.length === 0 };
};
// see http://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype-@@iterator
var StringIterator = function (s) {
ES.RequireObjectCoercible(s);
defineProperty(this, '_s', ES.ToString(s));
defineProperty(this, '_i', 0);
};
StringIterator.prototype.next = function () {
var s = this._s;
var i = this._i;
if (typeof s === 'undefined' || i >= s.length) {
this._s = void 0;
return iteratorResult();
}
var first = s.charCodeAt(i);
var second, len;
if (first < 0xD800 || first > 0xDBFF || (i + 1) === s.length) {
len = 1;
} else {
second = s.charCodeAt(i + 1);
len = (second < 0xDC00 || second > 0xDFFF) ? 1 : 2;
}
this._i = i + len;
return iteratorResult(s.substr(i, len));
};
addIterator(StringIterator.prototype);
addIterator(String.prototype, function () {
return new StringIterator(this);
});
var ArrayShims = {
from: function from(items) {
var C = this;
var mapFn;
if (arguments.length > 1) {
mapFn = arguments[1];
}
var mapping, T;
if (typeof mapFn === 'undefined') {
mapping = false;
} else {
if (!ES.IsCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function');
}
if (arguments.length > 2) {
T = arguments[2];
}
mapping = true;
}
// Note that that Arrays will use ArrayIterator:
// https://bugs.ecmascript.org/show_bug.cgi?id=2416
var usingIterator = typeof (isArguments(items) || ES.GetMethod(items, $iterator$)) !== 'undefined';
var length, result, i;
if (usingIterator) {
result = ES.IsConstructor(C) ? Object(new C()) : [];
var iterator = ES.GetIterator(items);
var next, nextValue;
i = 0;
while (true) {
next = ES.IteratorStep(iterator);
if (next === false) {
break;
}
nextValue = next.value;
try {
if (mapping) {
nextValue = typeof T === 'undefined' ? mapFn(nextValue, i) : _call(mapFn, T, nextValue, i);
}
result[i] = nextValue;
} catch (e) {
ES.IteratorClose(iterator, true);
throw e;
}
i += 1;
}
length = i;
} else {
var arrayLike = ES.ToObject(items);
length = ES.ToLength(arrayLike.length);
result = ES.IsConstructor(C) ? Object(new C(length)) : new Array(length);
var value;
for (i = 0; i < length; ++i) {
value = arrayLike[i];
if (mapping) {
value = typeof T === 'undefined' ? mapFn(value, i) : _call(mapFn, T, value, i);
}
createDataPropertyOrThrow(result, i, value);
}
}
result.length = length;
return result;
},
of: function of() {
var len = arguments.length;
var C = this;
var A = isArray(C) || !ES.IsCallable(C) ? new Array(len) : ES.Construct(C, [len]);
for (var k = 0; k < len; ++k) {
createDataPropertyOrThrow(A, k, arguments[k]);
}
A.length = len;
return A;
}
};
defineProperties(Array, ArrayShims);
addDefaultSpecies(Array);
// Our ArrayIterator is private; see
// https://github.com/paulmillr/es6-shim/issues/252
ArrayIterator = function (array, kind) {
defineProperty(this, 'i', 0);
defineProperty(this, 'array', array);
defineProperty(this, 'kind', kind);
};
defineProperties(ArrayIterator.prototype, {
next: function () {
var i = this.i;
var array = this.array;
if (!(this instanceof ArrayIterator)) {
throw new TypeError('Not an ArrayIterator');
}
if (typeof array !== 'undefined') {
var len = ES.ToLength(array.length);
if (i < len) {
//for (; i < len; i++) {
var kind = this.kind;
var retval;
if (kind === 'key') {
retval = i;
} else if (kind === 'value') {
retval = array[i];
} else if (kind === 'entry') {
retval = [i, array[i]];
}
this.i = i + 1;
return iteratorResult(retval);
}
}
this.array = void 0;
return iteratorResult();
}
});
addIterator(ArrayIterator.prototype);
/*
var orderKeys = function orderKeys(a, b) {
var aNumeric = String(ES.ToInteger(a)) === a;
var bNumeric = String(ES.ToInteger(b)) === b;
if (aNumeric && bNumeric) {
return b - a;
} else if (aNumeric && !bNumeric) {
return -1;
} else if (!aNumeric && bNumeric) {
return 1;
} else {
return a.localeCompare(b);
}
};
var getAllKeys = function getAllKeys(object) {
var ownKeys = [];
var keys = [];
for (var key in object) {
_push(_hasOwnProperty(object, key) ? ownKeys : keys, key);
}
_sort(ownKeys, orderKeys);
_sort(keys, orderKeys);
return _concat(ownKeys, keys);
};
*/
// note: this is positioned here because it depends on ArrayIterator
var arrayOfSupportsSubclassing = Array.of === ArrayShims.of || (function () {
// Detects a bug in Webkit nightly r181886
var Foo = function Foo(len) { this.length = len; };
Foo.prototype = [];
var fooArr = Array.of.apply(Foo, [1, 2]);
return fooArr instanceof Foo && fooArr.length === 2;
}());
if (!arrayOfSupportsSubclassing) {
overrideNative(Array, 'of', ArrayShims.of);
}
var ArrayPrototypeShims = {
copyWithin: function copyWithin(target, start) {
var o = ES.ToObject(this);
var len = ES.ToLength(o.length);
var relativeTarget = ES.ToInteger(target);
var relativeStart = ES.ToInteger(start);
var to = relativeTarget < 0 ? _max(len + relativeTarget, 0) : _min(relativeTarget, len);
var from = relativeStart < 0 ? _max(len + relativeStart, 0) : _min(relativeStart, len);
var end;
if (arguments.length > 2) {
end = arguments[2];
}
var relativeEnd = typeof end === 'undefined' ? len : ES.ToInteger(end);
var finalItem = relativeEnd < 0 ? _max(len + relativeEnd, 0) : _min(relativeEnd, len);
var count = _min(finalItem - from, len - to);
var direction = 1;
if (from < to && to < (from + count)) {
direction = -1;
from += count - 1;
to += count - 1;
}
while (count > 0) {
if (from in o) {
o[to] = o[from];
} else {
delete o[to];
}
from += direction;
to += direction;
count -= 1;
}
return o;
},
fill: function fill(value) {
var start;
if (arguments.length > 1) {
start = arguments[1];
}
var end;
if (arguments.length > 2) {
end = arguments[2];
}
var O = ES.ToObject(this);
var len = ES.ToLength(O.length);
start = ES.ToInteger(typeof start === 'undefined' ? 0 : start);
end = ES.ToInteger(typeof end === 'undefined' ? len : end);
var relativeStart = start < 0 ? _max(len + start, 0) : _min(start, len);
var relativeEnd = end < 0 ? len + end : end;
for (var i = relativeStart; i < len && i < relativeEnd; ++i) {
O[i] = value;
}
return O;
},
find: function find(predicate) {
var list = ES.ToObject(this);
var length = ES.ToLength(list.length);
if (!ES.IsCallable(predicate)) {
throw new TypeError('Array#find: predicate must be a function');
}
var thisArg = arguments.length > 1 ? arguments[1] : null;
for (var i = 0, value; i < length; i++) {
value = list[i];
if (thisArg) {
if (_call(predicate, thisArg, value, i, list)) {
return value;
}
} else if (predicate(value, i, list)) {
return value;
}
}
},
findIndex: function findIndex(predicate) {
var list = ES.ToObject(this);
var length = ES.ToLength(list.length);
if (!ES.IsCallable(predicate)) {
throw new TypeError('Array#findIndex: predicate must be a function');
}
var thisArg = arguments.length > 1 ? arguments[1] : null;
for (var i = 0; i < length; i++) {
if (thisArg) {
if (_call(predicate, thisArg, list[i], i, list)) {
return i;
}
} else if (predicate(list[i], i, list)) {
return i;
}
}
return -1;
},
keys: function keys() {
return new ArrayIterator(this, 'key');
},
values: function values() {
return new ArrayIterator(this, 'value');
},
entries: function entries() {
return new ArrayIterator(this, 'entry');
}
};
// Safari 7.1 defines Array#keys and Array#entries natively,
// but the resulting ArrayIterator objects don't have a "next" method.
if (Array.prototype.keys && !ES.IsCallable([1].keys().next)) {
delete Array.prototype.keys;
}
if (Array.prototype.entries && !ES.IsCallable([1].entries().next)) {
delete Array.prototype.entries;
}
// Chrome 38 defines Array#keys and Array#entries, and Array#@@iterator, but not Array#values
if (Array.prototype.keys && Array.prototype.entries && !Array.prototype.values && Array.prototype[$iterator$]) {
defineProperties(Array.prototype, {
values: Array.prototype[$iterator$]
});
if (Type.symbol(Symbol.unscopables)) {
Array.prototype[Symbol.unscopables].values = true;
}
}
// Chrome 40 defines Array#values with the incorrect name, although Array#{keys,entries} have the correct name
if (functionsHaveNames && Array.prototype.values && Array.prototype.values.name !== 'values') {
var originalArrayPrototypeValues = Array.prototype.values;
overrideNative(Array.prototype, 'values', function values() { return ES.Call(originalArrayPrototypeValues, this, arguments); });
defineProperty(Array.prototype, $iterator$, Array.prototype.values, true);
}
defineProperties(Array.prototype, ArrayPrototypeShims);
if (1 / [true].indexOf(true, -0) < 0) {
// indexOf when given a position arg of -0 should return +0.
// https://github.com/tc39/ecma262/pull/316
defineProperty(Array.prototype, 'indexOf', function indexOf(searchElement) {
var value = _arrayIndexOfApply(this, arguments);
if (value === 0 && (1 / value) < 0) {
return 0;
}
return value;
}, true);
}
addIterator(Array.prototype, function () { return this.values(); });
// Chrome defines keys/values/entries on Array, but doesn't give us
// any way to identify its iterator. So add our own shimmed field.
if (Object.getPrototypeOf) {
var ChromeArrayIterator = Object.getPrototypeOf([].values());
if (ChromeArrayIterator) { // in WSH, this is `undefined`
addIterator(ChromeArrayIterator);
}
}
// note: this is positioned here because it relies on Array#entries
var arrayFromSwallowsNegativeLengths = (function () {
// Detects a Firefox bug in v32
// https://bugzilla.mozilla.org/show_bug.cgi?id=1063993
return valueOrFalseIfThrows(function () {
return Array.from({ length: -1 }).length === 0;
});
}());
var arrayFromHandlesIterables = (function () {
// Detects a bug in Webkit nightly r181886
var arr = Array.from([0].entries());
return arr.length === 1 && isArray(arr[0]) && arr[0][0] === 0 && arr[0][1] === 0;
}());
if (!arrayFromSwallowsNegativeLengths || !arrayFromHandlesIterables) {
overrideNative(Array, 'from', ArrayShims.from);
}
var arrayFromHandlesUndefinedMapFunction = (function () {
// Microsoft Edge v0.11 throws if the mapFn argument is *provided* but undefined,
// but the spec doesn't care if it's provided or not - undefined doesn't throw.
return valueOrFalseIfThrows(function () {
return Array.from([0], void 0);
});
}());
if (!arrayFromHandlesUndefinedMapFunction) {
var origArrayFrom = Array.from;
overrideNative(Array, 'from', function from(items) {
if (arguments.length > 1 && typeof arguments[1] !== 'undefined') {
return ES.Call(origArrayFrom, this, arguments);
}
return _call(origArrayFrom, this, items);
});
}
var int32sAsOne = -(Math.pow(2, 32) - 1);
var toLengthsCorrectly = function (method, reversed) {
var obj = { length: int32sAsOne };
obj[reversed ? (obj.length >>> 0) - 1 : 0] = true;
return valueOrFalseIfThrows(function () {
_call(method, obj, function () {
// note: in nonconforming browsers, this will be called
// -1 >>> 0 times, which is 4294967295, so the throw matters.
throw new RangeError('should not reach here');
}, []);
return true;
});
};
if (!toLengthsCorrectly(Array.prototype.forEach)) {
var originalForEach = Array.prototype.forEach;
overrideNative(Array.prototype, 'forEach', function forEach(callbackFn) {
return ES.Call(originalForEach, this.length >= 0 ? this : [], arguments);
});
}
if (!toLengthsCorrectly(Array.prototype.map)) {
var originalMap = Array.prototype.map;
overrideNative(Array.prototype, 'map', function map(callbackFn) {
return ES.Call(originalMap, this.length >= 0 ? this : [], arguments);
});
}
if (!toLengthsCorrectly(Array.prototype.filter)) {
var originalFilter = Array.prototype.filter;
overrideNative(Array.prototype, 'filter', function filter(callbackFn) {
return ES.Call(originalFilter, this.length >= 0 ? this : [], arguments);
});
}
if (!toLengthsCorrectly(Array.prototype.some)) {
var originalSome = Array.prototype.some;
overrideNative(Array.prototype, 'some', function some(callbackFn) {
return ES.Call(originalSome, this.length >= 0 ? this : [], arguments);
});
}
if (!toLengthsCorrectly(Array.prototype.every)) {
var originalEvery = Array.prototype.every;
overrideNative(Array.prototype, 'every', function every(callbackFn) {
return ES.Call(originalEvery, this.length >= 0 ? this : [], arguments);
});
}
if (!toLengthsCorrectly(Array.prototype.reduce)) {
var originalReduce = Array.prototype.reduce;
overrideNative(Array.prototype, 'reduce', function reduce(callbackFn) {
return ES.Call(originalReduce, this.length >= 0 ? this : [], arguments);
});
}
if (!toLengthsCorrectly(Array.prototype.reduceRight, true)) {
var originalReduceRight = Array.prototype.reduceRight;
overrideNative(Array.prototype, 'reduceRight', function reduceRight(callbackFn) {
return ES.Call(originalReduceRight, this.length >= 0 ? this : [], arguments);
});
}
var lacksOctalSupport = Number('0o10') !== 8;
var lacksBinarySupport = Number('0b10') !== 2;
var trimsNonWhitespace = _some(nonWS, function (c) {
return Number(c + 0 + c) === 0;
});
if (lacksOctalSupport || lacksBinarySupport || trimsNonWhitespace) {
var OrigNumber = Number;
var binaryRegex = /^0b[01]+$/i;
var octalRegex = /^0o[0-7]+$/i;
// Note that in IE 8, RegExp.prototype.test doesn't seem to exist: ie, "test" is an own property of regexes. wtf.
var isBinary = binaryRegex.test.bind(binaryRegex);
var isOctal = octalRegex.test.bind(octalRegex);
var toPrimitive = function (O, hint) { // need to replace this with `es-to-primitive/es6`
var result;
if (typeof O.valueOf === 'function') {
result = O.valueOf();
if (Type.primitive(result)) {
return result;
}
}
if (typeof O.toString === 'function') {
result = O.toString();
if (Type.primitive(result)) {
return result;
}
}
throw new TypeError('No default value');
};
var hasNonWS = nonWSregex.test.bind(nonWSregex);
var isBadHex = isBadHexRegex.test.bind(isBadHexRegex);
var NumberShim = (function () {
// this is wrapped in an IIFE because of IE 6-8's wacky scoping issues with named function expressions.
var NumberShim = function Number(value) {
var primValue;
if (arguments.length > 0) {
primValue = Type.primitive(value) ? value : toPrimitive(value, 'number');
} else {
primValue = 0;
}
if (typeof primValue === 'string') {
primValue = ES.Call(trimShim, primValue);
if (isBinary(primValue)) {
primValue = parseInt(_strSlice(primValue, 2), 2);
} else if (isOctal(primValue)) {
primValue = parseInt(_strSlice(primValue, 2), 8);
} else if (hasNonWS(primValue) || isBadHex(primValue)) {
primValue = NaN;
}