agenda-libre-ruby/public/webshims/shims/es6.js

1888 lines
55 KiB
JavaScript
Raw Normal View History

// ES6-shim 0.8.0 (c) 2013 Paul Miller (paulmillr.com)
// ES6-shim may be freely distributed under the MIT license.
// For more details and documentation:
// https://github.com/paulmillr/es6-shim/
webshim.register('es6', function($, webshim, window, document, 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
// Define configurable, writable and non-enumerable props
// if they dont exist.
var defineProperties = function(object, map) {
Object.keys(map).forEach(function(name) {
var method = map[name];
if (name in object) return;
if (supportsDescriptors) {
Object.defineProperty(object, name, {
configurable: true,
enumerable: false,
writable: true,
value: method
});
} else {
object[name] = method;
}
});
};
// 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 === 'object' && 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);
};
// 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 Math.sign(number) * 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.substring(0, 8), 2));
str = str.substring(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.substring(0, 1), 2) ? -1 : 1;
e = parseInt(str.substring(1, 1 + ebits), 2);
f = parseInt(str.substring(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() {
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('');
}
});
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 trimBeginRegexp = new RegExp('^[' + ws + '][' + ws + ']*');
var trimEndRegexp = new RegExp('[' + ws + '][' + ws + ']*$');
defineProperties(String.prototype, {
trim: function() {
if (this === undefined || this === null) {
throw new TypeError("can't convert " + this + " to object");
}
return String(this)
.replace(trimBeginRegexp, "")
.replace(trimEndRegexp, "");
}
});
}
// 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;
}
defineProperties(Array, {
from: function(iterable) {
var mapFn = arguments.length > 1 ? arguments[1] : undefined;
var thisArg = arguments.length > 2 ? arguments[2] : 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 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 = usingIterator ? 0 : ES.ToLength(list.length);
var result = ES.IsCallable(this) ? Object(usingIterator ? new this() : new this(length)) : new Array(length);
var it = usingIterator ? ES.GetIterator(list) : null;
var value;
for (var i = 0; usingIterator || (i < length); i++) {
if (usingIterator) {
value = ES.IteratorNext(it);
if (value.done) {
length = i;
break;
}
value = value.value;
} else {
value = list[i];
}
if (mapFn) {
result[i] = thisArg ? mapFn.call(thisArg, value, i) : mapFn(value, i);
} else {
result[i] = value;
}
}
result.length = length;
return result;
},
of: function() {
return Array.from(arguments);
}
});
// 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 (i === undefined || this.kind === undefined) {
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);
defineProperties(Array.prototype, {
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[1], end = arguments[2]; // fill.length===1
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);
for (var i = relativeStart; i < len && i < end; ++i) {
O[i] = value;
}
return O;
},
find: function(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++) {
if (i in list) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) return value;
}
}
return undefined;
},
findIndex: function(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 (i in list) {
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");
}
});
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 typeof value === 'number' &&
!Number.isNaN(value) &&
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;
}
});
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) {
if (!ES.TypeIsObject(source)) {
throw new TypeError('source must be an object');
}
return Object.keys(source).reduce(function(target, key) {
target[key] = source[key];
return target;
}, target);
});
},
getOwnPropertyKeys: function(subject) {
return Object.keys(subject);
},
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
setPrototypeOf.polyfill = setPrototypeOf(
setPrototypeOf({}, null),
Object.prototype
) instanceof Object;
// setPrototypeOf.polyfill === true means it works as meant
// setPrototypeOf.polyfill === false means it's not 100% reliable
// setPrototypeOf.polyfill === undefined
// or
// setPrototypeOf.polyfill == null means it's not a polyfill
// which means it works as expected
// we can even delete Object.prototype.__proto__;
}
return setPrototypeOf;
})(Object, '__proto__')
});
}
// Workaround bug in Opera 12 where setPrototypeOf(x, null) doesn't work,
// but Object.create(null) does.
if (Object.setPrototypeOf && Object.getPrototypeOf &&
Object.getPrototypeOf(Object.setPrototypeOf({}, null)) !== null &&
Object.getPrototypeOf(Object.create(null)) === null) {
(function() {
var FAKENULL = Object.create(null);
var gpo = Object.getPrototypeOf, spo = Object.setPrototypeOf;
Object.getPrototypeOf = function(o) {
var result = gpo(o);
return result === FAKENULL ? null : result;
};
Object.setPrototypeOf = function(o, p) {
if (p === null) { p = FAKENULL; }
return spo(o, p);
};
Object.setPrototypeOf.polyfill = false;
})();
}
try {
Object.keys('foo');
} catch (e) {
var originalObjectKeys = Object.keys;
Object.keys = function (obj) {
return originalObjectKeys(ES.ToObject(obj));
};
}
var MathShims = {
acosh: function(value) {
value = Number(value);
if (Number.isNaN(value) || value < 1) return NaN;
if (value === 1) return 0;
if (value === Infinity) return value;
return Math.log(value + Math.sqrt(value * value - 1));
},
asinh: function(value) {
value = Number(value);
if (value === 0 || !global_isFinite(value)) {
return value;
}
return value < 0 ? -Math.asinh(-value) : Math.log(value + Math.sqrt(value * value + 1));
},
atanh: function(value) {
value = Number(value);
if (Number.isNaN(value) || value < -1 || value > 1) {
return NaN;
}
if (value === -1) return -Infinity;
if (value === 1) return Infinity;
if (value === 0) return value;
return 0.5 * Math.log((1 + value) / (1 - value));
},
cbrt: function(value) {
value = Number(value);
if (value === 0) return value;
var negate = value < 0, result;
if (negate) value = -value;
result = Math.pow(value, 1/3);
return negate ? -result : result;
},
clz32: function(value) {
// See https://bugs.ecmascript.org/show_bug.cgi?id=2465
value = Number(value);
if (Number.isNaN(value)) return NaN;
var number = ES.ToUint32(value);
if (number === 0) {
return 32;
}
return 32 - (number).toString(2).length;
},
cosh: function(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 (value < 0) value = -value;
if (value > 21) return Math.exp(value) / 2;
return (Math.exp(value) + Math.exp(-value)) / 2;
},
expm1: function(value) {
value = Number(value);
if (value === -Infinity) return -1;
if (!global_isFinite(value) || value === 0) return value;
return Math.exp(value) - 1;
},
hypot: function(x, y) {
var anyNaN = false;
var allZero = true;
var anyInfinity = false;
var numbers = [];
Array.prototype.every.call(arguments, function(arg) {
var num = Number(arg);
if (Number.isNaN(num)) anyNaN = true;
else if (num === Infinity || num === -Infinity) anyInfinity = true;
else if (num !== 0) allZero = false;
if (anyInfinity) {
return false;
} else if (!anyNaN) {
numbers.push(Math.abs(num));
}
return true;
});
if (anyInfinity) return Infinity;
if (anyNaN) return NaN;
if (allZero) return 0;
numbers.sort(function (a, b) { return b - a; });
var largest = numbers[0];
var divided = numbers.map(function (number) { return number / largest; });
var sum = divided.reduce(function (sum, number) { return sum += number * number; }, 0);
return largest * Math.sqrt(sum);
},
log2: function(value) {
return Math.log(value) * Math.LOG2E;
},
log10: function(value) {
return Math.log(value) * Math.LOG10E;
},
log1p: function(value) {
value = Number(value);
if (value < -1 || Number.isNaN(value)) return NaN;
if (value === 0 || value === Infinity) return value;
if (value === -1) return -Infinity;
var result = 0;
var n = 50;
if (value < 0 || value > 1) return Math.log(1 + value);
for (var i = 1; i < n; i++) {
if ((i % 2) === 0) {
result -= Math.pow(value, i) / i;
} else {
result += Math.pow(value, i) / i;
}
}
return result;
},
sign: function(value) {
var number = +value;
if (number === 0) return number;
if (Number.isNaN(number)) return number;
return number < 0 ? -1 : 1;
},
sinh: function(value) {
value = Number(value);
if (!global_isFinite(value) || value === 0) return value;
return (Math.exp(value) - Math.exp(-value)) / 2;
},
tanh: function(value) {
value = Number(value);
if (Number.isNaN(value) || value === 0) return value;
if (value === Infinity) return 1;
if (value === -Infinity) return -1;
return (Math.exp(value) - Math.exp(-value)) / (Math.exp(value) + Math.exp(-value));
},
trunc: function(value) {
var number = Number(value);
return number < 0 ? -Math.floor(-number) : Math.floor(number);
},
imul: function(x, y) {
// taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
var ah = (x >>> 16) & 0xffff;
var al = x & 0xffff;
var bh = (y >>> 16) & 0xffff;
var bl = y & 0xffff;
// the shift by 0 fixes the sign on the high part
// the final |0 converts the unsigned value into a signed value
return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0)|0);
},
fround: function(x) {
if (x === 0 || x === Infinity || x === -Infinity || Number.isNaN(x)) {
return x;
}
var num = Number(x);
return numberConversion.toFloat32(num);
}
};
defineProperties(Math, MathShims);
if (Math.imul(0xffffffff, 5) !== -5) {
// Safari 6.1, at least, reports "0" for this value
Math.imul = MathShims.imul;
}
// Promises
// Simplest possible implementation; use a 3rd-party library if you
// want the best possible speed and/or long stack traces.
var PromiseShim = (function() {
var Promise, Promise$prototype;
ES.IsPromise = function(promise) {
if (!ES.TypeIsObject(promise)) {
return false;
}
if (!promise._promiseConstructor) {
// _promiseConstructor is a bit more unique than _status, so we'll
// check that instead of the [[PromiseStatus]] internal field.
return false;
}
if (promise._status === undefined) {
return false; // uninitialized
}
return true;
};
// "PromiseCapability" in the spec is what most promise implementations
// call a "deferred".
var PromiseCapability = function(C) {
if (!ES.IsCallable(C)) {
throw new TypeError('bad promise constructor');
}
var capability = this;
var resolver = function(resolve, reject) {
capability.resolve = resolve;
capability.reject = reject;
};
capability.promise = ES.Construct(C, [resolver]);
// see https://bugs.ecmascript.org/show_bug.cgi?id=2478
if (!capability.promise._es6construct) {
throw new TypeError('bad promise constructor');
}
if (!(ES.IsCallable(capability.resolve) &&
ES.IsCallable(capability.reject))) {
throw new TypeError('bad promise constructor');
}
};
// find an appropriate setImmediate-alike
var setTimeout = globals.setTimeout;
var makeZeroTimeout;
if (typeof window !== 'undefined' && ES.IsCallable(window.postMessage)) {
makeZeroTimeout = function() {
// from http://dbaron.org/log/20100309-faster-timeouts
var timeouts = [];
var messageName = "zero-timeout-message";
var setZeroTimeout = function(fn) {
timeouts.push(fn);
window.postMessage(messageName, "*");
};
var handleMessage = function(event) {
if (event.source == window && event.data == messageName) {
event.stopPropagation();
if (timeouts.length === 0) { return; }
var fn = timeouts.shift();
fn();
}
};
window.addEventListener("message", handleMessage, true);
return setZeroTimeout;
};
}
var makePromiseAsap = function() {
// An efficient task-scheduler based on a pre-existing Promise
// implementation, which we can use even if we override the
// global Promise below (in order to workaround bugs)
// https://github.com/Raynos/observ-hash/issues/2#issuecomment-35857671
var P = globals.Promise;
return P && P.resolve && function(task) {
return P.resolve().then(task);
};
};
var enqueue = ES.IsCallable(globals.setImmediate) ?
globals.setImmediate.bind(globals) :
typeof process === 'object' && process.nextTick ? process.nextTick :
makePromiseAsap() ||
(ES.IsCallable(makeZeroTimeout) ? makeZeroTimeout() :
function(task) { setTimeout(task, 0); }); // fallback
var triggerPromiseReactions = function(reactions, x) {
reactions.forEach(function(reaction) {
enqueue(function() {
// PromiseReactionTask
var handler = reaction.handler;
var capability = reaction.capability;
var resolve = capability.resolve;
var reject = capability.reject;
try {
var result = handler(x);
if (result === capability.promise) {
throw new TypeError('self resolution');
}
var updateResult =
updatePromiseFromPotentialThenable(result, capability);
if (!updateResult) {
resolve(result);
}
} catch (e) {
reject(e);
}
});
});
};
var updatePromiseFromPotentialThenable = function(x, capability) {
if (!ES.TypeIsObject(x)) {
return false;
}
var resolve = capability.resolve;
var reject = capability.reject;
try {
var then = x.then; // only one invocation of accessor
if (!ES.IsCallable(then)) { return false; }
then.call(x, resolve, reject);
} catch(e) {
reject(e);
}
return true;
};
var promiseResolutionHandler = function(promise, onFulfilled, onRejected){
return function(x) {
if (x === promise) {
return onRejected(new TypeError('self resolution'));
}
var C = promise._promiseConstructor;
var capability = new PromiseCapability(C);
var updateResult = updatePromiseFromPotentialThenable(x, capability);
if (updateResult) {
return capability.promise.then(onFulfilled, onRejected);
} else {
return onFulfilled(x);
}
};
};
Promise = function(resolver) {
var promise = this;
promise = emulateES6construct(promise);
if (!promise._promiseConstructor) {
// we use _promiseConstructor as a stand-in for the internal
// [[PromiseStatus]] field; it's a little more unique.
throw new TypeError('bad promise');
}
if (promise._status !== undefined) {
throw new TypeError('promise already initialized');
}
// see https://bugs.ecmascript.org/show_bug.cgi?id=2482
if (!ES.IsCallable(resolver)) {
throw new TypeError('not a valid resolver');
}
promise._status = 'unresolved';
promise._resolveReactions = [];
promise._rejectReactions = [];
var resolve = function(resolution) {
if (promise._status !== 'unresolved') { return; }
var reactions = promise._resolveReactions;
promise._result = resolution;
promise._resolveReactions = undefined;
promise._rejectReactions = undefined;
promise._status = 'has-resolution';
triggerPromiseReactions(reactions, resolution);
};
var reject = function(reason) {
if (promise._status !== 'unresolved') { return; }
var reactions = promise._rejectReactions;
promise._result = reason;
promise._resolveReactions = undefined;
promise._rejectReactions = undefined;
promise._status = 'has-rejection';
triggerPromiseReactions(reactions, reason);
};
try {
resolver(resolve, reject);
} catch (e) {
reject(e);
}
return promise;
};
Promise$prototype = Promise.prototype;
defineProperties(Promise, {
'@@create': function(obj) {
var constructor = this;
// AllocatePromise
// The `obj` parameter is a hack we use for es5
// compatibility.
var prototype = constructor.prototype || Promise$prototype;
obj = obj || create(prototype);
defineProperties(obj, {
_status: undefined,
_result: undefined,
_resolveReactions: undefined,
_rejectReactions: undefined,
_promiseConstructor: undefined
});
obj._promiseConstructor = constructor;
return obj;
}
});
var _promiseAllResolver = function(index, values, capability, remaining) {
var done = false;
return function(x) {
if (done) { return; } // protect against being called multiple times
done = true;
values[index] = x;
if ((--remaining.count) === 0) {
var resolve = capability.resolve;
resolve(values); // call w/ this===undefined
}
};
};
Promise.all = function(iterable) {
var C = this;
var capability = new PromiseCapability(C);
var resolve = capability.resolve;
var reject = capability.reject;
try {
if (!ES.IsIterable(iterable)) {
throw new TypeError('bad iterable');
}
var it = ES.GetIterator(iterable);
var values = [], remaining = { count: 1 };
for (var index = 0; ; index++) {
var next = ES.IteratorNext(it);
if (next.done) {
break;
}
var nextPromise = C.resolve(next.value);
var resolveElement = _promiseAllResolver(
index, values, capability, remaining
);
remaining.count++;
nextPromise.then(resolveElement, capability.reject);
}
if ((--remaining.count) === 0) {
resolve(values); // call w/ this===undefined
}
} catch (e) {
reject(e);
}
return capability.promise;
};
Promise.race = function(iterable) {
var C = this;
var capability = new PromiseCapability(C);
var resolve = capability.resolve;
var reject = capability.reject;
try {
if (!ES.IsIterable(iterable)) {
throw new TypeError('bad iterable');
}
var it = ES.GetIterator(iterable);
while (true) {
var next = ES.IteratorNext(it);
if (next.done) {
// If iterable has no items, resulting promise will never
// resolve; see:
// https://github.com/domenic/promises-unwrapping/issues/75
// https://bugs.ecmascript.org/show_bug.cgi?id=2515
break;
}
var nextPromise = C.resolve(next.value);
nextPromise.then(resolve, reject);
}
} catch (e) {
reject(e);
}
return capability.promise;
};
Promise.reject = function(reason) {
var C = this;
var capability = new PromiseCapability(C);
var reject = capability.reject;
reject(reason); // call with this===undefined
return capability.promise;
};
Promise.resolve = function(v) {
var C = this;
if (ES.IsPromise(v)) {
var constructor = v._promiseConstructor;
if (constructor === C) { return v; }
}
var capability = new PromiseCapability(C);
var resolve = capability.resolve;
resolve(v); // call with this===undefined
return capability.promise;
};
Promise.prototype['catch'] = function( onRejected ) {
return this.then(undefined, onRejected);
};
Promise.prototype.then = function( onFulfilled, onRejected ) {
var promise = this;
if (!ES.IsPromise(promise)) { throw new TypeError('not a promise'); }
// this.constructor not this._promiseConstructor; see
// https://bugs.ecmascript.org/show_bug.cgi?id=2513
var C = this.constructor;
var capability = new PromiseCapability(C);
if (!ES.IsCallable(onRejected)) {
onRejected = function(e) { throw e; };
}
if (!ES.IsCallable(onFulfilled)) {
onFulfilled = function(x) { return x; };
}
var resolutionHandler =
promiseResolutionHandler(promise, onFulfilled, onRejected);
var resolveReaction =
{ capability: capability, handler: resolutionHandler };
var rejectReaction =
{ capability: capability, handler: onRejected };
switch (promise._status) {
case 'unresolved':
promise._resolveReactions.push(resolveReaction);
promise._rejectReactions.push(rejectReaction);
break;
case 'has-resolution':
triggerPromiseReactions([resolveReaction], promise._result);
break;
case 'has-rejection':
triggerPromiseReactions([rejectReaction], promise._result);
break;
default:
throw new TypeError('unexpected');
}
return capability.promise;
};
return Promise;
})();
// export the Promise constructor.
defineProperties(globals, { Promise: PromiseShim });
// In Chrome 33 (and thereabouts) Promise is defined, but the
// implementation is buggy in a number of ways. Let's check subclassing
// support to see if we have a buggy implementation.
var promiseSupportsSubclassing = supportsSubclassing(globals.Promise, function(S) {
return S.resolve(42) instanceof S;
});
var promiseIgnoresNonFunctionThenCallbacks = (function () {
try {
globals.Promise.reject(42).then(null, 5).then(null, function () {});
return true;
} catch (ex) {
return false;
}
}());
if (!promiseSupportsSubclassing || !promiseIgnoresNonFunctionThenCallbacks) {
globals.Promise = PromiseShim;
}
// Map and Set require a true ES5 environment
if (supportsDescriptors) {
var fastkey = function fastkey(key) {
var type = typeof key;
if (type === 'string') {
return '$' + key;
} else if (type === 'number') {
// note that -0 will get coerced to "0" when used as a property key
return key;
}
return null;
};
var emptyObject = function emptyObject() {
// accomodate some older not-quite-ES5 browsers
return Object.create ? Object.create(null) : {};
};
var collectionShims = {
Map: (function() {
var empty = {};
function MapEntry(key, value) {
this.key = key;
this.value = value;
this.next = null;
this.prev = null;
}
MapEntry.prototype.isRemoved = function() {
return this.key === empty;
};
function MapIterator(map, kind) {
this.head = map._head;
this.i = this.head;
this.kind = kind;
}
MapIterator.prototype = {
next: function() {
var i = this.i, kind = this.kind, head = this.head, result;
if (this.i === undefined) {
return { value: undefined, done: true };
}
while (i.isRemoved() && i !== head) {
// back up off of removed entries
i = i.prev;
}
// advance to next unreturned element.
while (i.next !== head) {
i = i.next;
if (!i.isRemoved()) {
if (kind === "key") {
result = i.key;
} else if (kind === "value") {
result = i.value;
} else {
result = [i.key, i.value];
}
this.i = i;
return { value: result, done: false };
}
}
// once the iterator is done, it is done forever.
this.i = undefined;
return { value: undefined, done: true };
}
};
addIterator(MapIterator.prototype);
function Map() {
var map = this;
map = emulateES6construct(map);
if (!map._es6map) {
throw new TypeError('bad map');
}
var head = new MapEntry(null, null);
// circular doubly-linked list.
head.next = head.prev = head;
defineProperties(map, {
'_head': head,
'_storage': emptyObject(),
'_size': 0
});
// Optionally initialize map from iterable
var iterable = arguments[0];
if (iterable !== undefined && iterable !== null) {
var it = ES.GetIterator(iterable);
var adder = map.set;
if (!ES.IsCallable(adder)) { throw new TypeError('bad map'); }
while (true) {
var next = ES.IteratorNext(it);
if (next.done) { break; }
var nextItem = next.value;
if (!ES.TypeIsObject(nextItem)) {
throw new TypeError('expected iterable of pairs');
}
adder.call(map, nextItem[0], nextItem[1]);
}
}
return map;
}
var Map$prototype = Map.prototype;
defineProperties(Map, {
'@@create': function(obj) {
var constructor = this;
var prototype = constructor.prototype || Map$prototype;
obj = obj || create(prototype);
defineProperties(obj, { _es6map: true });
return obj;
}
});
Object.defineProperty(Map.prototype, 'size', {
configurable: true,
enumerable: false,
get: function() {
if (typeof this._size === 'undefined') {
throw new TypeError('size method called on incompatible Map');
}
return this._size;
}
});
defineProperties(Map.prototype, {
get: function(key) {
var fkey = fastkey(key);
if (fkey !== null) {
// fast O(1) path
var entry = this._storage[fkey];
return entry ? entry.value : undefined;
}
var head = this._head, i = head;
while ((i = i.next) !== head) {
if (ES.SameValueZero(i.key, key)) {
return i.value;
}
}
return undefined;
},
has: function(key) {
var fkey = fastkey(key);
if (fkey !== null) {
// fast O(1) path
return typeof this._storage[fkey] !== 'undefined';
}
var head = this._head, i = head;
while ((i = i.next) !== head) {
if (ES.SameValueZero(i.key, key)) {
return true;
}
}
return false;
},
set: function(key, value) {
var head = this._head, i = head, entry;
var fkey = fastkey(key);
if (fkey !== null) {
// fast O(1) path
if (typeof this._storage[fkey] !== 'undefined') {
this._storage[fkey].value = value;
return;
} else {
entry = this._storage[fkey] = new MapEntry(key, value);
i = head.prev;
// fall through
}
}
while ((i = i.next) !== head) {
if (ES.SameValueZero(i.key, key)) {
i.value = value;
return;
}
}
entry = entry || new MapEntry(key, value);
if (ES.SameValue(-0, key)) {
entry.key = +0; // coerce -0 to +0 in entry
}
entry.next = this._head;
entry.prev = this._head.prev;
entry.prev.next = entry;
entry.next.prev = entry;
this._size += 1;
},
'delete': function(key) {
var head = this._head, i = head;
var fkey = fastkey(key);
if (fkey !== null) {
// fast O(1) path
if (typeof this._storage[fkey] === 'undefined') {
return false;
}
i = this._storage[fkey].prev;
delete this._storage[fkey];
// fall through
}
while ((i = i.next) !== head) {
if (ES.SameValueZero(i.key, key)) {
i.key = i.value = empty;
i.prev.next = i.next;
i.next.prev = i.prev;
this._size -= 1;
return true;
}
}
return false;
},
clear: function() {
this._size = 0;
this._storage = emptyObject();
var head = this._head, i = head, p = i.next;
while ((i = p) !== head) {
i.key = i.value = empty;
p = i.next;
i.next = i.prev = head;
}
head.next = head.prev = head;
},
keys: function() {
return new MapIterator(this, "key");
},
values: function() {
return new MapIterator(this, "value");
},
entries: function() {
return new MapIterator(this, "key+value");
},
forEach: function(callback) {
var context = arguments.length > 1 ? arguments[1] : null;
var it = this.entries();
for (var entry = it.next(); !entry.done; entry = it.next()) {
callback.call(context, entry.value[1], entry.value[0], this);
}
}
});
addIterator(Map.prototype, function() { return this.entries(); });
return Map;
})(),
Set: (function() {
// Creating a Map is expensive. To speed up the common case of
// Sets containing only string or numeric keys, we use an object
// as backing storage and lazily create a full Map only when
// required.
var SetShim = function Set() {
var set = this;
set = emulateES6construct(set);
if (!set._es6set) {
throw new TypeError('bad set');
}
defineProperties(set, {
'[[SetData]]': null,
'_storage': emptyObject()
});
// Optionally initialize map from iterable
var iterable = arguments[0];
if (iterable !== undefined && iterable !== null) {
var it = ES.GetIterator(iterable);
var adder = set.add;
if (!ES.IsCallable(adder)) { throw new TypeError('bad set'); }
while (true) {
var next = ES.IteratorNext(it);
if (next.done) { break; }
var nextItem = next.value;
adder.call(set, nextItem);
}
}
return set;
};
var Set$prototype = SetShim.prototype;
defineProperties(SetShim, {
'@@create': function(obj) {
var constructor = this;
var prototype = constructor.prototype || Set$prototype;
obj = obj || create(prototype);
defineProperties(obj, { _es6set: true });
return obj;
}
});
// Switch from the object backing storage to a full Map.
var ensureMap = function ensureMap(set) {
if (!set['[[SetData]]']) {
var m = set['[[SetData]]'] = new collectionShims.Map();
Object.keys(set._storage).forEach(function(k) {
// fast check for leading '$'
if (k.charCodeAt(0) === 36) {
k = k.substring(1);
} else {
k = +k;
}
m.set(k, k);
});
set._storage = null; // free old backing storage
}
};
Object.defineProperty(SetShim.prototype, 'size', {
configurable: true,
enumerable: false,
get: function() {
if (typeof this._storage === 'undefined') {
// https://github.com/paulmillr/es6-shim/issues/176
throw new TypeError('size method called on incompatible Set');
}
ensureMap(this);
return this['[[SetData]]'].size;
}
});
defineProperties(SetShim.prototype, {
has: function(key) {
var fkey;
if (this._storage && (fkey = fastkey(key)) !== null) {
return !!this._storage[fkey];
}
ensureMap(this);
return this['[[SetData]]'].has(key);
},
add: function(key) {
var fkey;
if (this._storage && (fkey = fastkey(key)) !== null) {
this._storage[fkey]=true;
return;
}
ensureMap(this);
return this['[[SetData]]'].set(key, key);
},
'delete': function(key) {
var fkey;
if (this._storage && (fkey = fastkey(key)) !== null) {
delete this._storage[fkey];
return;
}
ensureMap(this);
return this['[[SetData]]']['delete'](key);
},
clear: function() {
if (this._storage) {
this._storage = emptyObject();
return;
}
return this['[[SetData]]'].clear();
},
keys: function() {
ensureMap(this);
return this['[[SetData]]'].keys();
},
values: function() {
ensureMap(this);
return this['[[SetData]]'].values();
},
entries: function() {
ensureMap(this);
return this['[[SetData]]'].entries();
},
forEach: function(callback) {
var context = arguments.length > 1 ? arguments[1] : null;
var entireSet = this;
ensureMap(this);
this['[[SetData]]'].forEach(function(value, key) {
callback.call(context, key, key, entireSet);
});
}
});
addIterator(SetShim.prototype, function() { return this.values(); });
return SetShim;
})()
};
defineProperties(globals, collectionShims);
if (globals.Map || globals.Set) {
/*
- In Firefox < 23, Map#size is a function.
- In all current Firefox, Set#entries/keys/values & Map#clear do not exist
- https://bugzilla.mozilla.org/show_bug.cgi?id=869996
- In Firefox 24, Map and Set do not implement forEach
- In Firefox 25 at least, Map and Set are callable without "new"
*/
if (
typeof globals.Map.prototype.clear !== 'function' ||
new globals.Set().size !== 0 ||
new globals.Map().size !== 0 ||
typeof globals.Map.prototype.keys !== 'function' ||
typeof globals.Set.prototype.keys !== 'function' ||
typeof globals.Map.prototype.forEach !== 'function' ||
typeof globals.Set.prototype.forEach !== 'function' ||
isCallableWithoutNew(globals.Map) ||
isCallableWithoutNew(globals.Set) ||
!supportsSubclassing(globals.Map, function(M) {
return (new M([])) instanceof M;
})
) {
globals.Map = collectionShims.Map;
globals.Set = collectionShims.Set;
}
}
// Shim incomplete iterator implementations.
addIterator(Object.getPrototypeOf((new globals.Map()).keys()));
addIterator(Object.getPrototypeOf((new globals.Set()).keys()));
}
};
if (typeof define === 'function' && define.amd) {
define(main); // RequireJS
} else {
main(); // CommonJS and <script>
}
});