Repository navigation
Expand file tree
/
Copy pathindex.js
More file actions
170 lines (152 loc) · 5.25 KB
/
Copy pathindex.js
File metadata and controls
170 lines (152 loc) · 5.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/* global Map:readonly, Set:readonly, ArrayBuffer:readonly */
var hasElementType = typeof Element !== 'undefined';
var hasMap = typeof Map === 'function';
var hasSet = typeof Set === 'function';
var hasArrayBuffer = typeof ArrayBuffer === 'function' && !!ArrayBuffer.isView;
// Note: We **don't** need `envHasBigInt64Array` in fde es6/index.js
/**
* @param {any} a
* @param {any} b
* @returns {boolean}
*/
function equal(a, b) {
// START: fast-deep-equal es6/index.js 3.1.3
if (a === b) return true;
if (a && b && typeof a == 'object' && typeof b == 'object') {
if (a.constructor !== b.constructor) return false;
var length, i, keys;
if (Array.isArray(a)) {
length = a.length;
if (length != b.length) return false;
for (i = length; i-- !== 0;) if (!equal(a[i], b[i])) return false;
return true;
}
// START: Modifications:
// 1. Extra `has<Type> &&` helpers in initial condition allow es6 code
// to co-exist with es5.
// 2. Replace `for of` with es5 compliant iteration using `for`.
// Basically, take:
//
// ```js
// for (i of a.entries())
// if (!b.has(i[0])) return false;
// ```
//
// ... and convert to:
//
// ```js
// it = a.entries();
// while (!(i = it.next()).done)
// if (!b.has(i.value[0])) return false;
// ```
//
// **Note**: `i` access switches to `i.value`.
var it;
if (hasMap && a instanceof Map && b instanceof Map) {
if (a.size !== b.size) return false;
it = a.entries();
while (!(i = it.next()).done) if (!b.has(i.value[0])) return false;
it = a.entries();
while (!(i = it.next()).done)
if (!equal(i.value[1], b.get(i.value[0]))) return false;
return true;
}
if (hasSet && a instanceof Set && b instanceof Set) {
if (a.size !== b.size) return false;
it = a.entries();
while (!(i = it.next()).done) if (!b.has(i.value[0])) return false;
return true;
}
// END: Modifications
// Types: the casts stop `isView()` narrowing `a` and `b` to
// `ArrayBufferView`, which has no `length` or index signature (typed
// arrays have both, a `DataView` has neither).
if (
hasArrayBuffer &&
ArrayBuffer.isView(/** @type {unknown} */ (a)) &&
ArrayBuffer.isView(/** @type {unknown} */ (b))
) {
length = a.length;
if (length != b.length) return false;
for (i = length; i-- !== 0;) if (a[i] !== b[i]) return false;
return true;
}
if (a.constructor === RegExp)
return a.source === b.source && a.flags === b.flags;
// START: Modifications:
// Apply guards for `Object.create(null)` handling. See:
// - https://github.com/FormidableLabs/react-fast-compare/issues/64
// - https://github.com/epoberezkin/fast-deep-equal/issues/49
if (
a.valueOf !== Object.prototype.valueOf &&
typeof a.valueOf === 'function' &&
typeof b.valueOf === 'function'
)
return a.valueOf() === b.valueOf();
if (
a.toString !== Object.prototype.toString &&
typeof a.toString === 'function' &&
typeof b.toString === 'function'
)
return a.toString() === b.toString();
// END: Modifications
keys = Object.keys(a);
length = keys.length;
if (length !== Object.keys(b).length) return false;
for (i = length; i-- !== 0;)
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
// END: fast-deep-equal
// START: react-fast-compare
// custom handling for DOM elements
if (hasElementType && a instanceof Element) return false;
// custom handling for React/Preact
for (i = length; i-- !== 0;) {
if (
(keys[i] === '_owner' || keys[i] === '__v' || keys[i] === '__o') &&
a.$$typeof
) {
// React-specific: avoid traversing React elements' _owner
// Preact-specific: avoid traversing Preact elements' __v and __o
// __v = $_original / $_vnode
// __o = $_owner
// These properties contain circular references and are not needed when
// comparing the actual elements (and not their owners)
// .$$typeof and ._store on just reasonable markers of elements
continue;
}
// all other properties should be traversed as usual
if (!equal(a[keys[i]], b[keys[i]])) return false;
}
// END: react-fast-compare
// START: fast-deep-equal
return true;
}
return a !== a && b !== b;
}
// end fast-deep-equal
/**
* Deep equality check, tuned for React elements.
*
* @template [A=any]
* @template [B=any]
* @param {A} a
* @param {B} b
* @returns {boolean}
*/
module.exports = function isEqual(a, b) {
try {
return equal(a, b);
} catch (/** @type {any} */ error) {
if ((error.message || '').match(/stack|recursion/i)) {
// warn on circular references, don't crash
// browsers give this different errors name and messages:
// chrome/safari: "RangeError", "Maximum call stack size exceeded"
// firefox: "InternalError", too much recursion"
// edge: "Error", "Out of stack space"
console.warn('react-fast-compare cannot handle circular refs');
return false;
}
// some other error. we should definitely know about these
throw error;
}
};