cms-renderer 0.6.11 → 0.6.13
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/dist/lib/block-renderer.d.ts +16 -12
- package/dist/lib/block-renderer.js +107 -8
- package/dist/lib/block-renderer.js.map +1 -1
- package/dist/lib/block-toolbar.js +18 -4
- package/dist/lib/block-toolbar.js.map +1 -1
- package/dist/lib/client-editable-block.js +19 -5
- package/dist/lib/client-editable-block.js.map +1 -1
- package/dist/lib/custom-schemas.js.map +1 -1
- package/dist/lib/docs-markdown.d.ts +2 -2
- package/dist/lib/markdown-utils.js +19 -2
- package/dist/lib/markdown-utils.js.map +1 -1
- package/dist/lib/parametric-route.d.ts +15 -2
- package/dist/lib/parametric-route.js +137 -13
- package/dist/lib/parametric-route.js.map +1 -1
- package/dist/lib/renderer.d.ts +12 -3
- package/dist/lib/renderer.js +148 -13
- package/dist/lib/renderer.js.map +1 -1
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../lib/client-editable-block.tsx","../../lib/block-outline.tsx","../../lib/block-toolbar.tsx","../../lib/cms-post-message.ts"],"sourcesContent":["'use client';\n\nimport {\n useCallback,\n useEffect,\n useLayoutEffect as useLayoutEffectBase,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { BlockOutline } from './block-outline';\nimport { BlockToolbar } from './block-toolbar';\nimport { isTrustedCmsParentMessage, postMessageToCmsParent } from './cms-post-message';\n\n// Use useEffect as fallback for useLayoutEffect during SSR to avoid React warnings.\n// This is safe because the layout effect code only runs on the client anyway.\nconst useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffectBase : useEffect;\n\n// ---------------------------------------------------------------------------\n// Global styles + click-routing — injected once into <head> on first mount.\n// We do this programmatically because Next.js RSC marks body-level <style> and\n// <script> tags as inactive (they appear greyed-out in DevTools and are not\n// applied by the browser).\n// ---------------------------------------------------------------------------\n\nconst CMS_OVERLAY_ROOT_ID = 'cms-overlay-root';\n\nconst CMS_STYLES = `\n [data-cms-editable] { cursor: pointer; border-radius: 2px; }\n [data-cms-editable]:hover { outline: 2px solid #3b82f6; outline-offset: 2px; }\n #${CMS_OVERLAY_ROOT_ID} {\n position: fixed;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n pointer-events: none;\n z-index: 99998;\n }\n #${CMS_OVERLAY_ROOT_ID} > * {\n pointer-events: auto;\n }\n .cms-block-cursor {\n position: fixed; width: 22px; height: 22px;\n background: radial-gradient(circle, #fff 5px, #000 5px);\n border-radius: 50%;\n pointer-events: none; z-index: 99999;\n transform: translate(-50%, -50%);\n opacity: 0; transition: opacity 0.1s ease;\n }\n .cms-block-cursor.cms-cursor-visible { opacity: 1; }\n .cms-block-toolbar {\n position: fixed;\n display: flex; gap: 4px; background: #1f2937; border-radius: 6px; padding: 4px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.25);\n z-index: 99999; pointer-events: none;\n opacity: 0; transform: scale(0.9) translateY(4px);\n transition: opacity 0.15s ease, transform 0.15s ease;\n }\n .cms-block-toolbar.cms-toolbar-visible {\n opacity: 1; transform: scale(1) translateY(0); pointer-events: auto;\n }\n .cms-block-toolbar button {\n display: flex; align-items: center; justify-content: center;\n width: 28px; height: 28px; border: none; background: transparent;\n color: #9ca3af; border-radius: 4px; cursor: pointer;\n transition: background 0.15s ease, color 0.15s ease;\n }\n .cms-block-toolbar button:hover { background: #374151; color: #fff; }\n .cms-block-toolbar button.delete:hover { background: #dc2626; color: #fff; }\n .cms-block-toolbar button:disabled { opacity: 0.4; cursor: not-allowed; }\n .cms-block-toolbar button:disabled:hover { background: transparent; color: #9ca3af; }\n .cms-block-toolbar svg { width: 16px; height: 16px; }\n`;\n\nlet cmsGlobalInjected = false;\nlet cmsOverlayRoot: HTMLElement | null = null;\n\n/**\n * Returns the CMS overlay portal root element, creating it if necessary.\n * Uses a dedicated container instead of document.body to ensure compatibility\n * with both Next.js and TanStack Start's streaming SSR hydration.\n */\nfunction getCmsOverlayRoot(): HTMLElement | null {\n if (typeof document === 'undefined' || !document.body) return null;\n\n if (cmsOverlayRoot && document.contains(cmsOverlayRoot)) {\n return cmsOverlayRoot;\n }\n\n let root = document.getElementById(CMS_OVERLAY_ROOT_ID);\n if (!root) {\n root = document.createElement('div');\n root.id = CMS_OVERLAY_ROOT_ID;\n document.body.appendChild(root);\n }\n\n cmsOverlayRoot = root;\n return root;\n}\n\nfunction ensureCmsGlobals() {\n if (cmsGlobalInjected) return;\n if (typeof document === 'undefined' || typeof window === 'undefined') return;\n cmsGlobalInjected = true;\n\n if (document.head) {\n const style = document.createElement('style');\n style.setAttribute('data-cms', '');\n style.textContent = CMS_STYLES;\n document.head.appendChild(style);\n }\n\n if (!(window as Window & { __cmsEditableInitialized?: boolean }).__cmsEditableInitialized) {\n (window as Window & { __cmsEditableInitialized?: boolean }).__cmsEditableInitialized = true;\n document.addEventListener('click', (e) => {\n const target = e.target as Element;\n if (target.closest('.cms-block-toolbar')) return;\n\n const editable = target.closest('[data-cms-editable]');\n if (editable) {\n const msg = {\n type: 'cms-editable-click',\n blockId: editable.getAttribute('data-block-id'),\n blockType: editable.getAttribute('data-block-type'),\n contentPath: editable.getAttribute('data-content-path'),\n };\n postMessageToCmsParent(msg);\n return;\n }\n\n const block = target.closest('[data-cms-block]');\n if (block) {\n const msg = {\n type: 'cms-editable-click',\n blockId: block.getAttribute('data-block-id'),\n blockType: block.getAttribute('data-block-type'),\n contentPath: null,\n };\n postMessageToCmsParent(msg);\n }\n });\n }\n}\n\ninterface ContentEntry {\n v: string;\n p: string;\n}\n\ninterface ClientEditableBlockProps {\n blockId: string;\n blockType: string;\n contentEntries: ContentEntry[];\n children: React.ReactNode;\n}\n\n/**\n * Client-side block editable wrapper.\n *\n * Renders a hidden sentinel span followed by the block's children (no wrapper div).\n * On mount, finds the component's root element via nextElementSibling and:\n * - Stamps data-cms-block, data-block-id, data-block-type directly on it\n * - Injects data-cms-editable spans around matching text nodes\n * - Portals the BlockToolbar into a dedicated overlay root with position:fixed\n * so it is never clipped by overflow:hidden or stacking contexts on the block\n *\n * Uses a MutationObserver to re-inject spans after every DOM mutation\n * (e.g. animated state changes that swap visible elements).\n *\n * The overlay root (#cms-overlay-root) is created lazily on first mount to ensure\n * compatibility with both Next.js and TanStack Start's streaming SSR hydration.\n */\nexport function ClientEditableBlock({\n blockId,\n blockType,\n contentEntries,\n children,\n}: ClientEditableBlockProps) {\n const sentinelRef = useRef<HTMLSpanElement>(null);\n const observerRef = useRef<MutationObserver | null>(null);\n const isInjectingRef = useRef(false);\n const cursorElRef = useRef<HTMLDivElement>(null);\n const toolbarElRef = useRef<HTMLDivElement>(null);\n const toolbarVisibleRef = useRef(false);\n const [mounted, setMounted] = useState(false);\n const [hoverOutlineRect, setHoverOutlineRect] = useState<DOMRect | null>(null);\n const [selectedOutlineRect, setSelectedOutlineRect] = useState<DOMRect | null>(null);\n\n const getBlockRoot = useCallback((): HTMLElement | null => {\n return (sentinelRef.current?.nextElementSibling as HTMLElement) ?? null;\n }, []);\n\n const injectSpans = useCallback(() => {\n if (isInjectingRef.current) return;\n const blockRoot = getBlockRoot();\n if (!blockRoot) return;\n\n isInjectingRef.current = true;\n // Disconnect observer while we mutate the DOM to avoid re-entrant calls.\n observerRef.current?.disconnect();\n\n try {\n // Remove previously injected text-level spans, restoring the original text nodes.\n const existing = Array.from(\n blockRoot.querySelectorAll<HTMLElement>('span[data-cms-editable][data-content-path]')\n );\n for (const span of existing) {\n const parent = span.parentNode;\n if (!parent) continue;\n while (span.firstChild) parent.insertBefore(span.firstChild, span);\n parent.removeChild(span);\n }\n\n // Walk all visible text nodes and wrap the ones that match content values.\n const used = new Set<string>();\n const walker = document.createTreeWalker(blockRoot, NodeFilter.SHOW_TEXT, null);\n const textNodes: Text[] = [];\n let n = walker.nextNode();\n while (n !== null) {\n const textNode = n as Text;\n if (\n textNode.parentElement?.closest('.cms-block-toolbar') == null &&\n textNode.nodeValue?.trim()\n ) {\n textNodes.push(textNode);\n }\n n = walker.nextNode();\n }\n\n for (const textNode of textNodes) {\n // Never inject spans inside SVG — <span> is not valid SVG content\n if (textNode.parentElement?.closest('svg') != null) continue;\n\n const text = textNode.nodeValue;\n if (!text) continue;\n for (const entry of contentEntries) {\n if (used.has(entry.p)) continue;\n if (text.indexOf(entry.v) !== -1 && text.trim() === entry.v.trim()) {\n used.add(entry.p);\n const span = document.createElement('span');\n span.setAttribute('data-cms-editable', '');\n span.setAttribute('data-block-id', blockId);\n span.setAttribute('data-block-type', blockType);\n span.setAttribute('data-content-path', entry.p);\n textNode.parentNode?.insertBefore(span, textNode);\n span.appendChild(textNode);\n break;\n }\n }\n }\n } finally {\n isInjectingRef.current = false;\n // Reconnect after our mutations are done.\n const root = getBlockRoot();\n if (root && observerRef.current) {\n observerRef.current.observe(root, {\n childList: true,\n subtree: true,\n characterData: true,\n });\n }\n }\n }, [blockId, blockType, contentEntries, getBlockRoot]);\n\n useEffect(() => {\n if (process.env.NODE_ENV === 'development') {\n console.log('[CMS] ClientEditableBlock mounted', { blockId, blockType });\n }\n setMounted(true);\n }, [blockId, blockType]);\n\n useIsomorphicLayoutEffect(() => {\n ensureCmsGlobals();\n\n const blockRoot = getBlockRoot();\n if (!blockRoot) return;\n\n // Stamp CMS attributes directly on the component's root element.\n blockRoot.setAttribute('data-cms-block', '');\n blockRoot.setAttribute('data-block-id', blockId);\n blockRoot.setAttribute('data-block-type', blockType);\n\n // Position toolbar at (x, y) without animating the placement itself —\n // suppress top/left transitions for the instant snap, then restore.\n const positionToolbar = (x: number, y: number) => {\n const el = toolbarElRef.current;\n if (!el) return;\n const { width: tw, height: th } = el.getBoundingClientRect();\n const top = Math.max(4, y - th - 12);\n const left = Math.max(4, Math.min(x - tw / 2, window.innerWidth - tw - 4));\n el.style.transition = 'opacity 0.15s ease, transform 0.15s ease';\n el.style.top = `${top}px`;\n el.style.left = `${left}px`;\n };\n\n const refreshSelectedOutline = () => {\n setSelectedOutlineRect((current) => (current ? blockRoot.getBoundingClientRect() : current));\n };\n\n // Cursor circle follows the mouse to indicate the block is interactive.\n const showCursor = (e: MouseEvent) => {\n if (toolbarVisibleRef.current) return;\n setHoverOutlineRect(blockRoot.getBoundingClientRect());\n const el = cursorElRef.current;\n if (!el) return;\n el.style.top = `${e.clientY}px`;\n el.style.left = `${e.clientX}px`;\n el.classList.add('cms-cursor-visible');\n };\n const moveCursor = (e: MouseEvent) => {\n if (toolbarVisibleRef.current) return;\n const el = cursorElRef.current;\n if (!el) return;\n el.style.top = `${e.clientY}px`;\n el.style.left = `${e.clientX}px`;\n };\n const hideCursor = () => {\n cursorElRef.current?.classList.remove('cms-cursor-visible');\n setHoverOutlineRect(null);\n };\n\n // On right-click: first time suppresses the browser context menu and shows\n // the CMS toolbar instead. If the toolbar is already visible the event is\n // not prevented so the browser's native context menu opens as a fallback.\n const handleContextMenu = (e: MouseEvent) => {\n if ((e.target as Element).closest('[data-cms-toolbar]')) return;\n if (toolbarVisibleRef.current) return; // fall through to browser context menu\n e.preventDefault();\n hideCursor();\n positionToolbar(e.clientX, e.clientY);\n toolbarVisibleRef.current = true;\n toolbarElRef.current?.classList.add('cms-toolbar-visible');\n };\n\n // Dismiss toolbar when clicking outside this block or its toolbar.\n const handleClickOutside = (e: MouseEvent) => {\n if (!toolbarVisibleRef.current) return;\n const target = e.target as Element;\n if (target.closest('[data-cms-toolbar]')) return;\n if (blockRoot.contains(target)) return;\n toolbarElRef.current?.classList.remove('cms-toolbar-visible');\n toolbarVisibleRef.current = false;\n };\n\n const hideOnScroll = () => {\n hideCursor();\n toolbarElRef.current?.classList.remove('cms-toolbar-visible');\n toolbarVisibleRef.current = false;\n refreshSelectedOutline();\n };\n\n const handleWindowMessage = (event: MessageEvent) => {\n if (!isTrustedCmsParentMessage(event)) return;\n if (event.data?.type !== 'cms-select-block') return;\n const selectedBlockId = typeof event.data.blockId === 'string' ? event.data.blockId : null;\n if (selectedBlockId === blockId) {\n setSelectedOutlineRect(blockRoot.getBoundingClientRect());\n } else {\n setSelectedOutlineRect(null);\n }\n };\n\n blockRoot.addEventListener('mouseenter', showCursor);\n blockRoot.addEventListener('mousemove', moveCursor);\n blockRoot.addEventListener('mouseleave', hideCursor);\n blockRoot.addEventListener('contextmenu', handleContextMenu);\n document.addEventListener('click', handleClickOutside);\n window.addEventListener('scroll', hideOnScroll, { passive: true, capture: true });\n window.addEventListener('resize', refreshSelectedOutline, { passive: true });\n window.addEventListener('message', handleWindowMessage);\n\n // Initial span injection after React's first commit.\n injectSpans();\n\n // Re-inject whenever the child component mutates the DOM.\n const observer = new MutationObserver(injectSpans);\n observerRef.current = observer;\n observer.observe(blockRoot, {\n childList: true,\n subtree: true,\n characterData: true,\n });\n\n return () => {\n observer.disconnect();\n observerRef.current = null;\n blockRoot.removeEventListener('mouseenter', showCursor);\n blockRoot.removeEventListener('mousemove', moveCursor);\n blockRoot.removeEventListener('mouseleave', hideCursor);\n blockRoot.removeEventListener('contextmenu', handleContextMenu);\n document.removeEventListener('click', handleClickOutside);\n window.removeEventListener('scroll', hideOnScroll, { capture: true });\n window.removeEventListener('resize', refreshSelectedOutline);\n window.removeEventListener('message', handleWindowMessage);\n };\n }, [injectSpans, blockId, blockType, getBlockRoot]);\n\n const portalRoot = mounted ? getCmsOverlayRoot() : null;\n\n return (\n <>\n <span ref={sentinelRef} style={{ display: 'none' }} aria-hidden />\n {children}\n {portalRoot &&\n (selectedOutlineRect ?? hoverOutlineRect) &&\n createPortal(\n <BlockOutline blockRect={(selectedOutlineRect ?? hoverOutlineRect) as DOMRect} />,\n portalRoot\n )}\n {portalRoot &&\n createPortal(<div ref={cursorElRef} className=\"cms-block-cursor\" />, portalRoot)}\n {portalRoot &&\n createPortal(<BlockToolbar ref={toolbarElRef} blockId={blockId} />, portalRoot)}\n </>\n );\n}\n","'use client';\n\nimport { useLayoutEffect, useRef } from 'react';\n\n/**\n * Block Outline Component\n *\n * Renders a position:fixed border overlay around a hovered block.\n * Tries up to 3 offset values (4px → 0px → -2px inset) to keep every\n * edge of the border visible inside the viewport before giving up.\n */\nexport function BlockOutline({ blockRect }: { blockRect: DOMRect }) {\n const outlineRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n const el = outlineRef.current;\n if (!el) return;\n\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n // Attempt progressively smaller offsets until the border is fully visible.\n // offset=4 → normal outline-offset feel\n // offset=0 → border flush with block edge\n // offset=-2 → border drawn inside the block (inset)\n const offsets = [4, 0, -2];\n\n for (const offset of offsets) {\n const pad = offset + 2; // 2px border + offset\n el.style.top = `${blockRect.top - pad}px`;\n el.style.left = `${blockRect.left - pad}px`;\n el.style.width = `${blockRect.width + pad * 2}px`;\n el.style.height = `${blockRect.height + pad * 2}px`;\n\n const rect = el.getBoundingClientRect();\n if (rect.top >= 0 && rect.left >= 0 && rect.right <= vw && rect.bottom <= vh) break;\n }\n }, [blockRect]);\n\n return (\n <div\n ref={outlineRef}\n data-cms-outline=\"true\"\n style={{\n position: 'fixed',\n border: '2px solid #3b82f6',\n borderRadius: '2px',\n pointerEvents: 'none',\n zIndex: 99998,\n boxSizing: 'border-box',\n }}\n />\n );\n}\n","'use client';\n\nimport { ChevronDownIcon, ChevronUpIcon, PlusIcon, TrashIcon } from '@heroicons/react/24/outline';\nimport { forwardRef } from 'react';\nimport { postMessageToCmsParent } from './cms-post-message';\n\n/**\n * Block Toolbar Component\n *\n * Provides move up/down and delete controls for blocks in edit mode.\n * Position is managed imperatively by the parent via a forwarded ref —\n * the toolbar follows the mouse cursor and has no internal layout logic.\n */\n\nexport const BlockToolbar = forwardRef<HTMLDivElement, { blockId: string }>(function BlockToolbar(\n { blockId },\n ref\n) {\n const handleAction = (action: string) => {\n postMessageToCmsParent({ type: 'cms-block-action', action, blockId });\n };\n\n return (\n <div ref={ref} className=\"cms-block-toolbar\" data-cms-toolbar=\"true\">\n <button\n type=\"button\"\n title=\"Move up\"\n aria-label=\"Move up\"\n data-action=\"move-up\"\n onClick={(e) => {\n e.stopPropagation();\n handleAction('move-up');\n }}\n >\n <ChevronUpIcon />\n </button>\n <button\n type=\"button\"\n title=\"Move down\"\n aria-label=\"Move down\"\n data-action=\"move-down\"\n onClick={(e) => {\n e.stopPropagation();\n handleAction('move-down');\n }}\n >\n <ChevronDownIcon />\n </button>\n <button\n type=\"button\"\n title=\"Add block\"\n aria-label=\"Add block\"\n data-action=\"add-block\"\n onClick={(e) => {\n e.stopPropagation();\n handleAction('add-block');\n }}\n >\n <PlusIcon />\n </button>\n <button\n type=\"button\"\n className=\"delete\"\n title=\"Delete block\"\n aria-label=\"Delete block\"\n data-action=\"delete\"\n onClick={(e) => {\n e.stopPropagation();\n handleAction('delete');\n }}\n >\n <TrashIcon />\n </button>\n </div>\n );\n});\n","/**\n * Trusted-origin helpers for CMS template-builder postMessage traffic\n * between the admin UI (parent) and the site preview iframe (child).\n */\n\nexport const CMS_PARENT_ORIGIN_PARAM = 'cms_parent_origin';\n\nexport function parseOrigin(url: string | undefined): string | null {\n if (!url) return null;\n try {\n return new URL(url).origin;\n } catch {\n return null;\n }\n}\n\nfunction getParentOriginFromQueryParam(): string | null {\n if (typeof window === 'undefined') return null;\n const value = new URLSearchParams(window.location.search).get(CMS_PARENT_ORIGIN_PARAM);\n return parseOrigin(value ?? undefined);\n}\n\nfunction getReferrerOrigin(): string | null {\n if (typeof document === 'undefined' || !document.referrer) return null;\n return parseOrigin(document.referrer);\n}\n\n/** Same-origin embed (e.g. proxied admin + preview on the customer domain). */\nfunction getSameOriginParentOrigin(): string | null {\n if (typeof window === 'undefined' || !window.parent || window.parent === window) {\n return null;\n }\n try {\n return window.parent.location.origin;\n } catch {\n return null;\n }\n}\n\n/** Origins allowed to send messages to the preview iframe (CMS admin hosts). */\nexport function getAllowedCmsParentOrigins(explicitParentOrigin?: string): string[] {\n const origins = new Set<string>();\n const apiOrigin = parseOrigin(process.env.NEXT_PUBLIC_CMS_API_URL);\n if (apiOrigin) origins.add(apiOrigin);\n\n const fromQuery = parseOrigin(explicitParentOrigin) ?? getParentOriginFromQueryParam();\n if (fromQuery) origins.add(fromQuery);\n\n const referrerOrigin = getReferrerOrigin();\n if (referrerOrigin) origins.add(referrerOrigin);\n\n const sameOriginParent = getSameOriginParentOrigin();\n if (sameOriginParent) origins.add(sameOriginParent);\n\n return [...origins];\n}\n\n/**\n * Target origin when posting from the preview iframe to the CMS parent.\n *\n * When the admin is proxied on a customer domain, the parent window origin is\n * the customer site — not NEXT_PUBLIC_CMS_API_URL. Prefer explicit/referrer/\n * same-origin parent detection over the CMS API URL.\n */\nexport function getCmsParentTargetOrigin(\n preferredCmsUrl?: string,\n explicitParentOrigin?: string\n): string | null {\n const fromExplicit = parseOrigin(explicitParentOrigin) ?? getParentOriginFromQueryParam();\n if (fromExplicit) return fromExplicit;\n\n const referrerOrigin = getReferrerOrigin();\n if (referrerOrigin) return referrerOrigin;\n\n const sameOriginParent = getSameOriginParentOrigin();\n if (sameOriginParent) return sameOriginParent;\n\n const preferredOrigin = parseOrigin(preferredCmsUrl);\n if (preferredOrigin) return preferredOrigin;\n\n const allowed = getAllowedCmsParentOrigins(explicitParentOrigin);\n return allowed[0] ?? null;\n}\n\nexport function isTrustedCmsParentMessage(\n event: MessageEvent,\n explicitParentOrigin?: string\n): boolean {\n const allowed = getAllowedCmsParentOrigins(explicitParentOrigin);\n if (allowed.length === 0) return false;\n if (!allowed.includes(event.origin)) return false;\n return event.source === window.parent;\n}\n\nexport function postMessageToCmsParent(\n message: unknown,\n options?: { preferredCmsUrl?: string; explicitParentOrigin?: string }\n): void {\n if (typeof window === 'undefined' || !window.parent || window.parent === window) return;\n const targetOrigin = getCmsParentTargetOrigin(\n options?.preferredCmsUrl,\n options?.explicitParentOrigin\n );\n if (!targetOrigin) return;\n window.parent.postMessage(message, targetOrigin);\n}\n"],"mappings":"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","names":["useRef","jsx","BlockToolbar","jsx","jsxs","useRef"]}
|
|
1
|
+
{"version":3,"sources":["../../lib/client-editable-block.tsx","../../lib/block-outline.tsx","../../lib/block-toolbar.tsx","../../lib/cms-post-message.ts"],"sourcesContent":["'use client';\n\nimport {\n useCallback,\n useEffect,\n useLayoutEffect as useLayoutEffectBase,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { BlockOutline } from './block-outline';\nimport { BlockToolbar } from './block-toolbar';\nimport { isTrustedCmsParentMessage, postMessageToCmsParent } from './cms-post-message';\n\n// Use useEffect as fallback for useLayoutEffect during SSR to avoid React warnings.\n// This is safe because the layout effect code only runs on the client anyway.\nconst useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffectBase : useEffect;\n\n// ---------------------------------------------------------------------------\n// Global styles + click-routing — injected once into <head> on first mount.\n// We do this programmatically because Next.js RSC marks body-level <style> and\n// <script> tags as inactive (they appear greyed-out in DevTools and are not\n// applied by the browser).\n// ---------------------------------------------------------------------------\n\nconst CMS_OVERLAY_ROOT_ID = 'cms-overlay-root';\n\nconst CMS_STYLES = `\n [data-cms-editable] { cursor: pointer; border-radius: 2px; }\n [data-cms-editable]:hover { outline: 2px solid #3b82f6; outline-offset: 2px; }\n #${CMS_OVERLAY_ROOT_ID} {\n position: fixed;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n pointer-events: none;\n z-index: 99998;\n }\n #${CMS_OVERLAY_ROOT_ID} > * {\n pointer-events: none;\n }\n .cms-block-cursor {\n position: fixed; width: 22px; height: 22px;\n background: radial-gradient(circle, #fff 5px, #000 5px);\n border-radius: 50%;\n pointer-events: none; z-index: 99999;\n transform: translate(-50%, -50%);\n opacity: 0; transition: opacity 0.1s ease;\n }\n .cms-block-cursor.cms-cursor-visible { opacity: 1; }\n .cms-block-toolbar {\n position: fixed;\n display: flex; gap: 4px; background: #1f2937; border-radius: 6px; padding: 4px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.25);\n z-index: 99999; pointer-events: none;\n opacity: 0; transform: scale(0.9) translateY(4px);\n transition: opacity 0.15s ease, transform 0.15s ease;\n }\n .cms-block-toolbar.cms-toolbar-visible {\n opacity: 1; transform: scale(1) translateY(0); pointer-events: auto;\n }\n .cms-block-toolbar button {\n display: flex; align-items: center; justify-content: center;\n width: 28px; height: 28px; border: none; background: transparent;\n color: #9ca3af; border-radius: 4px; cursor: pointer;\n transition: background 0.15s ease, color 0.15s ease;\n }\n .cms-block-toolbar button:hover { background: #374151; color: #fff; }\n .cms-block-toolbar button.delete:hover { background: #dc2626; color: #fff; }\n .cms-block-toolbar button:disabled { opacity: 0.4; cursor: not-allowed; }\n .cms-block-toolbar button:disabled:hover { background: transparent; color: #9ca3af; }\n .cms-block-toolbar svg { width: 16px; height: 16px; }\n`;\n\nlet cmsGlobalInjected = false;\nlet cmsOverlayRoot: HTMLElement | null = null;\n\n/**\n * Returns the CMS overlay portal root element, creating it if necessary.\n * Uses a dedicated container instead of document.body to ensure compatibility\n * with both Next.js and TanStack Start's streaming SSR hydration.\n */\nfunction getCmsOverlayRoot(): HTMLElement | null {\n if (typeof document === 'undefined' || !document.body) return null;\n\n if (cmsOverlayRoot && document.contains(cmsOverlayRoot)) {\n return cmsOverlayRoot;\n }\n\n let root = document.getElementById(CMS_OVERLAY_ROOT_ID);\n if (!root) {\n root = document.createElement('div');\n root.id = CMS_OVERLAY_ROOT_ID;\n document.body.appendChild(root);\n }\n\n cmsOverlayRoot = root;\n return root;\n}\n\nfunction ensureCmsGlobals() {\n if (cmsGlobalInjected) return;\n if (typeof document === 'undefined' || typeof window === 'undefined') return;\n cmsGlobalInjected = true;\n\n if (document.head) {\n const style = document.createElement('style');\n style.setAttribute('data-cms', '');\n style.textContent = CMS_STYLES;\n document.head.appendChild(style);\n }\n\n if (!(window as Window & { __cmsEditableInitialized?: boolean }).__cmsEditableInitialized) {\n (window as Window & { __cmsEditableInitialized?: boolean }).__cmsEditableInitialized = true;\n document.addEventListener('click', (e) => {\n const target = e.target as Element;\n if (target.closest('.cms-block-toolbar')) return;\n\n const editable = target.closest('[data-cms-editable]');\n if (editable) {\n const msg = {\n type: 'cms-editable-click',\n blockId: editable.getAttribute('data-block-id'),\n blockType: editable.getAttribute('data-block-type'),\n contentPath: editable.getAttribute('data-content-path'),\n };\n postMessageToCmsParent(msg);\n return;\n }\n\n const block = target.closest('[data-cms-block]');\n if (block) {\n const msg = {\n type: 'cms-editable-click',\n blockId: block.getAttribute('data-block-id'),\n blockType: block.getAttribute('data-block-type'),\n contentPath: null,\n };\n postMessageToCmsParent(msg);\n }\n });\n }\n}\n\ninterface ContentEntry {\n v: string;\n p: string;\n}\n\ninterface ClientEditableBlockProps {\n blockId: string;\n blockType: string;\n contentEntries: ContentEntry[];\n children: React.ReactNode;\n}\n\n/**\n * Client-side block editable wrapper.\n *\n * Renders a hidden sentinel span followed by the block's children (no wrapper div).\n * On mount, finds the component's root element via nextElementSibling and:\n * - Stamps data-cms-block, data-block-id, data-block-type directly on it\n * - Injects data-cms-editable spans around matching text nodes\n * - Portals the BlockToolbar into a dedicated overlay root with position:fixed\n * so it is never clipped by overflow:hidden or stacking contexts on the block\n *\n * Uses a MutationObserver to re-inject spans after every DOM mutation\n * (e.g. animated state changes that swap visible elements).\n *\n * The overlay root (#cms-overlay-root) is created lazily on first mount to ensure\n * compatibility with both Next.js and TanStack Start's streaming SSR hydration.\n */\nexport function ClientEditableBlock({\n blockId,\n blockType,\n contentEntries,\n children,\n}: ClientEditableBlockProps) {\n const sentinelRef = useRef<HTMLSpanElement>(null);\n const observerRef = useRef<MutationObserver | null>(null);\n const isInjectingRef = useRef(false);\n const cursorElRef = useRef<HTMLDivElement>(null);\n const toolbarElRef = useRef<HTMLDivElement>(null);\n const toolbarVisibleRef = useRef(false);\n const [mounted, setMounted] = useState(false);\n const [hoverOutlineRect, setHoverOutlineRect] = useState<DOMRect | null>(null);\n const [selectedOutlineRect, setSelectedOutlineRect] = useState<DOMRect | null>(null);\n\n const getBlockRoot = useCallback((): HTMLElement | null => {\n return (sentinelRef.current?.nextElementSibling as HTMLElement) ?? null;\n }, []);\n\n const injectSpans = useCallback(() => {\n if (isInjectingRef.current) return;\n const blockRoot = getBlockRoot();\n if (!blockRoot) return;\n\n isInjectingRef.current = true;\n // Disconnect observer while we mutate the DOM to avoid re-entrant calls.\n observerRef.current?.disconnect();\n\n try {\n // Remove previously injected text-level spans, restoring the original text nodes.\n const existing = Array.from(\n blockRoot.querySelectorAll<HTMLElement>('span[data-cms-editable][data-content-path]')\n );\n for (const span of existing) {\n const parent = span.parentNode;\n if (!parent) continue;\n while (span.firstChild) parent.insertBefore(span.firstChild, span);\n parent.removeChild(span);\n }\n\n // Walk all visible text nodes and wrap the ones that match content values.\n const used = new Set<string>();\n const walker = document.createTreeWalker(blockRoot, NodeFilter.SHOW_TEXT, null);\n const textNodes: Text[] = [];\n let n = walker.nextNode();\n while (n !== null) {\n const textNode = n as Text;\n if (\n textNode.parentElement?.closest('.cms-block-toolbar') == null &&\n textNode.nodeValue?.trim()\n ) {\n textNodes.push(textNode);\n }\n n = walker.nextNode();\n }\n\n for (const textNode of textNodes) {\n // Never inject spans inside SVG — <span> is not valid SVG content\n if (textNode.parentElement?.closest('svg') != null) continue;\n\n const text = textNode.nodeValue;\n if (!text) continue;\n for (const entry of contentEntries) {\n if (used.has(entry.p)) continue;\n if (text.indexOf(entry.v) !== -1 && text.trim() === entry.v.trim()) {\n used.add(entry.p);\n const span = document.createElement('span');\n span.setAttribute('data-cms-editable', '');\n span.setAttribute('data-block-id', blockId);\n span.setAttribute('data-block-type', blockType);\n span.setAttribute('data-content-path', entry.p);\n textNode.parentNode?.insertBefore(span, textNode);\n span.appendChild(textNode);\n break;\n }\n }\n }\n } finally {\n isInjectingRef.current = false;\n // Reconnect after our mutations are done.\n const root = getBlockRoot();\n if (root && observerRef.current) {\n observerRef.current.observe(root, {\n childList: true,\n subtree: true,\n characterData: true,\n });\n }\n }\n }, [blockId, blockType, contentEntries, getBlockRoot]);\n\n useEffect(() => {\n if (process.env.NODE_ENV === 'development') {\n console.log('[CMS] ClientEditableBlock mounted', { blockId, blockType });\n }\n setMounted(true);\n }, [blockId, blockType]);\n\n useIsomorphicLayoutEffect(() => {\n ensureCmsGlobals();\n\n const blockRoot = getBlockRoot();\n if (!blockRoot) return;\n\n // Stamp CMS attributes directly on the component's root element.\n blockRoot.setAttribute('data-cms-block', '');\n blockRoot.setAttribute('data-block-id', blockId);\n blockRoot.setAttribute('data-block-type', blockType);\n\n // Position toolbar at (x, y) without animating the placement itself —\n // suppress top/left transitions for the instant snap, then restore.\n const positionToolbar = (x: number, y: number) => {\n const el = toolbarElRef.current;\n if (!el) return;\n const { width: tw, height: th } = el.getBoundingClientRect();\n const top = Math.max(4, y - th - 12);\n const left = Math.max(4, Math.min(x - tw / 2, window.innerWidth - tw - 4));\n el.style.transition = 'opacity 0.15s ease, transform 0.15s ease';\n el.style.top = `${top}px`;\n el.style.left = `${left}px`;\n };\n\n const refreshSelectedOutline = () => {\n setSelectedOutlineRect((current) => (current ? blockRoot.getBoundingClientRect() : current));\n };\n\n // Cursor circle follows the mouse to indicate the block is interactive.\n const showCursor = (e: MouseEvent) => {\n if (toolbarVisibleRef.current) return;\n setHoverOutlineRect(blockRoot.getBoundingClientRect());\n const el = cursorElRef.current;\n if (!el) return;\n el.style.top = `${e.clientY}px`;\n el.style.left = `${e.clientX}px`;\n el.classList.add('cms-cursor-visible');\n };\n const moveCursor = (e: MouseEvent) => {\n if (toolbarVisibleRef.current) return;\n const el = cursorElRef.current;\n if (!el) return;\n el.style.top = `${e.clientY}px`;\n el.style.left = `${e.clientX}px`;\n };\n const hideCursor = () => {\n cursorElRef.current?.classList.remove('cms-cursor-visible');\n setHoverOutlineRect(null);\n };\n\n // On right-click: first time suppresses the browser context menu and shows\n // the CMS toolbar instead. If the toolbar is already visible the event is\n // not prevented so the browser's native context menu opens as a fallback.\n const handleContextMenu = (e: MouseEvent) => {\n if ((e.target as Element).closest('[data-cms-toolbar]')) return;\n if (toolbarVisibleRef.current) return; // fall through to browser context menu\n e.preventDefault();\n hideCursor();\n positionToolbar(e.clientX, e.clientY);\n toolbarVisibleRef.current = true;\n toolbarElRef.current?.classList.add('cms-toolbar-visible');\n };\n\n // Dismiss toolbar when clicking outside this block or its toolbar.\n const handleClickOutside = (e: MouseEvent) => {\n if (!toolbarVisibleRef.current) return;\n const target = e.target as Element;\n if (target.closest('[data-cms-toolbar]')) return;\n if (blockRoot.contains(target)) return;\n toolbarElRef.current?.classList.remove('cms-toolbar-visible');\n toolbarVisibleRef.current = false;\n };\n\n const hideOnScroll = () => {\n hideCursor();\n toolbarElRef.current?.classList.remove('cms-toolbar-visible');\n toolbarVisibleRef.current = false;\n refreshSelectedOutline();\n };\n\n const handleWindowMessage = (event: MessageEvent) => {\n if (!isTrustedCmsParentMessage(event)) return;\n if (event.data?.type !== 'cms-select-block') return;\n const selectedBlockId = typeof event.data.blockId === 'string' ? event.data.blockId : null;\n if (selectedBlockId === blockId) {\n setSelectedOutlineRect(blockRoot.getBoundingClientRect());\n } else {\n setSelectedOutlineRect(null);\n }\n };\n\n blockRoot.addEventListener('mouseenter', showCursor);\n blockRoot.addEventListener('mousemove', moveCursor);\n blockRoot.addEventListener('mouseleave', hideCursor);\n blockRoot.addEventListener('contextmenu', handleContextMenu);\n document.addEventListener('click', handleClickOutside);\n window.addEventListener('scroll', hideOnScroll, { passive: true, capture: true });\n window.addEventListener('resize', refreshSelectedOutline, { passive: true });\n window.addEventListener('message', handleWindowMessage);\n\n // Initial span injection after React's first commit.\n injectSpans();\n\n // Re-inject whenever the child component mutates the DOM.\n const observer = new MutationObserver(injectSpans);\n observerRef.current = observer;\n observer.observe(blockRoot, {\n childList: true,\n subtree: true,\n characterData: true,\n });\n\n return () => {\n observer.disconnect();\n observerRef.current = null;\n blockRoot.removeEventListener('mouseenter', showCursor);\n blockRoot.removeEventListener('mousemove', moveCursor);\n blockRoot.removeEventListener('mouseleave', hideCursor);\n blockRoot.removeEventListener('contextmenu', handleContextMenu);\n document.removeEventListener('click', handleClickOutside);\n window.removeEventListener('scroll', hideOnScroll, { capture: true });\n window.removeEventListener('resize', refreshSelectedOutline);\n window.removeEventListener('message', handleWindowMessage);\n };\n }, [injectSpans, blockId, blockType, getBlockRoot]);\n\n const portalRoot = mounted ? getCmsOverlayRoot() : null;\n\n return (\n <>\n <span ref={sentinelRef} style={{ display: 'none' }} aria-hidden />\n {children}\n {portalRoot &&\n (selectedOutlineRect ?? hoverOutlineRect) &&\n createPortal(\n <BlockOutline blockRect={(selectedOutlineRect ?? hoverOutlineRect) as DOMRect} />,\n portalRoot\n )}\n {portalRoot &&\n createPortal(<div ref={cursorElRef} className=\"cms-block-cursor\" />, portalRoot)}\n {portalRoot &&\n createPortal(<BlockToolbar ref={toolbarElRef} blockId={blockId} />, portalRoot)}\n </>\n );\n}\n","'use client';\n\nimport { useLayoutEffect, useRef } from 'react';\n\n/**\n * Block Outline Component\n *\n * Renders a position:fixed border overlay around a hovered block.\n * Tries up to 3 offset values (4px → 0px → -2px inset) to keep every\n * edge of the border visible inside the viewport before giving up.\n */\nexport function BlockOutline({ blockRect }: { blockRect: DOMRect }) {\n const outlineRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n const el = outlineRef.current;\n if (!el) return;\n\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n // Attempt progressively smaller offsets until the border is fully visible.\n // offset=4 → normal outline-offset feel\n // offset=0 → border flush with block edge\n // offset=-2 → border drawn inside the block (inset)\n const offsets = [4, 0, -2];\n\n for (const offset of offsets) {\n const pad = offset + 2; // 2px border + offset\n el.style.top = `${blockRect.top - pad}px`;\n el.style.left = `${blockRect.left - pad}px`;\n el.style.width = `${blockRect.width + pad * 2}px`;\n el.style.height = `${blockRect.height + pad * 2}px`;\n\n const rect = el.getBoundingClientRect();\n if (rect.top >= 0 && rect.left >= 0 && rect.right <= vw && rect.bottom <= vh) break;\n }\n }, [blockRect]);\n\n return (\n <div\n ref={outlineRef}\n data-cms-outline=\"true\"\n style={{\n position: 'fixed',\n border: '2px solid #3b82f6',\n borderRadius: '2px',\n pointerEvents: 'none',\n zIndex: 99998,\n boxSizing: 'border-box',\n }}\n />\n );\n}\n","'use client';\n\nimport { ChevronDownIcon, ChevronUpIcon, PlusIcon, TrashIcon } from '@heroicons/react/24/outline';\nimport { forwardRef } from 'react';\nimport { postMessageToCmsParent } from './cms-post-message';\n\n/**\n * Block Toolbar Component\n *\n * Provides move up/down and delete controls for blocks in edit mode.\n * Position is managed imperatively by the parent via a forwarded ref —\n * the toolbar follows the mouse cursor and has no internal layout logic.\n */\n\nexport const BlockToolbar = forwardRef<HTMLDivElement, { blockId: string }>(function BlockToolbar(\n { blockId },\n ref\n) {\n const handleAction = (action: string) => {\n postMessageToCmsParent({ type: 'cms-block-action', action, blockId });\n };\n\n return (\n <div ref={ref} className=\"cms-block-toolbar\" data-cms-toolbar=\"true\">\n <button\n type=\"button\"\n title=\"Move up\"\n aria-label=\"Move up\"\n data-action=\"move-up\"\n onClick={(e) => {\n e.stopPropagation();\n handleAction('move-up');\n }}\n >\n <ChevronUpIcon />\n </button>\n <button\n type=\"button\"\n title=\"Move down\"\n aria-label=\"Move down\"\n data-action=\"move-down\"\n onClick={(e) => {\n e.stopPropagation();\n handleAction('move-down');\n }}\n >\n <ChevronDownIcon />\n </button>\n <button\n type=\"button\"\n title=\"Add block above\"\n aria-label=\"Add block above\"\n data-action=\"add-block-above\"\n onClick={(e) => {\n e.stopPropagation();\n handleAction('add-block-above');\n }}\n >\n <PlusIcon />\n </button>\n <button\n type=\"button\"\n title=\"Add block below\"\n aria-label=\"Add block below\"\n data-action=\"add-block-below\"\n onClick={(e) => {\n e.stopPropagation();\n handleAction('add-block-below');\n }}\n >\n <PlusIcon />\n </button>\n <button\n type=\"button\"\n className=\"delete\"\n title=\"Delete block\"\n aria-label=\"Delete block\"\n data-action=\"delete\"\n onClick={(e) => {\n e.stopPropagation();\n handleAction('delete');\n }}\n >\n <TrashIcon />\n </button>\n </div>\n );\n});\n","/**\n * Trusted-origin helpers for CMS template-builder postMessage traffic\n * between the admin UI (parent) and the site preview iframe (child).\n */\n\nexport const CMS_PARENT_ORIGIN_PARAM = 'cms_parent_origin';\n\nexport function parseOrigin(url: string | undefined): string | null {\n if (!url) return null;\n try {\n return new URL(url).origin;\n } catch {\n return null;\n }\n}\n\nfunction getParentOriginFromQueryParam(): string | null {\n if (typeof window === 'undefined') return null;\n const value = new URLSearchParams(window.location.search).get(CMS_PARENT_ORIGIN_PARAM);\n return parseOrigin(value ?? undefined);\n}\n\nfunction getReferrerOrigin(): string | null {\n if (typeof document === 'undefined' || !document.referrer) return null;\n return parseOrigin(document.referrer);\n}\n\n/** Same-origin embed (e.g. proxied admin + preview on the customer domain). */\nfunction getSameOriginParentOrigin(): string | null {\n if (typeof window === 'undefined' || !window.parent || window.parent === window) {\n return null;\n }\n try {\n return window.parent.location.origin;\n } catch {\n return null;\n }\n}\n\n/** Origins allowed to send messages to the preview iframe (CMS admin hosts). */\nexport function getAllowedCmsParentOrigins(explicitParentOrigin?: string): string[] {\n const origins = new Set<string>();\n const apiOrigin = parseOrigin(process.env.NEXT_PUBLIC_CMS_API_URL);\n if (apiOrigin) origins.add(apiOrigin);\n\n const fromQuery = parseOrigin(explicitParentOrigin) ?? getParentOriginFromQueryParam();\n if (fromQuery) origins.add(fromQuery);\n\n const referrerOrigin = getReferrerOrigin();\n if (referrerOrigin) origins.add(referrerOrigin);\n\n const sameOriginParent = getSameOriginParentOrigin();\n if (sameOriginParent) origins.add(sameOriginParent);\n\n return [...origins];\n}\n\n/**\n * Target origin when posting from the preview iframe to the CMS parent.\n *\n * When the admin is proxied on a customer domain, the parent window origin is\n * the customer site — not NEXT_PUBLIC_CMS_API_URL. Prefer explicit/referrer/\n * same-origin parent detection over the CMS API URL.\n */\nexport function getCmsParentTargetOrigin(\n preferredCmsUrl?: string,\n explicitParentOrigin?: string\n): string | null {\n const fromExplicit = parseOrigin(explicitParentOrigin) ?? getParentOriginFromQueryParam();\n if (fromExplicit) return fromExplicit;\n\n const referrerOrigin = getReferrerOrigin();\n if (referrerOrigin) return referrerOrigin;\n\n const sameOriginParent = getSameOriginParentOrigin();\n if (sameOriginParent) return sameOriginParent;\n\n const preferredOrigin = parseOrigin(preferredCmsUrl);\n if (preferredOrigin) return preferredOrigin;\n\n const allowed = getAllowedCmsParentOrigins(explicitParentOrigin);\n return allowed[0] ?? null;\n}\n\nexport function isTrustedCmsParentMessage(\n event: MessageEvent,\n explicitParentOrigin?: string\n): boolean {\n const allowed = getAllowedCmsParentOrigins(explicitParentOrigin);\n if (allowed.length === 0) return false;\n if (!allowed.includes(event.origin)) return false;\n return event.source === window.parent;\n}\n\nexport function postMessageToCmsParent(\n message: unknown,\n options?: { preferredCmsUrl?: string; explicitParentOrigin?: string }\n): void {\n if (typeof window === 'undefined' || !window.parent || window.parent === window) return;\n const targetOrigin = getCmsParentTargetOrigin(\n options?.preferredCmsUrl,\n options?.explicitParentOrigin\n );\n if (!targetOrigin) return;\n window.parent.postMessage(message, targetOrigin);\n}\n"],"mappings":"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","names":["useRef","jsx","BlockToolbar","jsx","jsxs","useRef"]}
|