You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
246 lines
9.1 KiB
246 lines
9.1 KiB
'use strict'; |
|
// ECMAScript 6 symbols shim |
|
var global = require('./_global'); |
|
var has = require('./_has'); |
|
var DESCRIPTORS = require('./_descriptors'); |
|
var $export = require('./_export'); |
|
var redefine = require('./_redefine'); |
|
var META = require('./_meta').KEY; |
|
var $fails = require('./_fails'); |
|
var shared = require('./_shared'); |
|
var setToStringTag = require('./_set-to-string-tag'); |
|
var uid = require('./_uid'); |
|
var wks = require('./_wks'); |
|
var wksExt = require('./_wks-ext'); |
|
var wksDefine = require('./_wks-define'); |
|
var enumKeys = require('./_enum-keys'); |
|
var isArray = require('./_is-array'); |
|
var anObject = require('./_an-object'); |
|
var isObject = require('./_is-object'); |
|
var toObject = require('./_to-object'); |
|
var toIObject = require('./_to-iobject'); |
|
var toPrimitive = require('./_to-primitive'); |
|
var createDesc = require('./_property-desc'); |
|
var _create = require('./_object-create'); |
|
var gOPNExt = require('./_object-gopn-ext'); |
|
var $GOPD = require('./_object-gopd'); |
|
var $GOPS = require('./_object-gops'); |
|
var $DP = require('./_object-dp'); |
|
var $keys = require('./_object-keys'); |
|
var gOPD = $GOPD.f; |
|
var dP = $DP.f; |
|
var gOPN = gOPNExt.f; |
|
var $Symbol = global.Symbol; |
|
var $JSON = global.JSON; |
|
var _stringify = $JSON && $JSON.stringify; |
|
var PROTOTYPE = 'prototype'; |
|
var HIDDEN = wks('_hidden'); |
|
var TO_PRIMITIVE = wks('toPrimitive'); |
|
var isEnum = {}.propertyIsEnumerable; |
|
var SymbolRegistry = shared('symbol-registry'); |
|
var AllSymbols = shared('symbols'); |
|
var OPSymbols = shared('op-symbols'); |
|
var ObjectProto = Object[PROTOTYPE]; |
|
var USE_NATIVE = typeof $Symbol == 'function' && !!$GOPS.f; |
|
var QObject = global.QObject; |
|
// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173 |
|
var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild; |
|
|
|
// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 |
|
var setSymbolDesc = DESCRIPTORS && $fails(function () { |
|
return _create(dP({}, 'a', { |
|
get: function () { return dP(this, 'a', { value: 7 }).a; } |
|
})).a != 7; |
|
}) ? function (it, key, D) { |
|
var protoDesc = gOPD(ObjectProto, key); |
|
if (protoDesc) delete ObjectProto[key]; |
|
dP(it, key, D); |
|
if (protoDesc && it !== ObjectProto) dP(ObjectProto, key, protoDesc); |
|
} : dP; |
|
|
|
var wrap = function (tag) { |
|
var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]); |
|
sym._k = tag; |
|
return sym; |
|
}; |
|
|
|
var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function (it) { |
|
return typeof it == 'symbol'; |
|
} : function (it) { |
|
return it instanceof $Symbol; |
|
}; |
|
|
|
var $defineProperty = function defineProperty(it, key, D) { |
|
if (it === ObjectProto) $defineProperty(OPSymbols, key, D); |
|
anObject(it); |
|
key = toPrimitive(key, true); |
|
anObject(D); |
|
if (has(AllSymbols, key)) { |
|
if (!D.enumerable) { |
|
if (!has(it, HIDDEN)) dP(it, HIDDEN, createDesc(1, {})); |
|
it[HIDDEN][key] = true; |
|
} else { |
|
if (has(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false; |
|
D = _create(D, { enumerable: createDesc(0, false) }); |
|
} return setSymbolDesc(it, key, D); |
|
} return dP(it, key, D); |
|
}; |
|
var $defineProperties = function defineProperties(it, P) { |
|
anObject(it); |
|
var keys = enumKeys(P = toIObject(P)); |
|
var i = 0; |
|
var l = keys.length; |
|
var key; |
|
while (l > i) $defineProperty(it, key = keys[i++], P[key]); |
|
return it; |
|
}; |
|
var $create = function create(it, P) { |
|
return P === undefined ? _create(it) : $defineProperties(_create(it), P); |
|
}; |
|
var $propertyIsEnumerable = function propertyIsEnumerable(key) { |
|
var E = isEnum.call(this, key = toPrimitive(key, true)); |
|
if (this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return false; |
|
return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true; |
|
}; |
|
var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key) { |
|
it = toIObject(it); |
|
key = toPrimitive(key, true); |
|
if (it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return; |
|
var D = gOPD(it, key); |
|
if (D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) D.enumerable = true; |
|
return D; |
|
}; |
|
var $getOwnPropertyNames = function getOwnPropertyNames(it) { |
|
var names = gOPN(toIObject(it)); |
|
var result = []; |
|
var i = 0; |
|
var key; |
|
while (names.length > i) { |
|
if (!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META) result.push(key); |
|
} return result; |
|
}; |
|
var $getOwnPropertySymbols = function getOwnPropertySymbols(it) { |
|
var IS_OP = it === ObjectProto; |
|
var names = gOPN(IS_OP ? OPSymbols : toIObject(it)); |
|
var result = []; |
|
var i = 0; |
|
var key; |
|
while (names.length > i) { |
|
if (has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true)) result.push(AllSymbols[key]); |
|
} return result; |
|
}; |
|
|
|
// 19.4.1.1 Symbol([description]) |
|
if (!USE_NATIVE) { |
|
$Symbol = function Symbol() { |
|
if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor!'); |
|
var tag = uid(arguments.length > 0 ? arguments[0] : undefined); |
|
var $set = function (value) { |
|
if (this === ObjectProto) $set.call(OPSymbols, value); |
|
if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false; |
|
setSymbolDesc(this, tag, createDesc(1, value)); |
|
}; |
|
if (DESCRIPTORS && setter) setSymbolDesc(ObjectProto, tag, { configurable: true, set: $set }); |
|
return wrap(tag); |
|
}; |
|
redefine($Symbol[PROTOTYPE], 'toString', function toString() { |
|
return this._k; |
|
}); |
|
|
|
$GOPD.f = $getOwnPropertyDescriptor; |
|
$DP.f = $defineProperty; |
|
require('./_object-gopn').f = gOPNExt.f = $getOwnPropertyNames; |
|
require('./_object-pie').f = $propertyIsEnumerable; |
|
$GOPS.f = $getOwnPropertySymbols; |
|
|
|
if (DESCRIPTORS && !require('./_library')) { |
|
redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true); |
|
} |
|
|
|
wksExt.f = function (name) { |
|
return wrap(wks(name)); |
|
}; |
|
} |
|
|
|
$export($export.G + $export.W + $export.F * !USE_NATIVE, { Symbol: $Symbol }); |
|
|
|
for (var es6Symbols = ( |
|
// 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14 |
|
'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables' |
|
).split(','), j = 0; es6Symbols.length > j;)wks(es6Symbols[j++]); |
|
|
|
for (var wellKnownSymbols = $keys(wks.store), k = 0; wellKnownSymbols.length > k;) wksDefine(wellKnownSymbols[k++]); |
|
|
|
$export($export.S + $export.F * !USE_NATIVE, 'Symbol', { |
|
// 19.4.2.1 Symbol.for(key) |
|
'for': function (key) { |
|
return has(SymbolRegistry, key += '') |
|
? SymbolRegistry[key] |
|
: SymbolRegistry[key] = $Symbol(key); |
|
}, |
|
// 19.4.2.5 Symbol.keyFor(sym) |
|
keyFor: function keyFor(sym) { |
|
if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol!'); |
|
for (var key in SymbolRegistry) if (SymbolRegistry[key] === sym) return key; |
|
}, |
|
useSetter: function () { setter = true; }, |
|
useSimple: function () { setter = false; } |
|
}); |
|
|
|
$export($export.S + $export.F * !USE_NATIVE, 'Object', { |
|
// 19.1.2.2 Object.create(O [, Properties]) |
|
create: $create, |
|
// 19.1.2.4 Object.defineProperty(O, P, Attributes) |
|
defineProperty: $defineProperty, |
|
// 19.1.2.3 Object.defineProperties(O, Properties) |
|
defineProperties: $defineProperties, |
|
// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P) |
|
getOwnPropertyDescriptor: $getOwnPropertyDescriptor, |
|
// 19.1.2.7 Object.getOwnPropertyNames(O) |
|
getOwnPropertyNames: $getOwnPropertyNames, |
|
// 19.1.2.8 Object.getOwnPropertySymbols(O) |
|
getOwnPropertySymbols: $getOwnPropertySymbols |
|
}); |
|
|
|
// Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives |
|
// https://bugs.chromium.org/p/v8/issues/detail?id=3443 |
|
var FAILS_ON_PRIMITIVES = $fails(function () { $GOPS.f(1); }); |
|
|
|
$export($export.S + $export.F * FAILS_ON_PRIMITIVES, 'Object', { |
|
getOwnPropertySymbols: function getOwnPropertySymbols(it) { |
|
return $GOPS.f(toObject(it)); |
|
} |
|
}); |
|
|
|
// 24.3.2 JSON.stringify(value [, replacer [, space]]) |
|
$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function () { |
|
var S = $Symbol(); |
|
// MS Edge converts symbol values to JSON as {} |
|
// WebKit converts symbol values to JSON as null |
|
// V8 throws on boxed symbols |
|
return _stringify([S]) != '[null]' || _stringify({ a: S }) != '{}' || _stringify(Object(S)) != '{}'; |
|
})), 'JSON', { |
|
stringify: function stringify(it) { |
|
var args = [it]; |
|
var i = 1; |
|
var replacer, $replacer; |
|
while (arguments.length > i) args.push(arguments[i++]); |
|
$replacer = replacer = args[1]; |
|
if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined |
|
if (!isArray(replacer)) replacer = function (key, value) { |
|
if (typeof $replacer == 'function') value = $replacer.call(this, key, value); |
|
if (!isSymbol(value)) return value; |
|
}; |
|
args[1] = replacer; |
|
return _stringify.apply($JSON, args); |
|
} |
|
}); |
|
|
|
// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint) |
|
$Symbol[PROTOTYPE][TO_PRIMITIVE] || require('./_hide')($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf); |
|
// 19.4.3.5 Symbol.prototype[@@toStringTag] |
|
setToStringTag($Symbol, 'Symbol'); |
|
// 20.2.1.9 Math[@@toStringTag] |
|
setToStringTag(Math, 'Math', true); |
|
// 24.3.3 JSON[@@toStringTag] |
|
setToStringTag(global.JSON, 'JSON', true);
|
|
|