UNPKG

es6-shim

Version:

ECMAScript 6 (Harmony) compatibility shims for legacy JavaScript engines

1,411 lines (1,304 loc) 139 kB
/*! * 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, '&quot;'); 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; }