| 1 | 'use strict';
|
|---|
| 2 | var $ = require('../internals/export');
|
|---|
| 3 | var uncurryThis = require('../internals/function-uncurry-this');
|
|---|
| 4 | var hiddenKeys = require('../internals/hidden-keys');
|
|---|
| 5 | var isObject = require('../internals/is-object');
|
|---|
| 6 | var hasOwn = require('../internals/has-own-property');
|
|---|
| 7 | var defineProperty = require('../internals/object-define-property').f;
|
|---|
| 8 | var getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');
|
|---|
| 9 | var getOwnPropertyNamesExternalModule = require('../internals/object-get-own-property-names-external');
|
|---|
| 10 | var isExtensible = require('../internals/object-is-extensible');
|
|---|
| 11 | var uid = require('../internals/uid');
|
|---|
| 12 | var FREEZING = require('../internals/freezing');
|
|---|
| 13 |
|
|---|
| 14 | var REQUIRED = false;
|
|---|
| 15 | var METADATA = uid('meta');
|
|---|
| 16 | var id = 0;
|
|---|
| 17 |
|
|---|
| 18 | var setMetadata = function (it) {
|
|---|
| 19 | defineProperty(it, METADATA, { value: {
|
|---|
| 20 | objectID: 'O' + id++, // object ID
|
|---|
| 21 | weakData: {} // weak collections IDs
|
|---|
| 22 | } });
|
|---|
| 23 | };
|
|---|
| 24 |
|
|---|
| 25 | var fastKey = function (it, create) {
|
|---|
| 26 | // return a primitive with prefix
|
|---|
| 27 | if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
|
|---|
| 28 | if (!hasOwn(it, METADATA)) {
|
|---|
| 29 | // can't set metadata to uncaught frozen object
|
|---|
| 30 | if (!isExtensible(it)) return 'F';
|
|---|
| 31 | // not necessary to add metadata
|
|---|
| 32 | if (!create) return 'E';
|
|---|
| 33 | // add missing metadata
|
|---|
| 34 | setMetadata(it);
|
|---|
| 35 | // return object ID
|
|---|
| 36 | } return it[METADATA].objectID;
|
|---|
| 37 | };
|
|---|
| 38 |
|
|---|
| 39 | var getWeakData = function (it, create) {
|
|---|
| 40 | if (!hasOwn(it, METADATA)) {
|
|---|
| 41 | // can't set metadata to uncaught frozen object
|
|---|
| 42 | if (!isExtensible(it)) return true;
|
|---|
| 43 | // not necessary to add metadata
|
|---|
| 44 | if (!create) return false;
|
|---|
| 45 | // add missing metadata
|
|---|
| 46 | setMetadata(it);
|
|---|
| 47 | // return the store of weak collections IDs
|
|---|
| 48 | } return it[METADATA].weakData;
|
|---|
| 49 | };
|
|---|
| 50 |
|
|---|
| 51 | // add metadata on freeze-family methods calling
|
|---|
| 52 | var onFreeze = function (it) {
|
|---|
| 53 | if (FREEZING && REQUIRED && isExtensible(it) && !hasOwn(it, METADATA)) setMetadata(it);
|
|---|
| 54 | return it;
|
|---|
| 55 | };
|
|---|
| 56 |
|
|---|
| 57 | var enable = function () {
|
|---|
| 58 | meta.enable = function () { /* empty */ };
|
|---|
| 59 | REQUIRED = true;
|
|---|
| 60 | var getOwnPropertyNames = getOwnPropertyNamesModule.f;
|
|---|
| 61 | var splice = uncurryThis([].splice);
|
|---|
| 62 | var test = {};
|
|---|
| 63 | // eslint-disable-next-line unicorn/no-immediate-mutation -- ES3 syntax limitation
|
|---|
| 64 | test[METADATA] = 1;
|
|---|
| 65 |
|
|---|
| 66 | // prevent exposing of metadata key
|
|---|
| 67 | if (getOwnPropertyNames(test).length) {
|
|---|
| 68 | getOwnPropertyNamesModule.f = function (it) {
|
|---|
| 69 | var result = getOwnPropertyNames(it);
|
|---|
| 70 | for (var i = 0, length = result.length; i < length; i++) {
|
|---|
| 71 | if (result[i] === METADATA) {
|
|---|
| 72 | splice(result, i, 1);
|
|---|
| 73 | break;
|
|---|
| 74 | }
|
|---|
| 75 | } return result;
|
|---|
| 76 | };
|
|---|
| 77 |
|
|---|
| 78 | $({ target: 'Object', stat: true, forced: true }, {
|
|---|
| 79 | getOwnPropertyNames: getOwnPropertyNamesExternalModule.f
|
|---|
| 80 | });
|
|---|
| 81 | }
|
|---|
| 82 | };
|
|---|
| 83 |
|
|---|
| 84 | var meta = module.exports = {
|
|---|
| 85 | enable: enable,
|
|---|
| 86 | fastKey: fastKey,
|
|---|
| 87 | getWeakData: getWeakData,
|
|---|
| 88 | onFreeze: onFreeze
|
|---|
| 89 | };
|
|---|
| 90 |
|
|---|
| 91 | hiddenKeys[METADATA] = true;
|
|---|