diff options
Diffstat (limited to 'js/vendor/es6-shim/es6-shim.js')
-rw-r--r-- | js/vendor/es6-shim/es6-shim.js | 1928 |
1 files changed, 1928 insertions, 0 deletions
diff --git a/js/vendor/es6-shim/es6-shim.js b/js/vendor/es6-shim/es6-shim.js new file mode 100644 index 000000000..5ac65e8c7 --- /dev/null +++ b/js/vendor/es6-shim/es6-shim.js @@ -0,0 +1,1928 @@ +// ES6-shim 0.18.0 (c) 2013-2014 Paul Miller (http://paulmillr.com) +// ES6-shim may be freely distributed under the MIT license. +// For more details and documentation: +// https://github.com/paulmillr/es6-shim/ + +(function(undefined) { + 'use strict'; + + var isCallableWithoutNew = function(func) { + try { func(); } + catch (e) { return false; } + return true; + }; + + 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, { + 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; + } + }; + + var startsWithRejectsRegex = function() { + var rejectsRegex = false; + if (String.prototype.startsWith) { + try { + '/a/'.startsWith(/a/); + } catch (e) { /* this is spec compliant */ + rejectsRegex = true; + } + } + return rejectsRegex; + }; + + /*jshint evil: true */ + var getGlobal = new Function('return this;'); + /*jshint evil: false */ + + var main = function() { + var globals = getGlobal(); + var global_isFinite = globals.isFinite; + var supportsDescriptors = !!Object.defineProperty && arePropertyDescriptorsSupported(); + var startsWithIsCompliant = startsWithRejectsRegex(); + var _slice = Array.prototype.slice; + var _indexOf = String.prototype.indexOf; + var _toString = Object.prototype.toString; + var _hasOwnProperty = Object.prototype.hasOwnProperty; + var ArrayIterator; // make our implementation private + + 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) { + Object.keys(map).forEach(function(name) { + var method = map[name]; + defineProperty(object, name, method, false); + }); + }; + + // Simple shim for Object.create on ES3 browsers + // (unlike real shim, no attempt to support `prototype === null`) + var create = Object.create || function(prototype, properties) { + function Type() {} + Type.prototype = prototype; + var object = new Type(); + if (typeof properties !== "undefined") { + defineProperties(object, properties); + } + return object; + }; + + // 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$ = (typeof Symbol === 'function' && Symbol.iterator) || + '_es6shim_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'; + } + var addIterator = function(prototype, impl) { + if (!impl) { impl = function iterator() { return this; }; } + var o = {}; + o[$iterator$] = impl; + defineProperties(prototype, o); + /* jshint notypeof: true */ + if (!prototype[$iterator$] && typeof $iterator$ === 'symbol') { + // implementations are buggy when $iterator$ is a Symbol + prototype[$iterator$] = impl; + } + }; + + // 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 isArguments = function isArguments(value) { + var str = _toString.call(value); + var result = str === '[object Arguments]'; + if (!result) { + result = str !== '[object Array]' && + value !== null && + typeof value === 'object' && + typeof value.length === 'number' && + value.length >= 0 && + _toString.call(value.callee) === '[object Function]'; + } + return result; + }; + + var emulateES6construct = function(o) { + if (!ES.TypeIsObject(o)) throw new TypeError('bad object'); + // es5 approximation to es6 subclass semantics: in es6, 'new Foo' + // would invoke Foo.@@create to allocation/initialize the new object. + // In es5 we just get the plain object. So if we detect an + // uninitialized object, invoke o.constructor.@@create + if (!o._es6construct) { + if (o.constructor && ES.IsCallable(o.constructor['@@create'])) { + o = o.constructor['@@create'](o); + } + defineProperties(o, { _es6construct: true }); + } + return o; + }; + + var ES = { + CheckObjectCoercible: function(x, optMessage) { + /* jshint eqnull:true */ + if (x == null) + throw new TypeError(optMessage || ('Cannot call method on ' + x)); + return x; + }, + + TypeIsObject: function(x) { + /* jshint eqnull:true */ + // this is expensive when it returns false; use this function + // when you expect it to return true in the common case. + return x != null && Object(x) === x; + }, + + ToObject: function(o, optMessage) { + return Object(ES.CheckObjectCoercible(o, optMessage)); + }, + + IsCallable: function(x) { + return typeof x === 'function' && + // some versions of IE say that typeof /abc/ === 'function' + _toString.call(x) === '[object Function]'; + }, + + ToInt32: function(x) { + return x >> 0; + }, + + ToUint32: function(x) { + return x >>> 0; + }, + + ToInteger: function(value) { + var number = +value; + if (Number.isNaN(number)) return 0; + if (number === 0 || !Number.isFinite(number)) return number; + return (number > 0 ? 1 : -1) * Math.floor(Math.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 Number.isNaN(a) && Number.isNaN(b); + }, + + SameValueZero: function(a, b) { + // same as SameValue except for SameValueZero(+0, -0) == true + return (a === b) || (Number.isNaN(a) && Number.isNaN(b)); + }, + + IsIterable: function(o) { + return ES.TypeIsObject(o) && + (o[$iterator$] !== undefined || isArguments(o)); + }, + + GetIterator: function(o) { + if (isArguments(o)) { + // special case support for `arguments` + return new ArrayIterator(o, "value"); + } + var it = o[$iterator$](); + if (!ES.TypeIsObject(it)) { + throw new TypeError('bad iterator'); + } + return it; + }, + + 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; + }, + + Construct: function(C, args) { + // CreateFromConstructor + var obj; + if (ES.IsCallable(C['@@create'])) { + obj = C['@@create'](); + } else { + // OrdinaryCreateFromConstructor + obj = create(C.prototype || null); + } + // Mark that we've used the es6 construct path + // (see emulateES6construct) + defineProperties(obj, { _es6construct: true }); + // Call the constructor. + var result = C.apply(obj, args); + return ES.TypeIsObject(result) ? result : obj; + } + }; + + 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, ln, + 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, { + fromCodePoint: function(_) { // length = 1 + var points = _slice.call(arguments, 0, arguments.length); + var result = []; + var next; + for (var i = 0, length = points.length; i < length; i++) { + next = Number(points[i]); + if (!ES.SameValue(next, ES.ToInteger(next)) || + next < 0 || next > 0x10FFFF) { + throw new RangeError('Invalid code point ' + next); + } + + if (next < 0x10000) { + result.push(String.fromCharCode(next)); + } else { + next -= 0x10000; + result.push(String.fromCharCode((next >> 10) + 0xD800)); + result.push(String.fromCharCode((next % 0x400) + 0xDC00)); + } + } + return result.join(''); + }, + + raw: function(callSite) { // raw.length===1 + var substitutions = _slice.call(arguments, 1, arguments.length); + var cooked = ES.ToObject(callSite, 'bad callSite'); + var rawValue = cooked.raw; + var raw = ES.ToObject(rawValue, 'bad raw value'); + var len = Object.keys(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 = String(nextIndex); + next = raw[nextKey]; + nextSeg = String(next); + stringElements.push(nextSeg); + if (nextIndex + 1 >= literalsegments) { + break; + } + next = substitutions[nextKey]; + if (next === undefined) { + break; + } + nextSub = String(next); + stringElements.push(nextSub); + nextIndex++; + } + 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 = String.fromCodePoint; + defineProperty(String, 'fromCodePoint', function (_) { return originalFromCodePoint.apply(this, arguments); }, true); + } + + var StringShims = { + // Fast repeat, uses the `Exponentiation by squaring` algorithm. + // Perf: http://jsperf.com/string-repeat2/2 + repeat: (function() { + var repeat = function(s, times) { + if (times < 1) return ''; + if (times % 2) return repeat(s, times - 1) + s; + var half = repeat(s, times / 2); + return half + half; + }; + + return function(times) { + var thisStr = String(ES.CheckObjectCoercible(this)); + times = ES.ToInteger(times); + if (times < 0 || times === Infinity) { + throw new RangeError('Invalid String#repeat value'); + } + return repeat(thisStr, times); + }; + })(), + + startsWith: function(searchStr) { + var thisStr = String(ES.CheckObjectCoercible(this)); + if (_toString.call(searchStr) === '[object RegExp]') throw new TypeError('Cannot call method "startsWith" with a regex'); + searchStr = String(searchStr); + var startArg = arguments.length > 1 ? arguments[1] : undefined; + var start = Math.max(ES.ToInteger(startArg), 0); + return thisStr.slice(start, start + searchStr.length) === searchStr; + }, + + endsWith: function(searchStr) { + var thisStr = String(ES.CheckObjectCoercible(this)); + if (_toString.call(searchStr) === '[object RegExp]') throw new TypeError('Cannot call method "endsWith" with a regex'); + searchStr = String(searchStr); + var thisLen = thisStr.length; + var posArg = arguments.length > 1 ? arguments[1] : undefined; + var pos = posArg === undefined ? thisLen : ES.ToInteger(posArg); + var end = Math.min(Math.max(pos, 0), thisLen); + return thisStr.slice(end - searchStr.length, end) === searchStr; + }, + + contains: function(searchString) { + var position = arguments.length > 1 ? arguments[1] : undefined; + // Somehow this trick makes method 100% compat with the spec. + return _indexOf.call(this, searchString, position) !== -1; + }, + + codePointAt: function(pos) { + var thisStr = String(ES.CheckObjectCoercible(this)); + var position = ES.ToInteger(pos); + var length = thisStr.length; + if (position < 0 || position >= length) return undefined; + 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; + } + }; + defineProperties(String.prototype, StringShims); + + var hasStringTrimBug = '\u0085'.trim().length !== 1; + if (hasStringTrimBug) { + var originalStringTrim = String.prototype.trim; + delete String.prototype.trim; + // 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'); + defineProperties(String.prototype, { + trim: function() { + if (this === undefined || this === null) { + throw new TypeError("can't convert " + this + " to object"); + } + return String(this).replace(trimRegexp, ""); + } + }); + } + + // see https://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype-@@iterator + var StringIterator = function(s) { + this._s = String(ES.CheckObjectCoercible(s)); + this._i = 0; + }; + StringIterator.prototype.next = function() { + var s = this._s, i = this._i; + if (s === undefined || i >= s.length) { + this._s = undefined; + return { value: undefined, done: true }; + } + var first = s.charCodeAt(i), 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 { value: s.substr(i, len), done: false }; + }; + addIterator(StringIterator.prototype); + addIterator(String.prototype, function() { + return new StringIterator(this); + }); + + if (!startsWithIsCompliant) { + // Firefox has a noncompliant startsWith implementation + String.prototype.startsWith = StringShims.startsWith; + String.prototype.endsWith = StringShims.endsWith; + } + + var ArrayShims = { + from: function(iterable) { + var mapFn = arguments.length > 1 ? arguments[1] : undefined; + + var list = ES.ToObject(iterable, 'bad iterable'); + if (mapFn !== undefined && !ES.IsCallable(mapFn)) { + throw new TypeError('Array.from: when provided, the second argument must be a function'); + } + + var hasThisArg = arguments.length > 2; + var thisArg = hasThisArg ? arguments[2] : undefined; + + var usingIterator = ES.IsIterable(list); + // does the spec really mean that Arrays should use ArrayIterator? + // https://bugs.ecmascript.org/show_bug.cgi?id=2416 + //if (Array.isArray(list)) { usingIterator=false; } + + var length; + var result, i, value; + if (usingIterator) { + i = 0; + result = ES.IsCallable(this) ? Object(new this()) : []; + var it = usingIterator ? ES.GetIterator(list) : null; + var iterationValue; + + do { + iterationValue = ES.IteratorNext(it); + if (!iterationValue.done) { + value = iterationValue.value; + if (mapFn) { + result[i] = hasThisArg ? mapFn.call(thisArg, value, i) : mapFn(value, i); + } else { + result[i] = value; + } + i += 1; + } + } while (!iterationValue.done); + length = i; + } else { + length = ES.ToLength(list.length); + result = ES.IsCallable(this) ? Object(new this(length)) : new Array(length); + for (i = 0; i < length; ++i) { + value = list[i]; + if (mapFn) { + result[i] = hasThisArg ? mapFn.call(thisArg, value, i) : mapFn(value, i); + } else { + result[i] = value; + } + } + } + + result.length = length; + return result; + }, + + of: function() { + return Array.from(arguments); + } + }; + 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); + } + + // Our ArrayIterator is private; see + // https://github.com/paulmillr/es6-shim/issues/252 + ArrayIterator = function(array, kind) { + this.i = 0; + this.array = array; + this.kind = kind; + }; + + defineProperties(ArrayIterator.prototype, { + next: function() { + var i = this.i, array = this.array; + if (!(this instanceof ArrayIterator)) { + throw new TypeError('Not an ArrayIterator'); + } + if (array !== undefined) { + var len = ES.ToLength(array.length); + 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 { value: retval, done: false }; + } + } + this.array = undefined; + return { value: undefined, done: true }; + } + }); + addIterator(ArrayIterator.prototype); + + var ArrayPrototypeShims = { + copyWithin: function(target, start) { + var end = arguments[2]; // copyWithin.length must be 2 + var o = ES.ToObject(this); + var len = ES.ToLength(o.length); + target = ES.ToInteger(target); + start = ES.ToInteger(start); + var to = target < 0 ? Math.max(len + target, 0) : Math.min(target, len); + var from = start < 0 ? Math.max(len + start, 0) : Math.min(start, len); + end = (end===undefined) ? len : ES.ToInteger(end); + var fin = end < 0 ? Math.max(len + end, 0) : Math.min(end, len); + var count = Math.min(fin - from, len - to); + var direction = 1; + if (from < to && to < (from + count)) { + direction = -1; + from += count - 1; + to += count - 1; + } + while (count > 0) { + if (_hasOwnProperty.call(o, from)) { + o[to] = o[from]; + } else { + delete o[from]; + } + from += direction; + to += direction; + count -= 1; + } + return o; + }, + + fill: function(value) { + var start = arguments.length > 1 ? arguments[1] : undefined; + var end = arguments.length > 2 ? arguments[2] : undefined; + var O = ES.ToObject(this); + var len = ES.ToLength(O.length); + start = ES.ToInteger(start === undefined ? 0 : start); + end = ES.ToInteger(end === undefined ? len : end); + + var relativeStart = start < 0 ? Math.max(len + start, 0) : Math.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[1]; + for (var i = 0, value; i < length; i++) { + value = list[i]; + if (predicate.call(thisArg, value, i, list)) { return value; } + } + return undefined; + }, + + 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[1]; + for (var i = 0; i < length; i++) { + if (predicate.call(thisArg, list[i], i, list)) { return i; } + } + return -1; + }, + + keys: function() { + return new ArrayIterator(this, "key"); + }, + + values: function() { + return new ArrayIterator(this, "value"); + }, + + entries: function() { + return new ArrayIterator(this, "entry"); + } + }; + defineProperties(Array.prototype, ArrayPrototypeShims); + 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) { + addIterator(Object.getPrototypeOf([].values())); + } + + var maxSafeInteger = Math.pow(2, 53) - 1; + defineProperties(Number, { + MAX_SAFE_INTEGER: maxSafeInteger, + MIN_SAFE_INTEGER: -maxSafeInteger, + EPSILON: 2.220446049250313e-16, + + parseInt: globals.parseInt, + parseFloat: globals.parseFloat, + + isFinite: function(value) { + return typeof value === 'number' && global_isFinite(value); + }, + + isInteger: function(value) { + return Number.isFinite(value) && + ES.ToInteger(value) === value; + }, + + isSafeInteger: function(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; + } + + }); + + // Work around bugs in Array#find and Array#findIndex -- early + // implementations skipped holes in sparse arrays. (Note that the + // implementations of find/findIndex indirectly use shimmed + // methods of Number, so this test has to happen down here.) + if (![, 1].find(function(item, idx) { return idx === 0; })) { + defineProperty(Array.prototype, 'find', ArrayPrototypeShims.find, true); + } + if ([, 1].findIndex(function(item, idx) { return idx === 0; }) !== 0) { + defineProperty(Array.prototype, 'findIndex', ArrayPrototypeShims.findIndex, true); + } + + if (supportsDescriptors) { + defineProperties(Object, { + getPropertyDescriptor: function(subject, name) { + var pd = Object.getOwnPropertyDescriptor(subject, name); + var proto = Object.getPrototypeOf(subject); + while (pd === undefined && proto !== null) { + pd = Object.getOwnPropertyDescriptor(proto, name); + proto = Object.getPrototypeOf(proto); + } + return pd; + }, + + getPropertyNames: function(subject) { + var result = Object.getOwnPropertyNames(subject); + var proto = Object.getPrototypeOf(subject); + + var addProperty = function(property) { + if (result.indexOf(property) === -1) { + result.push(property); + } + }; + + while (proto !== null) { + Object.getOwnPropertyNames(proto).forEach(addProperty); + proto = Object.getPrototypeOf(proto); + } + return result; + } + }); + + defineProperties(Object, { + // 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); + }, + + // 19.1.3.9 + // shim from https://gist.github.com/WebReflection/5593554 + setPrototypeOf: (function(Object, magic) { + var set; + + var checkArgs = function(O, proto) { + if (!ES.TypeIsObject(O)) { + throw new TypeError('cannot set prototype on a non-object'); + } + if (!(proto===null || ES.TypeIsObject(proto))) { + throw new TypeError('can only set prototype to an object or null'+proto); + } + }; + + var setPrototypeOf = function(O, proto) { + checkArgs(O, proto); + set.call(O, proto); + return O; + }; + + try { + // this works already in Firefox and Safari + set = Object.getOwnPropertyDescriptor(Object.prototype, magic).set; + set.call({}, null); + } catch (e) { + if (Object.prototype !== {}[magic]) { + // IE < 11 cannot be shimmed + return; + } + // probably Chrome or some old Mobile stock browser + set = function(proto) { + this[magic] = proto; + }; + // please note that this will **not** work + // in those browsers that do not inherit + // __proto__ by mistake from Object.prototype + // in these cases we should probably throw an error + // or at least be informed about the issue + se |