@replohq/sandbox-runtime 1.6.0 → 1.6.2
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/_vendor/schemas/generated/selectModeIframeRpc.d.ts +8 -1
- package/_vendor/schemas/selectModeIframeRpc.d.ts +126 -0
- package/_vendor/schemas/selectModeIframeRpc.mjs +10 -2
- package/buildMetadata.js +3 -3
- package/package.json +4 -4
- package/select-mode/descriptor/styleExtraction.js +67 -0
- package/select-mode/descriptor/styleExtraction.js.map +2 -2
- package/select-mode/fiber.d.ts +8 -1
- package/select-mode/fiber.js +37 -1
- package/select-mode/fiber.js.map +2 -2
- package/select-mode/hooks/useOptimisticOverrides.js +11 -8
- package/select-mode/hooks/useOptimisticOverrides.js.map +2 -2
- package/select-mode/optimisticOverrideDom.d.ts +2 -0
- package/select-mode/optimisticOverrideDom.js +7 -0
- package/select-mode/optimisticOverrideDom.js.map +7 -0
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type { DisplayMode, SelectModeSelectionType, SelectModeOptimisticUpdatePayload, SelectModeFormatCommand, SelectableData, SelectModeBoundingRect, SelectModeClickPosition, SelectModeSelectionRect, SelectModeTiptapActiveMarks } from "./selectMode";
|
|
1
|
+
import type { SelectedElement, DisplayMode, SelectModeSelectionType, SelectModeOptimisticUpdatePayload, SelectModeFormatCommand, SelectableData, SelectModeBoundingRect, SelectModeClickPosition, SelectModeSelectionRect, SelectModeTiptapActiveMarks } from "./selectMode";
|
|
2
|
+
export type SelectedComponentEditRequest = {
|
|
3
|
+
siteId: string;
|
|
4
|
+
element: SelectedElement;
|
|
5
|
+
};
|
|
2
6
|
export type IframeRuntimeBuildMetadata = {
|
|
3
7
|
packageName: string;
|
|
4
8
|
version: string;
|
|
@@ -7,6 +11,9 @@ export type IframeRuntimeBuildMetadata = {
|
|
|
7
11
|
builtAt: string | null;
|
|
8
12
|
};
|
|
9
13
|
export type SelectModeParentMessage = {
|
|
14
|
+
method: "editSelectedComponent";
|
|
15
|
+
data: SelectedComponentEditRequest;
|
|
16
|
+
} | {
|
|
10
17
|
method: "setDisplayMode";
|
|
11
18
|
data: {
|
|
12
19
|
displayMode: DisplayMode;
|
|
@@ -9,6 +9,68 @@ export declare const iframeRuntimeBuildMetadataSchema: z.ZodObject<{
|
|
|
9
9
|
commit: z.ZodNullable<z.ZodString>;
|
|
10
10
|
builtAt: z.ZodNullable<z.ZodString>;
|
|
11
11
|
}, z.core.$strip>;
|
|
12
|
+
export declare const selectedComponentEditRequestSchema: z.ZodObject<{
|
|
13
|
+
siteId: z.ZodUUID;
|
|
14
|
+
element: z.ZodObject<{
|
|
15
|
+
kind: z.ZodLiteral<"react-element">;
|
|
16
|
+
selector: z.ZodString;
|
|
17
|
+
tagName: z.ZodString;
|
|
18
|
+
elementType: z.ZodString;
|
|
19
|
+
textContent: z.ZodNullable<z.ZodString>;
|
|
20
|
+
rect: z.ZodObject<{
|
|
21
|
+
x: z.ZodNumber;
|
|
22
|
+
y: z.ZodNumber;
|
|
23
|
+
left: z.ZodNumber;
|
|
24
|
+
top: z.ZodNumber;
|
|
25
|
+
right: z.ZodNumber;
|
|
26
|
+
bottom: z.ZodNumber;
|
|
27
|
+
width: z.ZodNumber;
|
|
28
|
+
height: z.ZodNumber;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
textMetrics: z.ZodNullable<z.ZodObject<{
|
|
31
|
+
tightWidth: z.ZodNumber;
|
|
32
|
+
lineCount: z.ZodNumber;
|
|
33
|
+
lineHeight: z.ZodNumber;
|
|
34
|
+
}, z.core.$strip>>;
|
|
35
|
+
outerHTML: z.ZodString;
|
|
36
|
+
definedStyles: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
37
|
+
property: z.ZodString;
|
|
38
|
+
variant: z.ZodNullable<z.ZodObject<{
|
|
39
|
+
atRules: z.ZodArray<z.ZodObject<{
|
|
40
|
+
type: z.ZodString;
|
|
41
|
+
text: z.ZodString;
|
|
42
|
+
}, z.core.$strip>>;
|
|
43
|
+
pseudo: z.ZodNullable<z.ZodString>;
|
|
44
|
+
}, z.core.$strip>>;
|
|
45
|
+
className: z.ZodNullable<z.ZodString>;
|
|
46
|
+
raw: z.ZodString;
|
|
47
|
+
resolved: z.ZodString;
|
|
48
|
+
}, z.core.$strip>>>;
|
|
49
|
+
inheritedStyles: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
50
|
+
clickPosition: z.ZodObject<{
|
|
51
|
+
x: z.ZodNumber;
|
|
52
|
+
y: z.ZodNumber;
|
|
53
|
+
}, z.core.$strip>;
|
|
54
|
+
sourceLocation: z.ZodOptional<z.ZodObject<{
|
|
55
|
+
filePath: z.ZodString;
|
|
56
|
+
lineNumber: z.ZodNumber;
|
|
57
|
+
columnNumber: z.ZodOptional<z.ZodNumber>;
|
|
58
|
+
componentName: z.ZodOptional<z.ZodString>;
|
|
59
|
+
}, z.core.$strip>>;
|
|
60
|
+
fiberChain: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
61
|
+
sourceLocation: z.ZodObject<{
|
|
62
|
+
filePath: z.ZodString;
|
|
63
|
+
lineNumber: z.ZodNumber;
|
|
64
|
+
columnNumber: z.ZodOptional<z.ZodNumber>;
|
|
65
|
+
componentName: z.ZodOptional<z.ZodString>;
|
|
66
|
+
}, z.core.$strip>;
|
|
67
|
+
tagName: z.ZodOptional<z.ZodString>;
|
|
68
|
+
componentName: z.ZodOptional<z.ZodString>;
|
|
69
|
+
props: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
70
|
+
}, z.core.$strip>>>;
|
|
71
|
+
siblingSelectors: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
72
|
+
}, z.core.$strip>;
|
|
73
|
+
}, z.core.$strip>;
|
|
12
74
|
export declare const websiteBuilderToCanopyMethodConfig: {
|
|
13
75
|
symbolicateSelectedElement: {
|
|
14
76
|
inputSchema: z.ZodObject<{
|
|
@@ -572,6 +634,70 @@ export declare const canopyToWebsiteBuilderMethodConfig: {
|
|
|
572
634
|
};
|
|
573
635
|
};
|
|
574
636
|
export declare const selectModeParentMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
637
|
+
method: z.ZodLiteral<"editSelectedComponent">;
|
|
638
|
+
data: z.ZodObject<{
|
|
639
|
+
siteId: z.ZodUUID;
|
|
640
|
+
element: z.ZodObject<{
|
|
641
|
+
kind: z.ZodLiteral<"react-element">;
|
|
642
|
+
selector: z.ZodString;
|
|
643
|
+
tagName: z.ZodString;
|
|
644
|
+
elementType: z.ZodString;
|
|
645
|
+
textContent: z.ZodNullable<z.ZodString>;
|
|
646
|
+
rect: z.ZodObject<{
|
|
647
|
+
x: z.ZodNumber;
|
|
648
|
+
y: z.ZodNumber;
|
|
649
|
+
left: z.ZodNumber;
|
|
650
|
+
top: z.ZodNumber;
|
|
651
|
+
right: z.ZodNumber;
|
|
652
|
+
bottom: z.ZodNumber;
|
|
653
|
+
width: z.ZodNumber;
|
|
654
|
+
height: z.ZodNumber;
|
|
655
|
+
}, z.core.$strip>;
|
|
656
|
+
textMetrics: z.ZodNullable<z.ZodObject<{
|
|
657
|
+
tightWidth: z.ZodNumber;
|
|
658
|
+
lineCount: z.ZodNumber;
|
|
659
|
+
lineHeight: z.ZodNumber;
|
|
660
|
+
}, z.core.$strip>>;
|
|
661
|
+
outerHTML: z.ZodString;
|
|
662
|
+
definedStyles: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
663
|
+
property: z.ZodString;
|
|
664
|
+
variant: z.ZodNullable<z.ZodObject<{
|
|
665
|
+
atRules: z.ZodArray<z.ZodObject<{
|
|
666
|
+
type: z.ZodString;
|
|
667
|
+
text: z.ZodString;
|
|
668
|
+
}, z.core.$strip>>;
|
|
669
|
+
pseudo: z.ZodNullable<z.ZodString>;
|
|
670
|
+
}, z.core.$strip>>;
|
|
671
|
+
className: z.ZodNullable<z.ZodString>;
|
|
672
|
+
raw: z.ZodString;
|
|
673
|
+
resolved: z.ZodString;
|
|
674
|
+
}, z.core.$strip>>>;
|
|
675
|
+
inheritedStyles: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
676
|
+
clickPosition: z.ZodObject<{
|
|
677
|
+
x: z.ZodNumber;
|
|
678
|
+
y: z.ZodNumber;
|
|
679
|
+
}, z.core.$strip>;
|
|
680
|
+
sourceLocation: z.ZodOptional<z.ZodObject<{
|
|
681
|
+
filePath: z.ZodString;
|
|
682
|
+
lineNumber: z.ZodNumber;
|
|
683
|
+
columnNumber: z.ZodOptional<z.ZodNumber>;
|
|
684
|
+
componentName: z.ZodOptional<z.ZodString>;
|
|
685
|
+
}, z.core.$strip>>;
|
|
686
|
+
fiberChain: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
687
|
+
sourceLocation: z.ZodObject<{
|
|
688
|
+
filePath: z.ZodString;
|
|
689
|
+
lineNumber: z.ZodNumber;
|
|
690
|
+
columnNumber: z.ZodOptional<z.ZodNumber>;
|
|
691
|
+
componentName: z.ZodOptional<z.ZodString>;
|
|
692
|
+
}, z.core.$strip>;
|
|
693
|
+
tagName: z.ZodOptional<z.ZodString>;
|
|
694
|
+
componentName: z.ZodOptional<z.ZodString>;
|
|
695
|
+
props: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
696
|
+
}, z.core.$strip>>>;
|
|
697
|
+
siblingSelectors: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
698
|
+
}, z.core.$strip>;
|
|
699
|
+
}, z.core.$strip>;
|
|
700
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
575
701
|
method: z.ZodLiteral<"setDisplayMode">;
|
|
576
702
|
data: z.ZodObject<{
|
|
577
703
|
displayMode: z.ZodEnum<{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { selectModeFormatCommandSchema, selectModeOptimisticUpdatePayloadSchema, selectModeSelectionTypeSchema, displayModeSchema, selectModeTiptapActiveMarksSchema, selectModeBoundingRectSchema, selectableDataSchema, selectModeSelectionRectSchema, selectModeClickPositionSchema
|
|
1
|
+
import { selectedElementSchema, selectModeFormatCommandSchema, selectModeOptimisticUpdatePayloadSchema, selectModeSelectionTypeSchema, displayModeSchema, selectModeTiptapActiveMarksSchema, selectModeBoundingRectSchema, selectableDataSchema, selectModeSelectionRectSchema, selectModeClickPositionSchema } from '../../chunk-UOBGRB5I.mjs';
|
|
2
2
|
import '../../chunk-JUKCUPQ6.mjs';
|
|
3
3
|
import '../../chunk-FLYEIRFK.mjs';
|
|
4
4
|
import '../../chunk-TESFJQID.mjs';
|
|
@@ -14,6 +14,10 @@ var iframeRuntimeBuildMetadataSchema = z.object({
|
|
|
14
14
|
commit: z.string().nullable(),
|
|
15
15
|
builtAt: z.string().nullable()
|
|
16
16
|
}).describe("IframeRuntimeBuildMetadata");
|
|
17
|
+
var selectedComponentEditRequestSchema = z.object({
|
|
18
|
+
siteId: z.uuid(),
|
|
19
|
+
element: selectedElementSchema
|
|
20
|
+
}).describe("SelectedComponentEditRequest");
|
|
17
21
|
var websiteBuilderToCanopyMethodConfig = {
|
|
18
22
|
symbolicateSelectedElement: {
|
|
19
23
|
inputSchema: selectedElementSchema,
|
|
@@ -158,6 +162,10 @@ var canopyToWebsiteBuilderMethodConfig = {
|
|
|
158
162
|
}
|
|
159
163
|
};
|
|
160
164
|
var selectModeParentMessageSchema = z.discriminatedUnion("method", [
|
|
165
|
+
z.object({
|
|
166
|
+
method: z.literal("editSelectedComponent"),
|
|
167
|
+
data: selectedComponentEditRequestSchema
|
|
168
|
+
}),
|
|
161
169
|
z.object({
|
|
162
170
|
method: z.literal("setDisplayMode"),
|
|
163
171
|
data: websiteBuilderToCanopyMethodConfig.setDisplayMode.inputSchema
|
|
@@ -235,4 +243,4 @@ var selectModeIframeMessageSchema = z.discriminatedUnion("method", [
|
|
|
235
243
|
})
|
|
236
244
|
]).describe("SelectModeIframeMessage");
|
|
237
245
|
|
|
238
|
-
export { SELECT_MODE_IFRAME_RPC_CHANNEL_ID, SELECT_MODE_IFRAME_RPC_CHANNEL_VERSION, canopyToWebsiteBuilderMethodConfig, iframeRuntimeBuildMetadataSchema, selectModeIframeMessageSchema, selectModeParentMessageSchema, websiteBuilderToCanopyMethodConfig };
|
|
246
|
+
export { SELECT_MODE_IFRAME_RPC_CHANNEL_ID, SELECT_MODE_IFRAME_RPC_CHANNEL_VERSION, canopyToWebsiteBuilderMethodConfig, iframeRuntimeBuildMetadataSchema, selectModeIframeMessageSchema, selectModeParentMessageSchema, selectedComponentEditRequestSchema, websiteBuilderToCanopyMethodConfig };
|
package/buildMetadata.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const BUILD_METADATA = {
|
|
2
2
|
"packageName": "@replohq/sandbox-runtime",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"branch": "HEAD",
|
|
5
|
-
"commit": "
|
|
6
|
-
"builtAt": "2026-09-
|
|
5
|
+
"commit": "625dfbba5e75a1f3eeebb0cefa1bfeb1354c0de2",
|
|
6
|
+
"builtAt": "2026-09-11T22:39:30.736Z"
|
|
7
7
|
};
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@replohq/sandbox-runtime",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"reploBuild": {
|
|
5
5
|
"packageName": "@replohq/sandbox-runtime",
|
|
6
|
-
"version": "1.6.
|
|
6
|
+
"version": "1.6.2",
|
|
7
7
|
"branch": "HEAD",
|
|
8
|
-
"commit": "
|
|
9
|
-
"builtAt": "2026-09-
|
|
8
|
+
"commit": "625dfbba5e75a1f3eeebb0cefa1bfeb1354c0de2",
|
|
9
|
+
"builtAt": "2026-09-11T22:39:30.736Z"
|
|
10
10
|
},
|
|
11
11
|
"description": "Replo sandbox runtime — editor integration for agent-built Next.js sites.",
|
|
12
12
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SELECT_MODE_OVERRIDE_ATTRIBUTE,
|
|
3
|
+
SELECT_MODE_OVERRIDE_STYLE_ATTRIBUTE
|
|
4
|
+
} from "../optimisticOverrideDom";
|
|
1
5
|
const CONTROL_STYLE_PROPERTIES = [
|
|
2
6
|
"color",
|
|
3
7
|
"background-color",
|
|
@@ -250,10 +254,73 @@ function addInlineDefinedStyles({
|
|
|
250
254
|
});
|
|
251
255
|
}
|
|
252
256
|
}
|
|
257
|
+
function getOverrideStyleDeclarations(styleElement) {
|
|
258
|
+
const declarations = [];
|
|
259
|
+
const sheet = styleElement.sheet;
|
|
260
|
+
if (!sheet) {
|
|
261
|
+
return declarations;
|
|
262
|
+
}
|
|
263
|
+
for (const rule of Array.from(sheet.cssRules)) {
|
|
264
|
+
if (!(rule instanceof CSSStyleRule)) {
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
for (let styleIndex = 0; styleIndex < rule.style.length; styleIndex += 1) {
|
|
268
|
+
const property = rule.style.item(styleIndex);
|
|
269
|
+
if (!property) {
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
const raw = rule.style.getPropertyValue(property).trim();
|
|
273
|
+
if (raw) {
|
|
274
|
+
declarations.push({ property, raw });
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return declarations;
|
|
279
|
+
}
|
|
280
|
+
function addOptimisticDefinedStyles({
|
|
281
|
+
element,
|
|
282
|
+
definedStylesByKey
|
|
283
|
+
}) {
|
|
284
|
+
const tokens = (element.getAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE) ?? "").split(/\s+/).filter(Boolean);
|
|
285
|
+
if (tokens.length === 0) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const computedStyle = window.getComputedStyle(element);
|
|
289
|
+
for (const token of tokens) {
|
|
290
|
+
const styleElement = document.querySelector(
|
|
291
|
+
`style[${SELECT_MODE_OVERRIDE_STYLE_ATTRIBUTE}="${token}"]`
|
|
292
|
+
);
|
|
293
|
+
if (!styleElement) {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
for (const { property, raw } of getOverrideStyleDeclarations(
|
|
297
|
+
styleElement
|
|
298
|
+
)) {
|
|
299
|
+
if (!isControlStyleProperty(property)) {
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (raw.toLowerCase() === "revert") {
|
|
303
|
+
definedStylesByKey.delete(
|
|
304
|
+
getDefinedStyleKey({ property, variant: null })
|
|
305
|
+
);
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
setDefinedStyle({
|
|
309
|
+
definedStylesByKey,
|
|
310
|
+
property,
|
|
311
|
+
variant: null,
|
|
312
|
+
className: null,
|
|
313
|
+
raw,
|
|
314
|
+
resolved: computedStyle.getPropertyValue(property).trim() || raw
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
253
319
|
function getDefinedStyles(element) {
|
|
254
320
|
const definedStylesByKey = /* @__PURE__ */ new Map();
|
|
255
321
|
addClassDefinedStyles({ element, definedStylesByKey });
|
|
256
322
|
addInlineDefinedStyles({ element, definedStylesByKey });
|
|
323
|
+
addOptimisticDefinedStyles({ element, definedStylesByKey });
|
|
257
324
|
return Array.from(definedStylesByKey.values());
|
|
258
325
|
}
|
|
259
326
|
function getInheritedStyles(element) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../select-mode/descriptor/styleExtraction.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n SelectModeDefinedStyle,\n SelectModeStyleAtRule,\n SelectModeStyleVariant,\n} from \"schemas/generated/selectMode\";\n\nconst CONTROL_STYLE_PROPERTIES = [\n \"color\",\n \"background-color\",\n \"font-family\",\n \"font-size\",\n \"font-weight\",\n \"line-height\",\n \"letter-spacing\",\n \"text-align\",\n] as const;\n\ntype ControlStyleProperty = (typeof CONTROL_STYLE_PROPERTIES)[number];\n\nconst CONTROL_STYLE_PROPERTY_SET = new Set<string>(CONTROL_STYLE_PROPERTIES);\n\ntype SelectorMatch = {\n className: string;\n pseudo: string | null;\n};\n\nfunction isControlStyleProperty(\n propertyName: string,\n): propertyName is ControlStyleProperty {\n return CONTROL_STYLE_PROPERTY_SET.has(propertyName);\n}\n\nfunction getEscapedClassName(className: string) {\n return CSS.escape(className);\n}\n\nfunction getClassSelectorMatches({\n selectorText,\n classNames,\n}: {\n selectorText: string;\n classNames: string[];\n}): SelectorMatch[] {\n const matches: SelectorMatch[] = [];\n const selectorParts = selectorText.split(\",\").map((selectorPart) => {\n return selectorPart.trim();\n });\n\n for (const selectorPart of selectorParts) {\n for (const className of classNames) {\n const escapedClassName = getEscapedClassName(className);\n const baseSelector = `.${escapedClassName}`;\n if (selectorPart === baseSelector) {\n matches.push({ className, pseudo: null });\n continue;\n }\n\n if (!selectorPart.startsWith(`${baseSelector}:`)) {\n continue;\n }\n\n const pseudo = selectorPart.slice(baseSelector.length);\n const isSimplePseudoSelector =\n pseudo.startsWith(\":\") &&\n !/[ >+~#[.]/.test(pseudo) &&\n !pseudo.includes(\"::\");\n if (isSimplePseudoSelector) {\n matches.push({ className, pseudo });\n }\n }\n }\n\n return matches;\n}\n\nfunction getNestedAtRules({\n rule,\n activeAtRules,\n}: {\n rule: CSSRule;\n activeAtRules: SelectModeStyleAtRule[];\n}): SelectModeStyleAtRule[] {\n const nextAtRules = [...activeAtRules];\n if (rule instanceof CSSMediaRule) {\n nextAtRules.push({ type: \"@media\", text: rule.conditionText });\n } else if (rule instanceof CSSSupportsRule) {\n nextAtRules.push({ type: \"@supports\", text: rule.conditionText });\n } else if (\n rule.constructor?.name === \"CSSContainerRule\" &&\n \"conditionText\" in rule &&\n typeof rule.conditionText === \"string\"\n ) {\n nextAtRules.push({\n type: \"@container\",\n text: rule.conditionText,\n });\n }\n return nextAtRules;\n}\n\nfunction getNestedRuleList(rule: CSSRule): CSSRuleList | null {\n if (\n typeof CSSGroupingRule !== \"undefined\" &&\n rule instanceof CSSGroupingRule\n ) {\n return rule.cssRules;\n }\n return null;\n}\n\nfunction getStyleVariant({\n atRules,\n pseudo,\n}: {\n atRules: SelectModeStyleAtRule[];\n pseudo: string | null;\n}): SelectModeStyleVariant | null {\n if (atRules.length === 0 && !pseudo) {\n return null;\n }\n return { atRules, pseudo };\n}\n\nfunction getStyleVariantKey(variant: SelectModeStyleVariant | null) {\n return variant ? JSON.stringify(variant) : \"base\";\n}\n\nfunction getDefinedStyleKey({\n property,\n variant,\n}: {\n property: string;\n variant: SelectModeStyleVariant | null;\n}) {\n return `${property}:${getStyleVariantKey(variant)}`;\n}\n\nfunction getResolvedClassStyleValue({\n className,\n property,\n raw,\n variant,\n}: {\n className: string;\n property: string;\n raw: string;\n variant: SelectModeStyleVariant | null;\n}) {\n if (variant) {\n return raw;\n }\n\n const temporaryElement = document.createElement(\"div\");\n temporaryElement.className = className;\n document.body.append(temporaryElement);\n const resolved = window\n .getComputedStyle(temporaryElement)\n .getPropertyValue(property);\n temporaryElement.remove();\n\n return resolved.trim() || raw;\n}\n\nfunction setDefinedStyle({\n definedStylesByKey,\n property,\n variant,\n className,\n raw,\n resolved,\n}: {\n definedStylesByKey: Map<string, SelectModeDefinedStyle>;\n property: string;\n variant: SelectModeStyleVariant | null;\n className: string | null;\n raw: string;\n resolved: string;\n}) {\n definedStylesByKey.set(getDefinedStyleKey({ property, variant }), {\n property,\n variant,\n className,\n raw,\n resolved,\n });\n}\n\nfunction addRuleDefinedStyles({\n rule,\n activeAtRules,\n classNames,\n definedStylesByKey,\n}: {\n rule: CSSStyleRule;\n activeAtRules: SelectModeStyleAtRule[];\n classNames: string[];\n definedStylesByKey: Map<string, SelectModeDefinedStyle>;\n}) {\n const selectorMatches = getClassSelectorMatches({\n selectorText: rule.selectorText ?? \"\",\n classNames,\n });\n if (selectorMatches.length === 0) {\n return;\n }\n\n for (const selectorMatch of selectorMatches) {\n const variant = getStyleVariant({\n atRules: activeAtRules,\n pseudo: selectorMatch.pseudo,\n });\n\n for (let styleIndex = 0; styleIndex < rule.style.length; styleIndex += 1) {\n const property = rule.style.item(styleIndex);\n if (!property || !isControlStyleProperty(property)) {\n continue;\n }\n\n const raw = rule.style.getPropertyValue(property).trim();\n if (!raw) {\n continue;\n }\n\n setDefinedStyle({\n definedStylesByKey,\n property,\n variant,\n className: selectorMatch.className,\n raw,\n resolved: getResolvedClassStyleValue({\n className: selectorMatch.className,\n property,\n raw,\n variant,\n }),\n });\n }\n }\n}\n\nfunction addStyleRulesRecursively({\n ruleList,\n activeAtRules,\n classNames,\n definedStylesByKey,\n}: {\n ruleList: CSSRuleList;\n activeAtRules: SelectModeStyleAtRule[];\n classNames: string[];\n definedStylesByKey: Map<string, SelectModeDefinedStyle>;\n}) {\n for (const rule of Array.from(ruleList)) {\n const nestedRuleList = getNestedRuleList(rule);\n if (nestedRuleList) {\n addStyleRulesRecursively({\n ruleList: nestedRuleList,\n activeAtRules: getNestedAtRules({ rule, activeAtRules }),\n classNames,\n definedStylesByKey,\n });\n }\n\n if (rule instanceof CSSStyleRule) {\n addRuleDefinedStyles({\n rule,\n activeAtRules,\n classNames,\n definedStylesByKey,\n });\n }\n }\n}\n\nfunction addClassDefinedStyles({\n element,\n definedStylesByKey,\n}: {\n element: Element;\n definedStylesByKey: Map<string, SelectModeDefinedStyle>;\n}) {\n const classNames = Array.from(\n new Set([...element.classList].filter(Boolean)),\n );\n if (classNames.length === 0) {\n return;\n }\n\n for (const sheet of Array.from(document.styleSheets)) {\n if (sheet.href) {\n try {\n const sheetUrl = new URL(sheet.href);\n if (sheetUrl.origin !== window.location.origin) {\n continue;\n }\n } catch (error) {\n if (error instanceof TypeError) {\n continue;\n }\n throw error;\n }\n }\n\n try {\n addStyleRulesRecursively({\n ruleList: sheet.cssRules,\n activeAtRules: [],\n classNames,\n definedStylesByKey,\n });\n } catch (error) {\n if (error instanceof DOMException && error.name === \"SecurityError\") {\n continue;\n }\n throw error;\n }\n }\n}\n\nfunction addInlineDefinedStyles({\n element,\n definedStylesByKey,\n}: {\n element: Element;\n definedStylesByKey: Map<string, SelectModeDefinedStyle>;\n}) {\n if (!(element instanceof HTMLElement)) {\n return;\n }\n\n for (let styleIndex = 0; styleIndex < element.style.length; styleIndex += 1) {\n const property = element.style.item(styleIndex);\n if (!property || !isControlStyleProperty(property)) {\n continue;\n }\n const raw = element.style.getPropertyValue(property).trim();\n if (!raw) {\n continue;\n }\n setDefinedStyle({\n definedStylesByKey,\n property,\n variant: null,\n className: null,\n raw,\n resolved: raw,\n });\n }\n}\n\nexport function getDefinedStyles(element: Element): SelectModeDefinedStyle[] {\n const definedStylesByKey = new Map<string, SelectModeDefinedStyle>();\n addClassDefinedStyles({ element, definedStylesByKey });\n addInlineDefinedStyles({ element, definedStylesByKey });\n return Array.from(definedStylesByKey.values());\n}\n\nexport function getInheritedStyles(element: Element): Record<string, string> {\n const computedStyle = window.getComputedStyle(element);\n const inheritedStyles: Record<string, string> = {};\n for (const property of CONTROL_STYLE_PROPERTIES) {\n inheritedStyles[property] = computedStyle.getPropertyValue(property);\n }\n return inheritedStyles;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type {\n SelectModeDefinedStyle,\n SelectModeStyleAtRule,\n SelectModeStyleVariant,\n} from \"schemas/generated/selectMode\";\n\nimport {\n SELECT_MODE_OVERRIDE_ATTRIBUTE,\n SELECT_MODE_OVERRIDE_STYLE_ATTRIBUTE,\n} from \"../optimisticOverrideDom\";\n\nconst CONTROL_STYLE_PROPERTIES = [\n \"color\",\n \"background-color\",\n \"font-family\",\n \"font-size\",\n \"font-weight\",\n \"line-height\",\n \"letter-spacing\",\n \"text-align\",\n] as const;\n\ntype ControlStyleProperty = (typeof CONTROL_STYLE_PROPERTIES)[number];\n\nconst CONTROL_STYLE_PROPERTY_SET = new Set<string>(CONTROL_STYLE_PROPERTIES);\n\ntype SelectorMatch = {\n className: string;\n pseudo: string | null;\n};\n\nfunction isControlStyleProperty(\n propertyName: string,\n): propertyName is ControlStyleProperty {\n return CONTROL_STYLE_PROPERTY_SET.has(propertyName);\n}\n\nfunction getEscapedClassName(className: string) {\n return CSS.escape(className);\n}\n\nfunction getClassSelectorMatches({\n selectorText,\n classNames,\n}: {\n selectorText: string;\n classNames: string[];\n}): SelectorMatch[] {\n const matches: SelectorMatch[] = [];\n const selectorParts = selectorText.split(\",\").map((selectorPart) => {\n return selectorPart.trim();\n });\n\n for (const selectorPart of selectorParts) {\n for (const className of classNames) {\n const escapedClassName = getEscapedClassName(className);\n const baseSelector = `.${escapedClassName}`;\n if (selectorPart === baseSelector) {\n matches.push({ className, pseudo: null });\n continue;\n }\n\n if (!selectorPart.startsWith(`${baseSelector}:`)) {\n continue;\n }\n\n const pseudo = selectorPart.slice(baseSelector.length);\n const isSimplePseudoSelector =\n pseudo.startsWith(\":\") &&\n !/[ >+~#[.]/.test(pseudo) &&\n !pseudo.includes(\"::\");\n if (isSimplePseudoSelector) {\n matches.push({ className, pseudo });\n }\n }\n }\n\n return matches;\n}\n\nfunction getNestedAtRules({\n rule,\n activeAtRules,\n}: {\n rule: CSSRule;\n activeAtRules: SelectModeStyleAtRule[];\n}): SelectModeStyleAtRule[] {\n const nextAtRules = [...activeAtRules];\n if (rule instanceof CSSMediaRule) {\n nextAtRules.push({ type: \"@media\", text: rule.conditionText });\n } else if (rule instanceof CSSSupportsRule) {\n nextAtRules.push({ type: \"@supports\", text: rule.conditionText });\n } else if (\n rule.constructor?.name === \"CSSContainerRule\" &&\n \"conditionText\" in rule &&\n typeof rule.conditionText === \"string\"\n ) {\n nextAtRules.push({\n type: \"@container\",\n text: rule.conditionText,\n });\n }\n return nextAtRules;\n}\n\nfunction getNestedRuleList(rule: CSSRule): CSSRuleList | null {\n if (\n typeof CSSGroupingRule !== \"undefined\" &&\n rule instanceof CSSGroupingRule\n ) {\n return rule.cssRules;\n }\n return null;\n}\n\nfunction getStyleVariant({\n atRules,\n pseudo,\n}: {\n atRules: SelectModeStyleAtRule[];\n pseudo: string | null;\n}): SelectModeStyleVariant | null {\n if (atRules.length === 0 && !pseudo) {\n return null;\n }\n return { atRules, pseudo };\n}\n\nfunction getStyleVariantKey(variant: SelectModeStyleVariant | null) {\n return variant ? JSON.stringify(variant) : \"base\";\n}\n\nfunction getDefinedStyleKey({\n property,\n variant,\n}: {\n property: string;\n variant: SelectModeStyleVariant | null;\n}) {\n return `${property}:${getStyleVariantKey(variant)}`;\n}\n\nfunction getResolvedClassStyleValue({\n className,\n property,\n raw,\n variant,\n}: {\n className: string;\n property: string;\n raw: string;\n variant: SelectModeStyleVariant | null;\n}) {\n if (variant) {\n return raw;\n }\n\n const temporaryElement = document.createElement(\"div\");\n temporaryElement.className = className;\n document.body.append(temporaryElement);\n const resolved = window\n .getComputedStyle(temporaryElement)\n .getPropertyValue(property);\n temporaryElement.remove();\n\n return resolved.trim() || raw;\n}\n\nfunction setDefinedStyle({\n definedStylesByKey,\n property,\n variant,\n className,\n raw,\n resolved,\n}: {\n definedStylesByKey: Map<string, SelectModeDefinedStyle>;\n property: string;\n variant: SelectModeStyleVariant | null;\n className: string | null;\n raw: string;\n resolved: string;\n}) {\n definedStylesByKey.set(getDefinedStyleKey({ property, variant }), {\n property,\n variant,\n className,\n raw,\n resolved,\n });\n}\n\nfunction addRuleDefinedStyles({\n rule,\n activeAtRules,\n classNames,\n definedStylesByKey,\n}: {\n rule: CSSStyleRule;\n activeAtRules: SelectModeStyleAtRule[];\n classNames: string[];\n definedStylesByKey: Map<string, SelectModeDefinedStyle>;\n}) {\n const selectorMatches = getClassSelectorMatches({\n selectorText: rule.selectorText ?? \"\",\n classNames,\n });\n if (selectorMatches.length === 0) {\n return;\n }\n\n for (const selectorMatch of selectorMatches) {\n const variant = getStyleVariant({\n atRules: activeAtRules,\n pseudo: selectorMatch.pseudo,\n });\n\n for (let styleIndex = 0; styleIndex < rule.style.length; styleIndex += 1) {\n const property = rule.style.item(styleIndex);\n if (!property || !isControlStyleProperty(property)) {\n continue;\n }\n\n const raw = rule.style.getPropertyValue(property).trim();\n if (!raw) {\n continue;\n }\n\n setDefinedStyle({\n definedStylesByKey,\n property,\n variant,\n className: selectorMatch.className,\n raw,\n resolved: getResolvedClassStyleValue({\n className: selectorMatch.className,\n property,\n raw,\n variant,\n }),\n });\n }\n }\n}\n\nfunction addStyleRulesRecursively({\n ruleList,\n activeAtRules,\n classNames,\n definedStylesByKey,\n}: {\n ruleList: CSSRuleList;\n activeAtRules: SelectModeStyleAtRule[];\n classNames: string[];\n definedStylesByKey: Map<string, SelectModeDefinedStyle>;\n}) {\n for (const rule of Array.from(ruleList)) {\n const nestedRuleList = getNestedRuleList(rule);\n if (nestedRuleList) {\n addStyleRulesRecursively({\n ruleList: nestedRuleList,\n activeAtRules: getNestedAtRules({ rule, activeAtRules }),\n classNames,\n definedStylesByKey,\n });\n }\n\n if (rule instanceof CSSStyleRule) {\n addRuleDefinedStyles({\n rule,\n activeAtRules,\n classNames,\n definedStylesByKey,\n });\n }\n }\n}\n\nfunction addClassDefinedStyles({\n element,\n definedStylesByKey,\n}: {\n element: Element;\n definedStylesByKey: Map<string, SelectModeDefinedStyle>;\n}) {\n const classNames = Array.from(\n new Set([...element.classList].filter(Boolean)),\n );\n if (classNames.length === 0) {\n return;\n }\n\n for (const sheet of Array.from(document.styleSheets)) {\n if (sheet.href) {\n try {\n const sheetUrl = new URL(sheet.href);\n if (sheetUrl.origin !== window.location.origin) {\n continue;\n }\n } catch (error) {\n if (error instanceof TypeError) {\n continue;\n }\n throw error;\n }\n }\n\n try {\n addStyleRulesRecursively({\n ruleList: sheet.cssRules,\n activeAtRules: [],\n classNames,\n definedStylesByKey,\n });\n } catch (error) {\n if (error instanceof DOMException && error.name === \"SecurityError\") {\n continue;\n }\n throw error;\n }\n }\n}\n\nfunction addInlineDefinedStyles({\n element,\n definedStylesByKey,\n}: {\n element: Element;\n definedStylesByKey: Map<string, SelectModeDefinedStyle>;\n}) {\n if (!(element instanceof HTMLElement)) {\n return;\n }\n\n for (let styleIndex = 0; styleIndex < element.style.length; styleIndex += 1) {\n const property = element.style.item(styleIndex);\n if (!property || !isControlStyleProperty(property)) {\n continue;\n }\n const raw = element.style.getPropertyValue(property).trim();\n if (!raw) {\n continue;\n }\n setDefinedStyle({\n definedStylesByKey,\n property,\n variant: null,\n className: null,\n raw,\n resolved: raw,\n });\n }\n}\n\nfunction getOverrideStyleDeclarations(styleElement: HTMLStyleElement) {\n const declarations: { property: string; raw: string }[] = [];\n const sheet = styleElement.sheet;\n if (!sheet) {\n return declarations;\n }\n\n for (const rule of Array.from(sheet.cssRules)) {\n if (!(rule instanceof CSSStyleRule)) {\n continue;\n }\n\n for (let styleIndex = 0; styleIndex < rule.style.length; styleIndex += 1) {\n const property = rule.style.item(styleIndex);\n if (!property) {\n continue;\n }\n const raw = rule.style.getPropertyValue(property).trim();\n if (raw) {\n declarations.push({ property, raw });\n }\n }\n }\n\n return declarations;\n}\n\nfunction addOptimisticDefinedStyles({\n element,\n definedStylesByKey,\n}: {\n element: Element;\n definedStylesByKey: Map<string, SelectModeDefinedStyle>;\n}) {\n const tokens = (element.getAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE) ?? \"\")\n .split(/\\s+/)\n .filter(Boolean);\n if (tokens.length === 0) {\n return;\n }\n\n const computedStyle = window.getComputedStyle(element);\n for (const token of tokens) {\n const styleElement = document.querySelector<HTMLStyleElement>(\n `style[${SELECT_MODE_OVERRIDE_STYLE_ATTRIBUTE}=\"${token}\"]`,\n );\n if (!styleElement) {\n continue;\n }\n\n for (const { property, raw } of getOverrideStyleDeclarations(\n styleElement,\n )) {\n if (!isControlStyleProperty(property)) {\n continue;\n }\n\n if (raw.toLowerCase() === \"revert\") {\n definedStylesByKey.delete(\n getDefinedStyleKey({ property, variant: null }),\n );\n continue;\n }\n\n setDefinedStyle({\n definedStylesByKey,\n property,\n variant: null,\n className: null,\n raw,\n resolved: computedStyle.getPropertyValue(property).trim() || raw,\n });\n }\n }\n}\n\nexport function getDefinedStyles(element: Element): SelectModeDefinedStyle[] {\n const definedStylesByKey = new Map<string, SelectModeDefinedStyle>();\n addClassDefinedStyles({ element, definedStylesByKey });\n addInlineDefinedStyles({ element, definedStylesByKey });\n addOptimisticDefinedStyles({ element, definedStylesByKey });\n return Array.from(definedStylesByKey.values());\n}\n\nexport function getInheritedStyles(element: Element): Record<string, string> {\n const computedStyle = window.getComputedStyle(element);\n const inheritedStyles: Record<string, string> = {};\n for (const property of CONTROL_STYLE_PROPERTIES) {\n inheritedStyles[property] = computedStyle.getPropertyValue(property);\n }\n return inheritedStyles;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/select-mode/fiber.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface DebugSource {
|
|
|
5
5
|
}
|
|
6
6
|
export interface ReactFiber {
|
|
7
7
|
_debugStack?: unknown;
|
|
8
|
-
_debugOwner?: ReactFiber;
|
|
8
|
+
_debugOwner?: ReactFiber | ReactServerOwner;
|
|
9
9
|
type?: {
|
|
10
10
|
name?: string;
|
|
11
11
|
displayName?: string;
|
|
@@ -18,6 +18,12 @@ export interface ReactFiber {
|
|
|
18
18
|
memoizedProps?: Record<string, unknown>;
|
|
19
19
|
pendingProps?: Record<string, unknown>;
|
|
20
20
|
}
|
|
21
|
+
interface ReactServerOwner {
|
|
22
|
+
name: string;
|
|
23
|
+
debugStack?: unknown;
|
|
24
|
+
owner?: ReactFiber | ReactServerOwner;
|
|
25
|
+
props?: Record<string, unknown>;
|
|
26
|
+
}
|
|
21
27
|
export declare function getFiberFromElement(element: HTMLElement): ReactFiber | null;
|
|
22
28
|
export declare function getComponentName(fiber: ReactFiber | null | undefined): string | undefined;
|
|
23
29
|
export declare function findDebugSource(fiber: ReactFiber): {
|
|
@@ -42,3 +48,4 @@ export declare function getFiberChain(element: HTMLElement): {
|
|
|
42
48
|
componentName: string | undefined;
|
|
43
49
|
props: Record<string, unknown> | undefined;
|
|
44
50
|
}[];
|
|
51
|
+
export {};
|
package/select-mode/fiber.js
CHANGED
|
@@ -130,7 +130,9 @@ function findDebugSource(fiber) {
|
|
|
130
130
|
let depth = 0;
|
|
131
131
|
const maxDepth = 50;
|
|
132
132
|
while (current && depth < maxDepth) {
|
|
133
|
-
const debugStackSource = parseDebugStackSource(current._debugStack) ?? parseDebugStackSource(
|
|
133
|
+
const debugStackSource = parseDebugStackSource(current._debugStack) ?? parseDebugStackSource(
|
|
134
|
+
current._debugOwner && "_debugStack" in current._debugOwner ? current._debugOwner._debugStack : null
|
|
135
|
+
);
|
|
134
136
|
if (debugStackSource) {
|
|
135
137
|
return {
|
|
136
138
|
source: debugStackSource,
|
|
@@ -423,6 +425,7 @@ function getFiberChain(element) {
|
|
|
423
425
|
const rootFiber = getFiberFromElement(element);
|
|
424
426
|
const fiberChain = [];
|
|
425
427
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
428
|
+
const seenOwners = /* @__PURE__ */ new Set();
|
|
426
429
|
let currentFiber = rootFiber;
|
|
427
430
|
let depth = 0;
|
|
428
431
|
while (currentFiber && depth < MAX_FIBER_CHAIN_DEPTH) {
|
|
@@ -454,6 +457,39 @@ function getFiberChain(element) {
|
|
|
454
457
|
});
|
|
455
458
|
}
|
|
456
459
|
}
|
|
460
|
+
let owner = currentFiber._debugOwner;
|
|
461
|
+
while (owner && seenOwners.size < MAX_FIBER_CHAIN_DEPTH && !seenOwners.has(owner)) {
|
|
462
|
+
seenOwners.add(owner);
|
|
463
|
+
if ("name" in owner) {
|
|
464
|
+
const ownerSource = parseDebugStackSource(owner.debugStack);
|
|
465
|
+
if (ownerSource) {
|
|
466
|
+
const key = [
|
|
467
|
+
ownerSource.fileName,
|
|
468
|
+
ownerSource.lineNumber,
|
|
469
|
+
ownerSource.columnNumber ?? "",
|
|
470
|
+
"",
|
|
471
|
+
owner.name
|
|
472
|
+
].join(":");
|
|
473
|
+
if (!seenKeys.has(key)) {
|
|
474
|
+
seenKeys.add(key);
|
|
475
|
+
fiberChain.push({
|
|
476
|
+
sourceLocation: {
|
|
477
|
+
filePath: ownerSource.fileName,
|
|
478
|
+
lineNumber: ownerSource.lineNumber,
|
|
479
|
+
columnNumber: ownerSource.columnNumber,
|
|
480
|
+
componentName: owner.name
|
|
481
|
+
},
|
|
482
|
+
tagName: void 0,
|
|
483
|
+
componentName: owner.name,
|
|
484
|
+
props: getSerializableProps(owner.props)
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
owner = owner.owner;
|
|
489
|
+
} else {
|
|
490
|
+
owner = owner._debugOwner;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
457
493
|
currentFiber = currentFiber.return;
|
|
458
494
|
depth += 1;
|
|
459
495
|
}
|
package/select-mode/fiber.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../select-mode/fiber.ts"],
|
|
4
|
-
"sourcesContent": ["// =============================================================================\n// React Fiber / Source Location Utilities\n// =============================================================================\n\nimport { z } from \"zod\";\n\nexport interface DebugSource {\n fileName: string;\n lineNumber: number;\n columnNumber?: number;\n}\n\nexport interface ReactFiber {\n _debugStack?: unknown;\n _debugOwner?: ReactFiber;\n type?:\n | { name?: string; displayName?: string }\n | string\n | ((...args: unknown[]) => unknown)\n | null;\n return?: ReactFiber | null;\n child?: ReactFiber | null;\n sibling?: ReactFiber | null;\n alternate?: ReactFiber | null;\n stateNode?: unknown;\n memoizedProps?: Record<string, unknown>;\n pendingProps?: Record<string, unknown>;\n}\n\nconst MAX_FIBER_CHAIN_DEPTH = 80;\nconst MAX_SERIALIZED_PROP_COUNT = 24;\nconst MAX_SERIALIZED_STRING_LENGTH = 500;\nconst MAX_SIBLING_SCAN = 5000;\nconst MAX_SUBTREE_SCAN = 5000;\nconst MAX_ROOT_CLIMB_DEPTH = 1000;\nconst MAX_CURRENT_TREE_SCAN = 50_000;\n\n// Frames produced by React's own JSX runtime \u2014 these come first in\n// `_debugStack.stack` because the `Error` is constructed inside `jsxDEV`. We\n// want the frame *above* them, which is the actual JSX call site.\n//\n// Turbopack rewrites `node_modules/next/dist/compiled/react-server-dom-*` and\n// friends into mangled chunk paths like\n// `_next/static/chunks/<hash>_next_dist_compiled_react-server-dom-turbopack_<hash>._.js`,\n// so we match both the human-readable module paths and the chunk-name forms.\n// Without this, `_debugStack`'s top frame inside React's RSC runtime gets\n// surfaced as the \"host\" source location for every text node on the page \u2014\n// which then symbolicates back to bundled React, not user code.\nconst REACT_INTERNAL_FRAME_PATTERNS = [\n /react.*jsx-dev-runtime/,\n /react.*jsx-runtime/,\n /react-dom\\//,\n /react\\/cjs\\/react\\./,\n /react-server-dom/,\n /react_server_dom/,\n /next[/_.]dist[/_.]compiled/,\n /\\/node_modules\\/(next|react|react-dom)\\//,\n];\n\nfunction isReactInternalFrame(fileName: string): boolean {\n return REACT_INTERNAL_FRAME_PATTERNS.some((pattern) => {\n return pattern.test(fileName);\n });\n}\n\n// React constructs the `_debugStack` Error inside its JSX runtime (`jsxDEV`,\n// `jsx`, `jsxs`), so those frames sit *above* the real JSX call site we want.\n// The file-based check above skips them when their path is recognizable, but\n// Turbopack mangles the client JSX-runtime chunk to an opaque name like\n// `node_modules__pnpm_<hash>._.js` (no \"react\"/\"jsx-dev-runtime\" substring),\n// so the top `jsxDEV` frame slips through and gets surfaced as the element's\n// source \u2014 which then symbolicates back to bundled React, not user code.\n// Matching by function name is stable across Turbopack's chunk hashing.\n// NOTE (Noah, 2026-07-27): Only bites client components; server-component\n// frames carry a recognizable `react-server-dom-*` path.\nconst REACT_INTERNAL_METHOD_PATTERNS = [\n /(?:^|\\.)jsxDEV(?:Impl)?$/,\n /(?:^|\\.)jsxs?$/,\n /(?:^|\\.)fakeJSXCallSite$/,\n];\n\n// React invokes user components inside a sentinel-named function\n// (`react_stack_bottom_frame`, hyphenated in some builds) precisely so tools\n// can tell user frames from React internals: every frame at or below the\n// sentinel is React/scheduler/bootstrap code. Cutting there is robust even\n// when Turbopack mangles those frames' chunk paths beyond what\n// REACT_INTERNAL_FRAME_PATTERNS recognizes. (Sentinel treatment adapted from\n// bippy, MIT, https://github.com/aidenybai/bippy.)\nconst REACT_STACK_BOTTOM_FRAME_PATTERN = /react[-_]stack[-_]bottom[-_]frame/;\n\nfunction isReactInternalMethod(methodName: string | null): boolean {\n if (!methodName) {\n return false;\n }\n return REACT_INTERNAL_METHOD_PATTERNS.some((pattern) => {\n return pattern.test(methodName);\n });\n}\n\nfunction parseDebugStackSource(debugStack: unknown): DebugSource | null {\n let stackText: string | null = null;\n\n if (typeof debugStack === \"string\") {\n stackText = debugStack;\n } else if (\n typeof debugStack === \"object\" &&\n debugStack &&\n \"stack\" in debugStack\n ) {\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n const stack = (debugStack as { stack?: unknown }).stack;\n if (typeof stack === \"string\") {\n stackText = stack;\n }\n }\n\n if (!stackText) {\n return null;\n }\n\n for (const rawLine of stackText.split(\"\\n\")) {\n const line = rawLine.trim();\n if (!line) {\n continue;\n }\n\n if (REACT_STACK_BOTTOM_FRAME_PATTERN.test(line)) {\n // Everything from the sentinel down is React internals \u2014 a frame down\n // there can only be a false positive.\n return null;\n }\n\n // Prefer the framed form `at <method> (<file>:<line>:<col>)` (V8) or\n // `<method>@<file>:<line>:<col>` (JavaScriptCore/SpiderMonkey \u2014 Safari\n // and Firefox editors drive the same in-iframe code) so we can read the\n // function name and skip React's JSX-runtime frames even when Turbopack\n // has mangled their chunk file name beyond recognition.\n const framedMatch =\n line.match(/^at\\s+(.+?)\\s+\\((.*):(\\d+):(\\d+)\\)$/) ??\n // Method names never contain `/`, which keeps `@`-versioned path\n // segments (`.pnpm/react@19.2.4/\u2026`) from being read as a method.\n line.match(/^([^@/]*)@(.+):(\\d+):(\\d+)$/);\n const stackFrameMatch =\n framedMatch ??\n line.match(/^at\\s+(?:.*\\()?(.*):(\\d+):(\\d+)\\)?$/) ??\n line.match(/^(.*):(\\d+):(\\d+)$/);\n\n if (!stackFrameMatch) {\n continue;\n }\n\n const methodName = framedMatch ? framedMatch[1]!.trim() : null;\n const fileOffset = framedMatch ? 2 : 1;\n const fileName = stackFrameMatch[fileOffset]?.trim();\n const lineNumber = Number.parseInt(\n stackFrameMatch[fileOffset + 1] ?? \"\",\n 10,\n );\n const columnNumber = Number.parseInt(\n stackFrameMatch[fileOffset + 2] ?? \"\",\n 10,\n );\n\n if (\n !fileName ||\n !Number.isFinite(lineNumber) ||\n !Number.isFinite(columnNumber)\n ) {\n continue;\n }\n\n if (isReactInternalFrame(fileName) || isReactInternalMethod(methodName)) {\n continue;\n }\n\n return {\n fileName,\n lineNumber,\n columnNumber,\n };\n }\n\n return null;\n}\n\nexport function getFiberFromElement(element: HTMLElement): ReactFiber | null {\n if (!element || typeof element !== \"object\") {\n return null;\n }\n\n const symbolKeys = Object.getOwnPropertySymbols(element);\n const fiberSymbolKey = symbolKeys.find((symbolKey) => {\n return symbolKey.toString().includes(\"reactFiber\");\n });\n if (fiberSymbolKey) {\n return (\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n (element as unknown as Record<symbol, ReactFiber>)[fiberSymbolKey] ?? null\n );\n }\n\n const keys = Object.keys(element);\n const fiberKey = keys.find((key) => key.startsWith(\"__reactFiber$\"));\n if (fiberKey) {\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n return (element as unknown as Record<string, ReactFiber>)[fiberKey] ?? null;\n }\n return null;\n}\n\nexport function getComponentName(\n fiber: ReactFiber | null | undefined,\n): string | undefined {\n if (!fiber?.type) {\n return undefined;\n }\n\n if (typeof fiber.type === \"string\") {\n return undefined;\n }\n\n if (typeof fiber.type === \"function\") {\n return fiber.type.name || undefined;\n }\n\n if (typeof fiber.type === \"object\") {\n return fiber.type.displayName ?? fiber.type.name ?? undefined;\n }\n\n return undefined;\n}\n\n// The per-element source pointer is `fiber._debugStack`, an `Error`\n// constructed inside `jsxDEV` at the JSX call site (dev builds only). We pull\n// the topmost non-React frame out of that stack; it references a compiled\n// SSR/client chunk (e.g. `.next-dev/.../ssr/*.js`).\n// `symbolicateSelectedElement` later resolves those compiled frames to\n// original `.tsx` locations via Next.js's `/__nextjs_original-stack-frames`\n// dev-server endpoint.\nexport function findDebugSource(\n fiber: ReactFiber,\n): { source: DebugSource; componentName?: string } | null {\n let current: ReactFiber | null | undefined = fiber;\n let depth = 0;\n const maxDepth = 50;\n\n while (current && depth < maxDepth) {\n const debugStackSource =\n parseDebugStackSource(current._debugStack) ??\n parseDebugStackSource(current._debugOwner?._debugStack);\n if (debugStackSource) {\n return {\n source: debugStackSource,\n componentName: getComponentName(current),\n };\n }\n\n current = current.return;\n depth++;\n }\n\n return null;\n}\n\nexport function getSourceLocation(element: HTMLElement) {\n let currentElement: HTMLElement | null = element;\n\n while (currentElement) {\n const fiber = getFiberFromElement(currentElement);\n if (fiber) {\n const debugInfo = findDebugSource(fiber);\n if (debugInfo?.source) {\n return {\n filePath: debugInfo.source.fileName,\n lineNumber: debugInfo.source.lineNumber,\n columnNumber: debugInfo.source.columnNumber,\n componentName: debugInfo.componentName ?? undefined,\n };\n }\n }\n\n currentElement = currentElement.parentElement;\n }\n\n return undefined;\n}\n\nfunction getDebugSource(fiber: ReactFiber): DebugSource | undefined {\n return findDebugSource(fiber)?.source;\n}\n\nfunction getTagName(fiber: ReactFiber): string | undefined {\n return z.string().safeParse(fiber.type).data?.toLowerCase();\n}\n\n// Resolving a fiber's source requires parsing `_debugStack` in React 19, which\n// is expensive. Cache per fiber object. React reuses fiber objects across\n// updates (current/alternate double-buffering), but a fiber's JSX source\n// location is fixed for its lifetime, so the cached key stays valid. Entries\n// are dropped only when the fiber is GC'd (unmount / remount / navigation).\n// Known caveat: a fast-refresh edit that shifts line numbers can leave\n// long-lived fibers keyed against the old revision while newly mounted\n// siblings key against the new one, temporarily splitting a repetition\n// group. Dev-only, and it self-heals on remount.\nconst fiberSourceKeyCache = new WeakMap<ReactFiber, string | null>();\n\nfunction getFiberSourceKey(fiber: ReactFiber): string | null {\n const cached = fiberSourceKeyCache.get(fiber);\n if (cached !== undefined) {\n return cached;\n }\n const source = getDebugSource(fiber);\n const key = source\n ? `${source.fileName}:${source.lineNumber}:${source.columnNumber ?? \"\"}`\n : null;\n fiberSourceKeyCache.set(fiber, key);\n return key;\n}\n\n// A repetition group is >=2 sibling fibers under one parent that share the\n// clicked fiber's element `type` and JSX source location \u2014 i.e. the instances\n// produced by a single `.map()`/loop. Returns null when the fiber is not part\n// of such a group (source parsing is bounded to the direct siblings scanned).\nfunction findRepetitionGroup(fiber: ReactFiber): ReactFiber[] | null {\n const parent = fiber.return;\n if (!parent) {\n return null;\n }\n const type = fiber.type;\n const candidates: ReactFiber[] = [];\n let child: ReactFiber | null | undefined = parent.child;\n let scanned = 0;\n while (child && scanned < MAX_SIBLING_SCAN) {\n if (child.type === type) {\n candidates.push(child);\n }\n child = child.sibling;\n scanned += 1;\n }\n\n if (candidates.length < 2) {\n return null;\n }\n\n const sourceKey = getFiberSourceKey(fiber);\n if (!sourceKey) {\n return null;\n }\n const members = candidates.filter((candidate) => {\n return getFiberSourceKey(candidate) === sourceKey;\n });\n return members.length >= 2 ? members : null;\n}\n\nfunction descendChildPath(\n fiber: ReactFiber,\n path: number[],\n): ReactFiber | null {\n let current: ReactFiber | null | undefined = fiber;\n for (const childIndex of path) {\n if (!current) {\n return null;\n }\n let child: ReactFiber | null | undefined = current.child;\n let index = 0;\n while (child && index < childIndex) {\n child = child.sibling;\n index += 1;\n }\n if (!child) {\n return null;\n }\n current = child;\n }\n return current ?? null;\n}\n\nfunction getHostNode(fiber: ReactFiber | null): HTMLElement | null {\n return fiber?.stateNode instanceof HTMLElement ? fiber.stateNode : null;\n}\n\nfunction isMatchingHost(\n fiber: ReactFiber | null,\n type: ReactFiber[\"type\"],\n sourceKey: string | null,\n): boolean {\n if (!fiber || !(fiber.stateNode instanceof HTMLElement)) {\n return false;\n }\n return fiber.type === type && getFiberSourceKey(fiber) === sourceKey;\n}\n\n// Fallback for when the child-index path doesn't land on a matching host (e.g.\n// a repeated unit whose subtree structure differs slightly): DFS the unit's\n// subtree for the first host fiber matching the clicked node's identity.\nfunction findHostInSubtree(\n root: ReactFiber,\n type: ReactFiber[\"type\"],\n sourceKey: string | null,\n): HTMLElement | null {\n const stack: ReactFiber[] = [];\n let child: ReactFiber | null | undefined = root.child;\n while (child) {\n stack.push(child);\n child = child.sibling;\n }\n let scanned = 0;\n while (stack.length > 0 && scanned < MAX_SUBTREE_SCAN) {\n const current = stack.pop();\n scanned += 1;\n if (!current) {\n continue;\n }\n if (isMatchingHost(current, type, sourceKey)) {\n return getHostNode(current);\n }\n let next: ReactFiber | null | undefined = current.child;\n while (next) {\n stack.push(next);\n next = next.sibling;\n }\n }\n return null;\n}\n\n// Fallback current-generation heuristic: a fiber still linked into its\n// parent's child list is *probably* the live generation. Only locally\n// consistent \u2014 a stale parent's child list can still link the stale fiber \u2014\n// so this runs only when the authoritative root check below is unavailable.\nfunction resolveCurrentFiberByParentLinkage(fiber: ReactFiber): ReactFiber {\n const alternate = fiber.alternate;\n if (!alternate) {\n return fiber;\n }\n let child: ReactFiber | null | undefined = fiber.return?.child;\n let scanned = 0;\n while (child && scanned < MAX_SIBLING_SCAN) {\n if (child === fiber) {\n return fiber;\n }\n child = child.sibling;\n scanned += 1;\n }\n return alternate;\n}\n\nfunction getFiberRootCurrent(stateNode: unknown): ReactFiber | null {\n if (\n !stateNode ||\n typeof stateNode !== \"object\" ||\n !(\"current\" in stateNode)\n ) {\n return null;\n }\n const current: unknown = Reflect.get(stateNode, \"current\");\n if (current && typeof current === \"object\" && \"child\" in current) {\n // Legacy cast - structural check above is our fiber discriminator\n // eslint-disable-next-line replo/no-as-cast\n return current as ReactFiber;\n }\n return null;\n}\n\n// React sets a DOM node's fiber pointer once, at node creation, and never\n// re-points it. Under double-buffering the current tree alternates between\n// the two fiber generations on every commit, so after a structure-changing\n// re-render the cached fiber can be the non-current generation \u2014 its\n// parent/sibling linkage then describes a stale tree. Which generation is\n// current can only be answered authoritatively from the root: the HostRoot\n// fiber's `stateNode` is the FiberRoot, whose `current` pointer always\n// references the committed tree (both HostRoot generations share the same\n// FiberRoot object, so it doesn't matter which generation we climbed).\n// Whichever of {fiber, alternate} is reachable from `FiberRoot.current` is\n// the live one. Approach adapted from bippy's `getLatestFiber` (MIT,\n// https://github.com/aidenybai/bippy), with our bounded iterative traversal.\nfunction resolveCurrentFiber(fiber: ReactFiber): ReactFiber {\n const alternate = fiber.alternate;\n if (!alternate) {\n return fiber;\n }\n\n let rootFiber: ReactFiber = fiber;\n let climbed = 0;\n while (rootFiber.return && climbed < MAX_ROOT_CLIMB_DEPTH) {\n rootFiber = rootFiber.return;\n climbed += 1;\n }\n const currentRoot = rootFiber.return\n ? null\n : getFiberRootCurrent(rootFiber.stateNode);\n if (!currentRoot) {\n return resolveCurrentFiberByParentLinkage(fiber);\n }\n\n const stack: ReactFiber[] = [currentRoot];\n let scanned = 0;\n while (stack.length > 0 && scanned < MAX_CURRENT_TREE_SCAN) {\n const node = stack.pop();\n scanned += 1;\n if (!node) {\n continue;\n }\n if (node === fiber || node === alternate) {\n return node;\n }\n if (node.child) {\n stack.push(node.child);\n }\n if (node.sibling) {\n stack.push(node.sibling);\n }\n }\n if (scanned >= MAX_CURRENT_TREE_SCAN) {\n return resolveCurrentFiberByParentLinkage(fiber);\n }\n // Neither generation is reachable from the committed tree: the fiber is\n // detached (unmounted mid-click). Degrade to the cached fiber; downstream\n // returns just the clicked element.\n return fiber;\n}\n\n// Given a clicked element, return every host DOM node in its repetition group,\n// including the element itself. Traverses the fiber tree instead of walking the\n// whole document: climb to the lowest ancestor that forms a repetition group,\n// record the child-index path down to the clicked node, then descend that same\n// path inside each group member. Returns just `[element]` when the element is\n// not repeated.\nexport function getRepetitionHostNodes(element: HTMLElement): HTMLElement[] {\n const cachedFiber = getFiberFromElement(element);\n if (!cachedFiber) {\n return [element];\n }\n const selectedFiber = resolveCurrentFiber(cachedFiber);\n\n const climb: ReactFiber[] = [];\n let cursor: ReactFiber | null | undefined = selectedFiber;\n let depth = 0;\n let unit: ReactFiber | null = null;\n let group: ReactFiber[] | null = null;\n while (cursor && depth < MAX_FIBER_CHAIN_DEPTH) {\n climb.push(cursor);\n const candidate = findRepetitionGroup(cursor);\n if (candidate) {\n unit = cursor;\n group = candidate;\n break;\n }\n cursor = cursor.return;\n depth += 1;\n }\n\n if (!unit || !group) {\n return [element];\n }\n\n const downward = climb.slice(0, climb.indexOf(unit) + 1).reverse();\n // null when a climb step is not linked into its parent's child list (stale\n // generation slipped through) \u2014 every member then resolves via subtree\n // search instead of descending a path recorded against the wrong tree.\n let pathFromUnit: number[] | null = [];\n for (let i = 0; i < downward.length - 1 && pathFromUnit; i += 1) {\n const parentFiber = downward[i];\n const targetFiber = downward[i + 1];\n if (!parentFiber || !targetFiber) {\n break;\n }\n let child: ReactFiber | null | undefined = parentFiber.child;\n let index = 0;\n while (child && child !== targetFiber && child !== targetFiber.alternate) {\n child = child.sibling;\n index += 1;\n }\n if (child) {\n pathFromUnit.push(index);\n } else {\n pathFromUnit = null;\n }\n }\n\n const selectedType = selectedFiber.type;\n const selectedSourceKey = getFiberSourceKey(selectedFiber);\n const nodes: HTMLElement[] = [];\n const seen = new Set<HTMLElement>();\n for (const member of group) {\n const landed = pathFromUnit ? descendChildPath(member, pathFromUnit) : null;\n const node = isMatchingHost(landed, selectedType, selectedSourceKey)\n ? getHostNode(landed)\n : findHostInSubtree(member, selectedType, selectedSourceKey);\n if (node && !seen.has(node)) {\n seen.add(node);\n nodes.push(node);\n }\n }\n\n if (!seen.has(element)) {\n nodes.push(element);\n }\n\n return nodes;\n}\n\nfunction getSerializablePropValue(value: unknown): unknown {\n if (\n value === null ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n\n if (typeof value === \"string\") {\n return value.length > MAX_SERIALIZED_STRING_LENGTH\n ? `${value.slice(0, MAX_SERIALIZED_STRING_LENGTH)}...`\n : value;\n }\n\n if (Array.isArray(value)) {\n return value.slice(0, 20).map(getSerializablePropValue);\n }\n\n if (typeof value === \"object\") {\n return \"[object]\";\n }\n\n return undefined;\n}\n\nfunction getSerializableProps(\n props: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!props) {\n return undefined;\n }\n\n const serializedProps: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(props).slice(\n 0,\n MAX_SERIALIZED_PROP_COUNT,\n )) {\n if (\n key === \"children\" ||\n key === \"ref\" ||\n key.startsWith(\"on\") ||\n typeof value === \"function\" ||\n typeof value === \"symbol\"\n ) {\n continue;\n }\n\n const serializableValue = getSerializablePropValue(value);\n if (serializableValue !== undefined) {\n serializedProps[key] = serializableValue;\n }\n }\n\n return Object.keys(serializedProps).length > 0 ? serializedProps : undefined;\n}\n\nexport function getFiberChain(element: HTMLElement) {\n const rootFiber = getFiberFromElement(element);\n const fiberChain = [];\n const seenKeys = new Set<string>();\n let currentFiber: ReactFiber | null | undefined = rootFiber;\n let depth = 0;\n\n while (currentFiber && depth < MAX_FIBER_CHAIN_DEPTH) {\n const source = getDebugSource(currentFiber);\n if (source) {\n const tagName = getTagName(currentFiber);\n const componentName = getComponentName(currentFiber);\n const key = [\n source.fileName,\n source.lineNumber,\n source.columnNumber ?? \"\",\n tagName ?? \"\",\n componentName ?? \"\",\n ].join(\":\");\n\n if (!seenKeys.has(key)) {\n seenKeys.add(key);\n fiberChain.push({\n sourceLocation: {\n filePath: source.fileName,\n lineNumber: source.lineNumber,\n columnNumber: source.columnNumber,\n componentName,\n },\n tagName,\n componentName,\n props: getSerializableProps(\n currentFiber.memoizedProps ?? currentFiber.pendingProps,\n ),\n });\n }\n }\n\n currentFiber = currentFiber.return;\n depth += 1;\n }\n\n return fiberChain;\n}\n"],
|
|
5
|
-
"mappings": "AAIA,SAAS,SAAS;
|
|
4
|
+
"sourcesContent": ["// =============================================================================\n// React Fiber / Source Location Utilities\n// =============================================================================\n\nimport { z } from \"zod\";\n\nexport interface DebugSource {\n fileName: string;\n lineNumber: number;\n columnNumber?: number;\n}\n\nexport interface ReactFiber {\n _debugStack?: unknown;\n _debugOwner?: ReactFiber | ReactServerOwner;\n type?:\n | { name?: string; displayName?: string }\n | string\n | ((...args: unknown[]) => unknown)\n | null;\n return?: ReactFiber | null;\n child?: ReactFiber | null;\n sibling?: ReactFiber | null;\n alternate?: ReactFiber | null;\n stateNode?: unknown;\n memoizedProps?: Record<string, unknown>;\n pendingProps?: Record<string, unknown>;\n}\n\ninterface ReactServerOwner {\n name: string;\n debugStack?: unknown;\n owner?: ReactFiber | ReactServerOwner;\n props?: Record<string, unknown>;\n}\n\nconst MAX_FIBER_CHAIN_DEPTH = 80;\nconst MAX_SERIALIZED_PROP_COUNT = 24;\nconst MAX_SERIALIZED_STRING_LENGTH = 500;\nconst MAX_SIBLING_SCAN = 5000;\nconst MAX_SUBTREE_SCAN = 5000;\nconst MAX_ROOT_CLIMB_DEPTH = 1000;\nconst MAX_CURRENT_TREE_SCAN = 50_000;\n\n// Frames produced by React's own JSX runtime \u2014 these come first in\n// `_debugStack.stack` because the `Error` is constructed inside `jsxDEV`. We\n// want the frame *above* them, which is the actual JSX call site.\n//\n// Turbopack rewrites `node_modules/next/dist/compiled/react-server-dom-*` and\n// friends into mangled chunk paths like\n// `_next/static/chunks/<hash>_next_dist_compiled_react-server-dom-turbopack_<hash>._.js`,\n// so we match both the human-readable module paths and the chunk-name forms.\n// Without this, `_debugStack`'s top frame inside React's RSC runtime gets\n// surfaced as the \"host\" source location for every text node on the page \u2014\n// which then symbolicates back to bundled React, not user code.\nconst REACT_INTERNAL_FRAME_PATTERNS = [\n /react.*jsx-dev-runtime/,\n /react.*jsx-runtime/,\n /react-dom\\//,\n /react\\/cjs\\/react\\./,\n /react-server-dom/,\n /react_server_dom/,\n /next[/_.]dist[/_.]compiled/,\n /\\/node_modules\\/(next|react|react-dom)\\//,\n];\n\nfunction isReactInternalFrame(fileName: string): boolean {\n return REACT_INTERNAL_FRAME_PATTERNS.some((pattern) => {\n return pattern.test(fileName);\n });\n}\n\n// React constructs the `_debugStack` Error inside its JSX runtime (`jsxDEV`,\n// `jsx`, `jsxs`), so those frames sit *above* the real JSX call site we want.\n// The file-based check above skips them when their path is recognizable, but\n// Turbopack mangles the client JSX-runtime chunk to an opaque name like\n// `node_modules__pnpm_<hash>._.js` (no \"react\"/\"jsx-dev-runtime\" substring),\n// so the top `jsxDEV` frame slips through and gets surfaced as the element's\n// source \u2014 which then symbolicates back to bundled React, not user code.\n// Matching by function name is stable across Turbopack's chunk hashing.\n// NOTE (Noah, 2026-07-27): Only bites client components; server-component\n// frames carry a recognizable `react-server-dom-*` path.\nconst REACT_INTERNAL_METHOD_PATTERNS = [\n /(?:^|\\.)jsxDEV(?:Impl)?$/,\n /(?:^|\\.)jsxs?$/,\n /(?:^|\\.)fakeJSXCallSite$/,\n];\n\n// React invokes user components inside a sentinel-named function\n// (`react_stack_bottom_frame`, hyphenated in some builds) precisely so tools\n// can tell user frames from React internals: every frame at or below the\n// sentinel is React/scheduler/bootstrap code. Cutting there is robust even\n// when Turbopack mangles those frames' chunk paths beyond what\n// REACT_INTERNAL_FRAME_PATTERNS recognizes. (Sentinel treatment adapted from\n// bippy, MIT, https://github.com/aidenybai/bippy.)\nconst REACT_STACK_BOTTOM_FRAME_PATTERN = /react[-_]stack[-_]bottom[-_]frame/;\n\nfunction isReactInternalMethod(methodName: string | null): boolean {\n if (!methodName) {\n return false;\n }\n return REACT_INTERNAL_METHOD_PATTERNS.some((pattern) => {\n return pattern.test(methodName);\n });\n}\n\nfunction parseDebugStackSource(debugStack: unknown): DebugSource | null {\n let stackText: string | null = null;\n\n if (typeof debugStack === \"string\") {\n stackText = debugStack;\n } else if (\n typeof debugStack === \"object\" &&\n debugStack &&\n \"stack\" in debugStack\n ) {\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n const stack = (debugStack as { stack?: unknown }).stack;\n if (typeof stack === \"string\") {\n stackText = stack;\n }\n }\n\n if (!stackText) {\n return null;\n }\n\n for (const rawLine of stackText.split(\"\\n\")) {\n const line = rawLine.trim();\n if (!line) {\n continue;\n }\n\n if (REACT_STACK_BOTTOM_FRAME_PATTERN.test(line)) {\n // Everything from the sentinel down is React internals \u2014 a frame down\n // there can only be a false positive.\n return null;\n }\n\n // Prefer the framed form `at <method> (<file>:<line>:<col>)` (V8) or\n // `<method>@<file>:<line>:<col>` (JavaScriptCore/SpiderMonkey \u2014 Safari\n // and Firefox editors drive the same in-iframe code) so we can read the\n // function name and skip React's JSX-runtime frames even when Turbopack\n // has mangled their chunk file name beyond recognition.\n const framedMatch =\n line.match(/^at\\s+(.+?)\\s+\\((.*):(\\d+):(\\d+)\\)$/) ??\n // Method names never contain `/`, which keeps `@`-versioned path\n // segments (`.pnpm/react@19.2.4/\u2026`) from being read as a method.\n line.match(/^([^@/]*)@(.+):(\\d+):(\\d+)$/);\n const stackFrameMatch =\n framedMatch ??\n line.match(/^at\\s+(?:.*\\()?(.*):(\\d+):(\\d+)\\)?$/) ??\n line.match(/^(.*):(\\d+):(\\d+)$/);\n\n if (!stackFrameMatch) {\n continue;\n }\n\n const methodName = framedMatch ? framedMatch[1]!.trim() : null;\n const fileOffset = framedMatch ? 2 : 1;\n const fileName = stackFrameMatch[fileOffset]?.trim();\n const lineNumber = Number.parseInt(\n stackFrameMatch[fileOffset + 1] ?? \"\",\n 10,\n );\n const columnNumber = Number.parseInt(\n stackFrameMatch[fileOffset + 2] ?? \"\",\n 10,\n );\n\n if (\n !fileName ||\n !Number.isFinite(lineNumber) ||\n !Number.isFinite(columnNumber)\n ) {\n continue;\n }\n\n if (isReactInternalFrame(fileName) || isReactInternalMethod(methodName)) {\n continue;\n }\n\n return {\n fileName,\n lineNumber,\n columnNumber,\n };\n }\n\n return null;\n}\n\nexport function getFiberFromElement(element: HTMLElement): ReactFiber | null {\n if (!element || typeof element !== \"object\") {\n return null;\n }\n\n const symbolKeys = Object.getOwnPropertySymbols(element);\n const fiberSymbolKey = symbolKeys.find((symbolKey) => {\n return symbolKey.toString().includes(\"reactFiber\");\n });\n if (fiberSymbolKey) {\n return (\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n (element as unknown as Record<symbol, ReactFiber>)[fiberSymbolKey] ?? null\n );\n }\n\n const keys = Object.keys(element);\n const fiberKey = keys.find((key) => key.startsWith(\"__reactFiber$\"));\n if (fiberKey) {\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n return (element as unknown as Record<string, ReactFiber>)[fiberKey] ?? null;\n }\n return null;\n}\n\nexport function getComponentName(\n fiber: ReactFiber | null | undefined,\n): string | undefined {\n if (!fiber?.type) {\n return undefined;\n }\n\n if (typeof fiber.type === \"string\") {\n return undefined;\n }\n\n if (typeof fiber.type === \"function\") {\n return fiber.type.name || undefined;\n }\n\n if (typeof fiber.type === \"object\") {\n return fiber.type.displayName ?? fiber.type.name ?? undefined;\n }\n\n return undefined;\n}\n\n// The per-element source pointer is `fiber._debugStack`, an `Error`\n// constructed inside `jsxDEV` at the JSX call site (dev builds only). We pull\n// the topmost non-React frame out of that stack; it references a compiled\n// SSR/client chunk (e.g. `.next-dev/.../ssr/*.js`).\n// `symbolicateSelectedElement` later resolves those compiled frames to\n// original `.tsx` locations via Next.js's `/__nextjs_original-stack-frames`\n// dev-server endpoint.\nexport function findDebugSource(\n fiber: ReactFiber,\n): { source: DebugSource; componentName?: string } | null {\n let current: ReactFiber | null | undefined = fiber;\n let depth = 0;\n const maxDepth = 50;\n\n while (current && depth < maxDepth) {\n const debugStackSource =\n parseDebugStackSource(current._debugStack) ??\n parseDebugStackSource(\n current._debugOwner && \"_debugStack\" in current._debugOwner\n ? current._debugOwner._debugStack\n : null,\n );\n if (debugStackSource) {\n return {\n source: debugStackSource,\n componentName: getComponentName(current),\n };\n }\n\n current = current.return;\n depth++;\n }\n\n return null;\n}\n\nexport function getSourceLocation(element: HTMLElement) {\n let currentElement: HTMLElement | null = element;\n\n while (currentElement) {\n const fiber = getFiberFromElement(currentElement);\n if (fiber) {\n const debugInfo = findDebugSource(fiber);\n if (debugInfo?.source) {\n return {\n filePath: debugInfo.source.fileName,\n lineNumber: debugInfo.source.lineNumber,\n columnNumber: debugInfo.source.columnNumber,\n componentName: debugInfo.componentName ?? undefined,\n };\n }\n }\n\n currentElement = currentElement.parentElement;\n }\n\n return undefined;\n}\n\nfunction getDebugSource(fiber: ReactFiber): DebugSource | undefined {\n return findDebugSource(fiber)?.source;\n}\n\nfunction getTagName(fiber: ReactFiber): string | undefined {\n return z.string().safeParse(fiber.type).data?.toLowerCase();\n}\n\n// Resolving a fiber's source requires parsing `_debugStack` in React 19, which\n// is expensive. Cache per fiber object. React reuses fiber objects across\n// updates (current/alternate double-buffering), but a fiber's JSX source\n// location is fixed for its lifetime, so the cached key stays valid. Entries\n// are dropped only when the fiber is GC'd (unmount / remount / navigation).\n// Known caveat: a fast-refresh edit that shifts line numbers can leave\n// long-lived fibers keyed against the old revision while newly mounted\n// siblings key against the new one, temporarily splitting a repetition\n// group. Dev-only, and it self-heals on remount.\nconst fiberSourceKeyCache = new WeakMap<ReactFiber, string | null>();\n\nfunction getFiberSourceKey(fiber: ReactFiber): string | null {\n const cached = fiberSourceKeyCache.get(fiber);\n if (cached !== undefined) {\n return cached;\n }\n const source = getDebugSource(fiber);\n const key = source\n ? `${source.fileName}:${source.lineNumber}:${source.columnNumber ?? \"\"}`\n : null;\n fiberSourceKeyCache.set(fiber, key);\n return key;\n}\n\n// A repetition group is >=2 sibling fibers under one parent that share the\n// clicked fiber's element `type` and JSX source location \u2014 i.e. the instances\n// produced by a single `.map()`/loop. Returns null when the fiber is not part\n// of such a group (source parsing is bounded to the direct siblings scanned).\nfunction findRepetitionGroup(fiber: ReactFiber): ReactFiber[] | null {\n const parent = fiber.return;\n if (!parent) {\n return null;\n }\n const type = fiber.type;\n const candidates: ReactFiber[] = [];\n let child: ReactFiber | null | undefined = parent.child;\n let scanned = 0;\n while (child && scanned < MAX_SIBLING_SCAN) {\n if (child.type === type) {\n candidates.push(child);\n }\n child = child.sibling;\n scanned += 1;\n }\n\n if (candidates.length < 2) {\n return null;\n }\n\n const sourceKey = getFiberSourceKey(fiber);\n if (!sourceKey) {\n return null;\n }\n const members = candidates.filter((candidate) => {\n return getFiberSourceKey(candidate) === sourceKey;\n });\n return members.length >= 2 ? members : null;\n}\n\nfunction descendChildPath(\n fiber: ReactFiber,\n path: number[],\n): ReactFiber | null {\n let current: ReactFiber | null | undefined = fiber;\n for (const childIndex of path) {\n if (!current) {\n return null;\n }\n let child: ReactFiber | null | undefined = current.child;\n let index = 0;\n while (child && index < childIndex) {\n child = child.sibling;\n index += 1;\n }\n if (!child) {\n return null;\n }\n current = child;\n }\n return current ?? null;\n}\n\nfunction getHostNode(fiber: ReactFiber | null): HTMLElement | null {\n return fiber?.stateNode instanceof HTMLElement ? fiber.stateNode : null;\n}\n\nfunction isMatchingHost(\n fiber: ReactFiber | null,\n type: ReactFiber[\"type\"],\n sourceKey: string | null,\n): boolean {\n if (!fiber || !(fiber.stateNode instanceof HTMLElement)) {\n return false;\n }\n return fiber.type === type && getFiberSourceKey(fiber) === sourceKey;\n}\n\n// Fallback for when the child-index path doesn't land on a matching host (e.g.\n// a repeated unit whose subtree structure differs slightly): DFS the unit's\n// subtree for the first host fiber matching the clicked node's identity.\nfunction findHostInSubtree(\n root: ReactFiber,\n type: ReactFiber[\"type\"],\n sourceKey: string | null,\n): HTMLElement | null {\n const stack: ReactFiber[] = [];\n let child: ReactFiber | null | undefined = root.child;\n while (child) {\n stack.push(child);\n child = child.sibling;\n }\n let scanned = 0;\n while (stack.length > 0 && scanned < MAX_SUBTREE_SCAN) {\n const current = stack.pop();\n scanned += 1;\n if (!current) {\n continue;\n }\n if (isMatchingHost(current, type, sourceKey)) {\n return getHostNode(current);\n }\n let next: ReactFiber | null | undefined = current.child;\n while (next) {\n stack.push(next);\n next = next.sibling;\n }\n }\n return null;\n}\n\n// Fallback current-generation heuristic: a fiber still linked into its\n// parent's child list is *probably* the live generation. Only locally\n// consistent \u2014 a stale parent's child list can still link the stale fiber \u2014\n// so this runs only when the authoritative root check below is unavailable.\nfunction resolveCurrentFiberByParentLinkage(fiber: ReactFiber): ReactFiber {\n const alternate = fiber.alternate;\n if (!alternate) {\n return fiber;\n }\n let child: ReactFiber | null | undefined = fiber.return?.child;\n let scanned = 0;\n while (child && scanned < MAX_SIBLING_SCAN) {\n if (child === fiber) {\n return fiber;\n }\n child = child.sibling;\n scanned += 1;\n }\n return alternate;\n}\n\nfunction getFiberRootCurrent(stateNode: unknown): ReactFiber | null {\n if (\n !stateNode ||\n typeof stateNode !== \"object\" ||\n !(\"current\" in stateNode)\n ) {\n return null;\n }\n const current: unknown = Reflect.get(stateNode, \"current\");\n if (current && typeof current === \"object\" && \"child\" in current) {\n // Legacy cast - structural check above is our fiber discriminator\n // eslint-disable-next-line replo/no-as-cast\n return current as ReactFiber;\n }\n return null;\n}\n\n// React sets a DOM node's fiber pointer once, at node creation, and never\n// re-points it. Under double-buffering the current tree alternates between\n// the two fiber generations on every commit, so after a structure-changing\n// re-render the cached fiber can be the non-current generation \u2014 its\n// parent/sibling linkage then describes a stale tree. Which generation is\n// current can only be answered authoritatively from the root: the HostRoot\n// fiber's `stateNode` is the FiberRoot, whose `current` pointer always\n// references the committed tree (both HostRoot generations share the same\n// FiberRoot object, so it doesn't matter which generation we climbed).\n// Whichever of {fiber, alternate} is reachable from `FiberRoot.current` is\n// the live one. Approach adapted from bippy's `getLatestFiber` (MIT,\n// https://github.com/aidenybai/bippy), with our bounded iterative traversal.\nfunction resolveCurrentFiber(fiber: ReactFiber): ReactFiber {\n const alternate = fiber.alternate;\n if (!alternate) {\n return fiber;\n }\n\n let rootFiber: ReactFiber = fiber;\n let climbed = 0;\n while (rootFiber.return && climbed < MAX_ROOT_CLIMB_DEPTH) {\n rootFiber = rootFiber.return;\n climbed += 1;\n }\n const currentRoot = rootFiber.return\n ? null\n : getFiberRootCurrent(rootFiber.stateNode);\n if (!currentRoot) {\n return resolveCurrentFiberByParentLinkage(fiber);\n }\n\n const stack: ReactFiber[] = [currentRoot];\n let scanned = 0;\n while (stack.length > 0 && scanned < MAX_CURRENT_TREE_SCAN) {\n const node = stack.pop();\n scanned += 1;\n if (!node) {\n continue;\n }\n if (node === fiber || node === alternate) {\n return node;\n }\n if (node.child) {\n stack.push(node.child);\n }\n if (node.sibling) {\n stack.push(node.sibling);\n }\n }\n if (scanned >= MAX_CURRENT_TREE_SCAN) {\n return resolveCurrentFiberByParentLinkage(fiber);\n }\n // Neither generation is reachable from the committed tree: the fiber is\n // detached (unmounted mid-click). Degrade to the cached fiber; downstream\n // returns just the clicked element.\n return fiber;\n}\n\n// Given a clicked element, return every host DOM node in its repetition group,\n// including the element itself. Traverses the fiber tree instead of walking the\n// whole document: climb to the lowest ancestor that forms a repetition group,\n// record the child-index path down to the clicked node, then descend that same\n// path inside each group member. Returns just `[element]` when the element is\n// not repeated.\nexport function getRepetitionHostNodes(element: HTMLElement): HTMLElement[] {\n const cachedFiber = getFiberFromElement(element);\n if (!cachedFiber) {\n return [element];\n }\n const selectedFiber = resolveCurrentFiber(cachedFiber);\n\n const climb: ReactFiber[] = [];\n let cursor: ReactFiber | null | undefined = selectedFiber;\n let depth = 0;\n let unit: ReactFiber | null = null;\n let group: ReactFiber[] | null = null;\n while (cursor && depth < MAX_FIBER_CHAIN_DEPTH) {\n climb.push(cursor);\n const candidate = findRepetitionGroup(cursor);\n if (candidate) {\n unit = cursor;\n group = candidate;\n break;\n }\n cursor = cursor.return;\n depth += 1;\n }\n\n if (!unit || !group) {\n return [element];\n }\n\n const downward = climb.slice(0, climb.indexOf(unit) + 1).reverse();\n // null when a climb step is not linked into its parent's child list (stale\n // generation slipped through) \u2014 every member then resolves via subtree\n // search instead of descending a path recorded against the wrong tree.\n let pathFromUnit: number[] | null = [];\n for (let i = 0; i < downward.length - 1 && pathFromUnit; i += 1) {\n const parentFiber = downward[i];\n const targetFiber = downward[i + 1];\n if (!parentFiber || !targetFiber) {\n break;\n }\n let child: ReactFiber | null | undefined = parentFiber.child;\n let index = 0;\n while (child && child !== targetFiber && child !== targetFiber.alternate) {\n child = child.sibling;\n index += 1;\n }\n if (child) {\n pathFromUnit.push(index);\n } else {\n pathFromUnit = null;\n }\n }\n\n const selectedType = selectedFiber.type;\n const selectedSourceKey = getFiberSourceKey(selectedFiber);\n const nodes: HTMLElement[] = [];\n const seen = new Set<HTMLElement>();\n for (const member of group) {\n const landed = pathFromUnit ? descendChildPath(member, pathFromUnit) : null;\n const node = isMatchingHost(landed, selectedType, selectedSourceKey)\n ? getHostNode(landed)\n : findHostInSubtree(member, selectedType, selectedSourceKey);\n if (node && !seen.has(node)) {\n seen.add(node);\n nodes.push(node);\n }\n }\n\n if (!seen.has(element)) {\n nodes.push(element);\n }\n\n return nodes;\n}\n\nfunction getSerializablePropValue(value: unknown): unknown {\n if (\n value === null ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n\n if (typeof value === \"string\") {\n return value.length > MAX_SERIALIZED_STRING_LENGTH\n ? `${value.slice(0, MAX_SERIALIZED_STRING_LENGTH)}...`\n : value;\n }\n\n if (Array.isArray(value)) {\n return value.slice(0, 20).map(getSerializablePropValue);\n }\n\n if (typeof value === \"object\") {\n return \"[object]\";\n }\n\n return undefined;\n}\n\nfunction getSerializableProps(\n props: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!props) {\n return undefined;\n }\n\n const serializedProps: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(props).slice(\n 0,\n MAX_SERIALIZED_PROP_COUNT,\n )) {\n if (\n key === \"children\" ||\n key === \"ref\" ||\n key.startsWith(\"on\") ||\n typeof value === \"function\" ||\n typeof value === \"symbol\"\n ) {\n continue;\n }\n\n const serializableValue = getSerializablePropValue(value);\n if (serializableValue !== undefined) {\n serializedProps[key] = serializableValue;\n }\n }\n\n return Object.keys(serializedProps).length > 0 ? serializedProps : undefined;\n}\n\nexport function getFiberChain(element: HTMLElement) {\n const rootFiber = getFiberFromElement(element);\n const fiberChain = [];\n const seenKeys = new Set<string>();\n const seenOwners = new Set<ReactFiber | ReactServerOwner>();\n let currentFiber: ReactFiber | null | undefined = rootFiber;\n let depth = 0;\n\n while (currentFiber && depth < MAX_FIBER_CHAIN_DEPTH) {\n const source = getDebugSource(currentFiber);\n if (source) {\n const tagName = getTagName(currentFiber);\n const componentName = getComponentName(currentFiber);\n const key = [\n source.fileName,\n source.lineNumber,\n source.columnNumber ?? \"\",\n tagName ?? \"\",\n componentName ?? \"\",\n ].join(\":\");\n\n if (!seenKeys.has(key)) {\n seenKeys.add(key);\n fiberChain.push({\n sourceLocation: {\n filePath: source.fileName,\n lineNumber: source.lineNumber,\n columnNumber: source.columnNumber,\n componentName,\n },\n tagName,\n componentName,\n props: getSerializableProps(\n currentFiber.memoizedProps ?? currentFiber.pendingProps,\n ),\n });\n }\n }\n\n // Server components don't have DOM fibers. Their owner records carry\n // the JSX usage stack, which distinguishes separate renders of one component.\n let owner = currentFiber._debugOwner;\n while (\n owner &&\n seenOwners.size < MAX_FIBER_CHAIN_DEPTH &&\n !seenOwners.has(owner)\n ) {\n seenOwners.add(owner);\n if (\"name\" in owner) {\n const ownerSource = parseDebugStackSource(owner.debugStack);\n if (ownerSource) {\n const key = [\n ownerSource.fileName,\n ownerSource.lineNumber,\n ownerSource.columnNumber ?? \"\",\n \"\",\n owner.name,\n ].join(\":\");\n if (!seenKeys.has(key)) {\n seenKeys.add(key);\n fiberChain.push({\n sourceLocation: {\n filePath: ownerSource.fileName,\n lineNumber: ownerSource.lineNumber,\n columnNumber: ownerSource.columnNumber,\n componentName: owner.name,\n },\n tagName: undefined,\n componentName: owner.name,\n props: getSerializableProps(owner.props),\n });\n }\n }\n owner = owner.owner;\n } else {\n owner = owner._debugOwner;\n }\n }\n\n currentFiber = currentFiber.return;\n depth += 1;\n }\n\n return fiberChain;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
2
|
import { buildSelector } from "../descriptor/elementDescriptor";
|
|
3
|
+
import {
|
|
4
|
+
SELECT_MODE_OVERRIDE_ATTRIBUTE,
|
|
5
|
+
SELECT_MODE_OVERRIDE_STYLE_ATTRIBUTE
|
|
6
|
+
} from "../optimisticOverrideDom";
|
|
3
7
|
import { getRepetitionSiblingSelectors } from "./useSiblingResolution";
|
|
4
8
|
const OVERRIDE_REGISTRATION_TIMEOUT_MS = 15e3;
|
|
5
9
|
const SESSION_OUTCOME_RETENTION_MS = 6e4;
|
|
6
|
-
const OVERRIDE_ATTRIBUTE = "data-replo-select-overrides";
|
|
7
10
|
const OVERRIDE_REGISTRY_KEY = "reploSelectOverrideRegistryV2";
|
|
8
11
|
const SESSION_OUTCOME_REGISTRY_KEY = "reploSelectOverrideSessionOutcomesV2";
|
|
9
12
|
function getOverrideList() {
|
|
@@ -68,23 +71,23 @@ function getOriginalState({
|
|
|
68
71
|
}
|
|
69
72
|
function getStyleElement(token) {
|
|
70
73
|
return document.querySelector(
|
|
71
|
-
`style[
|
|
74
|
+
`style[${SELECT_MODE_OVERRIDE_STYLE_ATTRIBUTE}="${token}"]`
|
|
72
75
|
);
|
|
73
76
|
}
|
|
74
77
|
function addToken(element, token) {
|
|
75
78
|
const tokens = new Set(
|
|
76
|
-
(element.getAttribute(
|
|
79
|
+
(element.getAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE) ?? "").split(/\s+/).filter(Boolean)
|
|
77
80
|
);
|
|
78
81
|
tokens.add(token);
|
|
79
|
-
element.setAttribute(
|
|
82
|
+
element.setAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE, [...tokens].join(" "));
|
|
80
83
|
}
|
|
81
84
|
function removeToken(element, token) {
|
|
82
|
-
const tokens = (element.getAttribute(
|
|
85
|
+
const tokens = (element.getAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE) ?? "").split(/\s+/).filter((candidate) => candidate && candidate !== token);
|
|
83
86
|
if (tokens.length === 0) {
|
|
84
|
-
element.removeAttribute(
|
|
87
|
+
element.removeAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE);
|
|
85
88
|
return;
|
|
86
89
|
}
|
|
87
|
-
element.setAttribute(
|
|
90
|
+
element.setAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE, tokens.join(" "));
|
|
88
91
|
}
|
|
89
92
|
function applyPayload({
|
|
90
93
|
element,
|
|
@@ -128,7 +131,7 @@ function installCssRule(override) {
|
|
|
128
131
|
}
|
|
129
132
|
const style = document.createElement("style");
|
|
130
133
|
style.dataset.reploSelectOverride = override.token;
|
|
131
|
-
style.textContent = `[${
|
|
134
|
+
style.textContent = `[${SELECT_MODE_OVERRIDE_ATTRIBUTE}~="${override.token}"] { ${override.payload.property}: ${override.payload.value ?? "revert"} !important; }`;
|
|
132
135
|
document.head.append(style);
|
|
133
136
|
}
|
|
134
137
|
function resolveTarget(target) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../select-mode/hooks/useOptimisticOverrides.ts"],
|
|
4
|
-
"sourcesContent": ["import type { SelectModeOptimisticUpdatePayload } from \"schemas/generated/selectMode\";\n\nimport { useCallback } from \"react\";\n\nimport { buildSelector } from \"../descriptor/elementDescriptor\";\nimport { getRepetitionSiblingSelectors } from \"./useSiblingResolution\";\n\ntype OverrideTarget = {\n element: HTMLElement;\n originalState: OriginalPayloadState;\n selector: string;\n};\n\ntype OriginalPayloadState =\n | {\n kind: \"attributes\";\n values: { name: string; value: string | null }[];\n }\n | { kind: \"content\"; innerHTML: string }\n | { kind: \"css\" };\n\ntype IframeOverride = {\n editId: string;\n payload: SelectModeOptimisticUpdatePayload;\n registrationTimeout: number;\n sessionId: string | null;\n state: \"live\" | \"fired\";\n targets: OverrideTarget[];\n token: string;\n};\n\nconst OVERRIDE_REGISTRATION_TIMEOUT_MS = 15_000;\nconst SESSION_OUTCOME_RETENTION_MS = 60_000;\nconst OVERRIDE_ATTRIBUTE = \"data-replo-select-overrides\";\nconst OVERRIDE_REGISTRY_KEY = \"reploSelectOverrideRegistryV2\";\nconst SESSION_OUTCOME_REGISTRY_KEY = \"reploSelectOverrideSessionOutcomesV2\";\n\ntype SessionOutcome = \"persisted\" | \"failed\";\n\nfunction getOverrideList(): IframeOverride[] {\n const existing: unknown = Reflect.get(window, OVERRIDE_REGISTRY_KEY);\n if (Array.isArray(existing)) {\n return existing;\n }\n const overrides: IframeOverride[] = [];\n Reflect.set(window, OVERRIDE_REGISTRY_KEY, overrides);\n return overrides;\n}\n\nfunction setOverrideList(overrides: IframeOverride[]) {\n Reflect.set(window, OVERRIDE_REGISTRY_KEY, overrides);\n}\n\nfunction getSessionOutcomes(): Map<string, SessionOutcome> {\n const existing: unknown = Reflect.get(window, SESSION_OUTCOME_REGISTRY_KEY);\n if (existing instanceof Map) {\n return existing;\n }\n const outcomes = new Map<string, SessionOutcome>();\n Reflect.set(window, SESSION_OUTCOME_REGISTRY_KEY, outcomes);\n return outcomes;\n}\n\nfunction getElementsForTargetMode({\n element,\n targetMode,\n}: {\n element: HTMLElement;\n targetMode: \"primary\" | \"group\";\n}) {\n if (targetMode === \"primary\") {\n return [element];\n }\n\n return [\n element,\n ...getRepetitionSiblingSelectors({ element })\n .map((selector) => document.querySelector(selector))\n .filter((candidate): candidate is HTMLElement => {\n return candidate instanceof HTMLElement;\n }),\n ];\n}\n\nfunction isImageSourcePayload({\n element,\n payload,\n}: {\n element: HTMLElement;\n payload: SelectModeOptimisticUpdatePayload;\n}) {\n return (\n payload.kind === \"attribute\" &&\n payload.name.toLowerCase() === \"src\" &&\n element instanceof HTMLImageElement\n );\n}\n\nfunction getOriginalState({\n element,\n payload,\n}: {\n element: HTMLElement;\n payload: SelectModeOptimisticUpdatePayload;\n}): OriginalPayloadState {\n if (payload.kind === \"attribute\") {\n const names = isImageSourcePayload({ element, payload })\n ? [payload.name, \"srcset\"]\n : [payload.name];\n return {\n kind: \"attributes\",\n values: names.map((name) => ({\n name,\n value: element.getAttribute(name),\n })),\n };\n }\n if (payload.kind === \"content\") {\n return { kind: \"content\", innerHTML: element.innerHTML };\n }\n return { kind: \"css\" };\n}\n\nfunction getStyleElement(token: string) {\n return document.querySelector<HTMLStyleElement>(\n `style[data-replo-select-override=\"${token}\"]`,\n );\n}\n\nfunction addToken(element: HTMLElement, token: string) {\n const tokens = new Set(\n (element.getAttribute(OVERRIDE_ATTRIBUTE) ?? \"\")\n .split(/\\s+/)\n .filter(Boolean),\n );\n tokens.add(token);\n element.setAttribute(OVERRIDE_ATTRIBUTE, [...tokens].join(\" \"));\n}\n\nfunction removeToken(element: HTMLElement, token: string) {\n const tokens = (element.getAttribute(OVERRIDE_ATTRIBUTE) ?? \"\")\n .split(/\\s+/)\n .filter((candidate) => candidate && candidate !== token);\n if (tokens.length === 0) {\n element.removeAttribute(OVERRIDE_ATTRIBUTE);\n return;\n }\n element.setAttribute(OVERRIDE_ATTRIBUTE, tokens.join(\" \"));\n}\n\nfunction applyPayload({\n element,\n payload,\n token,\n}: {\n element: HTMLElement;\n payload: SelectModeOptimisticUpdatePayload;\n token: string;\n}) {\n if (payload.kind === \"css\") {\n addToken(element, token);\n return;\n }\n if (payload.kind === \"attribute\") {\n if (isImageSourcePayload({ element, payload })) {\n element.removeAttribute(\"srcset\");\n }\n element.setAttribute(payload.name, payload.value);\n return;\n }\n element.innerHTML = payload.innerHTML;\n}\n\nfunction restoreOriginalState({\n element,\n originalState,\n}: {\n element: HTMLElement;\n originalState: OriginalPayloadState;\n}) {\n if (originalState.kind === \"attributes\") {\n for (const { name, value } of originalState.values) {\n if (value === null) {\n element.removeAttribute(name);\n } else {\n element.setAttribute(name, value);\n }\n }\n return;\n }\n if (originalState.kind === \"content\") {\n element.innerHTML = originalState.innerHTML;\n }\n}\n\nfunction installCssRule(override: IframeOverride) {\n if (override.payload.kind !== \"css\") {\n return;\n }\n const style = document.createElement(\"style\");\n style.dataset.reploSelectOverride = override.token;\n style.textContent = `[${OVERRIDE_ATTRIBUTE}~=\"${override.token}\"] { ${override.payload.property}: ${override.payload.value ?? \"revert\"} !important; }`;\n document.head.append(style);\n}\n\nfunction resolveTarget(target: OverrideTarget) {\n if (target.element.isConnected) {\n return target.element;\n }\n const replacement = document.querySelector(target.selector);\n return replacement instanceof HTMLElement ? replacement : null;\n}\n\nfunction reapplyOverride({\n override,\n skipElement,\n}: {\n override: IframeOverride;\n skipElement: HTMLElement | null;\n}) {\n for (const target of override.targets) {\n const element = resolveTarget(target);\n if (!element || (skipElement && element.contains(skipElement))) {\n continue;\n }\n if (element !== target.element) {\n target.element = element;\n target.originalState = getOriginalState({\n element,\n payload: override.payload,\n });\n }\n applyPayload({ element, payload: override.payload, token: override.token });\n }\n}\n\nfunction removeOverride({\n editId,\n outcome,\n}: {\n editId: string;\n outcome: SessionOutcome;\n}) {\n const override = getOverrideList().find(\n (candidate) => candidate.editId === editId,\n );\n if (!override) {\n return;\n }\n\n clearTimeout(override.registrationTimeout);\n getStyleElement(override.token)?.remove();\n for (const target of override.targets) {\n const element = resolveTarget(target);\n if (!element) {\n continue;\n }\n removeToken(element, override.token);\n if (outcome === \"failed\") {\n restoreOriginalState({\n element,\n originalState: target.originalState,\n });\n }\n }\n setOverrideList(\n getOverrideList().filter((candidate) => candidate.editId !== editId),\n );\n\n if (outcome === \"failed\") {\n for (const remainingOverride of getOverrideList()) {\n reapplyOverride({ override: remainingOverride, skipElement: null });\n }\n }\n}\n\nexport function useOptimisticOverrides() {\n const applyOptimisticUpdate = useCallback(\n ({\n editId,\n payload,\n targetSelector,\n targetMode,\n }: {\n editId: string;\n payload: SelectModeOptimisticUpdatePayload;\n targetSelector: string;\n targetMode: \"primary\" | \"group\";\n }) => {\n const targetElement = document.querySelector(targetSelector);\n if (!(targetElement instanceof HTMLElement)) {\n return;\n }\n\n removeOverride({ editId, outcome: \"failed\" });\n const elements = getElementsForTargetMode({\n element: targetElement,\n targetMode,\n });\n const token = `override-${editId}`;\n const override: IframeOverride = {\n editId,\n payload,\n registrationTimeout: window.setTimeout(() => {\n removeOverride({ editId, outcome: \"failed\" });\n }, OVERRIDE_REGISTRATION_TIMEOUT_MS),\n sessionId: null,\n state: \"live\",\n targets: elements.map((element) => ({\n element,\n originalState: getOriginalState({ element, payload }),\n selector: buildSelector(element),\n })),\n token,\n };\n getOverrideList().push(override);\n installCssRule(override);\n reapplyOverride({ override, skipElement: null });\n },\n [],\n );\n\n const reapplyOverrides = useCallback(\n ({ skipElement }: { skipElement: HTMLElement | null }) => {\n for (const override of getOverrideList()) {\n reapplyOverride({ override, skipElement });\n }\n },\n [],\n );\n\n const markCommitted = useCallback((editId: string, sessionId: string) => {\n const override = getOverrideList().find((candidate) => {\n return candidate.editId === editId;\n });\n if (!override) {\n return;\n }\n clearTimeout(override.registrationTimeout);\n override.sessionId = sessionId;\n override.state = \"fired\";\n const outcome = getSessionOutcomes().get(sessionId);\n if (outcome) {\n removeOverride({ editId, outcome });\n }\n }, []);\n\n const resolveSessionOverrides = useCallback(\n (sessionId: string, outcome: SessionOutcome) => {\n getSessionOutcomes().set(sessionId, outcome);\n window.setTimeout(() => {\n getSessionOutcomes().delete(sessionId);\n }, SESSION_OUTCOME_RETENTION_MS);\n const editIds = getOverrideList()\n .filter((override) => override.sessionId === sessionId)\n .map((override) => override.editId);\n for (const editId of editIds) {\n removeOverride({ editId, outcome });\n }\n },\n [],\n );\n\n const revertOverride = useCallback((editId: string) => {\n removeOverride({ editId, outcome: \"failed\" });\n }, []);\n\n return {\n applyOptimisticUpdate,\n markCommitted,\n reapplyOverrides,\n resolveSessionOverrides,\n revertOverride,\n };\n}\n"],
|
|
5
|
-
"mappings": "AAEA,SAAS,mBAAmB;AAE5B,SAAS,qBAAqB;AAC9B,SAAS,qCAAqC;AA0B9C,MAAM,mCAAmC;AACzC,MAAM,+BAA+B;AACrC,MAAM,
|
|
4
|
+
"sourcesContent": ["import type { SelectModeOptimisticUpdatePayload } from \"schemas/generated/selectMode\";\n\nimport { useCallback } from \"react\";\n\nimport { buildSelector } from \"../descriptor/elementDescriptor\";\nimport {\n SELECT_MODE_OVERRIDE_ATTRIBUTE,\n SELECT_MODE_OVERRIDE_STYLE_ATTRIBUTE,\n} from \"../optimisticOverrideDom\";\nimport { getRepetitionSiblingSelectors } from \"./useSiblingResolution\";\n\ntype OverrideTarget = {\n element: HTMLElement;\n originalState: OriginalPayloadState;\n selector: string;\n};\n\ntype OriginalPayloadState =\n | {\n kind: \"attributes\";\n values: { name: string; value: string | null }[];\n }\n | { kind: \"content\"; innerHTML: string }\n | { kind: \"css\" };\n\ntype IframeOverride = {\n editId: string;\n payload: SelectModeOptimisticUpdatePayload;\n registrationTimeout: number;\n sessionId: string | null;\n state: \"live\" | \"fired\";\n targets: OverrideTarget[];\n token: string;\n};\n\nconst OVERRIDE_REGISTRATION_TIMEOUT_MS = 15_000;\nconst SESSION_OUTCOME_RETENTION_MS = 60_000;\nconst OVERRIDE_REGISTRY_KEY = \"reploSelectOverrideRegistryV2\";\nconst SESSION_OUTCOME_REGISTRY_KEY = \"reploSelectOverrideSessionOutcomesV2\";\n\ntype SessionOutcome = \"persisted\" | \"failed\";\n\nfunction getOverrideList(): IframeOverride[] {\n const existing: unknown = Reflect.get(window, OVERRIDE_REGISTRY_KEY);\n if (Array.isArray(existing)) {\n return existing;\n }\n const overrides: IframeOverride[] = [];\n Reflect.set(window, OVERRIDE_REGISTRY_KEY, overrides);\n return overrides;\n}\n\nfunction setOverrideList(overrides: IframeOverride[]) {\n Reflect.set(window, OVERRIDE_REGISTRY_KEY, overrides);\n}\n\nfunction getSessionOutcomes(): Map<string, SessionOutcome> {\n const existing: unknown = Reflect.get(window, SESSION_OUTCOME_REGISTRY_KEY);\n if (existing instanceof Map) {\n return existing;\n }\n const outcomes = new Map<string, SessionOutcome>();\n Reflect.set(window, SESSION_OUTCOME_REGISTRY_KEY, outcomes);\n return outcomes;\n}\n\nfunction getElementsForTargetMode({\n element,\n targetMode,\n}: {\n element: HTMLElement;\n targetMode: \"primary\" | \"group\";\n}) {\n if (targetMode === \"primary\") {\n return [element];\n }\n\n return [\n element,\n ...getRepetitionSiblingSelectors({ element })\n .map((selector) => document.querySelector(selector))\n .filter((candidate): candidate is HTMLElement => {\n return candidate instanceof HTMLElement;\n }),\n ];\n}\n\nfunction isImageSourcePayload({\n element,\n payload,\n}: {\n element: HTMLElement;\n payload: SelectModeOptimisticUpdatePayload;\n}) {\n return (\n payload.kind === \"attribute\" &&\n payload.name.toLowerCase() === \"src\" &&\n element instanceof HTMLImageElement\n );\n}\n\nfunction getOriginalState({\n element,\n payload,\n}: {\n element: HTMLElement;\n payload: SelectModeOptimisticUpdatePayload;\n}): OriginalPayloadState {\n if (payload.kind === \"attribute\") {\n const names = isImageSourcePayload({ element, payload })\n ? [payload.name, \"srcset\"]\n : [payload.name];\n return {\n kind: \"attributes\",\n values: names.map((name) => ({\n name,\n value: element.getAttribute(name),\n })),\n };\n }\n if (payload.kind === \"content\") {\n return { kind: \"content\", innerHTML: element.innerHTML };\n }\n return { kind: \"css\" };\n}\n\nfunction getStyleElement(token: string) {\n return document.querySelector<HTMLStyleElement>(\n `style[${SELECT_MODE_OVERRIDE_STYLE_ATTRIBUTE}=\"${token}\"]`,\n );\n}\n\nfunction addToken(element: HTMLElement, token: string) {\n const tokens = new Set(\n (element.getAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE) ?? \"\")\n .split(/\\s+/)\n .filter(Boolean),\n );\n tokens.add(token);\n element.setAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE, [...tokens].join(\" \"));\n}\n\nfunction removeToken(element: HTMLElement, token: string) {\n const tokens = (element.getAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE) ?? \"\")\n .split(/\\s+/)\n .filter((candidate) => candidate && candidate !== token);\n if (tokens.length === 0) {\n element.removeAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE);\n return;\n }\n element.setAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE, tokens.join(\" \"));\n}\n\nfunction applyPayload({\n element,\n payload,\n token,\n}: {\n element: HTMLElement;\n payload: SelectModeOptimisticUpdatePayload;\n token: string;\n}) {\n if (payload.kind === \"css\") {\n addToken(element, token);\n return;\n }\n if (payload.kind === \"attribute\") {\n if (isImageSourcePayload({ element, payload })) {\n element.removeAttribute(\"srcset\");\n }\n element.setAttribute(payload.name, payload.value);\n return;\n }\n element.innerHTML = payload.innerHTML;\n}\n\nfunction restoreOriginalState({\n element,\n originalState,\n}: {\n element: HTMLElement;\n originalState: OriginalPayloadState;\n}) {\n if (originalState.kind === \"attributes\") {\n for (const { name, value } of originalState.values) {\n if (value === null) {\n element.removeAttribute(name);\n } else {\n element.setAttribute(name, value);\n }\n }\n return;\n }\n if (originalState.kind === \"content\") {\n element.innerHTML = originalState.innerHTML;\n }\n}\n\nfunction installCssRule(override: IframeOverride) {\n if (override.payload.kind !== \"css\") {\n return;\n }\n const style = document.createElement(\"style\");\n style.dataset.reploSelectOverride = override.token;\n style.textContent = `[${SELECT_MODE_OVERRIDE_ATTRIBUTE}~=\"${override.token}\"] { ${override.payload.property}: ${override.payload.value ?? \"revert\"} !important; }`;\n document.head.append(style);\n}\n\nfunction resolveTarget(target: OverrideTarget) {\n if (target.element.isConnected) {\n return target.element;\n }\n const replacement = document.querySelector(target.selector);\n return replacement instanceof HTMLElement ? replacement : null;\n}\n\nfunction reapplyOverride({\n override,\n skipElement,\n}: {\n override: IframeOverride;\n skipElement: HTMLElement | null;\n}) {\n for (const target of override.targets) {\n const element = resolveTarget(target);\n if (!element || (skipElement && element.contains(skipElement))) {\n continue;\n }\n if (element !== target.element) {\n target.element = element;\n target.originalState = getOriginalState({\n element,\n payload: override.payload,\n });\n }\n applyPayload({ element, payload: override.payload, token: override.token });\n }\n}\n\nfunction removeOverride({\n editId,\n outcome,\n}: {\n editId: string;\n outcome: SessionOutcome;\n}) {\n const override = getOverrideList().find(\n (candidate) => candidate.editId === editId,\n );\n if (!override) {\n return;\n }\n\n clearTimeout(override.registrationTimeout);\n getStyleElement(override.token)?.remove();\n for (const target of override.targets) {\n const element = resolveTarget(target);\n if (!element) {\n continue;\n }\n removeToken(element, override.token);\n if (outcome === \"failed\") {\n restoreOriginalState({\n element,\n originalState: target.originalState,\n });\n }\n }\n setOverrideList(\n getOverrideList().filter((candidate) => candidate.editId !== editId),\n );\n\n if (outcome === \"failed\") {\n for (const remainingOverride of getOverrideList()) {\n reapplyOverride({ override: remainingOverride, skipElement: null });\n }\n }\n}\n\nexport function useOptimisticOverrides() {\n const applyOptimisticUpdate = useCallback(\n ({\n editId,\n payload,\n targetSelector,\n targetMode,\n }: {\n editId: string;\n payload: SelectModeOptimisticUpdatePayload;\n targetSelector: string;\n targetMode: \"primary\" | \"group\";\n }) => {\n const targetElement = document.querySelector(targetSelector);\n if (!(targetElement instanceof HTMLElement)) {\n return;\n }\n\n removeOverride({ editId, outcome: \"failed\" });\n const elements = getElementsForTargetMode({\n element: targetElement,\n targetMode,\n });\n const token = `override-${editId}`;\n const override: IframeOverride = {\n editId,\n payload,\n registrationTimeout: window.setTimeout(() => {\n removeOverride({ editId, outcome: \"failed\" });\n }, OVERRIDE_REGISTRATION_TIMEOUT_MS),\n sessionId: null,\n state: \"live\",\n targets: elements.map((element) => ({\n element,\n originalState: getOriginalState({ element, payload }),\n selector: buildSelector(element),\n })),\n token,\n };\n getOverrideList().push(override);\n installCssRule(override);\n reapplyOverride({ override, skipElement: null });\n },\n [],\n );\n\n const reapplyOverrides = useCallback(\n ({ skipElement }: { skipElement: HTMLElement | null }) => {\n for (const override of getOverrideList()) {\n reapplyOverride({ override, skipElement });\n }\n },\n [],\n );\n\n const markCommitted = useCallback((editId: string, sessionId: string) => {\n const override = getOverrideList().find((candidate) => {\n return candidate.editId === editId;\n });\n if (!override) {\n return;\n }\n clearTimeout(override.registrationTimeout);\n override.sessionId = sessionId;\n override.state = \"fired\";\n const outcome = getSessionOutcomes().get(sessionId);\n if (outcome) {\n removeOverride({ editId, outcome });\n }\n }, []);\n\n const resolveSessionOverrides = useCallback(\n (sessionId: string, outcome: SessionOutcome) => {\n getSessionOutcomes().set(sessionId, outcome);\n window.setTimeout(() => {\n getSessionOutcomes().delete(sessionId);\n }, SESSION_OUTCOME_RETENTION_MS);\n const editIds = getOverrideList()\n .filter((override) => override.sessionId === sessionId)\n .map((override) => override.editId);\n for (const editId of editIds) {\n removeOverride({ editId, outcome });\n }\n },\n [],\n );\n\n const revertOverride = useCallback((editId: string) => {\n removeOverride({ editId, outcome: \"failed\" });\n }, []);\n\n return {\n applyOptimisticUpdate,\n markCommitted,\n reapplyOverrides,\n resolveSessionOverrides,\n revertOverride,\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const SELECT_MODE_OVERRIDE_ATTRIBUTE = "data-replo-select-overrides";
|
|
2
|
+
const SELECT_MODE_OVERRIDE_STYLE_ATTRIBUTE = "data-replo-select-override";
|
|
3
|
+
export {
|
|
4
|
+
SELECT_MODE_OVERRIDE_ATTRIBUTE,
|
|
5
|
+
SELECT_MODE_OVERRIDE_STYLE_ATTRIBUTE
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=optimisticOverrideDom.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../select-mode/optimisticOverrideDom.ts"],
|
|
4
|
+
"sourcesContent": ["export const SELECT_MODE_OVERRIDE_ATTRIBUTE = \"data-replo-select-overrides\";\nexport const SELECT_MODE_OVERRIDE_STYLE_ATTRIBUTE =\n \"data-replo-select-override\";\n"],
|
|
5
|
+
"mappings": "AAAO,MAAM,iCAAiC;AACvC,MAAM,uCACX;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|