110 lines
4.2 KiB
JavaScript
110 lines
4.2 KiB
JavaScript
'use strict';
|
|
var FREEZING = require('../internals/freezing');
|
|
var global = require('../internals/global');
|
|
var uncurryThis = require('../internals/function-uncurry-this');
|
|
var defineBuiltIns = require('../internals/define-built-ins');
|
|
var InternalMetadataModule = require('../internals/internal-metadata');
|
|
var collection = require('../internals/collection');
|
|
var collectionWeak = require('../internals/collection-weak');
|
|
var isObject = require('../internals/is-object');
|
|
var enforceInternalState = require('../internals/internal-state').enforce;
|
|
var fails = require('../internals/fails');
|
|
var NATIVE_WEAK_MAP = require('../internals/weak-map-basic-detection');
|
|
|
|
var $Object = Object;
|
|
// eslint-disable-next-line es/no-array-isarray -- safe
|
|
var isArray = Array.isArray;
|
|
// eslint-disable-next-line es/no-object-isextensible -- safe
|
|
var isExtensible = $Object.isExtensible;
|
|
// eslint-disable-next-line es/no-object-isfrozen -- safe
|
|
var isFrozen = $Object.isFrozen;
|
|
// eslint-disable-next-line es/no-object-issealed -- safe
|
|
var isSealed = $Object.isSealed;
|
|
// eslint-disable-next-line es/no-object-freeze -- safe
|
|
var freeze = $Object.freeze;
|
|
// eslint-disable-next-line es/no-object-seal -- safe
|
|
var seal = $Object.seal;
|
|
|
|
var FROZEN = {};
|
|
var SEALED = {};
|
|
var IS_IE11 = !global.ActiveXObject && 'ActiveXObject' in global;
|
|
var InternalWeakMap;
|
|
|
|
var wrapper = function (init) {
|
|
return function WeakMap() {
|
|
return init(this, arguments.length ? arguments[0] : undefined);
|
|
};
|
|
};
|
|
|
|
// `WeakMap` constructor
|
|
// https://tc39.es/ecma262/#sec-weakmap-constructor
|
|
var $WeakMap = collection('WeakMap', wrapper, collectionWeak);
|
|
var WeakMapPrototype = $WeakMap.prototype;
|
|
var nativeSet = uncurryThis(WeakMapPrototype.set);
|
|
|
|
// Chakra Edge bug: adding frozen arrays to WeakMap unfreeze them
|
|
var hasMSEdgeFreezingBug = function () {
|
|
return FREEZING && fails(function () {
|
|
var frozenArray = freeze([]);
|
|
nativeSet(new $WeakMap(), frozenArray, 1);
|
|
return !isFrozen(frozenArray);
|
|
});
|
|
};
|
|
|
|
// IE11 WeakMap frozen keys fix
|
|
// We can't use feature detection because it crash some old IE builds
|
|
// https://github.com/zloirock/core-js/issues/485
|
|
if (NATIVE_WEAK_MAP) if (IS_IE11) {
|
|
InternalWeakMap = collectionWeak.getConstructor(wrapper, 'WeakMap', true);
|
|
InternalMetadataModule.enable();
|
|
var nativeDelete = uncurryThis(WeakMapPrototype['delete']);
|
|
var nativeHas = uncurryThis(WeakMapPrototype.has);
|
|
var nativeGet = uncurryThis(WeakMapPrototype.get);
|
|
defineBuiltIns(WeakMapPrototype, {
|
|
'delete': function (key) {
|
|
if (isObject(key) && !isExtensible(key)) {
|
|
var state = enforceInternalState(this);
|
|
if (!state.frozen) state.frozen = new InternalWeakMap();
|
|
return nativeDelete(this, key) || state.frozen['delete'](key);
|
|
} return nativeDelete(this, key);
|
|
},
|
|
has: function has(key) {
|
|
if (isObject(key) && !isExtensible(key)) {
|
|
var state = enforceInternalState(this);
|
|
if (!state.frozen) state.frozen = new InternalWeakMap();
|
|
return nativeHas(this, key) || state.frozen.has(key);
|
|
} return nativeHas(this, key);
|
|
},
|
|
get: function get(key) {
|
|
if (isObject(key) && !isExtensible(key)) {
|
|
var state = enforceInternalState(this);
|
|
if (!state.frozen) state.frozen = new InternalWeakMap();
|
|
return nativeHas(this, key) ? nativeGet(this, key) : state.frozen.get(key);
|
|
} return nativeGet(this, key);
|
|
},
|
|
set: function set(key, value) {
|
|
if (isObject(key) && !isExtensible(key)) {
|
|
var state = enforceInternalState(this);
|
|
if (!state.frozen) state.frozen = new InternalWeakMap();
|
|
nativeHas(this, key) ? nativeSet(this, key, value) : state.frozen.set(key, value);
|
|
} else nativeSet(this, key, value);
|
|
return this;
|
|
}
|
|
});
|
|
// Chakra Edge frozen keys fix
|
|
} else if (hasMSEdgeFreezingBug()) {
|
|
defineBuiltIns(WeakMapPrototype, {
|
|
set: function set(key, value) {
|
|
var arrayIntegrityLevel;
|
|
if (isArray(key)) {
|
|
if (isFrozen(key)) arrayIntegrityLevel = FROZEN;
|
|
else if (isSealed(key)) arrayIntegrityLevel = SEALED;
|
|
}
|
|
nativeSet(this, key, value);
|
|
if (arrayIntegrityLevel === FROZEN) freeze(key);
|
|
if (arrayIntegrityLevel === SEALED) seal(key);
|
|
return this;
|
|
}
|
|
});
|
|
}
|