diff options
Diffstat (limited to 'js/vendor/es6-shim/es6-shim.js')
-rw-r--r-- | js/vendor/es6-shim/es6-shim.js | 836 |
1 files changed, 440 insertions, 396 deletions
diff --git a/js/vendor/es6-shim/es6-shim.js b/js/vendor/es6-shim/es6-shim.js index 6d2160f12..f9bf1991c 100644 --- a/js/vendor/es6-shim/es6-shim.js +++ b/js/vendor/es6-shim/es6-shim.js @@ -27,59 +27,66 @@ }(this, function () { 'use strict'; - var isCallableWithoutNew = function (func) { + var not = function notThunker(func) { + return function notThunk() { return !func.apply(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; } - return true; }; + var isCallableWithoutNew = not(throwsError); + var supportsSubclassing = function (C, f) { - /* jshint proto:true */ - try { - var Sub = function () { C.apply(this, arguments); }; - if (!Sub.__proto__) { return false; /* skip test on IE < 11 */ } - Object.setPrototypeOf(Sub, C); - Sub.prototype = Object.create(C.prototype, { + 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; + }; + Sub.prototype = create(C.prototype, { constructor: { value: C } }); return f(Sub); - } catch (e) { - return false; - } + }); }; var arePropertyDescriptorsSupported = function () { - try { - Object.defineProperty({}, 'x', {}); - return true; - } catch (e) { /* this is IE 8. */ - return false; - } + // if Object.defineProperty exists but throws, it's IE 8 + return !throwsError(function () { Object.defineProperty({}, 'x', {}); }); }; var startsWithRejectsRegex = function () { - var rejectsRegex = false; - if (String.prototype.startsWith) { - try { - '/a/'.startsWith(/a/); - } catch (e) { /* this is spec compliant */ - rejectsRegex = true; - } - } - return rejectsRegex; + return String.prototype.startsWith && throwsError(function () { + /* throws if spec-compliant */ + '/a/'.startsWith(/a/); + }); }; + var startsWithHandlesInfinity = (function () { + return String.prototype.startsWith && 'abc'.startsWith('a', Infinity) === false; + }()); /*jshint evil: true */ var getGlobal = new Function('return this;'); /*jshint evil: false */ var globals = getGlobal(); - var global_isFinite = globals.isFinite; + var globalIsFinite = globals.isFinite; var supportsDescriptors = !!Object.defineProperty && arePropertyDescriptorsSupported(); - var startsWithIsCompliant = startsWithRejectsRegex(); + var hasStrictMode = (function () { return this === null; }.call(null)); + var startsWithIsCompliant = startsWithRejectsRegex() && startsWithHandlesInfinity; var _indexOf = Function.call.bind(String.prototype.indexOf); var _toString = Function.call.bind(Object.prototype.toString); var _hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty); @@ -99,6 +106,18 @@ } }; + 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 defineProperty = function (object, name, value, force) { if (!force && name in object) { return; } if (supportsDescriptors) { @@ -263,8 +282,8 @@ ToInteger: function (value) { var number = ES.ToNumber(value); - if (Number.isNaN(number)) { return 0; } - if (number === 0 || !Number.isFinite(number)) { return number; } + if (numberIsNaN(number)) { return 0; } + if (number === 0 || !numberIsFinite(number)) { return number; } return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); }, @@ -281,12 +300,12 @@ if (a === 0) { return 1 / a === 1 / b; } return true; } - return Number.isNaN(a) && Number.isNaN(b); + return numberIsNaN(a) && numberIsNaN(b); }, SameValueZero: function (a, b) { // same as SameValue except for SameValueZero(+0, -0) == true - return (a === b) || (Number.isNaN(a) && Number.isNaN(b)); + return (a === b) || (numberIsNaN(a) && numberIsNaN(b)); }, IsIterable: function (o) { @@ -363,146 +382,14 @@ return o; }; + // 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 = Function.apply.bind(String.fromCodePoint); + defineProperty(String, 'fromCodePoint', function fromCodePoint(codePoints) { return originalFromCodePoint(this, arguments); }, true); + } - var numberConversion = (function () { - // from https://github.com/inexorabletash/polyfill/blob/master/typedarray.js#L176-L266 - // with permission and license, per https://twitter.com/inexorabletash/status/372206509540659200 - - function roundToEven(n) { - var w = Math.floor(n), f = n - w; - if (f < 0.5) { - return w; - } - if (f > 0.5) { - return w + 1; - } - return w % 2 ? w + 1 : w; - } - - function packIEEE754(v, ebits, fbits) { - var bias = (1 << (ebits - 1)) - 1, - s, e, f, - i, bits, str, bytes; - - // Compute sign, exponent, fraction - if (v !== v) { - // NaN - // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping - e = (1 << ebits) - 1; - f = Math.pow(2, fbits - 1); - s = 0; - } else if (v === Infinity || v === -Infinity) { - e = (1 << ebits) - 1; - f = 0; - s = (v < 0) ? 1 : 0; - } else if (v === 0) { - e = 0; - f = 0; - s = (1 / v === -Infinity) ? 1 : 0; - } else { - s = v < 0; - v = Math.abs(v); - - if (v >= Math.pow(2, 1 - bias)) { - e = Math.min(Math.floor(Math.log(v) / Math.LN2), 1023); - f = roundToEven(v / Math.pow(2, e) * Math.pow(2, fbits)); - if (f / Math.pow(2, fbits) >= 2) { - e = e + 1; - f = 1; - } - if (e > bias) { - // Overflow - e = (1 << ebits) - 1; - f = 0; - } else { - // Normal - e = e + bias; - f = f - Math.pow(2, fbits); - } - } else { - // Subnormal - e = 0; - f = roundToEven(v / Math.pow(2, 1 - bias - fbits)); - } - } - - // Pack sign, exponent, fraction - bits = []; - for (i = fbits; i; i -= 1) { - bits.push(f % 2 ? 1 : 0); - f = Math.floor(f / 2); - } - for (i = ebits; i; i -= 1) { - bits.push(e % 2 ? 1 : 0); - e = Math.floor(e / 2); - } - bits.push(s ? 1 : 0); - bits.reverse(); - str = bits.join(''); - - // Bits to bytes - bytes = []; - while (str.length) { - bytes.push(parseInt(str.slice(0, 8), 2)); - str = str.slice(8); - } - return bytes; - } - - function unpackIEEE754(bytes, ebits, fbits) { - // Bytes to bits - var bits = [], i, j, b, str, - bias, s, e, f; - - for (i = bytes.length; i; i -= 1) { - b = bytes[i - 1]; - for (j = 8; j; j -= 1) { - bits.push(b % 2 ? 1 : 0); - b = b >> 1; - } - } - bits.reverse(); - str = bits.join(''); - - // Unpack sign, exponent, fraction - bias = (1 << (ebits - 1)) - 1; - s = parseInt(str.slice(0, 1), 2) ? -1 : 1; - e = parseInt(str.slice(1, 1 + ebits), 2); - f = parseInt(str.slice(1 + ebits), 2); - - // Produce number - if (e === (1 << ebits) - 1) { - return f !== 0 ? NaN : s * Infinity; - } else if (e > 0) { - // Normalized - return s * Math.pow(2, e - bias) * (1 + f / Math.pow(2, fbits)); - } else if (f !== 0) { - // Denormalized - return s * Math.pow(2, -(bias - 1)) * (f / Math.pow(2, fbits)); - } else { - return s < 0 ? -0 : 0; - } - } - - function unpackFloat64(b) { return unpackIEEE754(b, 11, 52); } - function packFloat64(v) { return packIEEE754(v, 11, 52); } - function unpackFloat32(b) { return unpackIEEE754(b, 8, 23); } - function packFloat32(v) { return packIEEE754(v, 8, 23); } - - var conversions = { - toFloat32: function (num) { return unpackFloat32(packFloat32(num)); } - }; - if (typeof Float32Array !== 'undefined') { - var float32array = new Float32Array(1); - conversions.toFloat32 = function (num) { - float32array[0] = num; - return float32array[0]; - }; - } - return conversions; - }()); - - defineProperties(String, { + var StringShims = { fromCodePoint: function fromCodePoint(codePoints) { var result = []; var next; @@ -525,8 +412,7 @@ raw: function raw(callSite) { var cooked = ES.ToObject(callSite, 'bad callSite'); - var rawValue = cooked.raw; - var rawString = ES.ToObject(rawValue, 'bad raw value'); + var rawString = ES.ToObject(cooked.raw, 'bad raw value'); var len = rawString.length; var literalsegments = ES.ToLength(len); if (literalsegments <= 0) { @@ -538,8 +424,7 @@ var nextKey, next, nextSeg, nextSub; while (nextIndex < literalsegments) { nextKey = String(nextIndex); - next = rawString[nextKey]; - nextSeg = String(next); + nextSeg = String(rawString[nextKey]); stringElements.push(nextSeg); if (nextIndex + 1 >= literalsegments) { break; @@ -551,13 +436,13 @@ } return stringElements.join(''); } - }); - - // Firefox 31 reports this function's length as 0 - // https://bugzilla.mozilla.org/show_bug.cgi?id=1062484 - if (String.fromCodePoint.length !== 1) { - var originalFromCodePoint = Function.apply.bind(String.fromCodePoint); - defineProperty(String, 'fromCodePoint', function fromCodePoint(codePoints) { return originalFromCodePoint(this, arguments); }, true); + }; + defineProperties(String, StringShims); + if (String.raw({ raw: { 0: 'x', 1: 'y', length: 2 } }) !== 'xy') { + // IE 11 TP has a broken String.raw implementation + var origStringRaw = String.raw; + defineProperty(String, 'raw', StringShims.raw, true); + Value.preserveToString(String.raw, origStringRaw); } // Fast repeat, uses the `Exponentiation by squaring` algorithm. @@ -570,7 +455,7 @@ }; var stringMaxLength = Infinity; - var StringShims = { + var StringPrototypeShims = { repeat: function repeat(times) { ES.RequireObjectCoercible(this); var thisStr = String(this); @@ -581,7 +466,7 @@ return stringRepeat(thisStr, times); }, - startsWith: function (searchStr) { + startsWith: function startsWith(searchStr) { ES.RequireObjectCoercible(this); var thisStr = String(this); if (Type.regex(searchStr)) { @@ -593,7 +478,7 @@ return thisStr.slice(start, start + searchStr.length) === searchStr; }, - endsWith: function (searchStr) { + endsWith: function endsWith(searchStr) { ES.RequireObjectCoercible(this); var thisStr = String(this); if (Type.regex(searchStr)) { @@ -613,7 +498,7 @@ return _indexOf(this, searchString, position) !== -1; }, - codePointAt: function (pos) { + codePointAt: function codePointAt(pos) { ES.RequireObjectCoercible(this); var thisStr = String(this); var position = ES.ToInteger(pos); @@ -628,7 +513,13 @@ } } }; - defineProperties(String.prototype, StringShims); + defineProperties(String.prototype, StringPrototypeShims); + + if ('a'.includes('a', Infinity) !== false) { + var origIncludes = String.prototype.includes; + defineProperty(String.prototype, 'includes', StringPrototypeShims.includes, true); + Value.preserveToString(String.prototype.includes, origIncludes); + } var hasStringTrimBug = '\u0085'.trim().length !== 1; if (hasStringTrimBug) { @@ -642,7 +533,7 @@ ].join(''); var trimRegexp = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g'); defineProperties(String.prototype, { - trim: function () { + trim: function trim() { if (typeof this === 'undefined' || this === null) { throw new TypeError("can't convert " + this + ' to object'); } @@ -679,9 +570,9 @@ }); if (!startsWithIsCompliant) { - // Firefox has a noncompliant startsWith implementation - defineProperty(String.prototype, 'startsWith', StringShims.startsWith, true); - defineProperty(String.prototype, 'endsWith', StringShims.endsWith, true); + // Firefox (< 37?) and IE 11 TP have a noncompliant startsWith implementation + defineProperty(String.prototype, 'startsWith', StringPrototypeShims.startsWith, true); + defineProperty(String.prototype, 'endsWith', StringPrototypeShims.endsWith, true); } var ArrayShims = { @@ -745,23 +636,10 @@ }; defineProperties(Array, ArrayShims); - var arrayFromSwallowsNegativeLengths = function () { - try { - return Array.from({ length: -1 }).length === 0; - } catch (e) { - return false; - } - }; - // Fixes a Firefox bug in v32 - // https://bugzilla.mozilla.org/show_bug.cgi?id=1063993 - if (!arrayFromSwallowsNegativeLengths()) { - defineProperty(Array, 'from', ArrayShims.from, true); - } - // 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 iterator_result = function (x) { + var iteratorResult = function (x) { return { value: x, done: arguments.length === 0 }; }; @@ -843,19 +721,33 @@ } if (this.kind === 'key') { - return iterator_result(key); + return iteratorResult(key); } else if (this.kind === 'value') { - return iterator_result(this.object[key]); + return iteratorResult(this.object[key]); } else { - return iterator_result([key, this.object[key]]); + return iteratorResult([key, this.object[key]]); } } - return iterator_result(); + return iteratorResult(); } }); addIterator(ObjectIterator.prototype); + // note: this is positioned here because it depends on ArrayIterator + var arrayOfSupportsSubclassing = (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) { + var origArrayOf = Array.of; + defineProperty(Array, 'of', ArrayShims.of, true); + Value.preserveToString(Array.of, origArrayOf); + } + var ArrayPrototypeShims = { copyWithin: function copyWithin(target, start) { var end = arguments[2]; // copyWithin.length must be 2 @@ -984,6 +876,23 @@ addIterator(Object.getPrototypeOf([].values())); } + // 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 && arr[0][0] === 0 && arr[0][1] === 1; + }()); + if (!arrayFromSwallowsNegativeLengths() || !arrayFromHandlesIterables) { + var origArrayFrom = Array.from; + defineProperty(Array, 'from', ArrayShims.from, true); + Value.preserveToString(Array.from, origArrayFrom); + } + var maxSafeInteger = Math.pow(2, 53) - 1; defineProperties(Number, { MAX_SAFE_INTEGER: maxSafeInteger, @@ -993,26 +902,17 @@ parseInt: globals.parseInt, parseFloat: globals.parseFloat, - isFinite: function (value) { - return typeof value === 'number' && global_isFinite(value); - }, + isFinite: numberIsFinite, - isInteger: function (value) { - return Number.isFinite(value) && ES.ToInteger(value) === value; + isInteger: function isInteger(value) { + return numberIsFinite(value) && ES.ToInteger(value) === value; }, - isSafeInteger: function (value) { + isSafeInteger: function isSafeInteger(value) { return Number.isInteger(value) && Math.abs(value) <= Number.MAX_SAFE_INTEGER; }, - isNaN: function (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; - } + isNaN: numberIsNaN }); // Work around bugs in Array#find and Array#findIndex -- early @@ -1028,23 +928,32 @@ } /*jshint elision: false */ + defineProperties(Object, { + is: function is(a, b) { + return ES.SameValue(a, b); + } + }); + if (supportsDescriptors) { - defineProperties(Object, { + var isEnumerableOn = Function.bind.call(Function.bind, Object.prototype.propertyIsEnumerable); + var assignReducer = function (target, source) { + var keys = Object.keys(Object(source)); + var symbols; + if (ES.IsCallable(Object.getOwnPropertySymbols)) { + symbols = Object.getOwnPropertySymbols(Object(source)).filter(isEnumerableOn(source)); + } + return keys.concat(symbols || []).reduce(function (target, key) { + target[key] = source[key]; + return target; + }, target); + }; + var ObjectShims = { // 19.1.3.1 assign: function (target, source) { if (!ES.TypeIsObject(target)) { throw new TypeError('target must be an object'); } - return Array.prototype.reduce.call(arguments, function (target, source) { - return Object.keys(Object(source)).reduce(function (target, key) { - target[key] = source[key]; - return target; - }, target); - }); - }, - - is: function (a, b) { - return ES.SameValue(a, b); + return Array.prototype.reduce.call(arguments, assignReducer); }, // 19.1.3.9 @@ -1099,7 +1008,24 @@ } return setPrototypeOf; }(Object, '__proto__')) - }); + }; + + var assignHasPendingExceptions = Object.assign && Object.preventExtensions && (function () { + // Firefox 37 still has "pending exception" logic in its Object.assign implementation, + // which is 72% slower than our shim, and Firefox 40's native implementation. + var thrower = Object.preventExtensions({ 1: 2 }); + try { + Object.assign(thrower, 'xy'); + } catch (e) { + return thrower[1] === 'y'; + } + }()); + if (assignHasPendingExceptions) { + var origAssign = Object.assign; + defineProperty(Object, 'assign', ObjectShims.assign, true); + Value.preserveToString(Object.assign, origAssign); + } + defineProperties(Object, ObjectShims); } // Workaround bug in Opera 12 where setPrototypeOf(x, null) doesn't work, @@ -1122,14 +1048,7 @@ }()); } - var objectKeysAcceptsPrimitives = (function () { - try { - Object.keys('foo'); - return true; - } catch (e) { - return false; - } - }()); + var objectKeysAcceptsPrimitives = !throwsError(function () { Object.keys('foo'); }); if (!objectKeysAcceptsPrimitives) { var originalObjectKeys = Object.keys; defineProperty(Object, 'keys', function keys(value) { @@ -1139,14 +1058,7 @@ } if (Object.getOwnPropertyNames) { - var objectGOPNAcceptsPrimitives = (function () { - try { - Object.getOwnPropertyNames('foo'); - return true; - } catch (e) { - return false; - } - }()); + var objectGOPNAcceptsPrimitives = !throwsError(function () { Object.getOwnPropertyNames('foo'); }); if (!objectGOPNAcceptsPrimitives) { var originalObjectGetOwnPropertyNames = Object.getOwnPropertyNames; defineProperty(Object, 'getOwnPropertyNames', function getOwnPropertyNames(value) { @@ -1156,14 +1068,7 @@ } } if (Object.getOwnPropertyDescriptor) { - var objectGOPDAcceptsPrimitives = (function () { - try { - Object.getOwnPropertyDescriptor('foo', 'bar'); - return true; - } catch (e) { - return false; - } - }()); + var objectGOPDAcceptsPrimitives = !throwsError(function () { Object.getOwnPropertyDescriptor('foo', 'bar'); }); if (!objectGOPDAcceptsPrimitives) { var originalObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; defineProperty(Object, 'getOwnPropertyDescriptor', function getOwnPropertyDescriptor(value, property) { @@ -1173,14 +1078,7 @@ } } if (Object.seal) { - var objectSealAcceptsPrimitives = (function () { - try { - Object.seal('foo'); - return true; - } catch (e) { - return false; - } - }()); + var objectSealAcceptsPrimitives = !throwsError(function () { Object.seal('foo'); }); if (!objectSealAcceptsPrimitives) { var originalObjectSeal = Object.seal; defineProperty(Object, 'seal', function seal(value) { @@ -1191,14 +1089,7 @@ } } if (Object.isSealed) { - var objectIsSealedAcceptsPrimitives = (function () { - try { - Object.isSealed('foo'); - return true; - } catch (e) { - return false; - } - }()); + var objectIsSealedAcceptsPrimitives = !throwsError(function () { Object.isSealed('foo'); }); if (!objectIsSealedAcceptsPrimitives) { var originalObjectIsSealed = Object.isSealed; defineProperty(Object, 'isSealed', function isSealed(value) { @@ -1209,14 +1100,7 @@ } } if (Object.freeze) { - var objectFreezeAcceptsPrimitives = (function () { - try { - Object.freeze('foo'); - return true; - } catch (e) { - return false; - } - }()); + var objectFreezeAcceptsPrimitives = !throwsError(function () { Object.freeze('foo'); }); if (!objectFreezeAcceptsPrimitives) { var originalObjectFreeze = Object.freeze; defineProperty(Object, 'freeze', function freeze(value) { @@ -1227,14 +1111,7 @@ } } if (Object.isFrozen) { - var objectIsFrozenAcceptsPrimitives = (function () { - try { - Object.isFrozen('foo'); - return true; - } catch (e) { - return false; - } - }()); + var objectIsFrozenAcceptsPrimitives = !throwsError(function () { Object.isFrozen('foo'); }); if (!objectIsFrozenAcceptsPrimitives) { var originalObjectIsFrozen = Object.isFrozen; defineProperty(Object, 'isFrozen', function isFrozen(value) { @@ -1245,14 +1122,7 @@ } } if (Object.preventExtensions) { - var objectPreventExtensionsAcceptsPrimitives = (function () { - try { - Object.preventExtensions('foo'); - return true; - } catch (e) { - return false; - } - }()); + var objectPreventExtensionsAcceptsPrimitives = !throwsError(function () { Object.preventExtensions('foo'); }); if (!objectPreventExtensionsAcceptsPrimitives) { var originalObjectPreventExtensions = Object.preventExtensions; defineProperty(Object, 'preventExtensions', function preventExtensions(value) { @@ -1263,14 +1133,7 @@ } } if (Object.isExtensible) { - var objectIsExtensibleAcceptsPrimitives = (function () { - try { - Object.isExtensible('foo'); - return true; - } catch (e) { - return false; - } - }()); + var objectIsExtensibleAcceptsPrimitives = !throwsError(function () { Object.isExtensible('foo'); }); if (!objectIsExtensibleAcceptsPrimitives) { var originalObjectIsExtensible = Object.isExtensible; defineProperty(Object, 'isExtensible', function isExtensible(value) { @@ -1281,14 +1144,7 @@ } } if (Object.getPrototypeOf) { - var objectGetProtoAcceptsPrimitives = (function () { - try { - Object.getPrototypeOf('foo'); - return true; - } catch (e) { - return false; - } - }()); + var objectGetProtoAcceptsPrimitives = !throwsError(function () { Object.getPrototypeOf('foo'); }); if (!objectGetProtoAcceptsPrimitives) { var originalGetProto = Object.getPrototypeOf; defineProperty(Object, 'getPrototypeOf', function getPrototypeOf(value) { @@ -1325,13 +1181,9 @@ Value.getter(RegExp.prototype, 'flags', regExpFlagsGetter); } - var regExpSupportsFlagsWithRegex = (function () { - try { - return String(new RegExp(/a/g, 'i')) === '/a/i'; - } catch (e) { - return false; - } - }()); + var regExpSupportsFlagsWithRegex = valueOrFalseIfThrows(function () { + return String(new RegExp(/a/g, 'i')) === '/a/i'; + }); if (!regExpSupportsFlagsWithRegex && supportsDescriptors) { var OrigRegExp = RegExp; @@ -1359,8 +1211,36 @@ /*globals RegExp: false */ } + if (supportsDescriptors) { + var regexGlobals = { + input: '$_', + lastMatch: '$&', + lastParen: '$+', + leftContext: '$`', + rightContext: '$\'' + }; + Object.keys(regexGlobals).forEach(function (prop) { + if (prop in RegExp && !(regexGlobals[prop] in RegExp)) { + Value.getter(RegExp, regexGlobals[prop], function get() { + return RegExp[prop]; + }); + } + }); + } + + var square = function (n) { return n * n; }; + var add = function (a, b) { return a + b; }; + var inverseEpsilon = 1 / Number.EPSILON; + var roundTiesToEven = function roundTiesToEven(n) { + // Even though this reduces down to `return n`, it takes advantage of built-in rounding. + return (n + inverseEpsilon) - inverseEpsilon; + }; + var BINARY_32_EPSILON = Math.pow(2, -23); + var BINARY_32_MAX_VALUE = Math.pow(2, 127) * (2 - BINARY_32_EPSILON); + var BINARY_32_MIN_VALUE = Math.pow(2, -126); + var MathShims = { - acosh: function (value) { + acosh: function acosh(value) { var x = Number(value); if (Number.isNaN(x) || value < 1) { return NaN; } if (x === 1) { return 0; } @@ -1368,15 +1248,15 @@ return Math.log(x / Math.E + Math.sqrt(x + 1) * Math.sqrt(x - 1) / Math.E) + 1; }, - asinh: function (value) { + asinh: function asinh(value) { value = Number(value); - if (value === 0 || !global_isFinite(value)) { + if (value === 0 || !globalIsFinite(value)) { return value; } return value < 0 ? -Math.asinh(-value) : Math.log(value + Math.sqrt(value * value + 1)); }, - atanh: function (value) { + atanh: function atanh(value) { value = Number(value); if (Number.isNaN(value) || value < -1 || value > 1) { return NaN; @@ -1387,7 +1267,7 @@ return 0.5 * Math.log((1 + value) / (1 - value)); }, - cbrt: function (value) { + cbrt: function cbrt(value) { value = Number(value); if (value === 0) { return value; } var negate = value < 0, result; @@ -1396,30 +1276,30 @@ return negate ? -result : result; }, - clz32: function (value) { + clz32: function clz32(value) { // See https://bugs.ecmascript.org/show_bug.cgi?id=2465 value = Number(value); var number = ES.ToUint32(value); if (number === 0) { return 32; } - return 32 - (number).toString(2).length; + return 31 - Math.floor(Math.log(number + 0.5) * Math.LOG2E); }, - cosh: function (value) { + cosh: function cosh(value) { value = Number(value); if (value === 0) { return 1; } // +0 or -0 if (Number.isNaN(value)) { return NaN; } - if (!global_isFinite(value)) { return Infinity; } + if (!globalIsFinite(value)) { return Infinity; } if (value < 0) { value = -value; } if (value > 21) { return Math.exp(value) / 2; } return (Math.exp(value) + Math.exp(-value)) / 2; }, - expm1: function (value) { + expm1: function expm1(value) { var x = Number(value); if (x === -Infinity) { return -1; } - if (!global_isFinite(x) || value === 0) { return x; } + if (!globalIsFinite(x) || value === 0) { return x; } if (Math.abs(x) > 0.5) { return Math.exp(x) - 1; } @@ -1436,7 +1316,7 @@ return sum; }, - hypot: function (x, y) { + hypot: function hypot(x, y) { var anyNaN = false; var allZero = true; var anyInfinity = false; @@ -1461,22 +1341,21 @@ if (anyNaN) { return NaN; } if (allZero) { return 0; } - numbers.sort(function (a, b) { return b - a; }); - var largest = numbers[0]; + var largest = Math.max.apply(Math, numbers); var divided = numbers.map(function (number) { return number / largest; }); - var sum = divided.reduce(function (sum, number) { return sum + (number * number); }, 0); + var sum = divided.map(square).reduce(add); return largest * Math.sqrt(sum); }, - log2: function (value) { + log2: function log2(value) { return Math.log(value) * Math.LOG2E; }, - log10: function (value) { + log10: function log10(value) { return Math.log(value) * Math.LOG10E; }, - log1p: function (value) { + log1p: function log1p(value) { var x = Number(value); if (x < -1 || Number.isNaN(x)) { return NaN; } if (x === 0 || x === Infinity) { return x; } @@ -1485,16 +1364,16 @@ return (1 + x) - 1 === 0 ? x : x * (Math.log(1 + x) / ((1 + x) - 1)); }, - sign: function (value) { + sign: function sign(value) { var number = +value; if (number === 0) { return number; } if (Number.isNaN(number)) { return number; } return number < 0 ? -1 : 1; }, - sinh: function (value) { + sinh: function sinh(value) { var x = Number(value); - if (!global_isFinite(value) || value === 0) { return value; } + if (!globalIsFinite(value) || value === 0) { return value; } if (Math.abs(x) < 1) { return (Math.expm1(x) - Math.expm1(-x)) / 2; @@ -1502,7 +1381,7 @@ return (Math.exp(x - 1) - Math.exp(-x - 1)) * Math.E / 2; }, - tanh: function (value) { + tanh: function tanh(value) { var x = Number(value); if (Number.isNaN(value) || x === 0) { return x; } if (x === Infinity) { return 1; } @@ -1514,12 +1393,12 @@ return (a - b) / (Math.exp(x) + Math.exp(-x)); }, - trunc: function (value) { + trunc: function trunc(value) { var number = Number(value); return number < 0 ? -Math.floor(-number) : Math.fl |