bippy 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +467 -117
- package/dist/core.cjs +745 -0
- package/dist/core.d.cts +196 -0
- package/dist/core.d.ts +196 -0
- package/dist/core.js +687 -0
- package/dist/extract/index.cjs +1019 -0
- package/dist/extract/index.d.cts +42 -0
- package/dist/extract/index.d.ts +42 -0
- package/dist/extract/index.global.js +9 -0
- package/dist/extract/index.js +1013 -0
- package/dist/index.cjs +322 -179
- package/dist/index.d.cts +6 -210
- package/dist/index.d.ts +6 -210
- package/dist/index.global.js +4 -5
- package/dist/index.js +295 -179
- package/dist/scan/index.cjs +1079 -0
- package/dist/scan/index.d.cts +24 -0
- package/dist/scan/index.d.ts +24 -0
- package/dist/scan/index.global.js +9 -0
- package/dist/scan/index.js +1071 -0
- package/dist/types-BqcvCznx.d.cts +69 -0
- package/dist/types-BqcvCznx.d.ts +69 -0
- package/package.json +22 -15
|
@@ -0,0 +1,1013 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license bippy
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Aiden Bai, Million Software, Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// src/rdt-hook.ts
|
|
11
|
+
var version = "0.2.0";
|
|
12
|
+
var BIPPY_INSTRUMENTATION_STRING = `bippy-${version}`;
|
|
13
|
+
var NO_OP = () => {
|
|
14
|
+
};
|
|
15
|
+
var checkDCE = (fn) => {
|
|
16
|
+
try {
|
|
17
|
+
const code = Function.prototype.toString.call(fn);
|
|
18
|
+
if (code.indexOf("^_^") > -1) {
|
|
19
|
+
setTimeout(() => {
|
|
20
|
+
throw new Error(
|
|
21
|
+
"React is running in production mode, but dead code elimination has not been applied. Read how to correctly configure React for production: https://reactjs.org/link/perf-use-production-build"
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
} catch {
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
var installRDTHook = (onActive) => {
|
|
29
|
+
const renderers = /* @__PURE__ */ new Map();
|
|
30
|
+
let i = 0;
|
|
31
|
+
const rdtHook = {
|
|
32
|
+
checkDCE,
|
|
33
|
+
supportsFiber: true,
|
|
34
|
+
supportsFlight: true,
|
|
35
|
+
hasUnsupportedRendererAttached: false,
|
|
36
|
+
renderers,
|
|
37
|
+
onCommitFiberRoot: NO_OP,
|
|
38
|
+
onCommitFiberUnmount: NO_OP,
|
|
39
|
+
onPostCommitFiberRoot: NO_OP,
|
|
40
|
+
inject(renderer) {
|
|
41
|
+
const nextID = ++i;
|
|
42
|
+
renderers.set(nextID, renderer);
|
|
43
|
+
if (!rdtHook._instrumentationIsActive) {
|
|
44
|
+
rdtHook._instrumentationIsActive = true;
|
|
45
|
+
onActive?.();
|
|
46
|
+
}
|
|
47
|
+
return nextID;
|
|
48
|
+
},
|
|
49
|
+
_instrumentationSource: BIPPY_INSTRUMENTATION_STRING,
|
|
50
|
+
_instrumentationIsActive: false
|
|
51
|
+
};
|
|
52
|
+
try {
|
|
53
|
+
Object.defineProperty(globalThis, "__REACT_DEVTOOLS_GLOBAL_HOOK__", {
|
|
54
|
+
value: rdtHook
|
|
55
|
+
});
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
return rdtHook;
|
|
59
|
+
};
|
|
60
|
+
var hasRDTHook = () => {
|
|
61
|
+
return Object.prototype.hasOwnProperty.call(
|
|
62
|
+
globalThis,
|
|
63
|
+
"__REACT_DEVTOOLS_GLOBAL_HOOK__"
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
var getRDTHook = (onActive) => {
|
|
67
|
+
let rdtHook = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
|
68
|
+
if (rdtHook) onActive?.();
|
|
69
|
+
if (!hasRDTHook()) {
|
|
70
|
+
rdtHook = installRDTHook(onActive);
|
|
71
|
+
}
|
|
72
|
+
return rdtHook;
|
|
73
|
+
};
|
|
74
|
+
try {
|
|
75
|
+
if (typeof window !== "undefined" && // @ts-expect-error `document` may not be defined in some enviroments
|
|
76
|
+
(window.document?.createElement || window.navigator?.product === "ReactNative") && typeof process !== "undefined" && process.versions != null && process.versions.node != null) {
|
|
77
|
+
installRDTHook();
|
|
78
|
+
}
|
|
79
|
+
} catch {
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/core.ts
|
|
83
|
+
var FunctionComponentTag = 0;
|
|
84
|
+
var ClassComponentTag = 1;
|
|
85
|
+
var HostRootTag = 3;
|
|
86
|
+
var HostComponentTag = 5;
|
|
87
|
+
var HostTextTag = 6;
|
|
88
|
+
var FragmentTag = 7;
|
|
89
|
+
var ContextConsumerTag = 9;
|
|
90
|
+
var ForwardRefTag = 11;
|
|
91
|
+
var SuspenseComponentTag = 13;
|
|
92
|
+
var MemoComponentTag = 14;
|
|
93
|
+
var SimpleMemoComponentTag = 15;
|
|
94
|
+
var DehydratedSuspenseComponentTag = 18;
|
|
95
|
+
var OffscreenComponentTag = 22;
|
|
96
|
+
var LegacyHiddenComponentTag = 23;
|
|
97
|
+
var HostHoistableTag = 26;
|
|
98
|
+
var HostSingletonTag = 27;
|
|
99
|
+
var CONCURRENT_MODE_NUMBER = 60111;
|
|
100
|
+
var CONCURRENT_MODE_SYMBOL_STRING = "Symbol(react.concurrent_mode)";
|
|
101
|
+
var DEPRECATED_ASYNC_MODE_SYMBOL_STRING = "Symbol(react.async_mode)";
|
|
102
|
+
var PerformedWork = 1;
|
|
103
|
+
var isHostFiber = (fiber) => {
|
|
104
|
+
switch (fiber.tag) {
|
|
105
|
+
case HostComponentTag:
|
|
106
|
+
// @ts-expect-error: it exists
|
|
107
|
+
case HostHoistableTag:
|
|
108
|
+
// @ts-expect-error: it exists
|
|
109
|
+
case HostSingletonTag:
|
|
110
|
+
return true;
|
|
111
|
+
default:
|
|
112
|
+
return typeof fiber.type === "string";
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
var isCompositeFiber = (fiber) => {
|
|
116
|
+
switch (fiber.tag) {
|
|
117
|
+
case FunctionComponentTag:
|
|
118
|
+
case ClassComponentTag:
|
|
119
|
+
case SimpleMemoComponentTag:
|
|
120
|
+
case MemoComponentTag:
|
|
121
|
+
case ForwardRefTag:
|
|
122
|
+
return true;
|
|
123
|
+
default:
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
var traverseProps = (fiber, selector) => {
|
|
128
|
+
try {
|
|
129
|
+
const nextProps = fiber.memoizedProps;
|
|
130
|
+
const prevProps = fiber.alternate?.memoizedProps || {};
|
|
131
|
+
const allKeys = /* @__PURE__ */ new Set([
|
|
132
|
+
...Object.keys(prevProps),
|
|
133
|
+
...Object.keys(nextProps)
|
|
134
|
+
]);
|
|
135
|
+
for (const propName of allKeys) {
|
|
136
|
+
const prevValue = prevProps?.[propName];
|
|
137
|
+
const nextValue = nextProps?.[propName];
|
|
138
|
+
if (selector(propName, nextValue, prevValue) === true) return true;
|
|
139
|
+
}
|
|
140
|
+
} catch {
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
};
|
|
144
|
+
var didFiberRender = (fiber) => {
|
|
145
|
+
const nextProps = fiber.memoizedProps;
|
|
146
|
+
const prevProps = fiber.alternate?.memoizedProps || {};
|
|
147
|
+
const flags = fiber.flags ?? fiber.effectTag ?? 0;
|
|
148
|
+
switch (fiber.tag) {
|
|
149
|
+
case ClassComponentTag:
|
|
150
|
+
case FunctionComponentTag:
|
|
151
|
+
case ContextConsumerTag:
|
|
152
|
+
case ForwardRefTag:
|
|
153
|
+
case MemoComponentTag:
|
|
154
|
+
case SimpleMemoComponentTag: {
|
|
155
|
+
return (flags & PerformedWork) === PerformedWork;
|
|
156
|
+
}
|
|
157
|
+
default:
|
|
158
|
+
if (!fiber.alternate) return true;
|
|
159
|
+
return prevProps !== nextProps || fiber.alternate.memoizedState !== fiber.memoizedState || fiber.alternate.ref !== fiber.ref;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
var getFiberStack = (fiber) => {
|
|
163
|
+
const stack = [];
|
|
164
|
+
let currentFiber = fiber;
|
|
165
|
+
while (currentFiber.return) {
|
|
166
|
+
stack.push(currentFiber);
|
|
167
|
+
currentFiber = currentFiber.return;
|
|
168
|
+
}
|
|
169
|
+
const newStack = new Array(stack.length);
|
|
170
|
+
for (let i = 0; i < stack.length; i++) {
|
|
171
|
+
newStack[i] = stack[stack.length - i - 1];
|
|
172
|
+
}
|
|
173
|
+
return newStack;
|
|
174
|
+
};
|
|
175
|
+
var shouldFilterFiber = (fiber) => {
|
|
176
|
+
switch (fiber.tag) {
|
|
177
|
+
case DehydratedSuspenseComponentTag:
|
|
178
|
+
return true;
|
|
179
|
+
case HostTextTag:
|
|
180
|
+
case FragmentTag:
|
|
181
|
+
case LegacyHiddenComponentTag:
|
|
182
|
+
case OffscreenComponentTag:
|
|
183
|
+
return true;
|
|
184
|
+
case HostRootTag:
|
|
185
|
+
return false;
|
|
186
|
+
default: {
|
|
187
|
+
const symbolOrNumber = typeof fiber.type === "object" && fiber.type !== null ? fiber.type.$$typeof : fiber.type;
|
|
188
|
+
const typeSymbol = typeof symbolOrNumber === "symbol" ? symbolOrNumber.toString() : symbolOrNumber;
|
|
189
|
+
switch (typeSymbol) {
|
|
190
|
+
case CONCURRENT_MODE_NUMBER:
|
|
191
|
+
case CONCURRENT_MODE_SYMBOL_STRING:
|
|
192
|
+
case DEPRECATED_ASYNC_MODE_SYMBOL_STRING:
|
|
193
|
+
return true;
|
|
194
|
+
default:
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
var getNearestHostFiber = (fiber, ascending = false) => {
|
|
201
|
+
let hostFiber = traverseFiber(fiber, isHostFiber, ascending);
|
|
202
|
+
if (!hostFiber) {
|
|
203
|
+
hostFiber = traverseFiber(fiber, isHostFiber, !ascending);
|
|
204
|
+
}
|
|
205
|
+
return hostFiber;
|
|
206
|
+
};
|
|
207
|
+
var traverseFiber = (fiber, selector, ascending = false) => {
|
|
208
|
+
if (!fiber) return null;
|
|
209
|
+
if (selector(fiber) === true) return fiber;
|
|
210
|
+
let child = ascending ? fiber.return : fiber.child;
|
|
211
|
+
while (child) {
|
|
212
|
+
const match = traverseFiber(child, selector, ascending);
|
|
213
|
+
if (match) return match;
|
|
214
|
+
child = ascending ? null : child.sibling;
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
};
|
|
218
|
+
var getType = (type) => {
|
|
219
|
+
const currentType = type;
|
|
220
|
+
if (typeof currentType === "function") {
|
|
221
|
+
return currentType;
|
|
222
|
+
}
|
|
223
|
+
if (typeof currentType === "object" && currentType) {
|
|
224
|
+
return getType(
|
|
225
|
+
currentType.type || currentType.render
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
return null;
|
|
229
|
+
};
|
|
230
|
+
var getDisplayName = (type) => {
|
|
231
|
+
const currentType = type;
|
|
232
|
+
if (typeof currentType !== "function" && !(typeof currentType === "object" && currentType)) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
const name = currentType.displayName || currentType.name || null;
|
|
236
|
+
if (name) return name;
|
|
237
|
+
const unwrappedType = getType(currentType);
|
|
238
|
+
if (!unwrappedType) return null;
|
|
239
|
+
return unwrappedType.displayName || unwrappedType.name || null;
|
|
240
|
+
};
|
|
241
|
+
var isUsingRDT = () => {
|
|
242
|
+
return "reactDevtoolsAgent" in getRDTHook();
|
|
243
|
+
};
|
|
244
|
+
var detectReactBuildType = (renderer) => {
|
|
245
|
+
try {
|
|
246
|
+
if (typeof renderer.version === "string" && renderer.bundleType > 0) {
|
|
247
|
+
return "development";
|
|
248
|
+
}
|
|
249
|
+
} catch {
|
|
250
|
+
}
|
|
251
|
+
return "production";
|
|
252
|
+
};
|
|
253
|
+
var fiberId = 0;
|
|
254
|
+
var fiberIdMap = /* @__PURE__ */ new WeakMap();
|
|
255
|
+
var setFiberId = (fiber, id = fiberId++) => {
|
|
256
|
+
fiberIdMap.set(fiber, id);
|
|
257
|
+
};
|
|
258
|
+
var getFiberId = (fiber) => {
|
|
259
|
+
let id = fiberIdMap.get(fiber);
|
|
260
|
+
if (!id && fiber.alternate) {
|
|
261
|
+
id = fiberIdMap.get(fiber.alternate);
|
|
262
|
+
}
|
|
263
|
+
if (!id) {
|
|
264
|
+
id = fiberId++;
|
|
265
|
+
setFiberId(fiber, id);
|
|
266
|
+
}
|
|
267
|
+
return id;
|
|
268
|
+
};
|
|
269
|
+
var mountFiberRecursively = (onRender, firstChild, traverseSiblings) => {
|
|
270
|
+
let fiber = firstChild;
|
|
271
|
+
while (fiber != null) {
|
|
272
|
+
if (!fiberIdMap.has(fiber)) {
|
|
273
|
+
getFiberId(fiber);
|
|
274
|
+
}
|
|
275
|
+
const shouldIncludeInTree = !shouldFilterFiber(fiber);
|
|
276
|
+
if (shouldIncludeInTree && didFiberRender(fiber)) {
|
|
277
|
+
onRender(fiber, "mount");
|
|
278
|
+
}
|
|
279
|
+
if (fiber.tag === SuspenseComponentTag) {
|
|
280
|
+
const isTimedOut = fiber.memoizedState !== null;
|
|
281
|
+
if (isTimedOut) {
|
|
282
|
+
const primaryChildFragment = fiber.child;
|
|
283
|
+
const fallbackChildFragment = primaryChildFragment ? primaryChildFragment.sibling : null;
|
|
284
|
+
if (fallbackChildFragment) {
|
|
285
|
+
const fallbackChild = fallbackChildFragment.child;
|
|
286
|
+
if (fallbackChild !== null) {
|
|
287
|
+
mountFiberRecursively(onRender, fallbackChild, false);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
} else {
|
|
291
|
+
let primaryChild = null;
|
|
292
|
+
if (fiber.child !== null) {
|
|
293
|
+
primaryChild = fiber.child.child;
|
|
294
|
+
}
|
|
295
|
+
if (primaryChild !== null) {
|
|
296
|
+
mountFiberRecursively(onRender, primaryChild, false);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
} else if (fiber.child != null) {
|
|
300
|
+
mountFiberRecursively(onRender, fiber.child, true);
|
|
301
|
+
}
|
|
302
|
+
fiber = traverseSiblings ? fiber.sibling : null;
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
var updateFiberRecursively = (onRender, nextFiber, prevFiber, parentFiber) => {
|
|
306
|
+
if (!fiberIdMap.has(nextFiber)) {
|
|
307
|
+
getFiberId(nextFiber);
|
|
308
|
+
}
|
|
309
|
+
if (!prevFiber) return;
|
|
310
|
+
if (!fiberIdMap.has(prevFiber)) {
|
|
311
|
+
getFiberId(prevFiber);
|
|
312
|
+
}
|
|
313
|
+
const isSuspense = nextFiber.tag === SuspenseComponentTag;
|
|
314
|
+
const shouldIncludeInTree = !shouldFilterFiber(nextFiber);
|
|
315
|
+
if (shouldIncludeInTree && didFiberRender(nextFiber)) {
|
|
316
|
+
onRender(nextFiber, "update");
|
|
317
|
+
}
|
|
318
|
+
const prevDidTimeout = isSuspense && prevFiber.memoizedState !== null;
|
|
319
|
+
const nextDidTimeOut = isSuspense && nextFiber.memoizedState !== null;
|
|
320
|
+
if (prevDidTimeout && nextDidTimeOut) {
|
|
321
|
+
const nextFallbackChildSet = nextFiber.child?.sibling ?? null;
|
|
322
|
+
const prevFallbackChildSet = prevFiber.child?.sibling ?? null;
|
|
323
|
+
if (nextFallbackChildSet !== null && prevFallbackChildSet !== null) {
|
|
324
|
+
updateFiberRecursively(
|
|
325
|
+
onRender,
|
|
326
|
+
nextFallbackChildSet,
|
|
327
|
+
prevFallbackChildSet);
|
|
328
|
+
}
|
|
329
|
+
} else if (prevDidTimeout && !nextDidTimeOut) {
|
|
330
|
+
const nextPrimaryChildSet = nextFiber.child;
|
|
331
|
+
if (nextPrimaryChildSet !== null) {
|
|
332
|
+
mountFiberRecursively(onRender, nextPrimaryChildSet, true);
|
|
333
|
+
}
|
|
334
|
+
} else if (!prevDidTimeout && nextDidTimeOut) {
|
|
335
|
+
unmountFiberChildrenRecursively(onRender, prevFiber);
|
|
336
|
+
const nextFallbackChildSet = nextFiber.child?.sibling ?? null;
|
|
337
|
+
if (nextFallbackChildSet !== null) {
|
|
338
|
+
mountFiberRecursively(onRender, nextFallbackChildSet, true);
|
|
339
|
+
}
|
|
340
|
+
} else if (nextFiber.child !== prevFiber.child) {
|
|
341
|
+
let nextChild = nextFiber.child;
|
|
342
|
+
while (nextChild) {
|
|
343
|
+
if (nextChild.alternate) {
|
|
344
|
+
const prevChild = nextChild.alternate;
|
|
345
|
+
updateFiberRecursively(
|
|
346
|
+
onRender,
|
|
347
|
+
nextChild,
|
|
348
|
+
prevChild);
|
|
349
|
+
} else {
|
|
350
|
+
mountFiberRecursively(onRender, nextChild, false);
|
|
351
|
+
}
|
|
352
|
+
nextChild = nextChild.sibling;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
var unmountFiber = (onRender, fiber) => {
|
|
357
|
+
const isRoot = fiber.tag === HostRootTag;
|
|
358
|
+
if (isRoot || !shouldFilterFiber(fiber)) {
|
|
359
|
+
onRender(fiber, "unmount");
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
var unmountFiberChildrenRecursively = (onRender, fiber) => {
|
|
363
|
+
const isTimedOutSuspense = fiber.tag === SuspenseComponentTag && fiber.memoizedState !== null;
|
|
364
|
+
let child = fiber.child;
|
|
365
|
+
if (isTimedOutSuspense) {
|
|
366
|
+
const primaryChildFragment = fiber.child;
|
|
367
|
+
const fallbackChildFragment = primaryChildFragment?.sibling ?? null;
|
|
368
|
+
child = fallbackChildFragment?.child ?? null;
|
|
369
|
+
}
|
|
370
|
+
while (child !== null) {
|
|
371
|
+
if (child.return !== null) {
|
|
372
|
+
unmountFiber(onRender, child);
|
|
373
|
+
unmountFiberChildrenRecursively(onRender, child);
|
|
374
|
+
}
|
|
375
|
+
child = child.sibling;
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
var commitId = 0;
|
|
379
|
+
var rootInstanceMap = /* @__PURE__ */ new WeakMap();
|
|
380
|
+
var traverseRenderedFibers = (root, onRender) => {
|
|
381
|
+
const fiber = "current" in root ? root.current : root;
|
|
382
|
+
let rootInstance = rootInstanceMap.get(root);
|
|
383
|
+
if (!rootInstance) {
|
|
384
|
+
rootInstance = { prevFiber: null, id: commitId++ };
|
|
385
|
+
rootInstanceMap.set(root, rootInstance);
|
|
386
|
+
}
|
|
387
|
+
const { prevFiber } = rootInstance;
|
|
388
|
+
if (!fiber) {
|
|
389
|
+
unmountFiber(onRender, fiber);
|
|
390
|
+
} else if (prevFiber !== null) {
|
|
391
|
+
const wasMounted = prevFiber && prevFiber.memoizedState != null && prevFiber.memoizedState.element != null && // A dehydrated root is not considered mounted
|
|
392
|
+
prevFiber.memoizedState.isDehydrated !== true;
|
|
393
|
+
const isMounted = fiber.memoizedState != null && fiber.memoizedState.element != null && // A dehydrated root is not considered mounted
|
|
394
|
+
fiber.memoizedState.isDehydrated !== true;
|
|
395
|
+
if (!wasMounted && isMounted) {
|
|
396
|
+
mountFiberRecursively(onRender, fiber, false);
|
|
397
|
+
} else if (wasMounted && isMounted) {
|
|
398
|
+
updateFiberRecursively(onRender, fiber, fiber.alternate);
|
|
399
|
+
} else if (wasMounted && !isMounted) {
|
|
400
|
+
unmountFiber(onRender, fiber);
|
|
401
|
+
}
|
|
402
|
+
} else {
|
|
403
|
+
mountFiberRecursively(onRender, fiber, true);
|
|
404
|
+
}
|
|
405
|
+
rootInstance.prevFiber = fiber;
|
|
406
|
+
};
|
|
407
|
+
var createFiberVisitor = ({
|
|
408
|
+
onRender
|
|
409
|
+
}) => {
|
|
410
|
+
return (_rendererID, root, _state) => {
|
|
411
|
+
traverseRenderedFibers(root, onRender);
|
|
412
|
+
};
|
|
413
|
+
};
|
|
414
|
+
var instrument = (options) => {
|
|
415
|
+
return getRDTHook(() => {
|
|
416
|
+
const rdtHook = getRDTHook();
|
|
417
|
+
options.onActive?.();
|
|
418
|
+
rdtHook._instrumentationSource = options.name ?? BIPPY_INSTRUMENTATION_STRING;
|
|
419
|
+
const prevOnCommitFiberRoot = rdtHook.onCommitFiberRoot;
|
|
420
|
+
if (options.onCommitFiberRoot) {
|
|
421
|
+
rdtHook.onCommitFiberRoot = (rendererID, root, priority) => {
|
|
422
|
+
if (prevOnCommitFiberRoot)
|
|
423
|
+
prevOnCommitFiberRoot(rendererID, root, priority);
|
|
424
|
+
options.onCommitFiberRoot?.(rendererID, root, priority);
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
const prevOnCommitFiberUnmount = rdtHook.onCommitFiberUnmount;
|
|
428
|
+
if (options.onCommitFiberUnmount) {
|
|
429
|
+
rdtHook.onCommitFiberUnmount = (rendererID, root) => {
|
|
430
|
+
if (prevOnCommitFiberUnmount)
|
|
431
|
+
prevOnCommitFiberUnmount(rendererID, root);
|
|
432
|
+
options.onCommitFiberUnmount?.(rendererID, root);
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
const prevOnPostCommitFiberRoot = rdtHook.onPostCommitFiberRoot;
|
|
436
|
+
if (options.onPostCommitFiberRoot) {
|
|
437
|
+
rdtHook.onPostCommitFiberRoot = (rendererID, root) => {
|
|
438
|
+
if (prevOnPostCommitFiberRoot)
|
|
439
|
+
prevOnPostCommitFiberRoot(rendererID, root);
|
|
440
|
+
options.onPostCommitFiberRoot?.(rendererID, root);
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
};
|
|
445
|
+
var getFiberFromHostInstance = (hostInstance) => {
|
|
446
|
+
const rdtHook = getRDTHook();
|
|
447
|
+
for (const renderer of rdtHook.renderers.values()) {
|
|
448
|
+
try {
|
|
449
|
+
const fiber = renderer.findFiberByHostInstance?.(hostInstance);
|
|
450
|
+
if (fiber) return fiber;
|
|
451
|
+
} catch {
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
if (typeof hostInstance === "object" && hostInstance != null) {
|
|
455
|
+
if ("_reactRootContainer" in hostInstance) {
|
|
456
|
+
return hostInstance._reactRootContainer?._internalRoot?.current?.child;
|
|
457
|
+
}
|
|
458
|
+
for (const key in hostInstance) {
|
|
459
|
+
if (key.startsWith("__reactInternalInstance$") || key.startsWith("__reactFiber")) {
|
|
460
|
+
return hostInstance[key];
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return null;
|
|
465
|
+
};
|
|
466
|
+
var secure = (options, secureOptions = {}) => {
|
|
467
|
+
const onActive = options.onActive;
|
|
468
|
+
const isRDTHookInstalled = hasRDTHook();
|
|
469
|
+
const isRDT = isUsingRDT();
|
|
470
|
+
let timeout;
|
|
471
|
+
let isProduction = false;
|
|
472
|
+
options.onActive = () => {
|
|
473
|
+
clearTimeout(timeout);
|
|
474
|
+
let isSecure = true;
|
|
475
|
+
try {
|
|
476
|
+
onActive?.();
|
|
477
|
+
const rdtHook = getRDTHook();
|
|
478
|
+
for (const renderer of rdtHook.renderers.values()) {
|
|
479
|
+
const [majorVersion] = renderer.version.split(".");
|
|
480
|
+
if (Number(majorVersion) < (secureOptions.minReactMajorVersion ?? 17)) {
|
|
481
|
+
isSecure = false;
|
|
482
|
+
}
|
|
483
|
+
const buildType = detectReactBuildType(renderer);
|
|
484
|
+
if (buildType !== "development") {
|
|
485
|
+
isProduction = true;
|
|
486
|
+
if (!secureOptions.dangerouslyRunInProduction) {
|
|
487
|
+
isSecure = false;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
} catch (err) {
|
|
492
|
+
secureOptions.onError?.(err);
|
|
493
|
+
}
|
|
494
|
+
if (!isSecure) {
|
|
495
|
+
options.onCommitFiberRoot = void 0;
|
|
496
|
+
options.onCommitFiberUnmount = void 0;
|
|
497
|
+
options.onPostCommitFiberRoot = void 0;
|
|
498
|
+
options.onActive = void 0;
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
try {
|
|
502
|
+
const onCommitFiberRoot = options.onCommitFiberRoot;
|
|
503
|
+
if (onCommitFiberRoot) {
|
|
504
|
+
options.onCommitFiberRoot = (rendererID, root, priority) => {
|
|
505
|
+
try {
|
|
506
|
+
onCommitFiberRoot(rendererID, root, priority);
|
|
507
|
+
} catch (err) {
|
|
508
|
+
secureOptions.onError?.(err);
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
const onCommitFiberUnmount = options.onCommitFiberUnmount;
|
|
513
|
+
if (onCommitFiberUnmount) {
|
|
514
|
+
options.onCommitFiberUnmount = (rendererID, root) => {
|
|
515
|
+
try {
|
|
516
|
+
onCommitFiberUnmount(rendererID, root);
|
|
517
|
+
} catch (err) {
|
|
518
|
+
secureOptions.onError?.(err);
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
const onPostCommitFiberRoot = options.onPostCommitFiberRoot;
|
|
523
|
+
if (onPostCommitFiberRoot) {
|
|
524
|
+
options.onPostCommitFiberRoot = (rendererID, root) => {
|
|
525
|
+
try {
|
|
526
|
+
onPostCommitFiberRoot(rendererID, root);
|
|
527
|
+
} catch (err) {
|
|
528
|
+
secureOptions.onError?.(err);
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
} catch (err) {
|
|
533
|
+
secureOptions.onError?.(err);
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
if (!isRDTHookInstalled && !isRDT) {
|
|
537
|
+
timeout = setTimeout(() => {
|
|
538
|
+
if (!isProduction) {
|
|
539
|
+
secureOptions.onError?.();
|
|
540
|
+
}
|
|
541
|
+
stop();
|
|
542
|
+
}, secureOptions.installCheckTimeout ?? 100);
|
|
543
|
+
}
|
|
544
|
+
return options;
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
// src/extract/index.ts
|
|
548
|
+
var ReactSpecNodeType = /* @__PURE__ */ ((ReactSpecNodeType2) => {
|
|
549
|
+
ReactSpecNodeType2["Component"] = "component";
|
|
550
|
+
ReactSpecNodeType2["Element"] = "element";
|
|
551
|
+
ReactSpecNodeType2["A11y"] = "a11y";
|
|
552
|
+
return ReactSpecNodeType2;
|
|
553
|
+
})(ReactSpecNodeType || {});
|
|
554
|
+
var fiberRoots = /* @__PURE__ */ new Set();
|
|
555
|
+
var getDpr = () => {
|
|
556
|
+
return Math.min(window.devicePixelRatio || 1, 2);
|
|
557
|
+
};
|
|
558
|
+
var CANVAS_HTML_STR = `<canvas style="position:fixed;top:0;left:0;pointer-events:none;z-index:2147483646" aria-hidden="true"></canvas>`;
|
|
559
|
+
var primaryColor = "115,97,230";
|
|
560
|
+
var lerp = (start, end) => {
|
|
561
|
+
return Math.floor(start + (end - start) * 0.2);
|
|
562
|
+
};
|
|
563
|
+
var init = () => {
|
|
564
|
+
let hasInitedIds = false;
|
|
565
|
+
let prevX;
|
|
566
|
+
let prevY;
|
|
567
|
+
let isAnimating = false;
|
|
568
|
+
const handleFiber = (fiber) => {
|
|
569
|
+
getFiberId(fiber);
|
|
570
|
+
};
|
|
571
|
+
const visit = createFiberVisitor({
|
|
572
|
+
onRender: handleFiber,
|
|
573
|
+
onError(error) {
|
|
574
|
+
console.error(error);
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
instrument(
|
|
578
|
+
secure(
|
|
579
|
+
{
|
|
580
|
+
onActive() {
|
|
581
|
+
globalThis.__RST__ = true;
|
|
582
|
+
},
|
|
583
|
+
onCommitFiberRoot(rendererID, root) {
|
|
584
|
+
fiberRoots.add(root);
|
|
585
|
+
if (!hasInitedIds) {
|
|
586
|
+
traverseFiber(root, handleFiber);
|
|
587
|
+
hasInitedIds = true;
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
visit(rendererID, root);
|
|
591
|
+
}
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
dangerouslyRunInProduction: true,
|
|
595
|
+
onError: (error) => {
|
|
596
|
+
if (error) {
|
|
597
|
+
console.error(error);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
)
|
|
602
|
+
);
|
|
603
|
+
let focusedElement = null;
|
|
604
|
+
let focusedFiber = null;
|
|
605
|
+
let text = null;
|
|
606
|
+
const draw = async () => {
|
|
607
|
+
if (!ctx) return;
|
|
608
|
+
const currentElement = focusedElement;
|
|
609
|
+
if (!currentElement) {
|
|
610
|
+
clear();
|
|
611
|
+
return false;
|
|
612
|
+
}
|
|
613
|
+
const elements = [currentElement];
|
|
614
|
+
if (focusedFiber) {
|
|
615
|
+
traverseFiber(focusedFiber, (fiber) => {
|
|
616
|
+
if (isHostFiber(fiber)) {
|
|
617
|
+
elements.push(fiber.stateNode);
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
const rectMap = await getRectMap(elements);
|
|
622
|
+
const currentRect = rectMap.get(currentElement);
|
|
623
|
+
if (!currentRect) return false;
|
|
624
|
+
clear();
|
|
625
|
+
let shouldContinueAnimating = false;
|
|
626
|
+
const interpolatedX = prevX !== void 0 ? lerp(prevX, currentRect.x) : currentRect.x;
|
|
627
|
+
const interpolatedY = prevY !== void 0 ? lerp(prevY, currentRect.y) : currentRect.y;
|
|
628
|
+
if (prevX !== void 0 && (Math.abs(interpolatedX - currentRect.x) > 0.1 || Math.abs(interpolatedY - currentRect.y) > 0.1)) {
|
|
629
|
+
shouldContinueAnimating = true;
|
|
630
|
+
}
|
|
631
|
+
for (const element of elements) {
|
|
632
|
+
const rect = rectMap.get(element);
|
|
633
|
+
if (!rect) continue;
|
|
634
|
+
const { width: width2, height: height2 } = rect;
|
|
635
|
+
const x = element === currentElement ? interpolatedX : rect.x;
|
|
636
|
+
const y = element === currentElement ? interpolatedY : rect.y;
|
|
637
|
+
ctx.beginPath();
|
|
638
|
+
ctx.rect(x, y, width2, height2);
|
|
639
|
+
ctx.strokeStyle = `rgba(${primaryColor},0.5)`;
|
|
640
|
+
if (currentElement === element) {
|
|
641
|
+
ctx.fillStyle = `rgba(${primaryColor},0.1)`;
|
|
642
|
+
ctx.strokeStyle = `rgba(${primaryColor})`;
|
|
643
|
+
ctx.fill();
|
|
644
|
+
}
|
|
645
|
+
ctx.stroke();
|
|
646
|
+
}
|
|
647
|
+
if (text) {
|
|
648
|
+
const { width: textWidth } = ctx.measureText(text);
|
|
649
|
+
const textHeight = 11;
|
|
650
|
+
ctx.textRendering = "optimizeSpeed";
|
|
651
|
+
ctx.font = "11px monospace";
|
|
652
|
+
let labelY = interpolatedY - textHeight - 4;
|
|
653
|
+
if (labelY < 0) {
|
|
654
|
+
labelY = 0;
|
|
655
|
+
}
|
|
656
|
+
ctx.fillStyle = `rgba(${primaryColor})`;
|
|
657
|
+
ctx.fillRect(interpolatedX, labelY, textWidth + 4, textHeight + 4);
|
|
658
|
+
ctx.fillStyle = "rgba(255,255,255)";
|
|
659
|
+
ctx.fillText(text, interpolatedX + 2, labelY + textHeight);
|
|
660
|
+
prevX = interpolatedX;
|
|
661
|
+
prevY = interpolatedY;
|
|
662
|
+
}
|
|
663
|
+
return shouldContinueAnimating;
|
|
664
|
+
};
|
|
665
|
+
const animate = async () => {
|
|
666
|
+
if (!isAnimating) return;
|
|
667
|
+
const shouldContinue = await draw();
|
|
668
|
+
if (shouldContinue) {
|
|
669
|
+
requestAnimationFrame(animate);
|
|
670
|
+
} else {
|
|
671
|
+
isAnimating = false;
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
const startAnimation = () => {
|
|
675
|
+
if (!isAnimating) {
|
|
676
|
+
isAnimating = true;
|
|
677
|
+
requestAnimationFrame(animate);
|
|
678
|
+
}
|
|
679
|
+
};
|
|
680
|
+
document.addEventListener("contextmenu", async (event) => {
|
|
681
|
+
if (event.button !== 2) return;
|
|
682
|
+
const target = event.target;
|
|
683
|
+
const fiber = getFiberFromHostInstance(event.target);
|
|
684
|
+
focusedElement = target;
|
|
685
|
+
if (fiber) {
|
|
686
|
+
focusedFiber = fiber;
|
|
687
|
+
const stack = getFiberStack(fiber);
|
|
688
|
+
const displayNames = stack.map((fiber2) => getDisplayName(fiber2));
|
|
689
|
+
const orderedDisplayNames = [];
|
|
690
|
+
let count = 0;
|
|
691
|
+
let nearestCompositeFiber = null;
|
|
692
|
+
let currentFiber = fiber;
|
|
693
|
+
while (currentFiber) {
|
|
694
|
+
if (isCompositeFiber(currentFiber)) {
|
|
695
|
+
nearestCompositeFiber = currentFiber;
|
|
696
|
+
break;
|
|
697
|
+
}
|
|
698
|
+
currentFiber = currentFiber.return;
|
|
699
|
+
}
|
|
700
|
+
for (let i = displayNames.length - 1; i >= 0; i--) {
|
|
701
|
+
const displayName = displayNames[i];
|
|
702
|
+
if (displayName) {
|
|
703
|
+
orderedDisplayNames.push(displayName);
|
|
704
|
+
count++;
|
|
705
|
+
}
|
|
706
|
+
if (count > 2) break;
|
|
707
|
+
}
|
|
708
|
+
text = orderedDisplayNames.join(" > ");
|
|
709
|
+
const rst = await createRSTWithFiber(
|
|
710
|
+
nearestCompositeFiber || fiber,
|
|
711
|
+
target
|
|
712
|
+
);
|
|
713
|
+
console.log(rst);
|
|
714
|
+
} else {
|
|
715
|
+
focusedFiber = null;
|
|
716
|
+
text = target.tagName.toLowerCase();
|
|
717
|
+
const rst = await createRSTWithElement(target);
|
|
718
|
+
console.log(rst);
|
|
719
|
+
}
|
|
720
|
+
startAnimation();
|
|
721
|
+
});
|
|
722
|
+
const clear = () => {
|
|
723
|
+
if (!ctx) return;
|
|
724
|
+
ctx.clearRect(0, 0, canvas.width / dpr, canvas.height / dpr);
|
|
725
|
+
};
|
|
726
|
+
const host = document.createElement("div");
|
|
727
|
+
host.setAttribute("data-react-scan", "true");
|
|
728
|
+
const shadowRoot = host.attachShadow({ mode: "open" });
|
|
729
|
+
shadowRoot.innerHTML = CANVAS_HTML_STR;
|
|
730
|
+
const canvas = shadowRoot.firstChild;
|
|
731
|
+
if (!canvas) return null;
|
|
732
|
+
let dpr = Math.min(window.devicePixelRatio || 1, 2);
|
|
733
|
+
const { innerWidth, innerHeight } = window;
|
|
734
|
+
canvas.style.width = `${innerWidth}px`;
|
|
735
|
+
canvas.style.height = `${innerHeight}px`;
|
|
736
|
+
const width = innerWidth * dpr;
|
|
737
|
+
const height = innerHeight * dpr;
|
|
738
|
+
canvas.width = width;
|
|
739
|
+
canvas.height = height;
|
|
740
|
+
const ctx = canvas.getContext("2d", { alpha: true });
|
|
741
|
+
if (ctx) {
|
|
742
|
+
ctx.scale(dpr, dpr);
|
|
743
|
+
}
|
|
744
|
+
let isResizeScheduled = false;
|
|
745
|
+
window.addEventListener("resize", () => {
|
|
746
|
+
if (!isResizeScheduled) {
|
|
747
|
+
isResizeScheduled = true;
|
|
748
|
+
setTimeout(() => {
|
|
749
|
+
const width2 = window.innerWidth;
|
|
750
|
+
const height2 = window.innerHeight;
|
|
751
|
+
dpr = getDpr();
|
|
752
|
+
canvas.style.width = `${width2}px`;
|
|
753
|
+
canvas.style.height = `${height2}px`;
|
|
754
|
+
canvas.width = width2 * dpr;
|
|
755
|
+
canvas.height = height2 * dpr;
|
|
756
|
+
if (ctx) {
|
|
757
|
+
ctx.resetTransform();
|
|
758
|
+
ctx.scale(dpr, dpr);
|
|
759
|
+
}
|
|
760
|
+
startAnimation();
|
|
761
|
+
isResizeScheduled = false;
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
});
|
|
765
|
+
let isScrollScheduled = false;
|
|
766
|
+
window.addEventListener("scroll", () => {
|
|
767
|
+
if (!isScrollScheduled) {
|
|
768
|
+
isScrollScheduled = true;
|
|
769
|
+
setTimeout(() => {
|
|
770
|
+
requestAnimationFrame(() => {
|
|
771
|
+
startAnimation();
|
|
772
|
+
});
|
|
773
|
+
isScrollScheduled = false;
|
|
774
|
+
}, 16 * 2);
|
|
775
|
+
}
|
|
776
|
+
});
|
|
777
|
+
let prevFocusedElement = null;
|
|
778
|
+
setInterval(() => {
|
|
779
|
+
if (prevFocusedElement === focusedElement) {
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
prevFocusedElement = focusedElement;
|
|
783
|
+
startAnimation();
|
|
784
|
+
}, 16 * 2);
|
|
785
|
+
shadowRoot.appendChild(canvas);
|
|
786
|
+
document.documentElement.appendChild(host);
|
|
787
|
+
};
|
|
788
|
+
init();
|
|
789
|
+
var createRSTWithFiber = async (fiber, element) => {
|
|
790
|
+
const root = await createRSTNode(fiber, element);
|
|
791
|
+
return { root };
|
|
792
|
+
};
|
|
793
|
+
var createRSTWithElement = async (element) => {
|
|
794
|
+
const root = await createRSTNodeFromElement(element);
|
|
795
|
+
return { root };
|
|
796
|
+
};
|
|
797
|
+
var createElementNode = async (element) => {
|
|
798
|
+
const rectMap = await getRectMap([element]);
|
|
799
|
+
const rect = rectMap.get(element) || element.getBoundingClientRect();
|
|
800
|
+
const computedStyle = window.getComputedStyle(element);
|
|
801
|
+
const styles = {};
|
|
802
|
+
Array.from({ length: computedStyle.length }).forEach((_, i) => {
|
|
803
|
+
const prop = computedStyle[i];
|
|
804
|
+
styles[prop] = computedStyle.getPropertyValue(prop);
|
|
805
|
+
});
|
|
806
|
+
return {
|
|
807
|
+
type: "element" /* Element */,
|
|
808
|
+
children: [],
|
|
809
|
+
x: rect.x,
|
|
810
|
+
y: rect.y,
|
|
811
|
+
width: rect.width,
|
|
812
|
+
height: rect.height,
|
|
813
|
+
eventHandlers: {},
|
|
814
|
+
classes: Array.from(element.classList),
|
|
815
|
+
styles,
|
|
816
|
+
element
|
|
817
|
+
};
|
|
818
|
+
};
|
|
819
|
+
var createA11yNode = (base, role, ariaLabel) => {
|
|
820
|
+
return {
|
|
821
|
+
...base,
|
|
822
|
+
type: "a11y" /* A11y */,
|
|
823
|
+
role,
|
|
824
|
+
ariaLabel
|
|
825
|
+
};
|
|
826
|
+
};
|
|
827
|
+
var createRSTNodeFromElement = async (element) => {
|
|
828
|
+
const base = await createElementNode(element);
|
|
829
|
+
for (const attr of Array.from(element.attributes)) {
|
|
830
|
+
if (attr.name.startsWith("on")) {
|
|
831
|
+
base.eventHandlers[attr.name] = attr.value;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
base.children = await Promise.all(
|
|
835
|
+
Array.from(element.children).map(createRSTNodeFromElement)
|
|
836
|
+
);
|
|
837
|
+
const role = element.getAttribute("role");
|
|
838
|
+
const ariaLabel = element.getAttribute("aria-label");
|
|
839
|
+
if (role || ariaLabel) {
|
|
840
|
+
return createA11yNode(base, role, ariaLabel);
|
|
841
|
+
}
|
|
842
|
+
return base;
|
|
843
|
+
};
|
|
844
|
+
var createRSTNode = async (fiber, element) => {
|
|
845
|
+
if (isCompositeFiber(fiber)) {
|
|
846
|
+
const props = {};
|
|
847
|
+
traverseProps(fiber, (propName, nextValue) => {
|
|
848
|
+
props[propName] = nextValue;
|
|
849
|
+
});
|
|
850
|
+
const children = [];
|
|
851
|
+
const childPromises = [];
|
|
852
|
+
traverseFiber(fiber.child, (childFiber) => {
|
|
853
|
+
if (isHostFiber(childFiber) && childFiber.stateNode) {
|
|
854
|
+
childPromises.push(
|
|
855
|
+
createRSTNode(childFiber, childFiber.stateNode).then((node) => {
|
|
856
|
+
children.push(node);
|
|
857
|
+
})
|
|
858
|
+
);
|
|
859
|
+
} else if (isCompositeFiber(childFiber)) {
|
|
860
|
+
const hostFiber = getNearestHostFiber(childFiber);
|
|
861
|
+
if (hostFiber?.stateNode) {
|
|
862
|
+
childPromises.push(
|
|
863
|
+
createRSTNode(childFiber, hostFiber.stateNode).then((node) => {
|
|
864
|
+
children.push(node);
|
|
865
|
+
})
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
});
|
|
870
|
+
await Promise.all(childPromises);
|
|
871
|
+
return {
|
|
872
|
+
type: "component" /* Component */,
|
|
873
|
+
children,
|
|
874
|
+
props,
|
|
875
|
+
name: getDisplayName(fiber.type)
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
if (isHostFiber(fiber)) {
|
|
879
|
+
const base = await createElementNode(element);
|
|
880
|
+
traverseProps(fiber, (propName, value) => {
|
|
881
|
+
if (propName.startsWith("on") && typeof value === "function") {
|
|
882
|
+
base.eventHandlers[propName] = value.toString();
|
|
883
|
+
}
|
|
884
|
+
});
|
|
885
|
+
base.children = [];
|
|
886
|
+
const childPromises = [];
|
|
887
|
+
traverseFiber(fiber.child, (childFiber) => {
|
|
888
|
+
if (isHostFiber(childFiber) && childFiber.stateNode) {
|
|
889
|
+
childPromises.push(
|
|
890
|
+
createRSTNode(childFiber, childFiber.stateNode).then((node) => {
|
|
891
|
+
base.children.push(node);
|
|
892
|
+
})
|
|
893
|
+
);
|
|
894
|
+
} else if (isCompositeFiber(childFiber)) {
|
|
895
|
+
const hostFiber = getNearestHostFiber(childFiber);
|
|
896
|
+
if (hostFiber?.stateNode) {
|
|
897
|
+
childPromises.push(
|
|
898
|
+
createRSTNode(childFiber, hostFiber.stateNode).then((node) => {
|
|
899
|
+
base.children.push(node);
|
|
900
|
+
})
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
});
|
|
905
|
+
await Promise.all(childPromises);
|
|
906
|
+
const role = element.getAttribute("role");
|
|
907
|
+
const ariaLabel = element.getAttribute("aria-label");
|
|
908
|
+
if (role || ariaLabel) {
|
|
909
|
+
return createA11yNode(base, role, ariaLabel);
|
|
910
|
+
}
|
|
911
|
+
return base;
|
|
912
|
+
}
|
|
913
|
+
throw new Error("Unknown fiber type");
|
|
914
|
+
};
|
|
915
|
+
var getRectMap = (elements) => {
|
|
916
|
+
return new Promise((resolve) => {
|
|
917
|
+
const rects = /* @__PURE__ */ new Map();
|
|
918
|
+
const observer = new IntersectionObserver((entries) => {
|
|
919
|
+
for (let i = 0, len = entries.length; i < len; i++) {
|
|
920
|
+
const entry = entries[i];
|
|
921
|
+
const element = entry.target;
|
|
922
|
+
const rect = entry.boundingClientRect;
|
|
923
|
+
if (entry.isIntersecting && rect.width && rect.height) {
|
|
924
|
+
rects.set(element, rect);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
observer.disconnect();
|
|
928
|
+
resolve(rects);
|
|
929
|
+
});
|
|
930
|
+
for (let i = 0, len = elements.length; i < len; i++) {
|
|
931
|
+
const element = elements[i];
|
|
932
|
+
observer.observe(element);
|
|
933
|
+
}
|
|
934
|
+
});
|
|
935
|
+
};
|
|
936
|
+
var stringifyWithCircularCheck = (value, seen = /* @__PURE__ */ new WeakSet()) => {
|
|
937
|
+
if (value === null || value === void 0) {
|
|
938
|
+
return String(value);
|
|
939
|
+
}
|
|
940
|
+
if (typeof value === "function") {
|
|
941
|
+
return value.toString().slice(0, 50) + (value.toString().length > 50 ? "..." : "");
|
|
942
|
+
}
|
|
943
|
+
if (typeof value !== "object") {
|
|
944
|
+
return JSON.stringify(value);
|
|
945
|
+
}
|
|
946
|
+
if (seen.has(value)) {
|
|
947
|
+
return "[Circular]";
|
|
948
|
+
}
|
|
949
|
+
seen.add(value);
|
|
950
|
+
if (Array.isArray(value)) {
|
|
951
|
+
const items = value.map((item) => stringifyWithCircularCheck(item, seen));
|
|
952
|
+
return `[${items.join(", ")}]`;
|
|
953
|
+
}
|
|
954
|
+
try {
|
|
955
|
+
const pairs = Object.entries(value).map(
|
|
956
|
+
([key, val]) => `${key}: ${stringifyWithCircularCheck(val, seen)}`
|
|
957
|
+
);
|
|
958
|
+
return `{${pairs.join(", ")}}`;
|
|
959
|
+
} catch {
|
|
960
|
+
return "[Object]";
|
|
961
|
+
}
|
|
962
|
+
};
|
|
963
|
+
var printRST = (tree, indent = 0) => {
|
|
964
|
+
const printNode = (node, indent2) => {
|
|
965
|
+
const spaces = " ".repeat(indent2);
|
|
966
|
+
if (node.type === "component" /* Component */ && "props" in node && "name" in node) {
|
|
967
|
+
const props = Object.entries(node.props).map(([key, value]) => `${key}={${stringifyWithCircularCheck(value)}}`).join(" ");
|
|
968
|
+
return `${spaces}<${node.name || "Unknown"}${props ? ` ${props}` : ""}>
|
|
969
|
+
${node.children.map((child) => printNode(child, indent2 + 1)).join("\n")}
|
|
970
|
+
${spaces}</${node.name || "Unknown"}>`;
|
|
971
|
+
}
|
|
972
|
+
const attrs = [];
|
|
973
|
+
if ("classes" in node && node.classes.length > 0) {
|
|
974
|
+
attrs.push(`class="${node.classes.join(" ")}"`);
|
|
975
|
+
}
|
|
976
|
+
if ("eventHandlers" in node) {
|
|
977
|
+
const eventHandlerAttrs = Object.entries(node.eventHandlers).map(
|
|
978
|
+
([event, handler]) => `${event}={${handler.slice(0, 50)}${handler.length > 50 ? "..." : ""}}`
|
|
979
|
+
).join(" ");
|
|
980
|
+
if (eventHandlerAttrs) {
|
|
981
|
+
attrs.push(eventHandlerAttrs);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
if ("styles" in node) {
|
|
985
|
+
const styleStr = stringifyWithCircularCheck(node.styles);
|
|
986
|
+
if (styleStr !== "{}") {
|
|
987
|
+
attrs.push(`style={${styleStr}}`);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
if (node.type === "a11y" /* A11y */ && "role" in node && "ariaLabel" in node) {
|
|
991
|
+
if (node.role) attrs.push(`role="${node.role}"`);
|
|
992
|
+
if (node.ariaLabel) attrs.push(`aria-label="${node.ariaLabel}"`);
|
|
993
|
+
}
|
|
994
|
+
if ("x" in node && "y" in node && "width" in node && "height" in node) {
|
|
995
|
+
const dimensions = `x=${Math.round(node.x)} y=${Math.round(node.y)} w=${Math.round(node.width)} h=${Math.round(node.height)}`;
|
|
996
|
+
attrs.push(dimensions);
|
|
997
|
+
}
|
|
998
|
+
const tagName = "element" in node ? node.element?.tagName.toLowerCase() || "unknown" : "unknown";
|
|
999
|
+
const attrsStr = attrs.length > 0 ? ` ${attrs.join(" ")}` : "";
|
|
1000
|
+
if (node.children.length === 0) {
|
|
1001
|
+
return `${spaces}<${tagName}${attrsStr} />`;
|
|
1002
|
+
}
|
|
1003
|
+
return `${spaces}<${tagName}${attrsStr}>
|
|
1004
|
+
${node.children.map((child) => printNode(child, indent2 + 1)).join("\n")}
|
|
1005
|
+
${spaces}</${tagName}>`;
|
|
1006
|
+
};
|
|
1007
|
+
if (!("type" in tree.root)) {
|
|
1008
|
+
throw new Error("Invalid RST: root node must have a type");
|
|
1009
|
+
}
|
|
1010
|
+
return printNode(tree.root, indent);
|
|
1011
|
+
};
|
|
1012
|
+
|
|
1013
|
+
export { ReactSpecNodeType, getRectMap, init, primaryColor, printRST };
|