Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81164 views
1
"use strict";
2
3
var originalObject = Object;
4
var originalDefProp = Object.defineProperty;
5
var originalCreate = Object.create;
6
7
function defProp(obj, name, value) {
8
if (originalDefProp) try {
9
originalDefProp.call(originalObject, obj, name, { value: value });
10
} catch (definePropertyIsBrokenInIE8) {
11
obj[name] = value;
12
} else {
13
obj[name] = value;
14
}
15
}
16
17
// For functions that will be invoked using .call or .apply, we need to
18
// define those methods on the function objects themselves, rather than
19
// inheriting them from Function.prototype, so that a malicious or clumsy
20
// third party cannot interfere with the functionality of this module by
21
// redefining Function.prototype.call or .apply.
22
function makeSafeToCall(fun) {
23
if (fun) {
24
defProp(fun, "call", fun.call);
25
defProp(fun, "apply", fun.apply);
26
}
27
return fun;
28
}
29
30
makeSafeToCall(originalDefProp);
31
makeSafeToCall(originalCreate);
32
33
var hasOwn = makeSafeToCall(Object.prototype.hasOwnProperty);
34
var numToStr = makeSafeToCall(Number.prototype.toString);
35
var strSlice = makeSafeToCall(String.prototype.slice);
36
37
var cloner = function(){};
38
function create(prototype) {
39
if (originalCreate) {
40
return originalCreate.call(originalObject, prototype);
41
}
42
cloner.prototype = prototype || null;
43
return new cloner;
44
}
45
46
var rand = Math.random;
47
var uniqueKeys = create(null);
48
49
function makeUniqueKey() {
50
// Collisions are highly unlikely, but this module is in the business of
51
// making guarantees rather than safe bets.
52
do var uniqueKey = internString(strSlice.call(numToStr.call(rand(), 36), 2));
53
while (hasOwn.call(uniqueKeys, uniqueKey));
54
return uniqueKeys[uniqueKey] = uniqueKey;
55
}
56
57
function internString(str) {
58
var obj = {};
59
obj[str] = true;
60
return Object.keys(obj)[0];
61
}
62
63
// External users might find this function useful, but it is not necessary
64
// for the typical use of this module.
65
defProp(exports, "makeUniqueKey", makeUniqueKey);
66
67
// Object.getOwnPropertyNames is the only way to enumerate non-enumerable
68
// properties, so if we wrap it to ignore our secret keys, there should be
69
// no way (except guessing) to access those properties.
70
var originalGetOPNs = Object.getOwnPropertyNames;
71
Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
72
for (var names = originalGetOPNs(object),
73
src = 0,
74
dst = 0,
75
len = names.length;
76
src < len;
77
++src) {
78
if (!hasOwn.call(uniqueKeys, names[src])) {
79
if (src > dst) {
80
names[dst] = names[src];
81
}
82
++dst;
83
}
84
}
85
names.length = dst;
86
return names;
87
};
88
89
function defaultCreatorFn(object) {
90
return create(null);
91
}
92
93
function makeAccessor(secretCreatorFn) {
94
var brand = makeUniqueKey();
95
var passkey = create(null);
96
97
secretCreatorFn = secretCreatorFn || defaultCreatorFn;
98
99
function register(object) {
100
var secret; // Created lazily.
101
102
function vault(key, forget) {
103
// Only code that has access to the passkey can retrieve (or forget)
104
// the secret object.
105
if (key === passkey) {
106
return forget
107
? secret = null
108
: secret || (secret = secretCreatorFn(object));
109
}
110
}
111
112
defProp(object, brand, vault);
113
}
114
115
function accessor(object) {
116
if (!hasOwn.call(object, brand))
117
register(object);
118
return object[brand](passkey);
119
}
120
121
accessor.forget = function(object) {
122
if (hasOwn.call(object, brand))
123
object[brand](passkey, true);
124
};
125
126
return accessor;
127
}
128
129
defProp(exports, "makeAccessor", makeAccessor);
130
131