@replohq/sandbox-runtime 1.7.1 → 1.7.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/ClientErrorBoundary.d.ts +1 -1
- package/ClientErrorBoundary.js +0 -5
- package/DocumentReadyBeacon.js +0 -1
- package/LinkInterceptor.js +0 -1
- package/NavigationReceiver.js +0 -1
- package/NextErrorReporter.js +0 -1
- package/_vendor/replo-utils/lib/fonts.mjs +0 -13
- package/_vendor/replo-utils/lib/geometry.mjs +0 -1
- package/_vendor/replo-utils/lib/math.d.ts +0 -4
- package/_vendor/replo-utils/lib/math.mjs +0 -1
- package/_vendor/replo-utils/lib/posthogReplay.mjs +0 -1
- package/_vendor/replo-utils/react/use-iframe-rpc-channel.mjs +0 -1
- package/_vendor/replo-utils/react/use-viewport-snapshot-responder.mjs +9 -25
- package/_vendor/schemas/componentPreview.mjs +0 -4
- package/_vendor/schemas/designLibrary.mjs +0 -2
- package/_vendor/schemas/errors.d.ts +0 -3
- package/_vendor/schemas/iframeRpcChannel.d.ts +1 -1
- package/_vendor/schemas/iframeRpcChannel.mjs +0 -22
- package/_vendor/schemas/pageAnnotations.mjs +0 -3
- package/_vendor/schemas/selectMode.d.ts +0 -4
- package/_vendor/schemas/selectModeIframeRpc.mjs +0 -10
- package/annotations/AnnotationLayerMount.js +0 -1
- package/annotations/annotationController.js +0 -3
- package/annotations/bridgeGate.js +0 -4
- package/buildMetadata.js +3 -3
- package/chunk-3YA3QXUQ.mjs +1 -4
- package/chunk-FLYEIRFK.mjs +0 -1
- package/chunk-G3S6ZNPF.mjs +0 -7
- package/chunk-JUKCUPQ6.mjs +5 -129
- package/chunk-SGKQ5HGT.mjs +0 -1
- package/chunk-TESFJQID.mjs +0 -1
- package/chunk-UOBGRB5I.mjs +0 -5
- package/design-library-preview/DesignLibraryPreview.js +0 -1
- package/next/component-preview-client.js +0 -1
- package/next/component-preview-href.js +0 -1
- package/next/component-preview-props.js +0 -1
- package/next/component-preview.js +0 -1
- package/next/config.js +0 -1
- package/package.json +4 -4
- package/posthog-relay.js +0 -5
- package/sandbox-runtime.js +0 -1
- package/select-mode/EditorSelection.d.ts +0 -2
- package/select-mode/EditorSelection.js +0 -1
- package/select-mode/annotationFrames.js +0 -1
- package/select-mode/descriptor/elementDescriptor.d.ts +0 -2
- package/select-mode/descriptor/elementDescriptor.js +0 -1
- package/select-mode/descriptor/styleExtraction.js +0 -1
- package/select-mode/displayModeStore.js +0 -2
- package/select-mode/fast-refresh-relay.js +0 -1
- package/select-mode/fiber.js +1 -5
- package/select-mode/hooks/useCrosshairCursor.d.ts +0 -2
- package/select-mode/hooks/useCrosshairCursor.js +0 -1
- package/select-mode/hooks/useEditModeStateMachine.js +0 -1
- package/select-mode/hooks/useOptimisticOverrides.js +0 -1
- package/select-mode/hooks/useParentMessaging.d.ts +0 -2
- package/select-mode/hooks/useParentMessaging.js +0 -1
- package/select-mode/hooks/useSelectModeController.js +0 -1
- package/select-mode/hooks/useSelectionHover.d.ts +0 -2
- package/select-mode/hooks/useSelectionHover.js +0 -1
- package/select-mode/hooks/useSelectionInteractions.d.ts +0 -2
- package/select-mode/hooks/useSelectionInteractions.js +0 -1
- package/select-mode/hooks/useSelectionScrollSync.d.ts +0 -2
- package/select-mode/hooks/useSelectionScrollSync.js +0 -1
- package/select-mode/hooks/useSiblingResolution.js +0 -1
- package/select-mode/iframeRpcChannel.js +0 -1
- package/select-mode/inlineTextMarks.js +0 -1
- package/select-mode/interactions/selectionGeometry.d.ts +0 -20
- package/select-mode/interactions/selectionGeometry.js +0 -1
- package/select-mode/optimisticOverrideDom.js +0 -1
- package/select-mode/selectModeSession.js +0 -1
- package/select-mode/selectionFrame.d.ts +0 -7
- package/select-mode/selectionFrame.js +0 -1
- package/select-mode/selectionPublish.js +0 -1
- package/select-mode/symbolicate.js +0 -1
- package/select-mode/tiptapInlineEditor.js +0 -5
- package/ClientErrorBoundary.js.map +0 -7
- package/DocumentReadyBeacon.js.map +0 -7
- package/LinkInterceptor.js.map +0 -7
- package/NavigationReceiver.js.map +0 -7
- package/NextErrorReporter.js.map +0 -7
- package/annotations/AnnotationLayerMount.js.map +0 -7
- package/annotations/annotationController.js.map +0 -7
- package/annotations/bridgeGate.js.map +0 -7
- package/buildMetadata.js.map +0 -7
- package/design-library-preview/DesignLibraryPreview.js.map +0 -7
- package/next/component-preview-client.js.map +0 -7
- package/next/component-preview-href.js.map +0 -7
- package/next/component-preview-props.js.map +0 -7
- package/next/component-preview.js.map +0 -7
- package/next/config.js.map +0 -7
- package/posthog-relay.js.map +0 -7
- package/sandbox-runtime.js.map +0 -7
- package/select-mode/EditorSelection.js.map +0 -7
- package/select-mode/annotationFrames.js.map +0 -7
- package/select-mode/descriptor/elementDescriptor.js.map +0 -7
- package/select-mode/descriptor/styleExtraction.js.map +0 -7
- package/select-mode/displayModeStore.js.map +0 -7
- package/select-mode/fast-refresh-relay.js.map +0 -7
- package/select-mode/fiber.js.map +0 -7
- package/select-mode/hooks/useCrosshairCursor.js.map +0 -7
- package/select-mode/hooks/useEditModeStateMachine.js.map +0 -7
- package/select-mode/hooks/useOptimisticOverrides.js.map +0 -7
- package/select-mode/hooks/useParentMessaging.js.map +0 -7
- package/select-mode/hooks/useSelectModeController.js.map +0 -7
- package/select-mode/hooks/useSelectionHover.js.map +0 -7
- package/select-mode/hooks/useSelectionInteractions.js.map +0 -7
- package/select-mode/hooks/useSelectionScrollSync.js.map +0 -7
- package/select-mode/hooks/useSiblingResolution.js.map +0 -7
- package/select-mode/iframeRpcChannel.js.map +0 -7
- package/select-mode/inlineTextMarks.js.map +0 -7
- package/select-mode/interactions/selectionGeometry.js.map +0 -7
- package/select-mode/optimisticOverrideDom.js.map +0 -7
- package/select-mode/selectModeSession.js.map +0 -7
- package/select-mode/selectionFrame.js.map +0 -7
- package/select-mode/selectionPublish.js.map +0 -7
- package/select-mode/symbolicate.js.map +0 -7
- package/select-mode/tiptapInlineEditor.js.map +0 -7
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../annotations/annotationController.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * In-iframe annotation controller: consumes declarative marker sets from the\n * editor bridge, resolves selectors against the live DOM, and drives the\n * shared annotation frame renderer. Scroll costs zero JavaScript (frames use\n * page coordinates); re-measure runs only on resize/mutation/container\n * scroll, batched per animation frame. Data-only protocol \u2014 the editor can\n * describe dots, never execute code.\n */\nimport type {\n PageAnnotationMarker,\n PageAnnotationsIframeMessage,\n} from \"schemas/generated/pageAnnotations\";\nimport type { AnnotationFrameSpec } from \"../select-mode/annotationFrames\";\n\nimport { clamp } from \"replo-utils/lib/math\";\nimport { exhaustiveSwitch } from \"replo-utils/lib/misc\";\nimport {\n PAGE_ANNOTATIONS_PROTOCOL_VERSION,\n pageAnnotationsParentMessageSchema,\n} from \"schemas/pageAnnotations\";\n\nimport {\n ANNOTATION_CONTAINER_ID,\n clearAnnotationFrames,\n getAnnotationBadgeViewportRect,\n setActiveAnnotationBadge,\n showAnnotationFrames,\n} from \"../select-mode/annotationFrames\";\nimport { getDocumentScrollOffset } from \"../select-mode/interactions/selectionGeometry\";\nimport { isAllowedEditorMessage, isAllowedEditorOrigin } from \"./bridgeGate\";\n\nconst CLUSTER_DISTANCE_PX = 24;\nconst CLUSTER_FAN_RADIUS_PX = 30;\n// Badges center on their element's top edge, so edge-hugging ones need insetting.\nconst BADGE_RADIUS_PX = 15;\nconst BADGE_EDGE_INSET_PX = BADGE_RADIUS_PX + 4;\nconst REMEASURE_DEBOUNCE_MS = 250;\n// Page-wide findings stack in a row near the top-left of the page and scroll\n// with it like any other annotation.\nconst PAGE_TOP_STACK_X_PX = 20;\nconst PAGE_TOP_STACK_Y_PX = 20;\nconst PAGE_TOP_STACK_GAP_PX = 36;\n\n// Replo brand palette (lattice --color-brand-*): the wire enum names stay\n// red/purple/amber but the rendered hues are brand magenta/purple/blue,\n// matching the editor-side dots and cards.\nconst COLOR_HEX: Record<PageAnnotationMarker[\"color\"], string> = {\n red: \"#ef196e\",\n purple: \"#8b32a8\",\n amber: \"#274ae2\",\n};\nconst COLOR_SEVERITY: PageAnnotationMarker[\"color\"][] = [\n \"red\",\n \"purple\",\n \"amber\",\n];\n\ninterface ResolvedMarker {\n marker: PageAnnotationMarker;\n element: Element | null;\n isFixed: boolean;\n rect: { x: number; y: number; width: number; height: number };\n // The editor-assigned wire number, rendered verbatim.\n displayNumber: number;\n}\n\ninterface MarkerCluster {\n id: string;\n centerX: number;\n centerY: number;\n isFixed: boolean;\n members: ResolvedMarker[];\n}\n\nlet isInitialized = false;\nlet editorOrigin: string | null = null;\nlet markers: PageAnnotationMarker[] = [];\nlet setId: string | null = null;\nlet expandedClusterId: string | null = null;\nlet activeMarkerId: string | null = null;\nlet remeasureFrameId: number | null = null;\nlet remeasureDebounceId: ReturnType<typeof setTimeout> | null = null;\nlet activeRectFrameId: number | null = null;\nlet observersActive = false;\nlet lastRenderSignature: string | null = null;\nlet resizeObserver: ResizeObserver | null = null;\nlet mutationObserver: MutationObserver | null = null;\n\nfunction postToEditor(message: PageAnnotationsIframeMessage) {\n if (editorOrigin === null) {\n return;\n }\n window.parent.postMessage(message, editorOrigin);\n}\n\nfunction hasFixedAncestor(element: Element): boolean {\n let current: Element | null = element;\n while (current !== null && current !== document.documentElement) {\n const position = getComputedStyle(current).position;\n if (position === \"fixed\" || position === \"sticky\") {\n return true;\n }\n current = current.parentElement;\n }\n return false;\n}\n\nfunction resolveMarkers(): {\n resolved: ResolvedMarker[];\n unresolvedIds: string[];\n} {\n const resolved: ResolvedMarker[] = [];\n const unresolvedIds: string[] = [];\n let pageTopSlot = 0;\n for (const marker of markers) {\n if (marker.placement === \"pageTop\") {\n // Page-wide finding: a fixed slot in the top-of-page stack, no selector.\n resolved.push({\n marker,\n element: null,\n isFixed: false,\n rect: {\n x: PAGE_TOP_STACK_X_PX + pageTopSlot * PAGE_TOP_STACK_GAP_PX,\n y: PAGE_TOP_STACK_Y_PX,\n width: 0,\n height: 0,\n },\n // The editor owns numbering; rendering the wire number keeps dots in sync with the panel.\n displayNumber: marker.number,\n });\n pageTopSlot += 1;\n continue;\n }\n let element: Element | null = null;\n try {\n element = document.querySelector(marker.selector);\n } catch {\n // Malformed selector \u2014 unresolved, never a throw.\n }\n const domRect = element?.getBoundingClientRect();\n if (!element || !domRect || (domRect.width === 0 && domRect.height === 0)) {\n unresolvedIds.push(marker.id);\n continue;\n }\n const isFixed = hasFixedAncestor(element);\n const scrollOffset = getDocumentScrollOffset();\n resolved.push({\n marker,\n element,\n isFixed,\n // Fixed frames use viewport coords; absolute frames use page coords.\n rect: {\n x: domRect.x + (isFixed ? 0 : scrollOffset.left),\n y: domRect.y + (isFixed ? 0 : scrollOffset.top),\n width: domRect.width,\n height: domRect.height,\n },\n displayNumber: marker.number,\n });\n }\n return { resolved, unresolvedIds };\n}\n\n// Greedy: a marker joins the first cluster whose badge anchor lies within\n// 24px; fixed and absolute markers never co-cluster (their coordinate spaces\n// diverge as soon as the page scrolls).\nfunction clusterResolvedMarkers(resolved: ResolvedMarker[]): MarkerCluster[] {\n const clusters: MarkerCluster[] = [];\n for (const entry of resolved) {\n const centerX = entry.rect.x + entry.rect.width / 2;\n const centerY = entry.rect.y;\n const host = clusters.find((cluster) => {\n return (\n cluster.isFixed === entry.isFixed &&\n Math.hypot(cluster.centerX - centerX, cluster.centerY - centerY) <\n CLUSTER_DISTANCE_PX\n );\n });\n if (host) {\n host.members.push(entry);\n } else {\n clusters.push({\n id: entry.marker.id,\n centerX,\n centerY,\n isFixed: entry.isFixed,\n members: [entry],\n });\n }\n }\n return clusters;\n}\n\n// Keeps a badge fully on screen: page box for absolute, viewport for fixed.\nfunction clampBadgeCenter({\n x,\n y,\n isFixed,\n}: {\n x: number;\n y: number;\n isFixed: boolean;\n}): { x: number; y: number } {\n const width = isFixed\n ? window.innerWidth\n : Math.max(document.documentElement.scrollWidth, window.innerWidth);\n const height = isFixed\n ? window.innerHeight\n : Math.max(document.documentElement.scrollHeight, window.innerHeight);\n return {\n x: clamp(\n x,\n BADGE_EDGE_INSET_PX,\n Math.max(BADGE_EDGE_INSET_PX, width - BADGE_EDGE_INSET_PX),\n ),\n y: clamp(\n y,\n BADGE_EDGE_INSET_PX,\n Math.max(BADGE_EDGE_INSET_PX, height - BADGE_EDGE_INSET_PX),\n ),\n };\n}\n\nfunction getMostSevereColorHex(members: ResolvedMarker[]): string {\n const color =\n COLOR_SEVERITY.find((candidate) => {\n return members.some((member) => member.marker.color === candidate);\n }) ?? \"amber\";\n return COLOR_HEX[color];\n}\n\nfunction activateMarker(id: string) {\n activeMarkerId = id;\n const viewportRect = getAnnotationBadgeViewportRect(id);\n if (viewportRect) {\n postToEditor({ type: \"replo:annotations:clicked\", id, viewportRect });\n }\n // Style-only: a rebuild here would race the pointer sequence and swallow\n // the very click being handled.\n setActiveAnnotationBadge(id);\n}\n\nfunction buildMemberSpec({\n member,\n badgeCenter,\n}: {\n member: ResolvedMarker;\n badgeCenter: { x: number; y: number };\n}): AnnotationFrameSpec {\n const marker = member.marker;\n return {\n id: marker.id,\n pageRect: member.rect,\n badgeCenter: clampBadgeCenter({ ...badgeCenter, isFixed: member.isFixed }),\n positioning: member.isFixed ? \"fixed\" : \"absolute\",\n colorHex: COLOR_HEX[marker.color],\n badgeLabel: String(member.displayNumber),\n badgeAriaLabel: `Page issue ${member.displayNumber}`,\n isActive: activeMarkerId === marker.id,\n onBadgeClick: () => activateMarker(marker.id),\n };\n}\n\nfunction buildClusterSpecs(cluster: MarkerCluster): AnnotationFrameSpec[] {\n const [only] = cluster.members;\n if (cluster.members.length === 1 && only) {\n return [\n buildMemberSpec({\n member: only,\n badgeCenter: { x: cluster.centerX, y: cluster.centerY },\n }),\n ];\n }\n const hub = {\n x: cluster.centerX,\n y: cluster.centerY,\n width: 0,\n height: 0,\n };\n if (expandedClusterId !== cluster.id) {\n return [\n {\n id: `cluster:${cluster.id}`,\n pageRect: hub,\n badgeCenter: clampBadgeCenter({\n x: cluster.centerX,\n y: cluster.centerY,\n isFixed: cluster.isFixed,\n }),\n positioning: cluster.isFixed ? \"fixed\" : \"absolute\",\n colorHex: getMostSevereColorHex(cluster.members),\n badgeLabel: String(cluster.members.length),\n badgeAriaLabel: `${cluster.members.length} page issues near this element`,\n isActive: false,\n onBadgeClick: () => {\n expandedClusterId = cluster.id;\n render();\n },\n },\n ];\n }\n const memberSpecs = cluster.members.map((member, index) => {\n const angle = (index / cluster.members.length) * 2 * Math.PI - Math.PI / 2;\n return buildMemberSpec({\n member,\n badgeCenter: {\n x: cluster.centerX + Math.cos(angle) * CLUSTER_FAN_RADIUS_PX,\n y: cluster.centerY + Math.sin(angle) * CLUSTER_FAN_RADIUS_PX,\n },\n });\n });\n return [\n {\n id: `cluster:${cluster.id}`,\n pageRect: hub,\n badgeCenter: clampBadgeCenter({\n x: cluster.centerX,\n y: cluster.centerY,\n isFixed: cluster.isFixed,\n }),\n positioning: cluster.isFixed ? \"fixed\" : \"absolute\",\n colorHex: \"#94a3b8\",\n badgeLabel: \"\u00D7\",\n badgeAriaLabel: \"Collapse issue cluster\",\n isActive: false,\n onBadgeClick: () => {\n expandedClusterId = null;\n render();\n },\n },\n ...memberSpecs,\n ];\n}\n\nfunction render() {\n if (markers.length === 0) {\n lastRenderSignature = null;\n clearAnnotationFrames();\n syncObservers();\n return;\n }\n const { resolved, unresolvedIds } = resolveMarkers();\n if (activeMarkerId !== null && unresolvedIds.includes(activeMarkerId)) {\n activeMarkerId = null;\n }\n // Rebuilding the node pool mid-pointer-sequence swallows clicks, so skip\n // renders whose output would be identical to what is already on screen.\n const signature = [\n resolved\n .map((entry) => {\n return `${entry.marker.id}:${Math.round(entry.rect.x)},${Math.round(entry.rect.y)}`;\n })\n .join(\"|\"),\n `active:${activeMarkerId ?? \"\"}`,\n `expanded:${expandedClusterId ?? \"\"}`,\n `unresolved:${unresolvedIds.join(\",\")}`,\n ].join(\"#\");\n if (signature === lastRenderSignature) {\n return;\n }\n lastRenderSignature = signature;\n const frames = clusterResolvedMarkers(resolved).flatMap((cluster) => {\n return buildClusterSpecs(cluster);\n });\n showAnnotationFrames({ frames });\n if (setId !== null) {\n postToEditor({\n type: \"replo:annotations:unresolved\",\n setId,\n ids: unresolvedIds,\n });\n }\n syncObservers();\n}\n\nfunction scheduleRemeasure() {\n remeasureFrameId ??= requestAnimationFrame(() => {\n remeasureFrameId = null;\n render();\n });\n}\n\nfunction scheduleDebouncedRemeasure() {\n if (remeasureDebounceId !== null) {\n clearTimeout(remeasureDebounceId);\n }\n remeasureDebounceId = setTimeout(scheduleRemeasure, REMEASURE_DEBOUNCE_MS);\n}\n\nfunction handleScroll(event: Event) {\n // Document scroll is free for absolute frames; scrolls of inner overflow\n // containers move elements relative to the page, so re-measure everything.\n if (event.target !== document) {\n scheduleRemeasure();\n }\n if (activeMarkerId !== null) {\n const id = activeMarkerId;\n activeRectFrameId ??= requestAnimationFrame(() => {\n activeRectFrameId = null;\n const viewportRect = getAnnotationBadgeViewportRect(id);\n if (viewportRect) {\n postToEditor({\n type: \"replo:annotations:activeRect\",\n id,\n viewportRect,\n });\n }\n });\n }\n}\n\nfunction syncObservers() {\n const shouldObserve = markers.length > 0;\n if (shouldObserve === observersActive) {\n return;\n }\n observersActive = shouldObserve;\n if (shouldObserve) {\n window.addEventListener(\"resize\", scheduleRemeasure);\n window.addEventListener(\"scroll\", handleScroll, { capture: true });\n if (typeof ResizeObserver !== \"undefined\") {\n resizeObserver = new ResizeObserver(scheduleRemeasure);\n resizeObserver.observe(document.body);\n }\n mutationObserver = new MutationObserver((records) => {\n // Rendering our own frames mutates body's subtree; reacting to that\n // would re-render forever. Only foreign mutations can move elements.\n const container = document.getElementById(ANNOTATION_CONTAINER_ID);\n const hasForeignMutation = records.some((record) => {\n return !container || !container.contains(record.target);\n });\n if (hasForeignMutation) {\n scheduleDebouncedRemeasure();\n }\n });\n mutationObserver.observe(document.body, { childList: true, subtree: true });\n } else {\n window.removeEventListener(\"resize\", scheduleRemeasure);\n window.removeEventListener(\"scroll\", handleScroll, { capture: true });\n resizeObserver?.disconnect();\n resizeObserver = null;\n mutationObserver?.disconnect();\n mutationObserver = null;\n // A pending remeasure would otherwise fire into a torn-down document.\n if (remeasureDebounceId !== null) {\n clearTimeout(remeasureDebounceId);\n remeasureDebounceId = null;\n }\n if (remeasureFrameId !== null) {\n cancelAnimationFrame(remeasureFrameId);\n remeasureFrameId = null;\n }\n }\n}\n\nfunction handleMessage(event: MessageEvent) {\n // Origin gate BEFORE any parsing \u2014 hostile embedders never reach the schema.\n if (!isAllowedEditorMessage(event)) {\n return;\n }\n const parsed = pageAnnotationsParentMessageSchema.safeParse(event.data);\n if (!parsed.success) {\n return;\n }\n editorOrigin = event.origin;\n exhaustiveSwitch(parsed.data)({\n \"replo:annotations:set\": (message) => {\n markers = message.markers;\n setId = message.setId;\n expandedClusterId = null;\n activeMarkerId = null;\n // A fresh set always paints (and re-posts unresolved), even if geometry\n // happens to match the previous render.\n lastRenderSignature = null;\n render();\n },\n \"replo:annotations:clear\": () => {\n markers = [];\n setId = null;\n expandedClusterId = null;\n activeMarkerId = null;\n render();\n },\n \"replo:annotations:requestReady\": () => {\n postToEditor({\n type: \"replo:annotations:ready\",\n protocolVersion: PAGE_ANNOTATIONS_PROTOCOL_VERSION,\n });\n },\n });\n}\n\nexport function initAnnotationLayer() {\n if (isInitialized || typeof window === \"undefined\") {\n return;\n }\n if (window.self === window.top) {\n return;\n }\n isInitialized = true;\n window.addEventListener(\"message\", handleMessage);\n // Announce on load for iframe-reload cases where the editor isn't polling;\n // the referrer origin is verified against the same allowlist first.\n try {\n const referrerOrigin = new URL(document.referrer).origin;\n if (isAllowedEditorOrigin(referrerOrigin)) {\n window.parent.postMessage(\n {\n type: \"replo:annotations:ready\",\n protocolVersion: PAGE_ANNOTATIONS_PROTOCOL_VERSION,\n },\n referrerOrigin,\n );\n }\n } catch {\n // No usable referrer \u2014 the editor's requestReady polling covers this.\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../annotations/bridgeGate.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Origin gate for inbound editor-bridge messages, checked BEFORE any payload\n * parsing. The select-mode bridge predates this and validates payload shape\n * only; its hardening ticket is expected to adopt this helper.\n */\n\nconst ALLOWED_EDITOR_ORIGIN_PATTERNS = [\n // Local dev editors (any port).\n /^https?:\\/\\/localhost(?::\\d+)?$/u,\n // Hosted editors and miniapps; multi-label hosts like website-builder.apps.replo.app must pass.\n /^https:\\/\\/(?:[a-z0-9-]+\\.)*replo\\.app$/u,\n // Dev front-door tunnels (`https://replo-<alias>.ngrok.app`).\n /^https:\\/\\/replo-[a-z0-9-]+\\.ngrok\\.app$/u,\n];\n\nexport function isAllowedEditorOrigin(origin: string): boolean {\n return ALLOWED_EDITOR_ORIGIN_PATTERNS.some((pattern) => pattern.test(origin));\n}\n\nexport function isAllowedEditorMessage(event: MessageEvent): boolean {\n // A top-level page has no editor parent; only embedded previews qualify.\n if (typeof window === \"undefined\" || window.self === window.top) {\n return false;\n }\n return isAllowedEditorOrigin(event.origin);\n}\n"],
|
|
5
|
-
"mappings": "AAMA,MAAM,iCAAiC;AAAA;AAAA,EAErC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AACF;AAEO,SAAS,sBAAsB,QAAyB;AAC7D,SAAO,+BAA+B,KAAK,CAAC,YAAY,QAAQ,KAAK,MAAM,CAAC;AAC9E;AAEO,SAAS,uBAAuB,OAA8B;AAEnE,MAAI,OAAO,WAAW,eAAe,OAAO,SAAS,OAAO,KAAK;AAC/D,WAAO;AAAA,EACT;AACA,SAAO,sBAAsB,MAAM,MAAM;AAC3C;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/buildMetadata.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../buildMetadata.ts"],
|
|
4
|
-
"sourcesContent": ["type BuildMetadata = {\n packageName: string;\n version: string;\n branch: string | null;\n commit: string | null;\n builtAt: string | null;\n};\n\nexport const BUILD_METADATA: BuildMetadata = {\n packageName: \"@replohq/sandbox-runtime\",\n version: \"0.0.0-dev\",\n branch: null,\n commit: null,\n builtAt: null,\n};\n"],
|
|
5
|
-
"mappings": "AAQO,MAAM,iBAAgC;AAAA,EAC3C,aAAa;AAAA,EACb,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AACX;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../design-library-preview/DesignLibraryPreview.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\";\n\nimport { useEffect, useRef } from \"react\";\n\nimport { buildGoogleFontsCssUrl } from \"replo-utils/lib/fonts\";\nimport { designLibraryPreviewMessageSchema } from \"schemas/designLibrary\";\n\nimport { isAllowedEditorMessage } from \"../annotations/bridgeGate\";\n\nconst FONT_LINK_DATA_KEY = \"reploDesignLibraryFont\";\n\nfunction escapeCssString(value: string): string {\n return value.replace(/\\\\/gu, \"\\\\\\\\\").replace(/'/gu, \"\\\\'\");\n}\n\nexport function DesignLibraryPreview() {\n // NOTE (Ben, 2026-06-03): The custom-property keys we set last time, so on the\n // next message we remove only the ones we own that the new override set drops.\n const ownedKeys = useRef<Set<string> | null>(null);\n // NOTE (Ben, 2026-06-05): The Google Font <link> hrefs we injected, keyed by\n // href so we de-dupe and remove only our own when the override set changes.\n const ownedFontLinks = useRef<Map<string, HTMLLinkElement> | null>(null);\n // NOTE (Ben, 2026-06-05): The @font-face <style> nodes for uploaded custom\n // fonts, keyed by family with the URL we injected, so we de-dupe, re-inject\n // when a family's asset URL changes (re-upload), and remove only our own when\n // the override set changes.\n const ownedFontFaces = useRef<Map<\n string,\n { url: string; style: HTMLStyleElement }\n > | null>(null);\n // NOTE (Ben, 2026-06-05): Whether we set the document default font-family, so\n // we can clear just that.\n const ownsDefaultFont = useRef(false);\n\n // eslint-disable-next-line replo/no-use-effect -- Subscribes to window message events from the parent editor.\n useEffect(() => {\n const handleMessage = (event: MessageEvent) => {\n if (!isAllowedEditorMessage(event)) return;\n const parsed = designLibraryPreviewMessageSchema.safeParse(event.data);\n if (!parsed.success) return;\n const { cssVars, fonts, defaultFontCssVar } = parsed.data;\n const root = document.documentElement;\n\n // --- CSS variable overrides (colors + font role vars) ---\n const nextVars: Record<string, string> = { ...cssVars };\n for (const font of fonts) {\n nextVars[font.cssVar] = `'${escapeCssString(font.family)}'`;\n }\n const owned = ownedKeys.current ?? new Set();\n for (const key of owned) {\n if (!(key in nextVars)) root.style.removeProperty(key);\n }\n ownedKeys.current = new Set(Object.keys(nextVars));\n for (const [key, value] of Object.entries(nextVars)) {\n root.style.setProperty(key, value);\n }\n\n // Custom uploaded fonts carry a faceUrl; Google fonts don't.\n const customFonts = fonts.filter((font) => Boolean(font.faceUrl));\n const googleFonts = fonts.filter((font) => !font.faceUrl);\n\n // --- Google Font stylesheets (<link> to the CDN) ---\n const links = ownedFontLinks.current ?? new Map();\n const nextHrefs = new Set(\n googleFonts.map((font) => buildGoogleFontsCssUrl(font.family)),\n );\n for (const [href, link] of links) {\n if (!nextHrefs.has(href)) {\n link.remove();\n links.delete(href);\n }\n }\n for (const href of nextHrefs) {\n if (links.has(href)) continue;\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = href;\n link.dataset[FONT_LINK_DATA_KEY] = \"\";\n document.head.append(link);\n links.set(href, link);\n }\n ownedFontLinks.current = links;\n\n // --- Custom uploaded fonts (@font-face from the asset URL) ---\n const faces = ownedFontFaces.current ?? new Map();\n const nextFamilies = new Set(customFonts.map((font) => font.family));\n for (const [family, entry] of faces) {\n if (!nextFamilies.has(family)) {\n entry.style.remove();\n faces.delete(family);\n }\n }\n for (const font of customFonts) {\n if (!font.faceUrl) continue;\n const existing = faces.get(font.family);\n // Re-upload reuses the family but changes the asset URL; replace the\n // stale node rather than skipping it.\n if (existing?.url === font.faceUrl) continue;\n existing?.style.remove();\n const style = document.createElement(\"style\");\n style.dataset[FONT_LINK_DATA_KEY] = \"\";\n const format = font.format\n ? ` format('${escapeCssString(font.format)}')`\n : \"\";\n style.textContent = `@font-face{font-family:'${escapeCssString(font.family)}';font-weight:400;font-style:normal;src:url('${escapeCssString(font.faceUrl)}')${format};font-display:swap;}`;\n document.head.append(style);\n faces.set(font.family, { url: font.faceUrl, style });\n }\n ownedFontFaces.current = faces;\n\n // --- Document default font ---\n if (defaultFontCssVar) {\n root.style.setProperty(\"font-family\", `var(${defaultFontCssVar})`);\n ownsDefaultFont.current = true;\n } else if (ownsDefaultFont.current) {\n root.style.removeProperty(\"font-family\");\n ownsDefaultFont.current = false;\n }\n };\n window.addEventListener(\"message\", handleMessage);\n return () => {\n window.removeEventListener(\"message\", handleMessage);\n };\n }, []);\n\n return null;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../next/component-preview-client.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\";\n\nimport type { ComponentType } from \"react\";\nimport type { z } from \"zod\";\n\nimport { useEffect, useMemo, useRef, useState, useTransition } from \"react\";\n\nimport { useRouter } from \"next/navigation\";\n\nimport { useIframeRpcChannel } from \"replo-utils/react/use-iframe-rpc-channel\";\nimport {\n COMPONENT_PREVIEW_IFRAME_RPC_CHANNEL_ID,\n COMPONENT_PREVIEW_IFRAME_RPC_CHANNEL_VERSION,\n COMPONENT_PREVIEW_PARENT_ORIGIN_PARAM,\n componentPreviewToWebsiteBuilderMethodConfig,\n websiteBuilderToComponentPreviewMethodConfig,\n} from \"schemas/componentPreview\";\nimport {\n createIframeRpcChannel,\n createIframeRpcRemote,\n} from \"schemas/iframeRpcChannel\";\n\nimport { getComponentPreviewHref } from \"./component-preview-href\";\nimport {\n mergeClientProps,\n productReferencesChanged,\n} from \"./component-preview-props\";\n\ntype SetPropsInput = z.output<\n (typeof websiteBuilderToComponentPreviewMethodConfig)[\"setProps\"][\"inputSchema\"]\n>;\ntype SetPropsResult = z.output<\n (typeof websiteBuilderToComponentPreviewMethodConfig)[\"setProps\"][\"outputSchema\"]\n>;\n\nfunction getParentOrigin(): string | null {\n const fromQuery = new URLSearchParams(window.location.search).get(\n COMPONENT_PREVIEW_PARENT_ORIGIN_PARAM,\n );\n if (fromQuery) {\n try {\n return new URL(fromQuery).origin;\n } catch {\n return null;\n }\n }\n return document.referrer ? new URL(document.referrer).origin : null;\n}\n\nfunction getCurrentHref() {\n return `${window.location.pathname}${window.location.search}${window.location.hash}`;\n}\n\n// Child side of the preview channel: announces readiness on subscribe and\n// routes incoming setProps calls to the caller. React Doctor rejects passing a\n// useEffectEvent result into channel handlers, so freshness comes from a plain\n// ref the stable closure reads at call time.\nfunction useComponentPreviewChannel(\n onSetProps: (input: SetPropsInput) => Promise<SetPropsResult>,\n) {\n const onSetPropsRef = useRef(onSetProps);\n onSetPropsRef.current = onSetProps;\n useIframeRpcChannel(\n useMemo(() => {\n if (typeof window === \"undefined\") {\n return null;\n }\n const parentOrigin = getParentOrigin();\n if (!parentOrigin) {\n return null;\n }\n const rpcChannel = createIframeRpcChannel({\n subscriberWindow: window,\n channelIdentifier: COMPONENT_PREVIEW_IFRAME_RPC_CHANNEL_ID,\n version: COMPONENT_PREVIEW_IFRAME_RPC_CHANNEL_VERSION,\n getTargetWindow: () => {\n return window.parent === window ? null : window.parent;\n },\n targetOrigin: parentOrigin,\n isExpectedMessage: (event) => {\n return (\n event.source === window.parent && event.origin === parentOrigin\n );\n },\n outgoingMethods: componentPreviewToWebsiteBuilderMethodConfig,\n incomingMethods: websiteBuilderToComponentPreviewMethodConfig,\n handlers: {\n setProps: (input) => onSetPropsRef.current(input),\n },\n });\n return {\n ...rpcChannel,\n subscribe() {\n const unsubscribe = rpcChannel.subscribe();\n const remote = createIframeRpcRemote(rpcChannel);\n remote.iframeReady();\n const content = document.querySelector(\n \"[data-replo-component-preview]\",\n );\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let lastHeight = -1;\n const measure = () => {\n clearTimeout(timeout);\n timeout = setTimeout(() => {\n if (!content) {\n return;\n }\n const bounds = content.getBoundingClientRect();\n const height = Math.min(\n 100_000,\n Math.ceil(\n bounds.height + Math.max(0, bounds.top + window.scrollY),\n ),\n );\n if (height !== lastHeight) {\n lastHeight = height;\n remote.contentBoundsChanged({ height });\n }\n }, 100);\n };\n const observer = new ResizeObserver(measure);\n if (content) {\n observer.observe(content);\n }\n measure();\n return () => {\n clearTimeout(timeout);\n observer.disconnect();\n unsubscribe();\n };\n },\n };\n }, []),\n );\n}\n\n// Server-render an in-frame navigation and resolve once the transition\n// settles, so the parent's ack tracks the actual repaint.\nfunction useNavigateAndSettle() {\n const router = useRouter();\n const [isNavigationPending, startNavigation] = useTransition();\n const settleResolvers = useRef<(() => void)[]>([]);\n // eslint-disable-next-line replo/no-use-effect -- Resolves promises held by the RPC channel, an external system, once the navigation transition settles.\n useEffect(() => {\n if (!isNavigationPending) {\n const resolvers = settleResolvers.current;\n settleResolvers.current = [];\n for (const resolve of resolvers) {\n resolve();\n }\n }\n }, [isNavigationPending]);\n // A navigation that never settles (a hung RSC fetch) never resolves \u2014 the\n // parent's channel timeout turns that into the disconnected state, and the\n // caller's refs stay uncommitted so the next sync retries the navigation.\n return (href: string) => {\n return new Promise<void>((resolve) => {\n settleResolvers.current.push(resolve);\n startNavigation(() => {\n router.replace(href, { scroll: false });\n });\n });\n };\n}\n\nexport function ComponentPreviewNavigation() {\n const navigateAndSettle = useNavigateAndSettle();\n useComponentPreviewChannel(\n async ({ props, sourceRevision }): Promise<SetPropsResult> => {\n const nextHref = getComponentPreviewHref({\n currentUrl: window.location.href,\n props,\n sourceRevision,\n });\n if (nextHref === getCurrentHref()) {\n return { mode: \"unchanged\" };\n }\n await navigateAndSettle(nextHref);\n return { mode: \"navigation\" };\n },\n );\n return null;\n}\n\nexport function ComponentPreviewStage({\n Component,\n initialProps,\n initialRawProps,\n initialSourceRevision,\n}: {\n Component: ComponentType<Record<string, unknown>>;\n initialProps: Record<string, unknown>;\n initialRawProps: Record<string, unknown>;\n initialSourceRevision: string;\n}) {\n const [props, setProps] = useState(initialProps);\n // A fresh server render (mount or in-frame navigation) is authoritative;\n // its props replace whatever the client store held.\n const [lastInitialProps, setLastInitialProps] = useState(initialProps);\n if (initialProps !== lastInitialProps) {\n setLastInitialProps(initialProps);\n setProps(initialProps);\n }\n const propsRef = useRef(props);\n propsRef.current = props;\n const lastRawPropsRef = useRef(initialRawProps);\n const lastSourceRevisionRef = useRef(initialSourceRevision);\n const navigateAndSettle = useNavigateAndSettle();\n\n useComponentPreviewChannel(\n async ({\n props: nextRawProps,\n sourceRevision,\n }): Promise<SetPropsResult> => {\n const nextHref = getComponentPreviewHref({\n currentUrl: window.location.href,\n props: nextRawProps,\n sourceRevision,\n });\n if (nextHref === getCurrentHref()) {\n return { mode: \"unchanged\" };\n }\n if (\n sourceRevision !== lastSourceRevisionRef.current ||\n productReferencesChanged({\n previous: lastRawPropsRef.current,\n next: nextRawProps,\n })\n ) {\n await navigateAndSettle(nextHref);\n lastRawPropsRef.current = nextRawProps;\n lastSourceRevisionRef.current = sourceRevision;\n return { mode: \"navigation\" };\n }\n setProps(\n mergeClientProps({\n currentResolved: propsRef.current,\n nextRaw: nextRawProps,\n }),\n );\n lastRawPropsRef.current = nextRawProps;\n // Keep the URL canonical without a server round trip, so a manual frame\n // reload restores the current props and the unchanged-check stays exact.\n window.history.replaceState(null, \"\", nextHref);\n return { mode: \"client\" };\n },\n );\n\n return (\n <div data-replo-component-preview style={{ display: \"flow-root\" }}>\n <Component {...props} />\n </div>\n );\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../next/component-preview-href.ts"],
|
|
4
|
-
"sourcesContent": ["export function getComponentPreviewHref({\n currentUrl,\n props,\n sourceRevision,\n}: {\n currentUrl: string;\n props: Record<string, unknown>;\n sourceRevision: string;\n}) {\n const url = new URL(currentUrl);\n url.searchParams.set(\"props\", JSON.stringify(props));\n url.searchParams.set(\"sourceRevision\", sourceRevision);\n return `${url.pathname}${url.search}${url.hash}`;\n}\n"],
|
|
5
|
-
"mappings": "AAAO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,MAAM,IAAI,IAAI,UAAU;AAC9B,MAAI,aAAa,IAAI,SAAS,KAAK,UAAU,KAAK,CAAC;AACnD,MAAI,aAAa,IAAI,kBAAkB,cAAc;AACrD,SAAO,GAAG,IAAI,QAAQ,GAAG,IAAI,MAAM,GAAG,IAAI,IAAI;AAChD;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../next/component-preview-props.ts"],
|
|
4
|
-
"sourcesContent": ["import { componentPreviewProductReferenceSchema } from \"schemas/componentPreview\";\n\nfunction isProductReference(value: unknown) {\n return componentPreviewProductReferenceSchema.safeParse(value).success;\n}\n\n// Product references need the server loader, so any change to one forces the\n// navigation path; everything else can apply in place.\nexport function productReferencesChanged({\n previous,\n next,\n}: {\n previous: Record<string, unknown>;\n next: Record<string, unknown>;\n}): boolean {\n const names = new Set([...Object.keys(previous), ...Object.keys(next)]);\n for (const name of names) {\n const previousIsReference = isProductReference(previous[name]);\n const nextIsReference = isProductReference(next[name]);\n if (!previousIsReference && !nextIsReference) {\n continue;\n }\n if (\n previousIsReference !== nextIsReference ||\n JSON.stringify(previous[name]) !== JSON.stringify(next[name])\n ) {\n return true;\n }\n }\n return false;\n}\n\n// Builds the next client-store props from an incoming raw payload: raw product\n// references are swapped for the already-resolved values in the current store\n// (only unchanged references reach this path \u2014 changed ones forced navigation),\n// and every other prop takes the incoming value. Keys absent from the payload\n// are dropped so the component's own defaults return.\nexport function mergeClientProps({\n currentResolved,\n nextRaw,\n}: {\n currentResolved: Record<string, unknown>;\n nextRaw: Record<string, unknown>;\n}): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(nextRaw).map(([name, value]) => {\n return isProductReference(value)\n ? [name, currentResolved[name]]\n : [name, value];\n }),\n );\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,8CAA8C;AAEvD,SAAS,mBAAmB,OAAgB;AAC1C,SAAO,uCAAuC,UAAU,KAAK,EAAE;AACjE;AAIO,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AACF,GAGY;AACV,QAAM,QAAQ,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,QAAQ,GAAG,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC;AACtE,aAAW,QAAQ,OAAO;AACxB,UAAM,sBAAsB,mBAAmB,SAAS,IAAI,CAAC;AAC7D,UAAM,kBAAkB,mBAAmB,KAAK,IAAI,CAAC;AACrD,QAAI,CAAC,uBAAuB,CAAC,iBAAiB;AAC5C;AAAA,IACF;AACA,QACE,wBAAwB,mBACxB,KAAK,UAAU,SAAS,IAAI,CAAC,MAAM,KAAK,UAAU,KAAK,IAAI,CAAC,GAC5D;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AACF,GAG4B;AAC1B,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;AAC7C,aAAO,mBAAmB,KAAK,IAC3B,CAAC,MAAM,gBAAgB,IAAI,CAAC,IAC5B,CAAC,MAAM,KAAK;AAAA,IAClB,CAAC;AAAA,EACH;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../next/component-preview.tsx"],
|
|
4
|
-
"sourcesContent": ["import type { ComponentType } from \"react\";\nimport type { ComponentPreviewProductReference } from \"schemas/generated/componentPreview\";\n\nimport {\n componentPreviewProductReferenceSchema,\n componentPreviewPropsSchema,\n MAX_COMPONENT_PREVIEW_PROPS_BYTES,\n} from \"schemas/componentPreview\";\n\nimport { DocumentReadyBeacon } from \"../DocumentReadyBeacon\";\nimport { NextErrorReporter } from \"../NextErrorReporter\";\nimport {\n ComponentPreviewNavigation,\n ComponentPreviewStage,\n} from \"./component-preview-client\";\n\nasync function getPreviewProps({\n value,\n getProduct,\n}: {\n value: unknown;\n getProduct?: (\n reference: ComponentPreviewProductReference,\n ) => Promise<unknown>;\n}): Promise<{\n rawProps: Record<string, unknown>;\n resolvedProps: Record<string, unknown>;\n}> {\n const previewPropsResult = componentPreviewPropsSchema.safeParse(value);\n if (!previewPropsResult.success) {\n return { rawProps: {}, resolvedProps: {} };\n }\n\n const rawProps: Record<string, unknown> = {};\n const resolvedProps: Record<string, unknown> = {};\n for (const [name, propValue] of Object.entries(previewPropsResult.data)) {\n rawProps[name] = propValue;\n const productReferenceResult =\n componentPreviewProductReferenceSchema.safeParse(propValue);\n if (!productReferenceResult.success) {\n resolvedProps[name] = propValue;\n continue;\n }\n // Without a resolver the raw reference passes through rather than the prop\n // silently vanishing; the component sees exactly what the URL carried.\n resolvedProps[name] = getProduct\n ? await getProduct(productReferenceResult.data)\n : propValue;\n }\n return { rawProps, resolvedProps };\n}\n\nasync function parseProps({\n value,\n getProduct,\n}: {\n value: string | string[] | undefined;\n getProduct?: (\n reference: ComponentPreviewProductReference,\n ) => Promise<unknown>;\n}) {\n if (\n typeof value !== \"string\" ||\n new TextEncoder().encode(value).byteLength >\n MAX_COMPONENT_PREVIEW_PROPS_BYTES\n ) {\n return { rawProps: {}, resolvedProps: {} };\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(value);\n } catch {\n return { rawProps: {}, resolvedProps: {} };\n }\n return await getPreviewProps({ value: parsed, getProduct });\n}\n\nexport function createComponentPreviewPage(\n Component: ComponentType<Record<string, unknown>>,\n options?: {\n getProduct?: (\n reference: ComponentPreviewProductReference,\n ) => Promise<unknown>;\n // Interactive components (\"use client\" in the component file) render\n // inside the client prop stage so plain prop edits apply without a server\n // round trip. Server components can only re-render via navigation.\n interactive?: boolean;\n },\n) {\n return async function ComponentPreviewPage({\n searchParams,\n }: {\n searchParams: Promise<{\n props?: string | string[];\n sourceRevision?: string | string[];\n }>;\n }) {\n const resolvedSearchParams = await searchParams;\n const { rawProps, resolvedProps } = await parseProps({\n value: resolvedSearchParams.props,\n getProduct: options?.getProduct,\n });\n if (options?.interactive) {\n return (\n <>\n <DocumentReadyBeacon />\n <NextErrorReporter />\n <ComponentPreviewStage\n Component={Component}\n initialProps={resolvedProps}\n initialRawProps={rawProps}\n initialSourceRevision={\n typeof resolvedSearchParams.sourceRevision === \"string\"\n ? resolvedSearchParams.sourceRevision\n : \"\"\n }\n />\n </>\n );\n }\n return (\n <>\n <ComponentPreviewNavigation />\n <DocumentReadyBeacon />\n <NextErrorReporter />\n <div data-replo-component-preview style={{ display: \"flow-root\" }}>\n <Component {...resolvedProps} />\n </div>\n </>\n );\n };\n}\n"],
|
|
5
|
-
"mappings": "AAwGQ,mBACE,KADF;AArGR;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,2BAA2B;AACpC,SAAS,yBAAyB;AAClC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEP,eAAe,gBAAgB;AAAA,EAC7B;AAAA,EACA;AACF,GAQG;AACD,QAAM,qBAAqB,4BAA4B,UAAU,KAAK;AACtE,MAAI,CAAC,mBAAmB,SAAS;AAC/B,WAAO,EAAE,UAAU,CAAC,GAAG,eAAe,CAAC,EAAE;AAAA,EAC3C;AAEA,QAAM,WAAoC,CAAC;AAC3C,QAAM,gBAAyC,CAAC;AAChD,aAAW,CAAC,MAAM,SAAS,KAAK,OAAO,QAAQ,mBAAmB,IAAI,GAAG;AACvE,aAAS,IAAI,IAAI;AACjB,UAAM,yBACJ,uCAAuC,UAAU,SAAS;AAC5D,QAAI,CAAC,uBAAuB,SAAS;AACnC,oBAAc,IAAI,IAAI;AACtB;AAAA,IACF;AAGA,kBAAc,IAAI,IAAI,aAClB,MAAM,WAAW,uBAAuB,IAAI,IAC5C;AAAA,EACN;AACA,SAAO,EAAE,UAAU,cAAc;AACnC;AAEA,eAAe,WAAW;AAAA,EACxB;AAAA,EACA;AACF,GAKG;AACD,MACE,OAAO,UAAU,YACjB,IAAI,YAAY,EAAE,OAAO,KAAK,EAAE,aAC9B,mCACF;AACA,WAAO,EAAE,UAAU,CAAC,GAAG,eAAe,CAAC,EAAE;AAAA,EAC3C;AACA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,KAAK;AAAA,EAC3B,QAAQ;AACN,WAAO,EAAE,UAAU,CAAC,GAAG,eAAe,CAAC,EAAE;AAAA,EAC3C;AACA,SAAO,MAAM,gBAAgB,EAAE,OAAO,QAAQ,WAAW,CAAC;AAC5D;AAEO,SAAS,2BACd,WACA,SASA;AACA,SAAO,eAAe,qBAAqB;AAAA,IACzC;AAAA,EACF,GAKG;AACD,UAAM,uBAAuB,MAAM;AACnC,UAAM,EAAE,UAAU,cAAc,IAAI,MAAM,WAAW;AAAA,MACnD,OAAO,qBAAqB;AAAA,MAC5B,YAAY,SAAS;AAAA,IACvB,CAAC;AACD,QAAI,SAAS,aAAa;AACxB,aACE,iCACE;AAAA,4BAAC,uBAAoB;AAAA,QACrB,oBAAC,qBAAkB;AAAA,QACnB;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,cAAc;AAAA,YACd,iBAAiB;AAAA,YACjB,uBACE,OAAO,qBAAqB,mBAAmB,WAC3C,qBAAqB,iBACrB;AAAA;AAAA,QAER;AAAA,SACF;AAAA,IAEJ;AACA,WACE,iCACE;AAAA,0BAAC,8BAA2B;AAAA,MAC5B,oBAAC,uBAAoB;AAAA,MACrB,oBAAC,qBAAkB;AAAA,MACnB,oBAAC,SAAI,gCAA4B,MAAC,OAAO,EAAE,SAAS,YAAY,GAC9D,8BAAC,aAAW,GAAG,eAAe,GAChC;AAAA,OACF;AAAA,EAEJ;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/next/config.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../next/config.ts"],
|
|
4
|
-
"sourcesContent": ["import { existsSync } from \"fs\";\nimport path from \"path\";\nimport type { NextConfig } from \"next\";\n\nconst DEFAULT_PAGE_EXTENSIONS = [\"tsx\", \"ts\", \"jsx\", \"js\"];\n// Routed only by the sandbox dev server: site-component previews and page drafts.\nconst DEVELOPMENT_ONLY_PAGE_EXTENSIONS = [\"dev.jsx\", \"dev.tsx\"];\n// Routed only by publish builds: the live copy of every page.\nconst BUILD_ONLY_PAGE_EXTENSIONS = [\"published.tsx\"];\nexport const PUBLISH_TSCONFIG_FILENAME = \"tsconfig.publish.json\";\n\nfunction getPageExtensions(configuredExtensions: string[] | undefined) {\n const baseExtensions = (\n configuredExtensions ?? DEFAULT_PAGE_EXTENSIONS\n ).filter((extension) => {\n return (\n !DEVELOPMENT_ONLY_PAGE_EXTENSIONS.includes(extension) &&\n !BUILD_ONLY_PAGE_EXTENSIONS.includes(extension)\n );\n });\n\n return process.env.BUILD_ENV === \"build\"\n ? [...BUILD_ONLY_PAGE_EXTENSIONS, ...baseExtensions]\n : [...DEVELOPMENT_ONLY_PAGE_EXTENSIONS, ...baseExtensions];\n}\n\n// Drafts are excluded from the publish typecheck so unfinished pages never block a publish; live files stay checked.\nfunction getTypescriptConfig(configured: NextConfig[\"typescript\"]) {\n if (process.env.BUILD_ENV !== \"build\") {\n return configured;\n }\n\n const tsconfigPath = path.join(process.cwd(), PUBLISH_TSCONFIG_FILENAME);\n return existsSync(tsconfigPath)\n ? { ...configured, tsconfigPath: PUBLISH_TSCONFIG_FILENAME }\n : configured;\n}\n\nexport function withComponentPreviewPageExtension(\n config: NextConfig,\n): NextConfig {\n return {\n ...config,\n pageExtensions: getPageExtensions(config.pageExtensions),\n typescript: getTypescriptConfig(config.typescript),\n };\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,kBAAkB;AAC3B,OAAO,UAAU;AAGjB,MAAM,0BAA0B,CAAC,OAAO,MAAM,OAAO,IAAI;AAEzD,MAAM,mCAAmC,CAAC,WAAW,SAAS;AAE9D,MAAM,6BAA6B,CAAC,eAAe;AAC5C,MAAM,4BAA4B;AAEzC,SAAS,kBAAkB,sBAA4C;AACrE,QAAM,kBACJ,wBAAwB,yBACxB,OAAO,CAAC,cAAc;AACtB,WACE,CAAC,iCAAiC,SAAS,SAAS,KACpD,CAAC,2BAA2B,SAAS,SAAS;AAAA,EAElD,CAAC;AAED,SAAO,QAAQ,IAAI,cAAc,UAC7B,CAAC,GAAG,4BAA4B,GAAG,cAAc,IACjD,CAAC,GAAG,kCAAkC,GAAG,cAAc;AAC7D;AAGA,SAAS,oBAAoB,YAAsC;AACjE,MAAI,QAAQ,IAAI,cAAc,SAAS;AACrC,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,KAAK,KAAK,QAAQ,IAAI,GAAG,yBAAyB;AACvE,SAAO,WAAW,YAAY,IAC1B,EAAE,GAAG,YAAY,cAAc,0BAA0B,IACzD;AACN;AAEO,SAAS,kCACd,QACY;AACZ,SAAO;AAAA,IACL,GAAG;AAAA,IACH,gBAAgB,kBAAkB,OAAO,cAAc;AAAA,IACvD,YAAY,oBAAoB,OAAO,UAAU;AAAA,EACnD;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/posthog-relay.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../posthog-relay.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\";\n\n/**\n * PostHog Cross-Origin Iframe Relay\n *\n * Initializes PostHog inside the sandbox iframe as a \"relay\" - it captures DOM\n * mutations via rrweb and sends them to the parent window's PostHog instance\n * via postMessage, enabling session recordings to include iframe content.\n */\nimport { useEffect } from \"react\";\n\nimport { startChildPostHogReplaySnapshotRelay } from \"replo-utils/lib/posthogReplay\";\n\nconst POSTHOG_PUBLIC_KEY = \"phc_dRETsj85vNkKrvQQszEFRBibH5kUF9l7rbjACuKPanZ\";\nconst POSTHOG_API_HOST = \"https://d99bbtllqsaif.cloudfront.net\";\n\ninterface PostHog {\n init: (apiKey: string, config: Record<string, unknown>) => void;\n sessionRecordingStarted: () => boolean;\n}\n\ndeclare global {\n interface Window {\n posthog?: PostHog;\n }\n}\n\nlet initPromise: Promise<void> | null = null;\n\nfunction loadPostHogScript() {\n return new Promise<void>((resolve) => {\n if (window.posthog) {\n resolve();\n return;\n }\n\n const script = document.createElement(\"script\");\n script.src = `${POSTHOG_API_HOST}/static/array.js`;\n script.async = true;\n script.addEventListener(\"load\", () => resolve());\n script.addEventListener(\"error\", () => {\n resolve();\n console.warn(\"[PostHog Relay] Failed to load PostHog script\");\n });\n document.head.append(script);\n });\n}\n\nfunction initPostHogRelay() {\n if (window.self === window.top) {\n return Promise.resolve();\n }\n\n if (initPromise) {\n return initPromise;\n }\n\n initPromise = (async () => {\n await loadPostHogScript();\n\n if (!window.posthog) {\n initPromise = null;\n console.warn(\"[PostHog Relay] PostHog not available after script load\");\n return;\n }\n\n window.posthog.init(POSTHOG_PUBLIC_KEY, {\n api_host: POSTHOG_API_HOST,\n persistence: \"localStorage\",\n autocapture: false,\n // (Noah, 2026-07-14, REPL-29305): Disable performance capture \u2014 its PerformanceObserver\n // relays a non-cloneable PerformanceServerTiming across the iframe boundary via postMessage,\n // throwing a DataCloneError in the preview. Matches the bedrock-sdk relay.\n capture_performance: false,\n capture_pageview: false,\n session_recording: {\n recordCrossOriginIframes: true,\n // NOTE (Nick, 2026-02-02, REPL-23284): Disable canvas recording to prevent SecurityError on tainted canvases\n captureCanvas: { recordCanvas: false },\n },\n });\n })();\n\n return initPromise;\n}\n\nexport default function PostHogRelay() {\n // eslint-disable-next-line replo/no-use-effect -- External replay script and cross-frame listener lifecycle.\n useEffect(() => {\n const stopRelayingSnapshotRequests = startChildPostHogReplaySnapshotRelay({\n isRecordingStarted: () => {\n return window.posthog?.sessionRecordingStarted() ?? false;\n },\n targetWindow: window,\n });\n void initPostHogRelay();\n return stopRelayingSnapshotRequests;\n }, []);\n\n return null;\n}\n"],
|
|
5
|
-
"mappings": ";AASA,SAAS,iBAAiB;AAE1B,SAAS,4CAA4C;AAErD,MAAM,qBAAqB;AAC3B,MAAM,mBAAmB;AAazB,IAAI,cAAoC;AAExC,SAAS,oBAAoB;AAC3B,SAAO,IAAI,QAAc,CAAC,YAAY;AACpC,QAAI,OAAO,SAAS;AAClB,cAAQ;AACR;AAAA,IACF;AAEA,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,MAAM,GAAG,gBAAgB;AAChC,WAAO,QAAQ;AACf,WAAO,iBAAiB,QAAQ,MAAM,QAAQ,CAAC;AAC/C,WAAO,iBAAiB,SAAS,MAAM;AACrC,cAAQ;AACR,cAAQ,KAAK,+CAA+C;AAAA,IAC9D,CAAC;AACD,aAAS,KAAK,OAAO,MAAM;AAAA,EAC7B,CAAC;AACH;AAEA,SAAS,mBAAmB;AAC1B,MAAI,OAAO,SAAS,OAAO,KAAK;AAC9B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAEA,MAAI,aAAa;AACf,WAAO;AAAA,EACT;AAEA,iBAAe,YAAY;AACzB,UAAM,kBAAkB;AAExB,QAAI,CAAC,OAAO,SAAS;AACnB,oBAAc;AACd,cAAQ,KAAK,yDAAyD;AACtE;AAAA,IACF;AAEA,WAAO,QAAQ,KAAK,oBAAoB;AAAA,MACtC,UAAU;AAAA,MACV,aAAa;AAAA,MACb,aAAa;AAAA;AAAA;AAAA;AAAA,MAIb,qBAAqB;AAAA,MACrB,kBAAkB;AAAA,MAClB,mBAAmB;AAAA,QACjB,0BAA0B;AAAA;AAAA,QAE1B,eAAe,EAAE,cAAc,MAAM;AAAA,MACvC;AAAA,IACF,CAAC;AAAA,EACH,GAAG;AAEH,SAAO;AACT;AAEe,SAAR,eAAgC;AAErC,YAAU,MAAM;AACd,UAAM,+BAA+B,qCAAqC;AAAA,MACxE,oBAAoB,MAAM;AACxB,eAAO,OAAO,SAAS,wBAAwB,KAAK;AAAA,MACtD;AAAA,MACA,cAAc;AAAA,IAChB,CAAC;AACD,SAAK,iBAAiB;AACtB,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,SAAO;AACT;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/sandbox-runtime.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../sandbox-runtime.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\";\n\nimport { useViewportSnapshotResponder } from \"replo-utils/react/use-viewport-snapshot-responder\";\n\nimport { AnnotationLayerMount } from \"./annotations/AnnotationLayerMount\";\nimport { ClientErrorBoundary } from \"./ClientErrorBoundary\";\nimport { DesignLibraryPreview } from \"./design-library-preview/DesignLibraryPreview\";\nimport { DocumentReadyBeacon } from \"./DocumentReadyBeacon\";\nimport LinkInterceptor from \"./LinkInterceptor\";\nimport { NavigationReceiver } from \"./NavigationReceiver\";\nimport { NextErrorReporter } from \"./NextErrorReporter\";\nimport PostHogRelay from \"./posthog-relay\";\nimport { EditorSelection } from \"./select-mode/EditorSelection\";\n\nfunction ViewportSnapshotResponder() {\n useViewportSnapshotResponder();\n return null;\n}\n\nexport function SandboxRuntime({ children }: React.PropsWithChildren) {\n // The editor only embeds dev servers (`next dev`), so editor-integration components render there only \u2014 production builds ship none of them and behave like plain Next apps.\n const isDevServer = process.env.NODE_ENV === \"development\";\n\n return isDevServer ? (\n <>\n <DocumentReadyBeacon />\n {/* NOTE (Max, 2026-06-08): Outside ClientErrorBoundary on purpose \u2014 when\n the boundary catches a runtime error it swaps its children for a\n neutral cover, which would unmount the reporter and freeze it in the\n error state. It must stay mounted to observe Next's overlay across\n error <-> recover. */}\n <NextErrorReporter />\n <ClientErrorBoundary>\n <LinkInterceptor />\n <NavigationReceiver />\n <PostHogRelay />\n <ViewportSnapshotResponder />\n <EditorSelection />\n <AnnotationLayerMount />\n <DesignLibraryPreview />\n {children}\n </ClientErrorBoundary>\n </>\n ) : (\n children\n );\n}\n"],
|
|
5
|
-
"mappings": ";AAwBI,mBACE,KAOA,YARF;AAtBJ,SAAS,oCAAoC;AAE7C,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AACpC,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AACpC,OAAO,qBAAqB;AAC5B,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,OAAO,kBAAkB;AACzB,SAAS,uBAAuB;AAEhC,SAAS,4BAA4B;AACnC,+BAA6B;AAC7B,SAAO;AACT;AAEO,SAAS,eAAe,EAAE,SAAS,GAA4B;AAEpE,QAAM,cAAc,QAAQ,IAAI,aAAa;AAE7C,SAAO,cACL,iCACE;AAAA,wBAAC,uBAAoB;AAAA,IAMrB,oBAAC,qBAAkB;AAAA,IACnB,qBAAC,uBACC;AAAA,0BAAC,mBAAgB;AAAA,MACjB,oBAAC,sBAAmB;AAAA,MACpB,oBAAC,gBAAa;AAAA,MACd,oBAAC,6BAA0B;AAAA,MAC3B,oBAAC,mBAAgB;AAAA,MACjB,oBAAC,wBAAqB;AAAA,MACtB,oBAAC,wBAAqB;AAAA,MACrB;AAAA,OACH;AAAA,KACF,IAEA;AAEJ;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../select-mode/EditorSelection.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\";\n\nimport { useCallback, useEffect } from \"react\";\n\nimport {\n buildElementDescriptor,\n buildSelector,\n} from \"./descriptor/elementDescriptor\";\nimport { installFastRefreshRelay } from \"./fast-refresh-relay\";\nimport { useCrosshairCursor } from \"./hooks/useCrosshairCursor\";\nimport { useEditModeStateMachine } from \"./hooks/useEditModeStateMachine\";\nimport { useOptimisticOverrides } from \"./hooks/useOptimisticOverrides\";\nimport { useParentMessaging } from \"./hooks/useParentMessaging\";\nimport { useSelectionHover } from \"./hooks/useSelectionHover\";\nimport { useSelectionInteractions } from \"./hooks/useSelectionInteractions\";\nimport { useSelectionScrollSync } from \"./hooks/useSelectionScrollSync\";\nimport { useSelectModeController } from \"./hooks/useSelectModeController\";\nimport { getRepetitionSiblingElements } from \"./hooks/useSiblingResolution\";\nimport { getWebsiteBuilderRpc } from \"./iframeRpcChannel\";\nimport { isSelectionStillCurrent } from \"./selectionPublish\";\nimport { symbolicateSelectedElement } from \"./symbolicate\";\n\n/**\n * Mounts the iframe-side selectMode controller. This is a render-less\n * component \u2014 every responsibility is delegated to a dedicated hook so each\n * concern (parent messaging, cursor styling, pointer interactions, hover\n * tracking, scroll syncing) can be read in isolation:\n *\n * - `useParentMessaging` \u2014 inbound messages from the parent (set mode,\n * set selection type) + outbound `IFRAME_READY` handshake.\n * - `useCrosshairCursor` \u2014 crosshair cursor + disable text/drag selection\n * while in selection mode.\n * - `useSelectionInteractions` \u2014 pointer-down / move / up state machine\n * that produces `ELEMENT_SELECTED`, `AREA_SELECTED`, and live\n * `DRAG_RECT_UPDATED` messages.\n * - `useSelectionHover` \u2014 hover-element rect updates.\n * - `useSelectionScrollSync` \u2014 keeps the parent overlay aligned with the\n * selected element/area when the iframe scrolls.\n *\n * The `interactionSessionRef` is the single source of truth for the\n * in-progress drag/selection \u2014 every hook reads/writes it via ref so we\n * don't trigger React re-renders during interaction-heavy operations.\n *\n * @author Kevin O'Connell 2026-04-17\n */\nexport function EditorSelection() {\n const {\n displayMode,\n interactionSessionRef,\n setDisplayMode,\n setSelectionType,\n } = useSelectModeController();\n const { beginEditing, editingElementRef, formatCommand, revert } =\n useEditModeStateMachine({\n displayMode,\n interactionSessionRef,\n });\n const {\n applyOptimisticUpdate,\n markCommitted,\n reapplyOverrides,\n resolveSessionOverrides,\n revertOverride,\n } = useOptimisticOverrides();\n\n const postSelectedElementSnapshot = useCallback(() => {\n const session = interactionSessionRef.current;\n if (session.type !== \"element\") {\n return;\n }\n\n const selectedElement =\n session.data.kind === \"react-element\"\n ? document.querySelector(session.data.selector)\n : null;\n const element = selectedElement ?? session.element;\n if (!(element instanceof Element) || !element.isConnected) {\n return;\n }\n\n // A fast refresh can replace the repeated DOM nodes, so the group is\n // re-resolved from the (possibly re-created) element rather than carried\n // over from the stale session.\n const siblingElements = getRepetitionSiblingElements({ element });\n const descriptor = buildElementDescriptor({\n element,\n clickPosition:\n session.clickPosition ??\n (session.data.kind === \"react-element\"\n ? session.data.clickPosition\n : { x: 0, y: 0 }),\n siblingSelectors: siblingElements.map(buildSelector),\n });\n if (descriptor.kind !== \"react-element\") {\n return;\n }\n\n interactionSessionRef.current = {\n ...session,\n element,\n siblingElements,\n data: descriptor,\n };\n\n void symbolicateSelectedElement(descriptor).then((symbolicated) => {\n if (\n !isSelectionStillCurrent({\n session: interactionSessionRef.current,\n selection: { type: \"element\", element },\n })\n ) {\n return;\n }\n getWebsiteBuilderRpc()?.elementSelected({ data: symbolicated });\n });\n }, [interactionSessionRef]);\n\n // eslint-disable-next-line replo/no-use-effect -- Installs a window-level console bridge for the preview iframe.\n useEffect(() => {\n installFastRefreshRelay({\n onComplete: () => {\n // Re-apply before re-symbolicating so the snapshot reads the\n // optimistic content, not the source the refresh just repainted.\n reapplyOverrides({ skipElement: editingElementRef.current });\n postSelectedElementSnapshot();\n },\n });\n }, [editingElementRef, postSelectedElementSnapshot, reapplyOverrides]);\n\n useParentMessaging({\n applyOptimisticUpdate,\n markCommitted,\n onExitEditMode: revert,\n onFormatCommand: formatCommand,\n resolveSessionOverrides,\n revertOverride,\n setDisplayMode,\n setSelectionType,\n });\n useCrosshairCursor({ displayMode });\n useSelectionInteractions({\n displayMode,\n editingElementRef,\n interactionSessionRef,\n onBeginEditing: beginEditing,\n });\n useSelectionHover({ displayMode, interactionSessionRef });\n useSelectionScrollSync({\n displayMode,\n interactionSessionRef,\n });\n\n return null;\n}\n"],
|
|
5
|
-
"mappings": ";AAEA,SAAS,aAAa,iBAAiB;AAEvC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,gCAAgC;AACzC,SAAS,8BAA8B;AACvC,SAAS,+BAA+B;AACxC,SAAS,oCAAoC;AAC7C,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AACxC,SAAS,kCAAkC;AAyBpC,SAAS,kBAAkB;AAChC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,wBAAwB;AAC5B,QAAM,EAAE,cAAc,mBAAmB,eAAe,OAAO,IAC7D,wBAAwB;AAAA,IACtB;AAAA,IACA;AAAA,EACF,CAAC;AACH,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,uBAAuB;AAE3B,QAAM,8BAA8B,YAAY,MAAM;AACpD,UAAM,UAAU,sBAAsB;AACtC,QAAI,QAAQ,SAAS,WAAW;AAC9B;AAAA,IACF;AAEA,UAAM,kBACJ,QAAQ,KAAK,SAAS,kBAClB,SAAS,cAAc,QAAQ,KAAK,QAAQ,IAC5C;AACN,UAAM,UAAU,mBAAmB,QAAQ;AAC3C,QAAI,EAAE,mBAAmB,YAAY,CAAC,QAAQ,aAAa;AACzD;AAAA,IACF;AAKA,UAAM,kBAAkB,6BAA6B,EAAE,QAAQ,CAAC;AAChE,UAAM,aAAa,uBAAuB;AAAA,MACxC;AAAA,MACA,eACE,QAAQ,kBACP,QAAQ,KAAK,SAAS,kBACnB,QAAQ,KAAK,gBACb,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,MACnB,kBAAkB,gBAAgB,IAAI,aAAa;AAAA,IACrD,CAAC;AACD,QAAI,WAAW,SAAS,iBAAiB;AACvC;AAAA,IACF;AAEA,0BAAsB,UAAU;AAAA,MAC9B,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA,MAAM;AAAA,IACR;AAEA,SAAK,2BAA2B,UAAU,EAAE,KAAK,CAAC,iBAAiB;AACjE,UACE,CAAC,wBAAwB;AAAA,QACvB,SAAS,sBAAsB;AAAA,QAC/B,WAAW,EAAE,MAAM,WAAW,QAAQ;AAAA,MACxC,CAAC,GACD;AACA;AAAA,MACF;AACA,2BAAqB,GAAG,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAAA,IAChE,CAAC;AAAA,EACH,GAAG,CAAC,qBAAqB,CAAC;AAG1B,YAAU,MAAM;AACd,4BAAwB;AAAA,MACtB,YAAY,MAAM;AAGhB,yBAAiB,EAAE,aAAa,kBAAkB,QAAQ,CAAC;AAC3D,oCAA4B;AAAA,MAC9B;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,mBAAmB,6BAA6B,gBAAgB,CAAC;AAErE,qBAAmB;AAAA,IACjB;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,qBAAmB,EAAE,YAAY,CAAC;AAClC,2BAAyB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,EAClB,CAAC;AACD,oBAAkB,EAAE,aAAa,sBAAsB,CAAC;AACxD,yBAAuB;AAAA,IACrB;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO;AACT;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../select-mode/annotationFrames.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * In-iframe annotation frame renderer \u2014 `selectionFrame`'s sibling surface.\n *\n * Same architecture and reasons as selection frames (see selectionFrame.ts):\n * page-coordinate `position: absolute` nodes in a body-level container, so\n * document scroll translates them with zero JavaScript per scroll frame, and\n * styling is vanilla inline CSS because customer pages have no tailwind.\n *\n * An annotation frame is an invisible positioning box over the annotated\n * element carrying a numbered badge dot \u2014 the dot is the entire visual.\n * Unlike selection frames these rebuild wholesale on each call: re-renders\n * happen on set/re-measure (rare), never per scroll, so pooling buys nothing.\n */\nimport { getOrCreateFramesLayerContainer } from \"./selectionFrame\";\n\nexport const ANNOTATION_CONTAINER_ID = \"replo-annotation-frames\";\nconst ANNOTATION_FONT_STYLE_ID = \"replo-annotation-font\";\nconst BADGE_SIZE_PX = 30;\n// The badge numerals use the same PP Editorial the editor brand uses, served\n// from the CDN asset the editor already loads \u2014 no font bytes ship in canopy,\n// and this layer only exists in dev previews. `swap` degrades to Georgia.\nconst EDITORIAL_ITALIC_FONT_URL =\n \"https://assets.replocdn.com/PPEditorialNew-Italic.woff2\";\nconst BADGE_FONT =\n 'italic 400 16px/1 \"PP Editorial New\", Georgia, \"Times New Roman\", serif';\n\nfunction ensureBadgeFont() {\n if (document.getElementById(ANNOTATION_FONT_STYLE_ID)) {\n return;\n }\n const style = document.createElement(\"style\");\n style.id = ANNOTATION_FONT_STYLE_ID;\n style.textContent = `@font-face{font-family:\"PP Editorial New\";src:url(\"${EDITORIAL_ITALIC_FONT_URL}\") format(\"woff2\");font-weight:normal;font-style:italic;font-display:swap;}`;\n document.head.append(style);\n}\n\ninterface AnnotationRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface AnnotationFrameSpec {\n id: string;\n pageRect: AnnotationRect;\n badgeCenter: { x: number; y: number };\n // \"fixed\" for elements inside fixed/sticky ancestors: those don't translate\n // on scroll, so their frame must not either (coords are viewport coords).\n positioning: \"absolute\" | \"fixed\";\n colorHex: string;\n badgeLabel: string;\n badgeAriaLabel: string;\n isActive: boolean;\n onBadgeClick: () => void;\n}\n\nconst badgeNodesById = new Map<string, HTMLButtonElement>();\nlet activeBadgeId: string | null = null;\n\nfunction badgeRestingTransform(id: string): string {\n return id === activeBadgeId ? \"scale(1.15)\" : \"scale(1)\";\n}\n\n/**\n * Style-only selection update: rebuilding the node pool mid-interaction would\n * race the pointer sequence and swallow the click, so the active state never\n * re-renders \u2014 it just retargets transforms on the existing nodes.\n */\nexport function setActiveAnnotationBadge(id: string | null) {\n activeBadgeId = id;\n for (const [badgeId, badge] of badgeNodesById) {\n badge.style.transform = badgeRestingTransform(badgeId);\n }\n}\n\nexport function getAnnotationBadgeViewportRect(\n id: string,\n): AnnotationRect | null {\n const badge = badgeNodesById.get(id);\n if (!badge?.isConnected) {\n return null;\n }\n const rect = badge.getBoundingClientRect();\n return { x: rect.x, y: rect.y, width: rect.width, height: rect.height };\n}\n\nfunction createFrameNode(spec: AnnotationFrameSpec): HTMLDivElement {\n const frame = document.createElement(\"div\");\n frame.style.cssText = [\n `position: ${spec.positioning}`,\n `left: ${spec.pageRect.x}px`,\n `top: ${spec.pageRect.y}px`,\n \"width: 0\",\n \"height: 0\",\n \"pointer-events: none\",\n \"margin: 0\",\n \"padding: 0\",\n ].join(\";\");\n\n const badge = document.createElement(\"button\");\n badge.type = \"button\";\n badge.setAttribute(\"aria-label\", spec.badgeAriaLabel);\n badge.textContent = spec.badgeLabel;\n badge.style.cssText = [\n \"position: absolute\",\n `left: ${spec.badgeCenter.x - spec.pageRect.x - BADGE_SIZE_PX / 2}px`,\n `top: ${spec.badgeCenter.y - spec.pageRect.y - BADGE_SIZE_PX / 2}px`,\n `width: ${BADGE_SIZE_PX}px`,\n `height: ${BADGE_SIZE_PX}px`,\n \"display: flex\",\n \"align-items: center\",\n \"justify-content: center\",\n \"border: none\",\n \"border-radius: 50%\",\n `background: ${spec.colorHex}`,\n \"color: #ffffff\",\n `font: ${BADGE_FONT}`,\n \"box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.9), 0 1px 3px rgba(0, 0, 0, 0.18)\",\n `transform: scale(${spec.isActive ? 1.15 : 1})`,\n \"transition: transform 120ms ease-out\",\n \"cursor: pointer\",\n \"pointer-events: auto\",\n \"margin: 0\",\n \"padding: 0 0 1px 0\",\n ].join(\";\");\n badge.addEventListener(\"pointerdown\", () => {\n badge.style.transform = \"scale(0.9)\";\n });\n badge.addEventListener(\"pointerup\", () => {\n badge.style.transform = badgeRestingTransform(spec.id);\n });\n badge.addEventListener(\"pointerleave\", () => {\n badge.style.transform = badgeRestingTransform(spec.id);\n });\n badge.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n spec.onBadgeClick();\n });\n\n frame.append(badge);\n badgeNodesById.set(spec.id, badge);\n return frame;\n}\n\nexport function showAnnotationFrames({\n frames,\n}: {\n frames: AnnotationFrameSpec[];\n}) {\n const container = getOrCreateFramesLayerContainer({\n id: ANNOTATION_CONTAINER_ID,\n zIndex: 2147483645,\n });\n if (!container) {\n return;\n }\n ensureBadgeFont();\n activeBadgeId = frames.find((spec) => spec.isActive)?.id ?? null;\n badgeNodesById.clear();\n container.replaceChildren(...frames.map((spec) => createFrameNode(spec)));\n}\n\nexport function clearAnnotationFrames() {\n badgeNodesById.clear();\n if (typeof document === \"undefined\") {\n return;\n }\n document.getElementById(ANNOTATION_CONTAINER_ID)?.replaceChildren();\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../select-mode/descriptor/elementDescriptor.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n SelectableData,\n SelectModeClickPosition,\n SelectModeTextMetrics,\n} from \"schemas/generated/selectMode\";\n\nimport {\n readSelectablePayload,\n SELECT_MODE_SELECTABLE_ATTRIBUTE,\n SELECT_MODE_SELECTABLE_PAYLOAD_ATTRIBUTE,\n} from \"schemas/selectMode\";\n\nimport { getFiberChain } from \"../fiber\";\nimport { skipInlineTextMarkElements } from \"../inlineTextMarks\";\nimport { getElementBoundingRect } from \"../interactions/selectionGeometry\";\nimport { getDefinedStyles, getInheritedStyles } from \"./styleExtraction\";\n\n/**\n * Element that should own a click/hover selection: skip TipTap/inline JSX\n * mark wrappers, then prefer an explicit selectable boundary when present.\n */\nexport function getNearestSelectableElement(element: Element): Element {\n const host = skipInlineTextMarkElements(element);\n return host.closest(`[${SELECT_MODE_SELECTABLE_ATTRIBUTE}]`) ?? host;\n}\n\nfunction getSelectableDataFromElement(element: Element): SelectableData | null {\n const selectableElement = element.closest(\n `[${SELECT_MODE_SELECTABLE_ATTRIBUTE}]`,\n );\n if (!selectableElement) {\n return null;\n }\n\n const selectablePayload = readSelectablePayload(\n selectableElement.getAttribute(SELECT_MODE_SELECTABLE_PAYLOAD_ATTRIBUTE),\n );\n if (!selectablePayload) {\n return null;\n }\n\n return {\n ...selectablePayload,\n rect: getElementBoundingRect(selectableElement),\n };\n}\n\n/**\n * Produce a short human-readable label for an element (used in chat tokens\n * and prompt context). Tag-aware so a `<button>` reads as `button: \"Save\"`\n * rather than just `button` \u2014 that extra detail is what lets the agent\n * resolve \"the save button\" without us having to send a screenshot.\n */\nfunction identifyElement(element: Element): string {\n const tagName = element.tagName.toLowerCase();\n\n if (\n tagName === \"button\" ||\n element.getAttribute(\"role\") === \"button\" ||\n tagName === \"input\"\n ) {\n const trimmedText = element.textContent?.trim();\n if (trimmedText) {\n return `${tagName}: \"${trimmedText.slice(0, 60)}\"`;\n }\n const ariaLabel = element.getAttribute(\"aria-label\");\n if (ariaLabel) {\n return `${tagName}: [${ariaLabel}]`;\n }\n if (tagName === \"input\") {\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n const inputType = (element as HTMLInputElement).type || \"text\";\n const placeholder = element.getAttribute(\"placeholder\");\n return placeholder\n ? `input(${inputType}): \"${placeholder}\"`\n : `input(${inputType})`;\n }\n return tagName;\n }\n\n if (tagName === \"a\") {\n const trimmedText = element.textContent?.trim();\n if (trimmedText) {\n return `link: \"${trimmedText.slice(0, 60)}\"`;\n }\n const href = element.getAttribute(\"href\");\n if (href) {\n return `link: [${href.slice(0, 60)}]`;\n }\n return \"link\";\n }\n\n if (tagName === \"img\") {\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n const alt = (element as HTMLImageElement).alt;\n if (alt) {\n return `image: \"${alt.slice(0, 60)}\"`;\n }\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n const src = (element as HTMLImageElement).src;\n if (src) {\n const filename = src.split(\"/\").pop()?.split(\"?\")[0] ?? src;\n return `image: [${filename.slice(0, 40)}]`;\n }\n return \"image\";\n }\n\n if (/^h[1-6]$/.test(tagName)) {\n const trimmedText = element.textContent?.trim();\n return trimmedText\n ? `heading(${tagName}): \"${trimmedText.slice(0, 60)}\"`\n : tagName;\n }\n\n if (\n [\"div\", \"main\", \"section\", \"article\", \"header\", \"footer\", \"nav\"].includes(\n tagName,\n )\n ) {\n const role = element.getAttribute(\"role\");\n if (role) {\n return role;\n }\n }\n\n const trimmedText = element.textContent?.trim();\n if (trimmedText && trimmedText.length < 120) {\n const role = element.getAttribute(\"role\");\n const label = role ?? tagName;\n return `${label}: \"${trimmedText.slice(0, 60)}\"`;\n }\n\n const role = element.getAttribute(\"role\");\n if (role) {\n return role;\n }\n\n const className = element.className;\n if (typeof className === \"string\" && className) {\n const meaningfulClassName = className.split(/\\s+/).find((classToken) => {\n return (\n !classToken.startsWith(\"_\") &&\n !classToken.match(/^[a-z]{1,2}\\d/) &&\n classToken.length > 2\n );\n });\n if (meaningfulClassName) {\n return `${tagName}.${meaningfulClassName}`;\n }\n }\n\n return tagName;\n}\n\n/**\n * Build a CSS selector path from `element` up to the document root. Stops\n * (and short-circuits) at the first ancestor with an `id`. Used so the\n * parent can identify the element later without holding a DOM reference.\n */\nexport function buildSelector(element: Element): string {\n const parts: string[] = [];\n let currentElement: Element | null = element;\n\n while (currentElement && currentElement !== document.documentElement) {\n const tag = currentElement.tagName.toLowerCase();\n const id = currentElement.id;\n\n if (id) {\n parts.unshift(`#${id}`);\n break;\n }\n\n const parentElement: Element | null = currentElement.parentElement;\n if (parentElement) {\n const currentTag = currentElement.tagName;\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n const siblings = Array.from(parentElement.children) as Element[];\n const siblingElementsWithSameTag = siblings.filter((sibling) => {\n return sibling.tagName === currentTag;\n });\n if (siblingElementsWithSameTag.length > 1) {\n const index = siblingElementsWithSameTag.indexOf(currentElement) + 1;\n parts.unshift(`${tag}:nth-of-type(${index})`);\n } else {\n parts.unshift(tag);\n }\n } else {\n parts.unshift(tag);\n }\n\n currentElement = parentElement;\n }\n\n return parts.join(\" > \");\n}\n\n/**\n * Measures the actual rendered text inside `element` \u2014 the tightest width\n * the text occupies, the line count, and the line height. We return this\n * alongside the element's bounding rect so the parent panel can position\n * itself relative to the *text* (not the element box) for text-heavy\n * elements like headings and paragraphs.\n */\nfunction getTextMetrics(element: Element): SelectModeTextMetrics | null {\n const text = element.textContent?.trim();\n if (!text) {\n return null;\n }\n\n const style = window.getComputedStyle(element);\n const parsedLineHeight = Number.parseFloat(style.lineHeight);\n const computedLineHeight = Number.isNaN(parsedLineHeight)\n ? Number.parseFloat(style.fontSize) * 1.2\n : parsedLineHeight;\n\n try {\n const range = document.createRange();\n range.selectNodeContents(element);\n\n const lineRects = Array.from(range.getClientRects()).filter((lineRect) => {\n return lineRect.width > 0 && lineRect.height > 0;\n });\n\n let tightWidth = 0;\n for (const lineRect of lineRects) {\n tightWidth = Math.max(tightWidth, lineRect.width);\n }\n\n const lineCount = lineRects.length;\n if (lineCount === 0) {\n return null;\n }\n\n return {\n tightWidth,\n lineCount,\n lineHeight: computedLineHeight,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * The single entrypoint for converting a DOM `Element` into the serialized\n * `SelectedElement` payload that crosses the iframe<->parent boundary.\n * Centralizes everything the parent (and downstream agent) need to know\n * about a selection: identification, geometry, source location, and a\n * style-inlined HTML snippet.\n *\n * @author Kevin O'Connell 2026-04-17\n */\nexport function buildElementDescriptor({\n element,\n clickPosition,\n siblingSelectors = [],\n}: {\n element: Element;\n clickPosition: SelectModeClickPosition;\n siblingSelectors?: string[];\n}): SelectableData {\n const selectableData = getSelectableDataFromElement(element);\n if (selectableData) {\n return selectableData;\n }\n\n const textMetrics = getTextMetrics(element);\n const fiberChain =\n element instanceof HTMLElement ? getFiberChain(element) : [];\n const sourceLocation = fiberChain[0]?.sourceLocation;\n\n return {\n kind: \"react-element\",\n selector: buildSelector(element),\n tagName: element.tagName.toLowerCase(),\n elementType: identifyElement(element),\n textContent: element.textContent?.trim()?.slice(0, 200) ?? null,\n rect: getElementBoundingRect(element),\n textMetrics,\n outerHTML: element.outerHTML.slice(0, 4000),\n definedStyles: getDefinedStyles(element),\n inheritedStyles: getInheritedStyles(element),\n clickPosition,\n sourceLocation,\n fiberChain,\n siblingSelectors,\n };\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["trimmedText", "role"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../select-mode/descriptor/styleExtraction.ts"],
|
|
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
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../select-mode/displayModeStore.ts"],
|
|
4
|
-
"sourcesContent": ["\"use client\";\n\nimport type { DisplayMode } from \"schemas/generated/selectMode\";\n\nimport { useSyncExternalStore } from \"react\";\n\n/**\n * Framework-agnostic singleton for the preview iframe's select-mode display\n * mode (\"browse\" vs \"selection\"). It lives as a module singleton so that\n * components that don't share a provider ancestor \u2014 `EditorSelection` (which\n * owns the pointer/selection machinery) and `LinkInterceptor` (a sibling under\n * `ReploProvider`) \u2014 can agree on whether the user is currently selecting.\n *\n * `LinkInterceptor` needs this because in agent-preview mode it observes\n * same-origin link clicks and reports the resulting navigation to the parent\n * editor (`replo:navigated`). While select mode is active that must stand\n * down so a link click selects the element instead of leaving the page \u2014\n * the two capture-phase click listeners otherwise race, and `stopPropagation`\n * can't suppress a sibling listener on the same node.\n *\n * @author Noah Gilmore 2026-07-23\n */\n\nconst listeners = new Set<() => void>();\nlet displayMode: DisplayMode = \"browse\";\n\n// select-mode DOM behavior is client-only, so the server snapshot is a stable\n// constant and never causes a hydration mismatch.\nconst SERVER_SNAPSHOT: DisplayMode = \"browse\";\n\nfunction notify() {\n for (const listener of listeners) {\n listener();\n }\n}\n\nexport const displayModeStore = {\n getSnapshot(): DisplayMode {\n return displayMode;\n },\n getServerSnapshot(): DisplayMode {\n return SERVER_SNAPSHOT;\n },\n subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n setDisplayMode(nextDisplayMode: DisplayMode) {\n if (nextDisplayMode === displayMode) {\n return;\n }\n displayMode = nextDisplayMode;\n notify();\n },\n /** Test-only: reset back to the default so specs don't leak state. */\n reset() {\n displayMode = \"browse\";\n },\n};\n\nexport function useDisplayMode(): DisplayMode {\n return useSyncExternalStore(\n displayModeStore.subscribe,\n displayModeStore.getSnapshot,\n displayModeStore.getServerSnapshot,\n );\n}\n"],
|
|
5
|
-
"mappings": ";AAIA,SAAS,4BAA4B;AAmBrC,MAAM,YAAY,oBAAI,IAAgB;AACtC,IAAI,cAA2B;AAI/B,MAAM,kBAA+B;AAErC,SAAS,SAAS;AAChB,aAAW,YAAY,WAAW;AAChC,aAAS;AAAA,EACX;AACF;AAEO,MAAM,mBAAmB;AAAA,EAC9B,cAA2B;AACzB,WAAO;AAAA,EACT;AAAA,EACA,oBAAiC;AAC/B,WAAO;AAAA,EACT;AAAA,EACA,UAAU,UAAkC;AAC1C,cAAU,IAAI,QAAQ;AACtB,WAAO,MAAM;AACX,gBAAU,OAAO,QAAQ;AAAA,IAC3B;AAAA,EACF;AAAA,EACA,eAAe,iBAA8B;AAC3C,QAAI,oBAAoB,aAAa;AACnC;AAAA,IACF;AACA,kBAAc;AACd,WAAO;AAAA,EACT;AAAA;AAAA,EAEA,QAAQ;AACN,kBAAc;AAAA,EAChB;AACF;AAEO,SAAS,iBAA8B;AAC5C,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,EACnB;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../select-mode/fast-refresh-relay.ts"],
|
|
4
|
-
"sourcesContent": ["import { getWebsiteBuilderRpc } from \"./iframeRpcChannel\";\n\nlet hasInstalledFastRefreshRelay = false;\nlet onFastRefreshComplete: (() => void) | null = null;\n\nexport function installFastRefreshRelay({\n onComplete,\n}: { onComplete?: () => void } = {}) {\n onFastRefreshComplete = onComplete ?? null;\n if (hasInstalledFastRefreshRelay) {\n return;\n }\n hasInstalledFastRefreshRelay = true;\n\n const originalLog = console.log;\n const originalInfo = console.info;\n const relayIfFastRefreshComplete = (...args: unknown[]) => {\n const message = args.join(\" \");\n if (message.includes(\"[Fast Refresh] done\")) {\n getWebsiteBuilderRpc()?.fastRefreshComplete(undefined);\n onFastRefreshComplete?.();\n }\n };\n\n console.log = (...args: unknown[]) => {\n relayIfFastRefreshComplete(...args);\n originalLog(...args);\n };\n console.info = (...args: unknown[]) => {\n relayIfFastRefreshComplete(...args);\n originalInfo(...args);\n };\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,4BAA4B;AAErC,IAAI,+BAA+B;AACnC,IAAI,wBAA6C;AAE1C,SAAS,wBAAwB;AAAA,EACtC;AACF,IAAiC,CAAC,GAAG;AACnC,0BAAwB,cAAc;AACtC,MAAI,8BAA8B;AAChC;AAAA,EACF;AACA,iCAA+B;AAE/B,QAAM,cAAc,QAAQ;AAC5B,QAAM,eAAe,QAAQ;AAC7B,QAAM,6BAA6B,IAAI,SAAoB;AACzD,UAAM,UAAU,KAAK,KAAK,GAAG;AAC7B,QAAI,QAAQ,SAAS,qBAAqB,GAAG;AAC3C,2BAAqB,GAAG,oBAAoB,MAAS;AACrD,8BAAwB;AAAA,IAC1B;AAAA,EACF;AAEA,UAAQ,MAAM,IAAI,SAAoB;AACpC,+BAA2B,GAAG,IAAI;AAClC,gBAAY,GAAG,IAAI;AAAA,EACrB;AACA,UAAQ,OAAO,IAAI,SAAoB;AACrC,+BAA2B,GAAG,IAAI;AAClC,iBAAa,GAAG,IAAI;AAAA,EACtB;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/select-mode/fiber.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 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 | 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
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../select-mode/hooks/useCrosshairCursor.ts"],
|
|
4
|
-
"sourcesContent": ["import type { DisplayMode } from \"schemas/generated/selectMode\";\n\nimport { useEffect } from \"react\";\n\n/**\n * Forces a crosshair cursor + disables text selection / drag while the iframe\n * is in `selection` mode. We inject a `<style>` tag into the iframe document\n * (rather than toggling a class on `<html>`) so that the `!important` rule\n * wins against any per-element cursor styling on the page being edited.\n *\n * @author Kevin O'Connell 2026-04-17\n */\nexport function useCrosshairCursor({\n displayMode,\n}: {\n displayMode: DisplayMode;\n}) {\n // eslint-disable-next-line replo/no-use-effect -- Legacy effect - may or may not be necessary\n useEffect(() => {\n if (displayMode !== \"selection\") {\n return;\n }\n\n const styleElement = document.createElement(\"style\");\n styleElement.textContent = `\n * { cursor: crosshair !important; user-select: none !important; -webkit-user-drag: none !important; }\n [data-select-mode-inline-editor][contenteditable=\"true\"],\n [data-select-mode-inline-editor][contenteditable=\"true\"] * { cursor: text !important; }\n `;\n document.head.append(styleElement);\n\n return () => {\n styleElement.remove();\n };\n }, [displayMode]);\n}\n"],
|
|
5
|
-
"mappings": "AAEA,SAAS,iBAAiB;AAUnB,SAAS,mBAAmB;AAAA,EACjC;AACF,GAEG;AAED,YAAU,MAAM;AACd,QAAI,gBAAgB,aAAa;AAC/B;AAAA,IACF;AAEA,UAAM,eAAe,SAAS,cAAc,OAAO;AACnD,iBAAa,cAAc;AAAA;AAAA;AAAA;AAAA;AAK3B,aAAS,KAAK,OAAO,YAAY;AAEjC,WAAO,MAAM;AACX,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAClB;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../select-mode/hooks/useEditModeStateMachine.ts"],
|
|
4
|
-
"sourcesContent": ["import type { MutableRefObject } from \"react\";\nimport type {\n DisplayMode,\n SelectableData,\n SelectModeFormatCommand,\n} from \"schemas/generated/selectMode\";\nimport type { SelectModeInteractionSession } from \"../selectModeSession\";\nimport type { InlineTiptapEditor } from \"../tiptapInlineEditor\";\n\nimport { useCallback, useEffect, useRef } from \"react\";\n\nimport {\n getWebsiteBuilderRpc,\n requestInlineTextEdit,\n} from \"../iframeRpcChannel\";\nimport { setSelectionFrameEditing } from \"../selectionFrame\";\nimport { symbolicateSelectedElement } from \"../symbolicate\";\nimport { createInlineTiptapEditor } from \"../tiptapInlineEditor\";\nimport { getRepetitionSiblingElements } from \"./useSiblingResolution\";\n\ntype ActiveMarks = {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strike: boolean;\n};\n\nconst EMPTY_ACTIVE_MARKS: ActiveMarks = {\n bold: false,\n italic: false,\n underline: false,\n strike: false,\n};\n\n// Notify the parent of the inline editor's state so it can show the inline\n// formatting controls (and live mark state) only while editing.\nfunction postEditorState({\n activeMarks,\n isEditing,\n}: {\n activeMarks: ActiveMarks;\n isEditing: boolean;\n}) {\n getWebsiteBuilderRpc()?.editorStateUpdate({ activeMarks, isEditing });\n}\n\nexport function isTextEditableElement(\n element: Element,\n): element is HTMLElement {\n const tagName = element.tagName.toLowerCase();\n return (\n element instanceof HTMLElement &&\n Boolean(element.textContent?.trim()) &&\n ![\n \"input\",\n \"textarea\",\n \"select\",\n \"option\",\n \"img\",\n \"video\",\n \"canvas\",\n ].includes(tagName)\n );\n}\n\n// Window after entering an edit during which a focus loss to the parent frame\n// is treated as the select-mode panel's composer auto-focus stealing focus\n// (and is reclaimed) rather than a deliberate move into the editor UI.\nconst FOCUS_STEAL_GUARD_MS = 1500;\n\nexport function useEditModeStateMachine({\n displayMode,\n interactionSessionRef,\n}: {\n displayMode: DisplayMode;\n interactionSessionRef: MutableRefObject<SelectModeInteractionSession>;\n}) {\n const editorRef = useRef<InlineTiptapEditor | null>(null);\n const editingElementRef = useRef<HTMLElement | null>(null);\n const editIdRef = useRef<string | null>(null);\n const pendingEditRef = useRef<{\n editId: string;\n element: HTMLElement;\n timeout: number;\n } | null>(null);\n const originalInnerHTMLRef = useRef<string | null>(null);\n // The editor's HTML right after it parsed the original content. tiptap\n // re-serializes the markup, so this \u2014 not the raw `originalInnerHTML` \u2014 is the\n // apples-to-apples baseline for detecting whether a commit actually changed\n // anything.\n const initialHTMLRef = useRef<string | null>(null);\n const isCommittingRef = useRef(false);\n const beginEditingAtRef = useRef(0);\n\n const destroyEditor = useCallback(() => {\n editorRef.current?.destroy();\n editorRef.current = null;\n editingElementRef.current = null;\n editIdRef.current = null;\n if (pendingEditRef.current) {\n clearTimeout(pendingEditRef.current.timeout);\n pendingEditRef.current = null;\n }\n originalInnerHTMLRef.current = null;\n initialHTMLRef.current = null;\n isCommittingRef.current = false;\n setSelectionFrameEditing(false);\n postEditorState({ activeMarks: EMPTY_ACTIVE_MARKS, isEditing: false });\n }, []);\n\n const commit = useCallback(() => {\n const editor = editorRef.current;\n const editingElement = editingElementRef.current;\n const originalInnerHTML = originalInnerHTMLRef.current;\n const editId = editIdRef.current;\n if (\n !editor ||\n !editId ||\n originalInnerHTML === null ||\n isCommittingRef.current\n ) {\n return;\n }\n\n isCommittingRef.current = true;\n const committedHTML = editor.getHTML();\n\n // A blur or Shift-Enter with no actual change must not spawn an edit\n // session. When the content is untouched, restore the original markup and\n // tear down without notifying the parent.\n if (committedHTML === initialHTMLRef.current) {\n destroyEditor();\n if (editingElement) {\n editingElement.innerHTML = originalInnerHTML;\n }\n return;\n }\n\n const committedJSON = editor.getJSON();\n getWebsiteBuilderRpc()?.textCommitted({\n editId,\n html: committedHTML,\n json: committedJSON,\n originalInnerHTML,\n });\n // NOTE (Noah Gilmore, 2026-07-16): A directly mounted ProseMirror view\n // clears its root during destroy, so final HTML must be restored afterward.\n destroyEditor();\n if (editingElement) {\n editingElement.innerHTML = committedHTML;\n }\n }, [destroyEditor]);\n\n const revert = useCallback(() => {\n const editingElement = editingElementRef.current;\n const originalInnerHTML = originalInnerHTMLRef.current;\n destroyEditor();\n if (editingElement && originalInnerHTML !== null) {\n editingElement.innerHTML = originalInnerHTML;\n }\n }, [destroyEditor]);\n\n const handleBlur = useCallback(() => {\n if (isCommittingRef.current) {\n return;\n }\n // Focus stayed inside the iframe \u2014 the user clicked elsewhere on the page,\n // so this is a real \"click away\": commit.\n if (typeof document !== \"undefined\" && document.hasFocus()) {\n commit();\n return;\n }\n // Focus left the iframe to the parent editor. When it happens right as the\n // edit opens, the select-mode panel's composer auto-focus stole it \u2014 pull\n // it back so a double-click keeps the caret in the text. A deliberate move\n // into the editor UI later is left alone, and never commits/destroys.\n if (Date.now() - beginEditingAtRef.current < FOCUS_STEAL_GUARD_MS) {\n editorRef.current?.focus();\n }\n }, [commit]);\n\n const formatCommand = useCallback((command: SelectModeFormatCommand) => {\n editorRef.current?.runFormatCommand(command);\n }, []);\n\n const clearPendingEdit = useCallback((editId: string) => {\n if (pendingEditRef.current?.editId !== editId) {\n return;\n }\n clearTimeout(pendingEditRef.current.timeout);\n pendingEditRef.current = null;\n }, []);\n\n const resolveEditRequest = useCallback(\n ({ editId, allowed }: { editId: string; allowed: boolean }) => {\n const pendingEdit = pendingEditRef.current;\n if (!pendingEdit || pendingEdit.editId !== editId) {\n return;\n }\n clearTimeout(pendingEdit.timeout);\n pendingEditRef.current = null;\n if (!allowed || !pendingEdit.element.isConnected) {\n return;\n }\n\n const element = pendingEdit.element;\n const originalInnerHTML = element.innerHTML;\n editingElementRef.current = element;\n editIdRef.current = editId;\n originalInnerHTMLRef.current = originalInnerHTML;\n\n editorRef.current = createInlineTiptapEditor({\n element,\n content: originalInnerHTML,\n onCommit: commit,\n onEscape: revert,\n onBlur: handleBlur,\n onSelectionUpdate: (activeMarks) => {\n postEditorState({ activeMarks, isEditing: true });\n },\n });\n initialHTMLRef.current = editorRef.current.getHTML();\n beginEditingAtRef.current = Date.now();\n editorRef.current.focusAndSelectAll();\n setSelectionFrameEditing(true);\n postEditorState({ activeMarks: EMPTY_ACTIVE_MARKS, isEditing: true });\n },\n [commit, handleBlur, revert],\n );\n\n const beginEditing = useCallback(\n ({\n element,\n descriptorPromise,\n }: {\n element: Element;\n descriptorPromise: Promise<SelectableData>;\n }) => {\n // Already editing this element \u2014 re-entering would re-read the mid-edit\n // DOM as the \"original\" and rebuild the editor over itself, wiping the\n // content. The pointer-up guard prevents the usual trigger; this is the\n // backstop for any other path.\n if (editingElementRef.current === element) {\n return;\n }\n if (!isTextEditableElement(element)) {\n return;\n }\n // Same element already awaiting symbolicate / parent allow \u2014 ignore.\n // A different element supersedes the in-flight attempt below.\n if (pendingEditRef.current?.element === element) {\n return;\n }\n\n void descriptorPromise.then((descriptor) => {\n if (descriptor.kind !== \"react-element\" || !element.isConnected) {\n return;\n }\n interactionSessionRef.current = {\n type: \"element\",\n element,\n siblingElements: getRepetitionSiblingElements({ element }),\n clickPosition: null,\n data: descriptor,\n };\n const editId = crypto.randomUUID();\n if (pendingEditRef.current) {\n clearTimeout(pendingEditRef.current.timeout);\n }\n // Symbolicate has no AbortSignal; a wedged sandbox can hang forever.\n // Self-clear so a hung attempt can't permanently block inline edit.\n const timeout = window.setTimeout(() => {\n clearPendingEdit(editId);\n }, 5000);\n pendingEditRef.current = { editId, element, timeout };\n void symbolicateSelectedElement(descriptor).then(\n (symbolicated) => {\n if (pendingEditRef.current?.editId !== editId) {\n return;\n }\n void requestInlineTextEdit({\n editId,\n element: symbolicated,\n }).then(\n ({ allowed }) => {\n resolveEditRequest({ editId, allowed });\n },\n () => {\n resolveEditRequest({ editId, allowed: false });\n },\n );\n },\n () => {\n clearPendingEdit(editId);\n },\n );\n });\n },\n [clearPendingEdit, interactionSessionRef, resolveEditRequest],\n );\n\n // eslint-disable-next-line replo/no-use-effect -- Tears down the inline editor when leaving selection mode.\n useEffect(() => {\n if (displayMode !== \"selection\") {\n revert();\n }\n }, [displayMode, revert]);\n\n return {\n beginEditing,\n editingElementRef,\n formatCommand,\n revert,\n };\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|