dopecanvas 0.1.2 → 0.1.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"dopecanvas.js","sources":["../src/components/Page.tsx","../src/core/types.ts","../src/components/PagedView.tsx","../src/core/PageLayoutEngine.ts","../src/core/EditableManager.ts","../src/components/DopeCanvas.tsx","../src/core/DocumentEngine.ts","../src/api/DocumentAPI.ts","../src/hooks/useSelectionContext.ts","../src/components/Toolbar/TextToolbar.tsx","../src/components/Toolbar/PageSetupToolbar.tsx","../src/components/Toolbar/Toolbar.tsx","../src/hooks/useDocumentEngine.ts"],"sourcesContent":["// ============================================================\n// Page — Single page frame component\n// ============================================================\n// Renders a fixed-size white page with margins and page number.\n// ============================================================\n\nimport React from 'react';\nimport type { PageDimensions, PageMargins } from '../core/types';\n\ninterface PageProps {\n /** Page dimensions in pixels */\n dimensions: PageDimensions;\n /** Page margins in pixels */\n margins: PageMargins;\n /** Page number (1-indexed) */\n pageNumber: number;\n /** Total number of pages */\n totalPages: number;\n /** The content blocks to render inside the page */\n children: React.ReactNode;\n}\n\nexport const Page: React.FC<PageProps> = ({\n dimensions,\n margins,\n pageNumber,\n totalPages,\n children,\n}) => {\n return (\n <div\n className=\"dopecanvas-page\"\n style={{\n width: `${dimensions.width}px`,\n height: `${dimensions.height}px`,\n backgroundColor: '#ffffff',\n boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15), 0 0 1px rgba(0, 0, 0, 0.1)',\n position: 'relative',\n overflow: 'hidden',\n flexShrink: 0,\n }}\n >\n {/* Content area with margins */}\n <div\n className=\"dopecanvas-page-content\"\n style={{\n paddingTop: `${margins.top}px`,\n paddingRight: `${margins.right}px`,\n paddingBottom: `${margins.bottom}px`,\n paddingLeft: `${margins.left}px`,\n height: '100%',\n boxSizing: 'border-box',\n overflow: 'hidden',\n }}\n >\n {children}\n </div>\n\n {/* Page number footer */}\n <div\n className=\"dopecanvas-page-number\"\n style={{\n position: 'absolute',\n bottom: `${Math.max(margins.bottom / 3, 16)}px`,\n left: 0,\n right: 0,\n textAlign: 'center',\n fontSize: '11px',\n color: '#999',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n pointerEvents: 'none',\n userSelect: 'none',\n }}\n >\n {pageNumber} / {totalPages}\n </div>\n </div>\n );\n};\n","// ============================================================\n// DopeCanvas Core Types\n// ============================================================\n\n/** Named page size presets */\nexport type PageSizeName = 'letter' | 'a4' | 'legal';\n\n/** Custom page dimensions in pixels */\nexport interface PageDimensions {\n width: number;\n height: number;\n}\n\n/** Page margins in pixels */\nexport interface PageMargins {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\n/** Full page configuration */\nexport interface PageConfig {\n size: PageSizeName | PageDimensions;\n margins: PageMargins;\n}\n\n/** A single page containing block element indices */\nexport interface PageContent {\n /** Indices into the flat block array */\n blockIndices: number[];\n}\n\n/** Result of the pagination algorithm */\nexport interface PaginationResult {\n pages: PageContent[];\n pageCount: number;\n}\n\n/** Block measurement info */\nexport interface BlockMeasurement {\n index: number;\n height: number;\n element: HTMLElement;\n breakBefore: boolean;\n breakAfter: boolean;\n}\n\n/** Toolbar context — what kind of element is selected */\nexport type ToolbarContext = 'text' | 'table' | 'image' | 'chart' | 'none';\n\n/** Undo/redo snapshot */\nexport interface UndoSnapshot {\n html: string;\n timestamp: number;\n}\n\n/** Unsubscribe function returned by event listeners */\nexport type Unsubscribe = () => void;\n\n// ============================================================\n// Page size presets (at 96 DPI)\n// ============================================================\n\n/** Page sizes in pixels at 96 DPI */\nexport const PAGE_SIZE_PRESETS: Record<PageSizeName, PageDimensions> = {\n letter: { width: 816, height: 1056 }, // 8.5 x 11 inches\n a4: { width: 794, height: 1123 }, // 210 x 297 mm\n legal: { width: 816, height: 1344 }, // 8.5 x 14 inches\n};\n\n/** Default margins: 1 inch (96px) on all sides */\nexport const DEFAULT_MARGINS: PageMargins = {\n top: 96,\n right: 96,\n bottom: 96,\n left: 96,\n};\n\n/** Default page config */\nexport const DEFAULT_PAGE_CONFIG: PageConfig = {\n size: 'letter',\n margins: { ...DEFAULT_MARGINS },\n};\n","// ============================================================\n// PagedView — Renders paginated blocks across page frames\n// ============================================================\n// Takes HTML content, paginates it into visual pages, and makes\n// each block editable via contentEditable.\n//\n// After initial pagination, the live DOM is the source of truth.\n// User edits trigger live re-pagination when the block distribution\n// across pages changes (e.g. content grows past a page boundary).\n// Cursor position is saved/restored across re-pagination re-renders.\n// ============================================================\n\nimport React, { useRef, useEffect, useCallback, useState } from 'react';\nimport { Page } from './Page';\nimport type { PageLayoutEngine } from '../core/PageLayoutEngine';\nimport type { EditableManager } from '../core/EditableManager';\nimport type {\n PageConfig,\n PaginationResult,\n PageSizeName,\n} from '../core/types';\nimport { PAGE_SIZE_PRESETS } from '../core/types';\n\ninterface PagedViewProps {\n /** The raw HTML content to render */\n html: string;\n /** Optional CSS to inject */\n css?: string;\n /** Page configuration */\n pageConfig: PageConfig;\n /** The layout engine instance */\n layoutEngine: PageLayoutEngine;\n /** The editable manager instance */\n editableManager: EditableManager;\n /** Callback when content changes (after user edit) — updates a ref, NOT state */\n onContentChange?: (html: string) => void;\n /** Callback when pagination changes */\n onPaginationChange?: (result: PaginationResult) => void;\n}\n\n/**\n * Represents a block of content assigned to a specific page.\n * We store the HTML string so React can render it once, then\n * the live DOM takes over for editing.\n */\ninterface PageData {\n blocks: string[]; // outerHTML of each block in this page\n}\n\n/**\n * Execute <script> tags found in a container.\n * Scripts set via innerHTML / dangerouslySetInnerHTML do NOT auto-execute.\n * We clone each one into a fresh <script> element so the browser runs it.\n */\nfunction activateScripts(container: HTMLElement): HTMLScriptElement[] {\n const activated: HTMLScriptElement[] = [];\n\n container.querySelectorAll('script').forEach((orig) => {\n const fresh = document.createElement('script');\n // Preserve attributes (type, src, data-*, etc.)\n Array.from(orig.attributes).forEach((attr) =>\n fresh.setAttribute(attr.name, attr.value)\n );\n fresh.textContent = orig.textContent || '';\n // Replacing the node triggers synchronous execution for inline scripts\n orig.parentNode?.replaceChild(fresh, orig);\n activated.push(fresh);\n });\n\n return activated;\n}\n\n// ----------------------------------------------------------\n// Cursor save / restore — used across re-pagination re-renders\n// ----------------------------------------------------------\n\ninterface CursorState {\n /** Global index of the block wrapper the cursor is inside */\n blockIndex: number;\n /** Character offset within that block's text content */\n textOffset: number;\n}\n\n/** Save the current cursor position relative to block wrappers */\nfunction saveCursorPosition(container: HTMLElement): CursorState | null {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return null;\n\n const range = sel.getRangeAt(0);\n const anchorNode = range.startContainer;\n\n const wrappers = Array.from(\n container.querySelectorAll('.dopecanvas-block-wrapper')\n );\n const blockIndex = wrappers.findIndex((w) => w.contains(anchorNode));\n if (blockIndex === -1) return null;\n\n // Compute character offset within the block\n try {\n const preRange = document.createRange();\n preRange.selectNodeContents(wrappers[blockIndex]);\n preRange.setEnd(range.startContainer, range.startOffset);\n const textOffset = preRange.toString().length;\n return { blockIndex, textOffset };\n } catch {\n return null;\n }\n}\n\n/** Restore cursor position after a re-pagination re-render */\nfunction restoreCursorPosition(\n container: HTMLElement,\n state: CursorState\n): void {\n const wrappers = container.querySelectorAll('.dopecanvas-block-wrapper');\n if (state.blockIndex >= wrappers.length) return;\n\n const wrapper = wrappers[state.blockIndex];\n const walker = document.createTreeWalker(wrapper, NodeFilter.SHOW_TEXT);\n let remaining = state.textOffset;\n\n while (walker.nextNode()) {\n const textNode = walker.currentNode as Text;\n if (remaining <= textNode.length) {\n try {\n const range = document.createRange();\n range.setStart(textNode, remaining);\n range.collapse(true);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n } catch {\n // Best effort — position may have shifted\n }\n return;\n }\n remaining -= textNode.length;\n }\n\n // Fallback: place cursor at the end of the block\n try {\n const range = document.createRange();\n range.selectNodeContents(wrapper);\n range.collapse(false);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n } catch {\n // Ignore\n }\n}\n\nexport const PagedView: React.FC<PagedViewProps> = ({\n html,\n css,\n pageConfig,\n layoutEngine,\n editableManager: _editableManager,\n onContentChange,\n onPaginationChange,\n}) => {\n const measureRef = useRef<HTMLDivElement>(null);\n const pagesContainerRef = useRef<HTMLDivElement>(null);\n const mutationObserverRef = useRef<MutationObserver | null>(null);\n const onContentChangeRef = useRef(onContentChange);\n onContentChangeRef.current = onContentChange;\n\n // Pages state — set during pagination AND live re-pagination\n const [pages, setPages] = useState<PageData[]>([]);\n\n // Refs for live re-pagination\n const pendingCursorRef = useRef<CursorState | null>(null);\n const isRePaginatingRef = useRef(false);\n const pagesRef = useRef<PageData[]>([]);\n\n // Resolve page dimensions\n const dimensions =\n typeof pageConfig.size === 'string'\n ? PAGE_SIZE_PRESETS[pageConfig.size as PageSizeName]\n : pageConfig.size;\n\n // ----------------------------------------------------------\n // Collect current HTML from the live DOM (no re-render)\n // ----------------------------------------------------------\n\n const collectHTMLFromDOM = useCallback(() => {\n if (!pagesContainerRef.current) return;\n\n const wrappers = pagesContainerRef.current.querySelectorAll(\n '.dopecanvas-block-wrapper'\n );\n\n const htmlParts: string[] = [];\n wrappers.forEach((wrapper) => {\n // The wrapper contains the actual content element\n const content = wrapper.firstElementChild as HTMLElement;\n if (content) {\n htmlParts.push(content.outerHTML);\n }\n });\n\n const updatedHTML = htmlParts.join('\\n');\n onContentChangeRef.current?.(updatedHTML);\n }, []);\n\n // ----------------------------------------------------------\n // Live re-pagination — runs after user edits change block sizes\n // ----------------------------------------------------------\n\n const rePaginateFromDOM = useCallback(() => {\n if (!pagesContainerRef.current || !measureRef.current) return;\n\n const container = pagesContainerRef.current;\n\n // Save cursor position before we potentially re-render\n const cursor = saveCursorPosition(container);\n\n // Collect block HTML from the live DOM\n const wrappers = container.querySelectorAll('.dopecanvas-block-wrapper');\n const blockHTMLs: string[] = [];\n wrappers.forEach((w) => {\n const content = w.firstElementChild as HTMLElement;\n if (content) blockHTMLs.push(content.outerHTML);\n });\n if (blockHTMLs.length === 0) return;\n\n // Set up hidden measure container\n const mc = measureRef.current;\n const contentWidth = layoutEngine.getContentAreaWidth();\n mc.style.width = `${contentWidth}px`;\n mc.style.position = 'absolute';\n mc.style.left = '-9999px';\n mc.style.top = '0';\n mc.style.visibility = 'hidden';\n mc.innerHTML = '';\n\n if (css) {\n const styleEl = document.createElement('style');\n styleEl.textContent = css;\n mc.appendChild(styleEl);\n }\n\n const measureWrapper = document.createElement('div');\n measureWrapper.innerHTML = blockHTMLs.join('\\n');\n mc.appendChild(measureWrapper);\n\n // Measure and paginate\n const measurements = layoutEngine.measureBlocks(measureWrapper);\n const measuredHTMLs = measurements.map(\n (m) => (m.element.cloneNode(true) as HTMLElement).outerHTML\n );\n const result = layoutEngine.paginate(measurements);\n mc.innerHTML = '';\n\n // Build new page data\n const newPages: PageData[] = result.pages.map((p) => ({\n blocks: p.blockIndices.map((idx) => measuredHTMLs[idx]),\n }));\n\n // Only re-render if the block distribution across pages actually changed\n const oldDist = pagesRef.current.map((p) => p.blocks.length);\n const newDist = newPages.map((p) => p.blocks.length);\n const changed =\n oldDist.length !== newDist.length ||\n oldDist.some((count, i) => count !== newDist[i]);\n\n if (changed) {\n isRePaginatingRef.current = true;\n pendingCursorRef.current = cursor;\n pagesRef.current = newPages;\n setPages(newPages);\n onPaginationChange?.(result);\n }\n }, [css, layoutEngine, onPaginationChange]);\n\n // Keep a stable ref so the MutationObserver closure always calls the latest version\n const rePaginateFromDOMRef = useRef(rePaginateFromDOM);\n rePaginateFromDOMRef.current = rePaginateFromDOM;\n\n // ----------------------------------------------------------\n // Pagination — runs on initial load and config changes\n // ----------------------------------------------------------\n\n const runPagination = useCallback(() => {\n if (!measureRef.current) return;\n\n const measureContainer = measureRef.current;\n const contentWidth = layoutEngine.getContentAreaWidth();\n\n // Set up hidden measurement container\n measureContainer.style.width = `${contentWidth}px`;\n measureContainer.style.position = 'absolute';\n measureContainer.style.left = '-9999px';\n measureContainer.style.top = '0';\n measureContainer.style.visibility = 'hidden';\n measureContainer.innerHTML = '';\n\n // Inject CSS if provided via prop\n if (css) {\n const styleEl = document.createElement('style');\n styleEl.textContent = css;\n measureContainer.appendChild(styleEl);\n }\n\n // Parse the LLM-authored HTML.\n // An LLM may produce a full document (<!DOCTYPE html><html><head>\n // <style>…</style></head><body>…</body></html>) or a plain fragment.\n // DOMParser handles both: for fragments it wraps in html/body;\n // for full documents it parses normally. We then move any <head>\n // styles/links into the body so they participate in pagination\n // as zero-height blocks and their styles apply to the content.\n const parsed = new DOMParser().parseFromString(html, 'text/html');\n\n // Rescue <style> and <link rel=\"stylesheet\"> from <head>\n parsed.head\n .querySelectorAll('style, link[rel=\"stylesheet\"]')\n .forEach((el) => {\n parsed.body.insertBefore(el, parsed.body.firstChild);\n });\n\n const contentHTML = parsed.body.innerHTML;\n\n // Inject content into a wrapper for measurement\n const wrapper = document.createElement('div');\n wrapper.innerHTML = contentHTML;\n measureContainer.appendChild(wrapper);\n\n // Measure all blocks\n const measurements = layoutEngine.measureBlocks(wrapper);\n\n // Clone block elements and get their HTML\n const blockHTMLs = measurements.map(\n (m) => (m.element.cloneNode(true) as HTMLElement).outerHTML\n );\n\n // Run pagination algorithm\n const result = layoutEngine.paginate(measurements);\n\n // Build page data (HTML strings, not live elements)\n const pageData: PageData[] = result.pages.map((page) => ({\n blocks: page.blockIndices.map((idx) => blockHTMLs[idx]),\n }));\n\n // Clean up\n measureContainer.innerHTML = '';\n\n // Update state — this triggers a React render\n pagesRef.current = pageData;\n setPages(pageData);\n onPaginationChange?.(result);\n }, [html, css, layoutEngine, onPaginationChange]);\n\n // Run pagination when html or pageConfig changes\n useEffect(() => {\n runPagination();\n }, [runPagination]);\n\n // ----------------------------------------------------------\n // After pages render: make editable + observe changes\n // ----------------------------------------------------------\n\n useEffect(() => {\n const container = pagesContainerRef.current;\n if (!container) return;\n\n // Disconnect previous observer\n if (mutationObserverRef.current) {\n mutationObserverRef.current.disconnect();\n }\n\n // Make all blocks contentEditable\n const blockWrappers = container.querySelectorAll('.dopecanvas-block-wrapper');\n blockWrappers.forEach((wrapper) => {\n const child = wrapper.firstElementChild as HTMLElement;\n if (!child) return;\n\n if (child.tagName === 'TABLE') {\n // For tables, make individual cells editable\n const cells = child.querySelectorAll('td, th');\n cells.forEach((cell) => {\n (cell as HTMLElement).contentEditable = 'true';\n });\n } else if (child.tagName === 'SCRIPT' || child.tagName === 'STYLE') {\n // Don't make script/style blocks editable\n } else {\n child.contentEditable = 'true';\n }\n });\n\n // Execute <script> tags embedded in the LLM-authored HTML.\n // This must run AFTER contentEditable setup so scripts can override\n // editability on specific cells (e.g. formula cells).\n const activatedScripts = activateScripts(container);\n\n // Set up MutationObserver — collects HTML and re-paginates when needed\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n const observer = new MutationObserver(() => {\n if (isRePaginatingRef.current) return;\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => {\n collectHTMLFromDOM();\n rePaginateFromDOMRef.current();\n }, 300);\n });\n\n observer.observe(container, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: false,\n });\n\n mutationObserverRef.current = observer;\n\n // Restore cursor after a re-pagination re-render\n if (pendingCursorRef.current) {\n requestAnimationFrame(() => {\n if (pendingCursorRef.current && pagesContainerRef.current) {\n restoreCursorPosition(\n pagesContainerRef.current,\n pendingCursorRef.current\n );\n pendingCursorRef.current = null;\n }\n isRePaginatingRef.current = false;\n });\n } else {\n isRePaginatingRef.current = false;\n }\n\n return () => {\n observer.disconnect();\n activatedScripts.forEach((s) => s.remove());\n if (debounceTimer) clearTimeout(debounceTimer);\n };\n }, [pages, collectHTMLFromDOM]);\n\n // ----------------------------------------------------------\n // Render\n // ----------------------------------------------------------\n\n return (\n <div className=\"dopecanvas-paged-view\" style={scrollContainerStyle}>\n {/* Hidden measurement container */}\n <div ref={measureRef} aria-hidden=\"true\" />\n\n {/* Visible pages */}\n <div ref={pagesContainerRef} style={pagesWrapperStyle}>\n {css && <style dangerouslySetInnerHTML={{ __html: css }} />}\n {pages.map((pageData, pageIndex) => (\n <Page\n key={pageIndex}\n dimensions={dimensions}\n margins={pageConfig.margins}\n pageNumber={pageIndex + 1}\n totalPages={pages.length}\n >\n {pageData.blocks.map((blockHTML, blockIndex) => (\n <div\n key={`${pageIndex}-${blockIndex}`}\n className=\"dopecanvas-block-wrapper\"\n dangerouslySetInnerHTML={{ __html: blockHTML }}\n />\n ))}\n </Page>\n ))}\n\n {/* Show at least one empty page if no content */}\n {pages.length === 0 && (\n <Page\n dimensions={dimensions}\n margins={pageConfig.margins}\n pageNumber={1}\n totalPages={1}\n >\n <div\n contentEditable=\"true\"\n style={{ minHeight: '1em', outline: 'none' }}\n data-placeholder=\"Start typing...\"\n />\n </Page>\n )}\n </div>\n </div>\n );\n};\n\n// ----------------------------------------------------------\n// Styles\n// ----------------------------------------------------------\n\nconst scrollContainerStyle: React.CSSProperties = {\n flex: 1,\n overflow: 'auto',\n backgroundColor: '#e8e8e8',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n};\n\nconst pagesWrapperStyle: React.CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '24px',\n padding: '24px 0',\n};\n","// ============================================================\n// PageLayoutEngine — Pagination algorithm\n// ============================================================\n// Pure TypeScript class with no React dependency.\n// Takes a container of block elements, measures them, and\n// distributes them across fixed-size pages.\n// ============================================================\n\nimport type {\n PageConfig,\n PageDimensions,\n PageSizeName,\n PaginationResult,\n BlockMeasurement,\n} from './types';\nimport {\n PAGE_SIZE_PRESETS,\n DEFAULT_PAGE_CONFIG,\n} from './types';\n\nexport class PageLayoutEngine {\n private config: PageConfig;\n\n constructor(config: PageConfig = DEFAULT_PAGE_CONFIG) {\n this.config = { ...config };\n }\n\n // ----------------------------------------------------------\n // Config accessors\n // ----------------------------------------------------------\n\n getConfig(): PageConfig {\n return { ...this.config };\n }\n\n setConfig(config: Partial<PageConfig>): void {\n if (config.size !== undefined) {\n this.config.size = config.size;\n }\n if (config.margins !== undefined) {\n this.config.margins = { ...config.margins };\n }\n }\n\n /** Resolve page size name to pixel dimensions */\n getPageDimensions(): PageDimensions {\n if (typeof this.config.size === 'string') {\n return PAGE_SIZE_PRESETS[this.config.size as PageSizeName];\n }\n return this.config.size;\n }\n\n /** Usable content area height (page height minus top+bottom margins) */\n getContentAreaHeight(): number {\n const dims = this.getPageDimensions();\n return dims.height - this.config.margins.top - this.config.margins.bottom;\n }\n\n /** Usable content area width (page width minus left+right margins) */\n getContentAreaWidth(): number {\n const dims = this.getPageDimensions();\n return dims.width - this.config.margins.left - this.config.margins.right;\n }\n\n // ----------------------------------------------------------\n // Measurement\n // ----------------------------------------------------------\n\n /**\n * Measure all direct child block elements of the container.\n * The container should be styled to match the content area width\n * so that measurements reflect actual rendered heights.\n */\n measureBlocks(container: HTMLElement): BlockMeasurement[] {\n const children = Array.from(container.children) as HTMLElement[];\n const measurements: BlockMeasurement[] = [];\n\n for (let i = 0; i < children.length; i++) {\n const el = children[i];\n const style = window.getComputedStyle(el);\n\n // Check for CSS break-before / break-after\n const breakBefore =\n style.getPropertyValue('break-before') === 'page' ||\n style.getPropertyValue('page-break-before') === 'always';\n const breakAfter =\n style.getPropertyValue('break-after') === 'page' ||\n style.getPropertyValue('page-break-after') === 'always';\n\n // Use getBoundingClientRect for precise measurement including margins\n const rect = el.getBoundingClientRect();\n const marginTop = parseFloat(style.marginTop) || 0;\n const marginBottom = parseFloat(style.marginBottom) || 0;\n const totalHeight = rect.height + marginTop + marginBottom;\n\n measurements.push({\n index: i,\n height: totalHeight,\n element: el,\n breakBefore,\n breakAfter,\n });\n }\n\n return measurements;\n }\n\n // ----------------------------------------------------------\n // Pagination\n // ----------------------------------------------------------\n\n /**\n * Paginate: distribute measured blocks across pages.\n * \n * Algorithm:\n * 1. Walk blocks sequentially\n * 2. Accumulate height on current page\n * 3. When a block would overflow, start a new page\n * 4. Respect break-before / break-after CSS\n * 5. If a single block is taller than a page, give it its own page\n */\n paginate(measurements: BlockMeasurement[]): PaginationResult {\n if (measurements.length === 0) {\n return { pages: [{ blockIndices: [] }], pageCount: 1 };\n }\n\n const contentHeight = this.getContentAreaHeight();\n const pages: { blockIndices: number[] }[] = [];\n let currentPage: number[] = [];\n let currentHeight = 0;\n\n for (let i = 0; i < measurements.length; i++) {\n const block = measurements[i];\n\n // Force a new page if break-before is set (and current page has content)\n if (block.breakBefore && currentPage.length > 0) {\n pages.push({ blockIndices: currentPage });\n currentPage = [];\n currentHeight = 0;\n }\n\n // Check if adding this block would overflow the current page\n if (currentHeight + block.height > contentHeight && currentPage.length > 0) {\n // Current page is full — start a new one\n pages.push({ blockIndices: currentPage });\n currentPage = [];\n currentHeight = 0;\n }\n\n // Add block to current page\n currentPage.push(block.index);\n currentHeight += block.height;\n\n // Force a new page after this block if break-after is set\n if (block.breakAfter) {\n pages.push({ blockIndices: currentPage });\n currentPage = [];\n currentHeight = 0;\n }\n }\n\n // Push the last page if it has content\n if (currentPage.length > 0) {\n pages.push({ blockIndices: currentPage });\n }\n\n // Ensure at least one page\n if (pages.length === 0) {\n pages.push({ blockIndices: [] });\n }\n\n return {\n pages,\n pageCount: pages.length,\n };\n }\n}\n","// ============================================================\n// EditableManager — contentEditable integration\n// ============================================================\n// Manages making block elements editable, tracking changes\n// via MutationObserver, and providing undo/redo.\n// ============================================================\n\nimport type { UndoSnapshot, Unsubscribe, ToolbarContext } from './types';\n\nexport type ChangeCallback = () => void;\nexport type ContextChangeCallback = (context: ToolbarContext) => void;\n\nexport class EditableManager {\n private observer: MutationObserver | null = null;\n private changeCallbacks: Set<ChangeCallback> = new Set();\n private contextCallbacks: Set<ContextChangeCallback> = new Set();\n private undoStack: UndoSnapshot[] = [];\n private redoStack: UndoSnapshot[] = [];\n private container: HTMLElement | null = null;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private selectionHandler: (() => void) | null = null;\n private currentContext: ToolbarContext = 'none';\n\n private static readonly MAX_UNDO_STACK = 100;\n private static readonly DEBOUNCE_MS = 150;\n\n // ----------------------------------------------------------\n // Lifecycle\n // ----------------------------------------------------------\n\n /**\n * Attach to a container element. Sets up contentEditable on\n * all direct child blocks and starts observing changes.\n */\n attach(container: HTMLElement): void {\n this.detach(); // Clean up any previous attachment\n this.container = container;\n\n // Make all direct children editable\n this.makeChildrenEditable(container);\n\n // Take initial snapshot for undo\n this.pushUndoSnapshot();\n\n // Start observing mutations\n this.observer = new MutationObserver(this.handleMutations);\n this.observer.observe(container, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: ['style', 'class'],\n });\n\n // Listen for selection changes to detect context\n this.selectionHandler = this.handleSelectionChange.bind(this);\n document.addEventListener('selectionchange', this.selectionHandler);\n }\n\n /**\n * Detach from the container. Stop observing and clean up.\n */\n detach(): void {\n if (this.observer) {\n this.observer.disconnect();\n this.observer = null;\n }\n if (this.selectionHandler) {\n document.removeEventListener('selectionchange', this.selectionHandler);\n this.selectionHandler = null;\n }\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n this.container = null;\n }\n\n // ----------------------------------------------------------\n // Make elements editable\n // ----------------------------------------------------------\n\n /**\n * Set contentEditable on all direct children of the container.\n * Table cells get individual editability; other blocks are editable as wholes.\n */\n makeChildrenEditable(container: HTMLElement): void {\n const children = Array.from(container.children) as HTMLElement[];\n for (const child of children) {\n if (child.tagName === 'TABLE') {\n // For tables, make individual cells editable (not the table itself)\n this.makeTableCellsEditable(child);\n } else {\n child.contentEditable = 'true';\n }\n }\n }\n\n private makeTableCellsEditable(table: HTMLElement): void {\n const cells = table.querySelectorAll('td, th');\n cells.forEach((cell) => {\n (cell as HTMLElement).contentEditable = 'true';\n });\n }\n\n // ----------------------------------------------------------\n // Mutation handling\n // ----------------------------------------------------------\n\n private handleMutations = (_mutations: MutationRecord[]): void => {\n // Debounce to avoid excessive re-pagination\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n this.debounceTimer = setTimeout(() => {\n this.pushUndoSnapshot();\n this.notifyChange();\n }, EditableManager.DEBOUNCE_MS);\n };\n\n // ----------------------------------------------------------\n // Selection / context detection\n // ----------------------------------------------------------\n\n private handleSelectionChange(): void {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0 || !this.container) {\n this.setContext('none');\n return;\n }\n\n const range = selection.getRangeAt(0);\n const node = range.startContainer;\n\n // Walk up from the selection to find context\n let current: Node | null = node;\n while (current && current !== this.container) {\n if (current instanceof HTMLElement) {\n const tag = current.tagName;\n if (tag === 'TD' || tag === 'TH' || tag === 'TABLE') {\n this.setContext('table');\n return;\n }\n if (tag === 'IMG') {\n this.setContext('image');\n return;\n }\n if (current.dataset?.dopecanvasChart) {\n this.setContext('chart');\n return;\n }\n }\n current = current.parentNode;\n }\n\n // Default to text context if inside our container\n if (this.container.contains(node)) {\n this.setContext('text');\n } else {\n this.setContext('none');\n }\n }\n\n private setContext(ctx: ToolbarContext): void {\n if (ctx !== this.currentContext) {\n this.currentContext = ctx;\n this.contextCallbacks.forEach((cb) => cb(ctx));\n }\n }\n\n getContext(): ToolbarContext {\n return this.currentContext;\n }\n\n // ----------------------------------------------------------\n // Undo / Redo\n // ----------------------------------------------------------\n\n private pushUndoSnapshot(): void {\n if (!this.container) return;\n const html = this.container.innerHTML;\n const last = this.undoStack[this.undoStack.length - 1];\n // Don't push duplicates\n if (last && last.html === html) return;\n\n this.undoStack.push({ html, timestamp: Date.now() });\n // Clear redo stack on new change\n this.redoStack = [];\n // Limit stack size\n if (this.undoStack.length > EditableManager.MAX_UNDO_STACK) {\n this.undoStack.shift();\n }\n }\n\n undo(): boolean {\n if (!this.container || this.undoStack.length <= 1) return false;\n\n // Pop current state to redo stack\n const current = this.undoStack.pop()!;\n this.redoStack.push(current);\n\n // Restore previous state\n const previous = this.undoStack[this.undoStack.length - 1];\n this.pauseObserver(() => {\n this.container!.innerHTML = previous.html;\n this.makeChildrenEditable(this.container!);\n });\n this.notifyChange();\n return true;\n }\n\n redo(): boolean {\n if (!this.container || this.redoStack.length === 0) return false;\n\n const next = this.redoStack.pop()!;\n this.undoStack.push(next);\n\n this.pauseObserver(() => {\n this.container!.innerHTML = next.html;\n this.makeChildrenEditable(this.container!);\n });\n this.notifyChange();\n return true;\n }\n\n /** Temporarily disconnect observer to avoid feedback loops */\n private pauseObserver(fn: () => void): void {\n if (this.observer) {\n this.observer.disconnect();\n }\n fn();\n if (this.observer && this.container) {\n this.observer.observe(this.container, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: ['style', 'class'],\n });\n }\n }\n\n // ----------------------------------------------------------\n // Event callbacks\n // ----------------------------------------------------------\n\n onChange(callback: ChangeCallback): Unsubscribe {\n this.changeCallbacks.add(callback);\n return () => {\n this.changeCallbacks.delete(callback);\n };\n }\n\n onContextChange(callback: ContextChangeCallback): Unsubscribe {\n this.contextCallbacks.add(callback);\n return () => {\n this.contextCallbacks.delete(callback);\n };\n }\n\n private notifyChange(): void {\n this.changeCallbacks.forEach((cb) => cb());\n }\n\n // ----------------------------------------------------------\n // Formatting commands\n // ----------------------------------------------------------\n\n /**\n * Execute a formatting command on the current selection.\n * Uses document.execCommand for broad browser support.\n */\n execCommand(command: string, value?: string): boolean {\n return document.execCommand(command, false, value);\n }\n\n /** Check if a command is active for the current selection */\n queryCommandState(command: string): boolean {\n return document.queryCommandState(command);\n }\n\n /** Get the value of a command for the current selection */\n queryCommandValue(command: string): string {\n return document.queryCommandValue(command);\n }\n\n // ----------------------------------------------------------\n // Content access\n // ----------------------------------------------------------\n\n getHTML(): string {\n if (!this.container) return '';\n return this.container.innerHTML;\n }\n\n getPlainText(): string {\n if (!this.container) return '';\n return this.container.innerText || this.container.textContent || '';\n }\n}\n","// ============================================================\n// DopeCanvas — Main canvas component\n// ============================================================\n// The top-level React component that composes the paged view\n// and document engine together.\n//\n// The toolbar is NOT rendered by default. Instead, all toolbar\n// actions are exposed via a ref-based API (DopeCanvasHandle).\n// Consumers can build their own toolbar UI or use the provided\n// Toolbar components separately.\n//\n// CRITICAL DESIGN: Content edits from the user update a ref,\n// NOT state. This prevents React from re-rendering (and thus\n// destroying) the live editable DOM. Only page config changes\n// or external HTML loads trigger re-pagination.\n// ============================================================\n\nimport React, { useMemo, useCallback, useState, useRef, useEffect, useImperativeHandle, forwardRef } from 'react';\nimport { PagedView } from './PagedView';\nimport { PageLayoutEngine } from '../core/PageLayoutEngine';\nimport { EditableManager } from '../core/EditableManager';\nimport type {\n PageConfig,\n PaginationResult,\n} from '../core/types';\nimport { DEFAULT_PAGE_CONFIG } from '../core/types';\n\n// ----------------------------------------------------------\n// Public API handle exposed via ref\n// ----------------------------------------------------------\n\nexport interface DopeCanvasHandle {\n // Text formatting\n /** Execute a formatting command (e.g. 'bold', 'italic', 'fontSize') */\n execCommand: (command: string, value?: string) => boolean;\n /** Check if a command is active for the current selection */\n queryCommandState: (command: string) => boolean;\n /** Get the value of a command for the current selection */\n queryCommandValue: (command: string) => string;\n\n // Page configuration\n /** Get the current page configuration */\n getPageConfig: () => PageConfig;\n /** Update page configuration (size, margins). Triggers re-pagination. */\n setPageConfig: (config: Partial<PageConfig>) => void;\n /** Get the current number of pages */\n getPageCount: () => number;\n\n // Content access\n /** Get the current document HTML (reflects user edits) */\n getHTML: () => string;\n /** Get the document content as plain text */\n getPlainText: () => string;\n\n // Undo / Redo\n /** Undo the last edit. Returns false if nothing to undo. */\n undo: () => boolean;\n /** Redo the last undone edit. Returns false if nothing to redo. */\n redo: () => boolean;\n}\n\n// ----------------------------------------------------------\n// Component props\n// ----------------------------------------------------------\n\nexport interface DopeCanvasProps {\n /** Initial HTML content to load */\n html?: string;\n /** Optional CSS to inject alongside the HTML */\n css?: string;\n /** Page configuration */\n pageConfig?: PageConfig;\n /** Callback when content changes */\n onContentChange?: (html: string) => void;\n /** Callback when page config changes */\n onPageConfigChange?: (config: PageConfig) => void;\n /** Style overrides for the root container */\n style?: React.CSSProperties;\n}\n\nexport const DopeCanvas = forwardRef<DopeCanvasHandle, DopeCanvasProps>(({\n html = '',\n css,\n pageConfig: externalPageConfig,\n onContentChange,\n onPageConfigChange,\n style,\n}, ref) => {\n const [internalPageConfig, setInternalPageConfig] = useState<PageConfig>(\n externalPageConfig || DEFAULT_PAGE_CONFIG\n );\n const [paginationResult, setPaginationResult] = useState<PaginationResult>({\n pages: [],\n pageCount: 0,\n });\n // Store the latest HTML in a ref — edits update this without triggering re-render\n const currentHTMLRef = useRef(html);\n\n // Stable callback ref for onContentChange so PagedView doesn't re-render\n const onContentChangeRef = useRef(onContentChange);\n onContentChangeRef.current = onContentChange;\n\n // Use external config if provided, otherwise internal\n const pageConfig = externalPageConfig || internalPageConfig;\n\n // Create engine instances (stable across renders)\n const layoutEngine = useMemo(() => new PageLayoutEngine(pageConfig), []);\n const editableManager = useMemo(() => new EditableManager(), []);\n\n // Update layout engine when config changes\n useEffect(() => {\n layoutEngine.setConfig(pageConfig);\n }, [pageConfig, layoutEngine]);\n\n // Handle content changes from editing — update ref only, no state\n const handleContentChange = useCallback(\n (newHTML: string) => {\n currentHTMLRef.current = newHTML;\n onContentChangeRef.current?.(newHTML);\n },\n []\n );\n\n // Handle page config changes\n const handlePageConfigChange = useCallback(\n (newConfig: Partial<PageConfig>) => {\n const updated = {\n ...pageConfig,\n ...newConfig,\n margins: {\n ...pageConfig.margins,\n ...(newConfig.margins || {}),\n },\n };\n setInternalPageConfig(updated);\n layoutEngine.setConfig(updated);\n onPageConfigChange?.(updated);\n },\n [pageConfig, layoutEngine, onPageConfigChange]\n );\n\n // Handle pagination updates\n const handlePaginationChange = useCallback((result: PaginationResult) => {\n setPaginationResult(result);\n }, []);\n\n // ----------------------------------------------------------\n // Expose API via ref\n // ----------------------------------------------------------\n\n useImperativeHandle(ref, () => ({\n execCommand: (command: string, value?: string) => {\n return editableManager.execCommand(command, value);\n },\n queryCommandState: (command: string) => {\n return editableManager.queryCommandState(command);\n },\n queryCommandValue: (command: string) => {\n return editableManager.queryCommandValue(command);\n },\n getPageConfig: () => ({ ...pageConfig }),\n setPageConfig: (config: Partial<PageConfig>) => {\n handlePageConfigChange(config);\n },\n getPageCount: () => paginationResult.pageCount,\n getHTML: () => currentHTMLRef.current,\n getPlainText: () => {\n const tmp = document.createElement('div');\n tmp.innerHTML = currentHTMLRef.current;\n return tmp.innerText || tmp.textContent || '';\n },\n undo: () => editableManager.undo(),\n redo: () => editableManager.redo(),\n }), [editableManager, pageConfig, paginationResult.pageCount, handlePageConfigChange]);\n\n return (\n <div\n className=\"dopecanvas-root\"\n style={{\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n width: '100%',\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, sans-serif',\n ...style,\n }}\n >\n {/* Paged document view */}\n <PagedView\n html={html}\n css={css}\n pageConfig={pageConfig}\n layoutEngine={layoutEngine}\n editableManager={editableManager}\n onContentChange={handleContentChange}\n onPaginationChange={handlePaginationChange}\n />\n </div>\n );\n});\n","// ============================================================\n// DocumentEngine — Core orchestrator\n// ============================================================\n// Ties PageLayoutEngine and EditableManager together.\n// Manages the lifecycle: load → parse → paginate → edit → re-paginate\n// ============================================================\n\nimport { PageLayoutEngine } from './PageLayoutEngine';\nimport { EditableManager } from './EditableManager';\nimport type {\n PageConfig,\n PaginationResult,\n BlockMeasurement,\n Unsubscribe,\n} from './types';\nimport { DEFAULT_PAGE_CONFIG } from './types';\n\nexport class DocumentEngine {\n private layoutEngine: PageLayoutEngine;\n private editableManager: EditableManager;\n private sourceHTML: string = '';\n private sourceCSS: string = '';\n private measureContainer: HTMLElement | null = null;\n private contentContainer: HTMLElement | null = null;\n private paginationResult: PaginationResult = { pages: [], pageCount: 0 };\n private paginationCallbacks: Set<(result: PaginationResult) => void> = new Set();\n private changeCallbacks: Set<(html: string) => void> = new Set();\n\n constructor(config: PageConfig = DEFAULT_PAGE_CONFIG) {\n this.layoutEngine = new PageLayoutEngine(config);\n this.editableManager = new EditableManager();\n }\n\n // ----------------------------------------------------------\n // Accessors\n // ----------------------------------------------------------\n\n getLayoutEngine(): PageLayoutEngine {\n return this.layoutEngine;\n }\n\n getEditableManager(): EditableManager {\n return this.editableManager;\n }\n\n getPaginationResult(): PaginationResult {\n return this.paginationResult;\n }\n\n getSourceHTML(): string {\n return this.sourceHTML;\n }\n\n getPageConfig(): PageConfig {\n return this.layoutEngine.getConfig();\n }\n\n // ----------------------------------------------------------\n // Load HTML content\n // ----------------------------------------------------------\n\n /**\n * Load LLM-generated HTML (and optional CSS) into the engine.\n * This parses the HTML and prepares it for pagination.\n */\n loadHTML(html: string, css?: string): void {\n this.sourceHTML = html;\n this.sourceCSS = css || '';\n }\n\n // ----------------------------------------------------------\n // Attach to DOM containers\n // ----------------------------------------------------------\n\n /**\n * Set the measurement container — a hidden container styled\n * to match the content area width. Used for measuring block heights.\n */\n setMeasureContainer(el: HTMLElement): void {\n this.measureContainer = el;\n }\n\n /**\n * Set the content container — the visible container where\n * editable blocks live. The EditableManager attaches here.\n */\n setContentContainer(el: HTMLElement): void {\n if (this.contentContainer) {\n this.editableManager.detach();\n }\n this.contentContainer = el;\n }\n\n // ----------------------------------------------------------\n // Pagination cycle\n // ----------------------------------------------------------\n\n /**\n * Run the full pagination cycle:\n * 1. Inject HTML into measure container\n * 2. Inject CSS (via <style> tag)\n * 3. Measure all blocks\n * 4. Run pagination algorithm\n * 5. Return result for rendering\n */\n runPagination(): { result: PaginationResult; measurements: BlockMeasurement[] } {\n if (!this.measureContainer) {\n return {\n result: { pages: [{ blockIndices: [] }], pageCount: 1 },\n measurements: [],\n };\n }\n\n // Set up the measure container width to match content area\n const contentWidth = this.layoutEngine.getContentAreaWidth();\n this.measureContainer.style.width = `${contentWidth}px`;\n this.measureContainer.style.position = 'absolute';\n this.measureContainer.style.left = '-9999px';\n this.measureContainer.style.top = '0';\n this.measureContainer.style.visibility = 'hidden';\n\n // Inject CSS if provided\n let styleEl: HTMLStyleElement | null = null;\n if (this.sourceCSS) {\n styleEl = document.createElement('style');\n styleEl.textContent = this.sourceCSS;\n this.measureContainer.appendChild(styleEl);\n }\n\n // Inject HTML content\n const contentWrapper = document.createElement('div');\n contentWrapper.innerHTML = this.sourceHTML;\n this.measureContainer.appendChild(contentWrapper);\n\n // Measure blocks\n const measurements = this.layoutEngine.measureBlocks(contentWrapper);\n\n // Paginate\n this.paginationResult = this.layoutEngine.paginate(measurements);\n\n // Clean up measure container\n this.measureContainer.innerHTML = '';\n\n // Notify listeners\n this.paginationCallbacks.forEach((cb) => cb(this.paginationResult));\n\n return { result: this.paginationResult, measurements };\n }\n\n /**\n * Re-paginate using the current content container's live DOM.\n * Called after user edits.\n */\n rePaginate(): PaginationResult {\n if (!this.contentContainer) {\n return this.paginationResult;\n }\n\n // Measure from the live content\n const measurements = this.layoutEngine.measureBlocks(this.contentContainer);\n this.paginationResult = this.layoutEngine.paginate(measurements);\n\n // Notify\n this.paginationCallbacks.forEach((cb) => cb(this.paginationResult));\n return this.paginationResult;\n }\n\n // ----------------------------------------------------------\n // Attach editing\n // ----------------------------------------------------------\n\n /**\n * Attach the editable manager to the content container\n * and set up change listener for re-pagination.\n */\n attachEditing(container: HTMLElement): void {\n this.contentContainer = container;\n this.editableManager.attach(container);\n\n // Re-paginate on content change\n this.editableManager.onChange(() => {\n // Update source HTML from live DOM\n this.sourceHTML = container.innerHTML;\n this.changeCallbacks.forEach((cb) => cb(this.sourceHTML));\n });\n }\n\n // ----------------------------------------------------------\n // Page config\n // ----------------------------------------------------------\n\n setPageConfig(config: Partial<PageConfig>): void {\n this.layoutEngine.setConfig(config);\n }\n\n // ----------------------------------------------------------\n // Event listeners\n // ----------------------------------------------------------\n\n onPagination(callback: (result: PaginationResult) => void): Unsubscribe {\n this.paginationCallbacks.add(callback);\n return () => {\n this.paginationCallbacks.delete(callback);\n };\n }\n\n onChange(callback: (html: string) => void): Unsubscribe {\n this.changeCallbacks.add(callback);\n return () => {\n this.changeCallbacks.delete(callback);\n };\n }\n\n // ----------------------------------------------------------\n // Content access\n // ----------------------------------------------------------\n\n getHTML(): string {\n if (this.contentContainer) {\n return this.contentContainer.innerHTML;\n }\n return this.sourceHTML;\n }\n\n getPlainText(): string {\n if (this.contentContainer) {\n return this.contentContainer.innerText || this.contentContainer.textContent || '';\n }\n return '';\n }\n\n // ----------------------------------------------------------\n // Cleanup\n // ----------------------------------------------------------\n\n destroy(): void {\n this.editableManager.detach();\n this.paginationCallbacks.clear();\n this.changeCallbacks.clear();\n this.measureContainer = null;\n this.contentContainer = null;\n }\n}\n","// ============================================================\n// DocumentAPI — External programmatic interface\n// ============================================================\n// This class provides a clean API for external systems\n// (LLMs, database sync, parent applications) to interact\n// with a DopeCanvas document.\n// ============================================================\n\nimport type { PageConfig, PaginationResult, Unsubscribe } from '../core/types';\n\n/**\n * DocumentAPI provides a programmatic interface to the DopeCanvas\n * document. It wraps the internal state management and exposes\n * methods for loading, reading, and modifying document content.\n *\n * Usage:\n * const api = new DocumentAPI();\n * // Connect to a DopeCanvas instance (done internally by DopeCanvas component)\n * api.loadHTML('<h1>Hello</h1><p>World</p>');\n * api.onChange((html) => console.log('Content changed:', html));\n */\nexport class DocumentAPI {\n private _html: string = '';\n private _css: string = '';\n private _pageConfig: PageConfig | null = null;\n private _paginationResult: PaginationResult = { pages: [], pageCount: 0 };\n\n // Callbacks\n private _changeCallbacks: Set<(html: string) => void> = new Set();\n private _loadCallbacks: Set<(html: string, css?: string) => void> = new Set();\n private _pageConfigCallbacks: Set<(config: PageConfig) => void> = new Set();\n\n // Connector functions set by DopeCanvas component\n private _getHTMLFn: (() => string) | null = null;\n private _getPlainTextFn: (() => string) | null = null;\n\n // ----------------------------------------------------------\n // Content loading\n // ----------------------------------------------------------\n\n /**\n * Load HTML content into the canvas.\n * Optionally provide CSS to inject alongside.\n */\n loadHTML(html: string, css?: string): void {\n this._html = html;\n this._css = css || '';\n this._loadCallbacks.forEach((cb) => cb(html, css));\n }\n\n /**\n * Get the current document HTML content.\n * Reflects any user edits.\n */\n getHTML(): string {\n if (this._getHTMLFn) {\n return this._getHTMLFn();\n }\n return this._html;\n }\n\n /**\n * Get the document content as plain text.\n */\n getPlainText(): string {\n if (this._getPlainTextFn) {\n return this._getPlainTextFn();\n }\n // Fallback: strip HTML tags\n const tmp = document.createElement('div');\n tmp.innerHTML = this._html;\n return tmp.innerText || tmp.textContent || '';\n }\n\n // ----------------------------------------------------------\n // Event listeners\n // ----------------------------------------------------------\n\n /**\n * Listen for content changes (triggered by user edits).\n * Returns an unsubscribe function.\n */\n onChange(callback: (html: string) => void): Unsubscribe {\n this._changeCallbacks.add(callback);\n return () => {\n this._changeCallbacks.delete(callback);\n };\n }\n\n /**\n * Listen for load events (when loadHTML is called).\n */\n onLoad(callback: (html: string, css?: string) => void): Unsubscribe {\n this._loadCallbacks.add(callback);\n return () => {\n this._loadCallbacks.delete(callback);\n };\n }\n\n /**\n * Listen for page config changes.\n */\n onPageConfigChange(callback: (config: PageConfig) => void): Unsubscribe {\n this._pageConfigCallbacks.add(callback);\n return () => {\n this._pageConfigCallbacks.delete(callback);\n };\n }\n\n // ----------------------------------------------------------\n // Page operations\n // ----------------------------------------------------------\n\n /**\n * Get the current number of pages.\n */\n getPageCount(): number {\n return this._paginationResult.pageCount;\n }\n\n /**\n * Get the current page configuration.\n */\n getPageConfig(): PageConfig | null {\n return this._pageConfig;\n }\n\n /**\n * Set page configuration (size, margins).\n * Triggers re-pagination.\n */\n setPageConfig(config: Partial<PageConfig>): void {\n if (this._pageConfig) {\n this._pageConfig = {\n ...this._pageConfig,\n ...config,\n margins: {\n ...this._pageConfig.margins,\n ...(config.margins || {}),\n },\n };\n this._pageConfigCallbacks.forEach((cb) => cb(this._pageConfig!));\n }\n }\n\n // ----------------------------------------------------------\n // Element access (for future DB sync)\n // ----------------------------------------------------------\n\n /**\n * Query elements within the document by CSS selector.\n * Useful for targeting specific sections for database sync.\n */\n querySelectorAll(selector: string): Element[] {\n const tmp = document.createElement('div');\n tmp.innerHTML = this.getHTML();\n return Array.from(tmp.querySelectorAll(selector));\n }\n\n /**\n * Get the innerHTML of a specific element by its ID.\n */\n getElementContent(id: string): string | null {\n const tmp = document.createElement('div');\n tmp.innerHTML = this.getHTML();\n const el = tmp.querySelector(`#${id}`);\n return el ? el.innerHTML : null;\n }\n\n /**\n * Set the innerHTML of a specific element by its ID.\n * Re-loads the full document with the modification.\n */\n setElementContent(id: string, html: string): void {\n const tmp = document.createElement('div');\n tmp.innerHTML = this.getHTML();\n const el = tmp.querySelector(`#${id}`);\n if (el) {\n el.innerHTML = html;\n this.loadHTML(tmp.innerHTML, this._css);\n }\n }\n\n // ----------------------------------------------------------\n // Internal connectors (used by DopeCanvas component)\n // ----------------------------------------------------------\n\n /** @internal Called by DopeCanvas to wire up live content access */\n _connectGetHTML(fn: () => string): void {\n this._getHTMLFn = fn;\n }\n\n /** @internal Called by DopeCanvas to wire up plain text access */\n _connectGetPlainText(fn: () => string): void {\n this._getPlainTextFn = fn;\n }\n\n /** @internal Called by DopeCanvas when content changes */\n _notifyChange(html: string): void {\n this._html = html;\n this._changeCallbacks.forEach((cb) => cb(html));\n }\n\n /** @internal Called by DopeCanvas when pagination runs */\n _updatePagination(result: PaginationResult): void {\n this._paginationResult = result;\n }\n\n /** @internal Called by DopeCanvas when page config changes */\n _updatePageConfig(config: PageConfig): void {\n this._pageConfig = config;\n }\n}\n","// ============================================================\n// useSelectionContext — Track what element type is selected\n// ============================================================\n\nimport { useState, useEffect, useCallback } from 'react';\nimport type { ToolbarContext } from '../core/types';\nimport type { EditableManager } from '../core/EditableManager';\n\nexport function useSelectionContext(\n editableManager: EditableManager | null\n): ToolbarContext {\n const [context, setContext] = useState<ToolbarContext>('none');\n\n useEffect(() => {\n if (!editableManager) return;\n\n const unsub = editableManager.onContextChange((ctx) => {\n setContext(ctx);\n });\n\n return unsub;\n }, [editableManager]);\n\n return context;\n}\n\n/**\n * Hook to query the current formatting state (bold, italic, etc.)\n * from the browser's selection.\n */\nexport function useFormattingState() {\n const [state, setState] = useState({\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n justifyLeft: false,\n justifyCenter: false,\n justifyRight: false,\n justifyFull: false,\n });\n\n const updateState = useCallback(() => {\n setState({\n bold: document.queryCommandState('bold'),\n italic: document.queryCommandState('italic'),\n underline: document.queryCommandState('underline'),\n strikethrough: document.queryCommandState('strikethrough'),\n justifyLeft: document.queryCommandState('justifyLeft'),\n justifyCenter: document.queryCommandState('justifyCenter'),\n justifyRight: document.queryCommandState('justifyRight'),\n justifyFull: document.queryCommandState('justifyFull'),\n });\n }, []);\n\n useEffect(() => {\n document.addEventListener('selectionchange', updateState);\n return () => {\n document.removeEventListener('selectionchange', updateState);\n };\n }, [updateState]);\n\n return state;\n}\n","// ============================================================\n// TextToolbar — Text formatting tools\n// ============================================================\n\nimport React, { useCallback, useRef } from 'react';\nimport { useFormattingState } from '../../hooks/useSelectionContext';\n\ninterface TextToolbarProps {\n onExecCommand: (command: string, value?: string) => void;\n}\n\nexport const TextToolbar: React.FC<TextToolbarProps> = ({ onExecCommand }) => {\n const formatState = useFormattingState();\n\n // ----------------------------------------------------------\n // Selection save / restore\n // ----------------------------------------------------------\n // Toolbar controls (selects, color pickers) steal focus from\n // the contentEditable area, clearing the browser selection.\n // We save the range on mouseDown (before focus moves) and\n // restore it before executing the formatting command.\n // ----------------------------------------------------------\n\n const savedRangeRef = useRef<Range | null>(null);\n\n const saveSelection = useCallback(() => {\n const sel = window.getSelection();\n if (sel && sel.rangeCount > 0) {\n savedRangeRef.current = sel.getRangeAt(0).cloneRange();\n }\n }, []);\n\n const restoreSelection = useCallback(() => {\n const range = savedRangeRef.current;\n if (!range) return;\n const sel = window.getSelection();\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(range);\n }\n }, []);\n\n const handleCommand = useCallback(\n (command: string, value?: string) => (e: React.MouseEvent) => {\n e.preventDefault(); // Don't steal focus from content\n onExecCommand(command, value);\n },\n [onExecCommand]\n );\n\n const handleFontSize = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n restoreSelection();\n onExecCommand('fontSize', e.target.value);\n },\n [onExecCommand, restoreSelection]\n );\n\n const handleHeading = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n restoreSelection();\n const value = e.target.value;\n if (value === 'p') {\n onExecCommand('formatBlock', 'p');\n } else {\n onExecCommand('formatBlock', value);\n }\n },\n [onExecCommand, restoreSelection]\n );\n\n const handleForeColor = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n restoreSelection();\n onExecCommand('foreColor', e.target.value);\n },\n [onExecCommand, restoreSelection]\n );\n\n const handleBackColor = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n restoreSelection();\n onExecCommand('hiliteColor', e.target.value);\n },\n [onExecCommand, restoreSelection]\n );\n\n return (\n <div style={toolbarSectionStyle}>\n {/* Block format */}\n <select\n onChange={handleHeading}\n defaultValue=\"p\"\n style={selectStyle}\n title=\"Block Format\"\n onMouseDown={saveSelection}\n >\n <option value=\"p\">Paragraph</option>\n <option value=\"h1\">Heading 1</option>\n <option value=\"h2\">Heading 2</option>\n <option value=\"h3\">Heading 3</option>\n <option value=\"h4\">Heading 4</option>\n <option value=\"h5\">Heading 5</option>\n <option value=\"h6\">Heading 6</option>\n </select>\n\n <div style={dividerStyle} />\n\n {/* Font size */}\n <select\n onChange={handleFontSize}\n defaultValue=\"3\"\n style={selectStyle}\n title=\"Font Size\"\n onMouseDown={saveSelection}\n >\n <option value=\"1\">8pt</option>\n <option value=\"2\">10pt</option>\n <option value=\"3\">12pt</option>\n <option value=\"4\">14pt</option>\n <option value=\"5\">18pt</option>\n <option value=\"6\">24pt</option>\n <option value=\"7\">36pt</option>\n </select>\n\n <div style={dividerStyle} />\n\n {/* Inline formatting */}\n <ToolbarButton\n icon=\"B\"\n title=\"Bold (Ctrl+B)\"\n active={formatState.bold}\n onMouseDown={handleCommand('bold')}\n extraStyle={{ fontWeight: 'bold' }}\n />\n <ToolbarButton\n icon=\"I\"\n title=\"Italic (Ctrl+I)\"\n active={formatState.italic}\n onMouseDown={handleCommand('italic')}\n extraStyle={{ fontStyle: 'italic' }}\n />\n\n <div style={dividerStyle} />\n\n {/* Colors */}\n <label style={colorLabelStyle} title=\"Text Color\" onMouseDown={saveSelection}>\n A\n <input\n type=\"color\"\n defaultValue=\"#000000\"\n onChange={handleForeColor}\n style={colorInputStyle}\n />\n </label>\n <label style={colorLabelStyle} title=\"Highlight Color\" onMouseDown={saveSelection}>\n <span style={{ backgroundColor: '#ffff00', padding: '0 2px' }}>A</span>\n <input\n type=\"color\"\n defaultValue=\"#ffff00\"\n onChange={handleBackColor}\n style={colorInputStyle}\n />\n </label>\n </div>\n );\n};\n\n// ----------------------------------------------------------\n// ToolbarButton sub-component\n// ----------------------------------------------------------\n\ninterface ToolbarButtonProps {\n icon: string;\n title: string;\n active?: boolean;\n onMouseDown: (e: React.MouseEvent) => void;\n extraStyle?: React.CSSProperties;\n}\n\nconst ToolbarButton: React.FC<ToolbarButtonProps> = ({\n icon,\n title,\n active,\n onMouseDown,\n extraStyle,\n}) => {\n return (\n <button\n type=\"button\"\n title={title}\n onMouseDown={onMouseDown}\n style={{\n width: '28px',\n height: '28px',\n borderWidth: '1px',\n borderStyle: 'solid',\n borderColor: active ? '#b0b5bd' : 'transparent',\n borderRadius: '3px',\n backgroundColor: active ? '#d0d5dd' : 'transparent',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '13px',\n color: '#333',\n padding: 0,\n fontFamily: 'inherit',\n ...extraStyle,\n }}\n dangerouslySetInnerHTML={{ __html: icon }}\n />\n );\n};\n\n// ----------------------------------------------------------\n// Styles\n// ----------------------------------------------------------\n\nconst toolbarSectionStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '2px',\n flexWrap: 'wrap',\n};\n\nconst selectStyle: React.CSSProperties = {\n height: '28px',\n borderWidth: '1px',\n borderStyle: 'solid',\n borderColor: '#ccc',\n borderRadius: '3px',\n fontSize: '12px',\n padding: '0 4px',\n cursor: 'pointer',\n backgroundColor: '#fff',\n};\n\nconst dividerStyle: React.CSSProperties = {\n width: '1px',\n height: '20px',\n backgroundColor: '#ddd',\n margin: '0 4px',\n};\n\nconst colorLabelStyle: React.CSSProperties = {\n position: 'relative',\n width: '28px',\n height: '28px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n fontSize: '13px',\n fontWeight: 'bold',\n};\n\nconst colorInputStyle: React.CSSProperties = {\n position: 'absolute',\n bottom: 0,\n left: 0,\n width: '100%',\n height: '4px',\n padding: 0,\n borderWidth: 0,\n borderStyle: 'none',\n cursor: 'pointer',\n};\n","// ============================================================\n// PageSetupToolbar — Page size and margin controls\n// ============================================================\n\nimport React, { useCallback } from 'react';\nimport type { PageConfig, PageSizeName } from '../../core/types';\n\ninterface PageSetupToolbarProps {\n pageConfig: PageConfig;\n pageCount: number;\n onPageConfigChange: (config: Partial<PageConfig>) => void;\n}\n\nexport const PageSetupToolbar: React.FC<PageSetupToolbarProps> = ({\n pageConfig,\n pageCount,\n onPageConfigChange,\n}) => {\n const handleSizeChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n const value = e.target.value as PageSizeName;\n onPageConfigChange({ size: value });\n },\n [onPageConfigChange]\n );\n\n const handleMarginChange = useCallback(\n (side: keyof typeof pageConfig.margins) =>\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = Math.max(0, parseInt(e.target.value) || 0);\n onPageConfigChange({\n margins: {\n ...pageConfig.margins,\n [side]: value,\n },\n });\n },\n [pageConfig.margins, onPageConfigChange]\n );\n\n const currentSize =\n typeof pageConfig.size === 'string' ? pageConfig.size : 'custom';\n\n return (\n <div style={sectionStyle}>\n {/* Page size */}\n <label style={labelStyle}>\n Page:\n <select\n value={currentSize}\n onChange={handleSizeChange}\n style={selectStyle}\n >\n <option value=\"letter\">Letter (8.5 x 11)</option>\n <option value=\"a4\">A4 (210 x 297mm)</option>\n <option value=\"legal\">Legal (8.5 x 14)</option>\n </select>\n </label>\n\n <div style={dividerStyle} />\n\n {/* Margins */}\n <span style={{ fontSize: '12px', color: '#666' }}>Margins (px):</span>\n <MarginInput\n label=\"T\"\n value={pageConfig.margins.top}\n onChange={handleMarginChange('top')}\n />\n <MarginInput\n label=\"R\"\n value={pageConfig.margins.right}\n onChange={handleMarginChange('right')}\n />\n <MarginInput\n label=\"B\"\n value={pageConfig.margins.bottom}\n onChange={handleMarginChange('bottom')}\n />\n <MarginInput\n label=\"L\"\n value={pageConfig.margins.left}\n onChange={handleMarginChange('left')}\n />\n\n <div style={dividerStyle} />\n\n {/* Page count */}\n <span style={{ fontSize: '12px', color: '#666' }}>\n {pageCount} {pageCount === 1 ? 'page' : 'pages'}\n </span>\n </div>\n );\n};\n\n// ----------------------------------------------------------\n// MarginInput sub-component\n// ----------------------------------------------------------\n\ninterface MarginInputProps {\n label: string;\n value: number;\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\nconst MarginInput: React.FC<MarginInputProps> = ({ label, value, onChange }) => (\n <label style={marginLabelStyle} title={`${label} margin`}>\n {label}:\n <input\n type=\"number\"\n value={value}\n onChange={onChange}\n style={marginInputStyle}\n min={0}\n max={300}\n step={12}\n />\n </label>\n);\n\n// ----------------------------------------------------------\n// Styles\n// ----------------------------------------------------------\n\nconst sectionStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n flexWrap: 'wrap',\n};\n\nconst labelStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n fontSize: '12px',\n color: '#666',\n};\n\nconst selectStyle: React.CSSProperties = {\n height: '26px',\n borderWidth: '1px',\n borderStyle: 'solid',\n borderColor: '#ccc',\n borderRadius: '3px',\n fontSize: '12px',\n padding: '0 4px',\n cursor: 'pointer',\n backgroundColor: '#fff',\n};\n\nconst dividerStyle: React.CSSProperties = {\n width: '1px',\n height: '20px',\n backgroundColor: '#ddd',\n margin: '0 4px',\n};\n\nconst marginLabelStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '2px',\n fontSize: '11px',\n color: '#666',\n};\n\nconst marginInputStyle: React.CSSProperties = {\n width: '44px',\n height: '24px',\n borderWidth: '1px',\n borderStyle: 'solid',\n borderColor: '#ccc',\n borderRadius: '3px',\n fontSize: '11px',\n textAlign: 'center',\n padding: '0 2px',\n};\n","// ============================================================\n// Toolbar — Main toolbar container with context switching\n// ============================================================\n\nimport React from 'react';\nimport { TextToolbar } from './TextToolbar';\nimport { PageSetupToolbar } from './PageSetupToolbar';\nimport type { PageConfig } from '../../core/types';\n\ninterface ToolbarProps {\n pageConfig: PageConfig;\n pageCount: number;\n onExecCommand: (command: string, value?: string) => void;\n onPageConfigChange: (config: Partial<PageConfig>) => void;\n}\n\nexport const Toolbar: React.FC<ToolbarProps> = ({\n pageConfig,\n pageCount,\n onExecCommand,\n onPageConfigChange,\n}) => {\n return (\n <div style={toolbarContainerStyle}>\n {/* Top row: Text formatting */}\n <div style={toolbarRowStyle}>\n <TextToolbar onExecCommand={onExecCommand} />\n </div>\n\n {/* Bottom row: Page setup */}\n <div style={toolbarRowStyle}>\n <PageSetupToolbar\n pageConfig={pageConfig}\n pageCount={pageCount}\n onPageConfigChange={onPageConfigChange}\n />\n </div>\n </div>\n );\n};\n\n// ----------------------------------------------------------\n// Styles\n// ----------------------------------------------------------\n\nconst toolbarContainerStyle: React.CSSProperties = {\n borderBottomWidth: '1px',\n borderBottomStyle: 'solid',\n borderBottomColor: '#d0d0d0',\n backgroundColor: '#f8f8f8',\n padding: '4px 8px',\n display: 'flex',\n flexDirection: 'column',\n gap: '4px',\n flexShrink: 0,\n zIndex: 10,\n};\n\nconst toolbarRowStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n minHeight: '32px',\n};\n","// ============================================================\n// useDocumentEngine — React hook wrapping DocumentEngine\n// ============================================================\n\nimport { useRef, useState, useCallback, useEffect } from 'react';\nimport { DocumentEngine } from '../core/DocumentEngine';\nimport type { PageConfig, PaginationResult } from '../core/types';\nimport { DEFAULT_PAGE_CONFIG } from '../core/types';\n\ninterface UseDocumentEngineOptions {\n initialHTML?: string;\n initialCSS?: string;\n initialConfig?: PageConfig;\n}\n\ninterface UseDocumentEngineReturn {\n engine: DocumentEngine;\n paginationResult: PaginationResult;\n pageConfig: PageConfig;\n loadHTML: (html: string, css?: string) => void;\n setPageConfig: (config: Partial<PageConfig>) => void;\n triggerPagination: () => void;\n getHTML: () => string;\n getPlainText: () => string;\n}\n\nexport function useDocumentEngine(\n options: UseDocumentEngineOptions = {}\n): UseDocumentEngineReturn {\n const {\n initialHTML = '',\n initialCSS = '',\n initialConfig = DEFAULT_PAGE_CONFIG,\n } = options;\n\n const engineRef = useRef<DocumentEngine>(new DocumentEngine(initialConfig));\n const [paginationResult, setPaginationResult] = useState<PaginationResult>({\n pages: [{ blockIndices: [] }],\n pageCount: 1,\n });\n const [pageConfig, setPageConfigState] = useState<PageConfig>(initialConfig);\n\n // Load HTML into engine\n const loadHTML = useCallback((html: string, css?: string) => {\n engineRef.current.loadHTML(html, css);\n }, []);\n\n // Set page configuration\n const setPageConfig = useCallback((config: Partial<PageConfig>) => {\n engineRef.current.setPageConfig(config);\n setPageConfigState(engineRef.current.getPageConfig());\n }, []);\n\n // Trigger re-pagination\n const triggerPagination = useCallback(() => {\n const { result } = engineRef.current.runPagination();\n setPaginationResult(result);\n }, []);\n\n // Get current HTML content\n const getHTML = useCallback(() => {\n return engineRef.current.getHTML();\n }, []);\n\n // Get plain text\n const getPlainText = useCallback(() => {\n return engineRef.current.getPlainText();\n }, []);\n\n // Load initial HTML\n useEffect(() => {\n if (initialHTML) {\n engineRef.current.loadHTML(initialHTML, initialCSS);\n }\n }, [initialHTML, initialCSS]);\n\n // Subscribe to pagination events\n useEffect(() => {\n const unsub = engineRef.current.onPagination((result) => {\n setPaginationResult(result);\n });\n return unsub;\n }, []);\n\n // Cleanup\n useEffect(() => {\n return () => {\n engineRef.current.destroy();\n };\n }, []);\n\n return {\n engine: engineRef.current,\n paginationResult,\n pageConfig,\n loadHTML,\n setPageConfig,\n triggerPagination,\n getHTML,\n getPlainText,\n };\n}\n"],"names":["Page","dimensions","margins","pageNumber","totalPages","children","jsxs","jsx","PAGE_SIZE_PRESETS","DEFAULT_MARGINS","DEFAULT_PAGE_CONFIG","activateScripts","container","activated","orig","fresh","attr","saveCursorPosition","sel","range","anchorNode","wrappers","blockIndex","w","preRange","textOffset","restoreCursorPosition","state","wrapper","walker","remaining","textNode","PagedView","html","css","pageConfig","layoutEngine","_editableManager","onContentChange","onPaginationChange","measureRef","useRef","pagesContainerRef","mutationObserverRef","onContentChangeRef","pages","setPages","useState","pendingCursorRef","isRePaginatingRef","pagesRef","collectHTMLFromDOM","useCallback","htmlParts","content","updatedHTML","rePaginateFromDOM","cursor","blockHTMLs","mc","contentWidth","styleEl","measureWrapper","measurements","measuredHTMLs","m","result","newPages","p","idx","oldDist","newDist","count","i","rePaginateFromDOMRef","runPagination","measureContainer","parsed","el","contentHTML","pageData","page","useEffect","child","cell","activatedScripts","debounceTimer","observer","s","scrollContainerStyle","pagesWrapperStyle","pageIndex","blockHTML","PageLayoutEngine","config","style","breakBefore","breakAfter","rect","marginTop","marginBottom","totalHeight","contentHeight","currentPage","currentHeight","block","EditableManager","table","_mutations","selection","node","current","tag","ctx","cb","last","previous","next","fn","callback","command","value","DopeCanvas","forwardRef","externalPageConfig","onPageConfigChange","ref","internalPageConfig","setInternalPageConfig","paginationResult","setPaginationResult","currentHTMLRef","useMemo","editableManager","handleContentChange","newHTML","handlePageConfigChange","newConfig","updated","handlePaginationChange","useImperativeHandle","tmp","DocumentEngine","contentWrapper","DocumentAPI","selector","id","useSelectionContext","context","setContext","useFormattingState","setState","updateState","TextToolbar","onExecCommand","formatState","savedRangeRef","saveSelection","restoreSelection","handleCommand","e","handleFontSize","handleHeading","handleForeColor","handleBackColor","toolbarSectionStyle","selectStyle","dividerStyle","ToolbarButton","colorLabelStyle","colorInputStyle","icon","title","active","onMouseDown","extraStyle","PageSetupToolbar","pageCount","handleSizeChange","handleMarginChange","side","currentSize","sectionStyle","labelStyle","MarginInput","label","onChange","marginLabelStyle","marginInputStyle","Toolbar","toolbarContainerStyle","toolbarRowStyle","useDocumentEngine","options","initialHTML","initialCSS","initialConfig","engineRef","setPageConfigState","loadHTML","setPageConfig","triggerPagination","getHTML","getPlainText"],"mappings":"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"}
1
+ {"version":3,"file":"dopecanvas.js","sources":["../src/components/Page.tsx","../src/components/BlockToolbar.tsx","../src/components/HTMLEditorModal.tsx","../src/core/types.ts","../src/components/PagedView.tsx","../src/core/PageLayoutEngine.ts","../src/core/EditableManager.ts","../src/components/DopeCanvas.tsx","../src/core/DocumentEngine.ts","../src/api/DocumentAPI.ts","../src/hooks/useSelectionContext.ts","../src/components/Toolbar/TextToolbar.tsx","../src/components/Toolbar/PageSetupToolbar.tsx","../src/components/Toolbar/Toolbar.tsx","../src/hooks/useDocumentEngine.ts"],"sourcesContent":["// ============================================================\n// Page — Single page frame component\n// ============================================================\n// Renders a fixed-size white page with margins and page number.\n// ============================================================\n\nimport React from 'react';\nimport type { PageDimensions, PageMargins } from '../core/types';\n\ninterface PageProps {\n /** Page dimensions in pixels */\n dimensions: PageDimensions;\n /** Page margins in pixels */\n margins: PageMargins;\n /** Page number (1-indexed) */\n pageNumber: number;\n /** Total number of pages */\n totalPages: number;\n /** The content blocks to render inside the page */\n children: React.ReactNode;\n}\n\nexport const Page: React.FC<PageProps> = ({\n dimensions,\n margins,\n pageNumber,\n totalPages,\n children,\n}) => {\n return (\n <div\n className=\"dopecanvas-page\"\n style={{\n width: `${dimensions.width}px`,\n height: `${dimensions.height}px`,\n backgroundColor: '#ffffff',\n boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15), 0 0 1px rgba(0, 0, 0, 0.1)',\n position: 'relative',\n overflow: 'hidden',\n flexShrink: 0,\n }}\n >\n {/* Content area with margins */}\n <div\n className=\"dopecanvas-page-content\"\n style={{\n paddingTop: `${margins.top}px`,\n paddingRight: `${margins.right}px`,\n paddingBottom: `${margins.bottom}px`,\n paddingLeft: `${margins.left}px`,\n height: '100%',\n boxSizing: 'border-box',\n overflow: 'hidden',\n }}\n >\n {children}\n </div>\n\n {/* Page number footer */}\n <div\n className=\"dopecanvas-page-number\"\n style={{\n position: 'absolute',\n bottom: `${Math.max(margins.bottom / 3, 16)}px`,\n left: 0,\n right: 0,\n textAlign: 'center',\n fontSize: '11px',\n color: '#999',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n pointerEvents: 'none',\n userSelect: 'none',\n }}\n >\n {pageNumber} / {totalPages}\n </div>\n </div>\n );\n};\n","// ============================================================\n// BlockToolbar — Hover controls for individual content blocks\n// ============================================================\n// Shows add / edit-HTML / delete actions when a block is hovered.\n// Positioned absolutely in the left margin of the block.\n// ============================================================\n\nimport React, { useState } from 'react';\n\ninterface BlockToolbarProps {\n /** Whether the toolbar is currently visible */\n visible: boolean;\n /** Add a new empty block below this one */\n onAddBelow: () => void;\n /** Open the HTML source editor for this block */\n onEditHTML: () => void;\n /** Delete this block */\n onDelete: () => void;\n}\n\nexport const BlockToolbar: React.FC<BlockToolbarProps> = ({\n visible,\n onAddBelow,\n onEditHTML,\n onDelete,\n}) => (\n <div\n className=\"dopecanvas-block-toolbar\"\n style={{\n ...toolbarStyle,\n display: visible ? 'flex' : 'none',\n }}\n onMouseDown={(e) => e.preventDefault()}\n >\n <Btn onClick={onAddBelow} title=\"Add block below\">\n <PlusIcon />\n </Btn>\n <Btn onClick={onEditHTML} title=\"Edit HTML\">\n <CodeIcon />\n </Btn>\n <Btn onClick={onDelete} title=\"Delete block\" danger>\n <TrashIcon />\n </Btn>\n </div>\n);\n\n// ----------------------------------------------------------\n// Tiny SVG icons (no external dependencies)\n// ----------------------------------------------------------\n\nconst PlusIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\">\n <line x1=\"7\" y1=\"3\" x2=\"7\" y2=\"11\" />\n <line x1=\"3\" y1=\"7\" x2=\"11\" y2=\"7\" />\n </svg>\n);\n\nconst CodeIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"4.5,3 1.5,7 4.5,11\" />\n <polyline points=\"9.5,3 12.5,7 9.5,11\" />\n </svg>\n);\n\nconst TrashIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M2.5 4h9M5 4V2.5h4V4M3.5 4l.5 8h6l.5-8\" />\n </svg>\n);\n\n// ----------------------------------------------------------\n// Button sub-component with hover effect\n// ----------------------------------------------------------\n\nconst Btn: React.FC<{\n onClick: () => void;\n title: string;\n children: React.ReactNode;\n danger?: boolean;\n}> = ({ onClick, title, children, danger }) => {\n const [hovered, setHovered] = useState(false);\n return (\n <button\n onClick={onClick}\n title={title}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n ...btnStyle,\n background: hovered\n ? danger\n ? '#fff0f0'\n : '#f0f0f0'\n : 'transparent',\n color: hovered && danger ? '#d32f2f' : '#666',\n }}\n >\n {children}\n </button>\n );\n};\n\n// ----------------------------------------------------------\n// Styles\n// ----------------------------------------------------------\n\nconst toolbarStyle: React.CSSProperties = {\n position: 'absolute',\n top: 0,\n left: -40,\n flexDirection: 'column',\n gap: '1px',\n zIndex: 100,\n background: '#fff',\n borderRadius: '6px',\n boxShadow: '0 1px 5px rgba(0,0,0,0.12)',\n padding: '3px',\n paddingRight: '6px',\n};\n\nconst btnStyle: React.CSSProperties = {\n width: '30px',\n height: '26px',\n border: 'none',\n cursor: 'pointer',\n borderRadius: '4px',\n fontSize: '13px',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 0,\n transition: 'background 0.1s, color 0.1s',\n};\n","// ============================================================\n// HTMLEditorModal — Raw HTML editor for a single block\n// ============================================================\n// Full-screen modal with a code-editor-style textarea.\n// Rendered as a React Portal to document.body.\n// ============================================================\n\nimport React, { useState } from 'react';\nimport { createPortal } from 'react-dom';\n\ninterface HTMLEditorModalProps {\n /** The current HTML of the block being edited */\n html: string;\n /** Called with the updated HTML when the user saves */\n onSave: (html: string) => void;\n /** Called when the user cancels editing */\n onCancel: () => void;\n}\n\nexport const HTMLEditorModal: React.FC<HTMLEditorModalProps> = ({\n html,\n onSave,\n onCancel,\n}) => {\n const [value, setValue] = useState(html);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n // Cmd/Ctrl+Enter → save\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n onSave(value);\n }\n // Escape → cancel\n if (e.key === 'Escape') {\n e.preventDefault();\n onCancel();\n }\n // Tab → insert 2 spaces\n if (e.key === 'Tab') {\n e.preventDefault();\n const ta = e.target as HTMLTextAreaElement;\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const updated = value.substring(0, start) + ' ' + value.substring(end);\n setValue(updated);\n requestAnimationFrame(() => {\n ta.selectionStart = ta.selectionEnd = start + 2;\n });\n }\n };\n\n return createPortal(\n <div style={overlayStyle} onClick={onCancel}>\n <div style={modalStyle} onClick={(e) => e.stopPropagation()}>\n {/* Header */}\n <div style={headerStyle}>\n <span style={{ fontWeight: 600, fontSize: '14px' }}>Edit Block HTML</span>\n <span style={{ fontSize: '11px', color: '#888' }}>\n ⌘Enter to save &middot; Escape to cancel\n </span>\n </div>\n\n {/* Editor */}\n <textarea\n style={textareaStyle}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n spellCheck={false}\n autoFocus\n />\n\n {/* Footer */}\n <div style={footerStyle}>\n <button\n style={cancelBtnStyle}\n onClick={onCancel}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.borderColor = '#888';\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.borderColor = '#555';\n }}\n >\n Cancel\n </button>\n <button\n style={saveBtnStyle}\n onClick={() => onSave(value)}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.background = '#0055dd';\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.background = '#0066ff';\n }}\n >\n Save\n </button>\n </div>\n </div>\n </div>,\n document.body\n );\n};\n\n// ----------------------------------------------------------\n// Styles\n// ----------------------------------------------------------\n\nconst overlayStyle: React.CSSProperties = {\n position: 'fixed',\n inset: 0,\n background: 'rgba(0, 0, 0, 0.5)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 10000,\n};\n\nconst modalStyle: React.CSSProperties = {\n width: 'min(800px, 90vw)',\n height: 'min(600px, 80vh)',\n background: '#1e1e1e',\n borderRadius: '10px',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n boxShadow: '0 20px 60px rgba(0, 0, 0, 0.4)',\n};\n\nconst headerStyle: React.CSSProperties = {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 16px',\n background: '#2d2d2d',\n color: '#ccc',\n borderBottom: '1px solid #444',\n};\n\nconst textareaStyle: React.CSSProperties = {\n flex: 1,\n background: '#1e1e1e',\n color: '#d4d4d4',\n border: 'none',\n padding: '16px',\n fontFamily: \"'SF Mono', 'Fira Code', 'Consolas', 'Monaco', monospace\",\n fontSize: '13px',\n lineHeight: '1.6',\n resize: 'none',\n outline: 'none',\n tabSize: 2,\n};\n\nconst footerStyle: React.CSSProperties = {\n display: 'flex',\n justifyContent: 'flex-end',\n gap: '8px',\n padding: '12px 16px',\n background: '#2d2d2d',\n borderTop: '1px solid #444',\n};\n\nconst cancelBtnStyle: React.CSSProperties = {\n padding: '6px 16px',\n border: '1px solid #555',\n borderRadius: '6px',\n background: 'transparent',\n color: '#ccc',\n cursor: 'pointer',\n fontSize: '13px',\n transition: 'border-color 0.15s',\n};\n\nconst saveBtnStyle: React.CSSProperties = {\n padding: '6px 16px',\n border: 'none',\n borderRadius: '6px',\n background: '#0066ff',\n color: '#fff',\n cursor: 'pointer',\n fontSize: '13px',\n fontWeight: 500,\n transition: 'background 0.15s',\n};\n","// ============================================================\n// DopeCanvas Core Types\n// ============================================================\n\n/** Named page size presets */\nexport type PageSizeName = 'letter' | 'a4' | 'legal';\n\n/** Custom page dimensions in pixels */\nexport interface PageDimensions {\n width: number;\n height: number;\n}\n\n/** Page margins in pixels */\nexport interface PageMargins {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\n/** Full page configuration */\nexport interface PageConfig {\n size: PageSizeName | PageDimensions;\n margins: PageMargins;\n}\n\n/** A single page containing block element indices */\nexport interface PageContent {\n /** Indices into the flat block array */\n blockIndices: number[];\n}\n\n/** Result of the pagination algorithm */\nexport interface PaginationResult {\n pages: PageContent[];\n pageCount: number;\n}\n\n/** Block measurement info */\nexport interface BlockMeasurement {\n index: number;\n height: number;\n element: HTMLElement;\n breakBefore: boolean;\n breakAfter: boolean;\n}\n\n/** Toolbar context — what kind of element is selected */\nexport type ToolbarContext = 'text' | 'table' | 'image' | 'chart' | 'none';\n\n/** Undo/redo snapshot */\nexport interface UndoSnapshot {\n html: string;\n timestamp: number;\n}\n\n/** Unsubscribe function returned by event listeners */\nexport type Unsubscribe = () => void;\n\n// ============================================================\n// Page size presets (at 96 DPI)\n// ============================================================\n\n/** Page sizes in pixels at 96 DPI */\nexport const PAGE_SIZE_PRESETS: Record<PageSizeName, PageDimensions> = {\n letter: { width: 816, height: 1056 }, // 8.5 x 11 inches\n a4: { width: 794, height: 1123 }, // 210 x 297 mm\n legal: { width: 816, height: 1344 }, // 8.5 x 14 inches\n};\n\n/** Default margins: 1 inch (96px) on all sides */\nexport const DEFAULT_MARGINS: PageMargins = {\n top: 96,\n right: 96,\n bottom: 96,\n left: 96,\n};\n\n/** Default page config */\nexport const DEFAULT_PAGE_CONFIG: PageConfig = {\n size: 'letter',\n margins: { ...DEFAULT_MARGINS },\n};\n","// ============================================================\n// PagedView — Renders paginated blocks across page frames\n// ============================================================\n// Takes HTML content, paginates it into visual pages, and makes\n// each block editable via contentEditable.\n//\n// After initial pagination, the live DOM is the source of truth.\n// User edits trigger live re-pagination when the block distribution\n// across pages changes (e.g. content grows past a page boundary).\n// Cursor position is saved/restored across re-pagination re-renders.\n// ============================================================\n\nimport React, { useRef, useEffect, useCallback, useState } from 'react';\nimport { Page } from './Page';\nimport { BlockToolbar } from './BlockToolbar';\nimport { HTMLEditorModal } from './HTMLEditorModal';\nimport type { PageLayoutEngine } from '../core/PageLayoutEngine';\nimport type { EditableManager } from '../core/EditableManager';\nimport type {\n PageConfig,\n PaginationResult,\n PageSizeName,\n} from '../core/types';\nimport { PAGE_SIZE_PRESETS } from '../core/types';\n\ninterface PagedViewProps {\n /** The raw HTML content to render */\n html: string;\n /** Optional CSS to inject */\n css?: string;\n /** Page configuration */\n pageConfig: PageConfig;\n /** The layout engine instance */\n layoutEngine: PageLayoutEngine;\n /** The editable manager instance */\n editableManager: EditableManager;\n /** Callback when content changes (after user edit) — updates a ref, NOT state */\n onContentChange?: (html: string) => void;\n /** Callback when pagination changes */\n onPaginationChange?: (result: PaginationResult) => void;\n}\n\n/**\n * Represents a block of content assigned to a specific page.\n * We store the HTML string so React can render it once, then\n * the live DOM takes over for editing.\n */\ninterface PageData {\n blocks: string[]; // outerHTML of each block in this page\n}\n\n/**\n * Execute <script> tags found in a container.\n * Scripts set via innerHTML / dangerouslySetInnerHTML do NOT auto-execute.\n * We clone each one into a fresh <script> element so the browser runs it.\n */\nfunction activateScripts(container: HTMLElement): HTMLScriptElement[] {\n const activated: HTMLScriptElement[] = [];\n\n container.querySelectorAll('script').forEach((orig) => {\n const fresh = document.createElement('script');\n // Preserve attributes (type, src, data-*, etc.)\n Array.from(orig.attributes).forEach((attr) =>\n fresh.setAttribute(attr.name, attr.value)\n );\n fresh.textContent = orig.textContent || '';\n // Replacing the node triggers synchronous execution for inline scripts\n orig.parentNode?.replaceChild(fresh, orig);\n activated.push(fresh);\n });\n\n return activated;\n}\n\n// ----------------------------------------------------------\n// Cursor save / restore — used across re-pagination re-renders\n// ----------------------------------------------------------\n\ninterface CursorState {\n /** Global index of the block wrapper the cursor is inside */\n blockIndex: number;\n /** Character offset within that block's text content */\n textOffset: number;\n}\n\n/** Save the current cursor position relative to block content divs */\nfunction saveCursorPosition(container: HTMLElement): CursorState | null {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return null;\n\n const range = sel.getRangeAt(0);\n const anchorNode = range.startContainer;\n\n const wrappers = Array.from(\n container.querySelectorAll('.dopecanvas-block-content')\n );\n const blockIndex = wrappers.findIndex((w) => w.contains(anchorNode));\n if (blockIndex === -1) return null;\n\n // Compute character offset within the block\n try {\n const preRange = document.createRange();\n preRange.selectNodeContents(wrappers[blockIndex]);\n preRange.setEnd(range.startContainer, range.startOffset);\n const textOffset = preRange.toString().length;\n return { blockIndex, textOffset };\n } catch {\n return null;\n }\n}\n\n/** Restore cursor position after a re-pagination re-render */\nfunction restoreCursorPosition(\n container: HTMLElement,\n state: CursorState\n): void {\n const wrappers = container.querySelectorAll('.dopecanvas-block-content');\n if (state.blockIndex >= wrappers.length) return;\n\n const wrapper = wrappers[state.blockIndex];\n const walker = document.createTreeWalker(wrapper, NodeFilter.SHOW_TEXT);\n let remaining = state.textOffset;\n\n while (walker.nextNode()) {\n const textNode = walker.currentNode as Text;\n if (remaining <= textNode.length) {\n try {\n const range = document.createRange();\n range.setStart(textNode, remaining);\n range.collapse(true);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n } catch {\n // Best effort — position may have shifted\n }\n return;\n }\n remaining -= textNode.length;\n }\n\n // Fallback: place cursor at the end of the block\n try {\n const range = document.createRange();\n range.selectNodeContents(wrapper);\n range.collapse(false);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n } catch {\n // Ignore\n }\n}\n\n/**\n * Memoized block content — prevents React from re-rendering (and\n * resetting innerHTML) when unrelated state like hoveredBlockIndex\n * changes. User edits via contentEditable are preserved.\n */\nconst MemoizedBlockContent = React.memo<{\n html: string;\n isEditable: boolean;\n isTable: boolean;\n}>(({ html, isEditable, isTable }) => (\n <div\n className=\"dopecanvas-block-content\"\n contentEditable={isEditable && !isTable ? true : undefined}\n suppressContentEditableWarning\n dangerouslySetInnerHTML={{ __html: html }}\n />\n));\n\nexport const PagedView: React.FC<PagedViewProps> = ({\n html,\n css,\n pageConfig,\n layoutEngine,\n editableManager: _editableManager,\n onContentChange,\n onPaginationChange,\n}) => {\n const measureRef = useRef<HTMLDivElement>(null);\n const pagesContainerRef = useRef<HTMLDivElement>(null);\n const mutationObserverRef = useRef<MutationObserver | null>(null);\n const onContentChangeRef = useRef(onContentChange);\n onContentChangeRef.current = onContentChange;\n\n // Pages state — set during pagination AND live re-pagination\n const [pages, setPages] = useState<PageData[]>([]);\n\n // Refs for live re-pagination\n const pendingCursorRef = useRef<CursorState | null>(null);\n const isRePaginatingRef = useRef(false);\n const pagesRef = useRef<PageData[]>([]);\n\n // Block management state\n const [hoveredBlockIndex, setHoveredBlockIndex] = useState<number | null>(null);\n const [editingBlockIndex, setEditingBlockIndex] = useState<number | null>(null);\n const [editingHTML, setEditingHTML] = useState<string>('');\n const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Resolve page dimensions\n const dimensions =\n typeof pageConfig.size === 'string'\n ? PAGE_SIZE_PRESETS[pageConfig.size as PageSizeName]\n : pageConfig.size;\n\n // ----------------------------------------------------------\n // Collect current HTML from the live DOM (no re-render)\n // ----------------------------------------------------------\n\n const collectHTMLFromDOM = useCallback(() => {\n if (!pagesContainerRef.current) return;\n\n const contentDivs = pagesContainerRef.current.querySelectorAll(\n '.dopecanvas-block-content'\n );\n\n const htmlParts: string[] = [];\n contentDivs.forEach((contentDiv) => {\n const content = contentDiv.firstElementChild as HTMLElement;\n if (content) {\n htmlParts.push(content.outerHTML);\n }\n });\n\n const updatedHTML = htmlParts.join('\\n');\n onContentChangeRef.current?.(updatedHTML);\n }, []);\n\n // ----------------------------------------------------------\n // Shared pagination: measure + paginate any HTML string\n // ----------------------------------------------------------\n\n const paginateHTML = useCallback((htmlContent: string) => {\n if (!measureRef.current) return;\n\n const mc = measureRef.current;\n mc.style.width = `${layoutEngine.getContentAreaWidth()}px`;\n mc.style.position = 'absolute';\n mc.style.left = '-9999px';\n mc.style.top = '0';\n mc.style.visibility = 'hidden';\n mc.innerHTML = '';\n\n if (css) {\n const styleEl = document.createElement('style');\n styleEl.textContent = css;\n mc.appendChild(styleEl);\n }\n\n const wrapper = document.createElement('div');\n wrapper.innerHTML = htmlContent;\n mc.appendChild(wrapper);\n\n const measurements = layoutEngine.measureBlocks(wrapper);\n const blockHTMLs = measurements.map(\n (m) => (m.element.cloneNode(true) as HTMLElement).outerHTML\n );\n const result = layoutEngine.paginate(measurements);\n\n const pageData: PageData[] = result.pages.map((page) => ({\n blocks: page.blockIndices.map((idx) => blockHTMLs[idx]),\n }));\n\n mc.innerHTML = '';\n\n pagesRef.current = pageData;\n setPages(pageData);\n onPaginationChange?.(result);\n onContentChangeRef.current?.(htmlContent);\n }, [css, layoutEngine, onPaginationChange]);\n\n // ----------------------------------------------------------\n // Live re-pagination — runs after user edits change block sizes\n // ----------------------------------------------------------\n\n const rePaginateFromDOM = useCallback(() => {\n if (!pagesContainerRef.current || !measureRef.current) return;\n\n const container = pagesContainerRef.current;\n\n // Save cursor position before we potentially re-render\n const cursor = saveCursorPosition(container);\n\n // Collect block HTML from the live DOM\n const contentDivs = container.querySelectorAll('.dopecanvas-block-content');\n const blockHTMLs: string[] = [];\n contentDivs.forEach((div) => {\n const content = div.firstElementChild as HTMLElement;\n if (content) blockHTMLs.push(content.outerHTML);\n });\n if (blockHTMLs.length === 0) return;\n\n // Set up hidden measure container\n const mc = measureRef.current;\n const contentWidth = layoutEngine.getContentAreaWidth();\n mc.style.width = `${contentWidth}px`;\n mc.style.position = 'absolute';\n mc.style.left = '-9999px';\n mc.style.top = '0';\n mc.style.visibility = 'hidden';\n mc.innerHTML = '';\n\n if (css) {\n const styleEl = document.createElement('style');\n styleEl.textContent = css;\n mc.appendChild(styleEl);\n }\n\n const measureWrapper = document.createElement('div');\n measureWrapper.innerHTML = blockHTMLs.join('\\n');\n mc.appendChild(measureWrapper);\n\n // Measure and paginate\n const measurements = layoutEngine.measureBlocks(measureWrapper);\n const measuredHTMLs = measurements.map(\n (m) => (m.element.cloneNode(true) as HTMLElement).outerHTML\n );\n const result = layoutEngine.paginate(measurements);\n mc.innerHTML = '';\n\n // Build new page data\n const newPages: PageData[] = result.pages.map((p) => ({\n blocks: p.blockIndices.map((idx) => measuredHTMLs[idx]),\n }));\n\n // Only re-render if the block distribution across pages actually changed\n const oldDist = pagesRef.current.map((p) => p.blocks.length);\n const newDist = newPages.map((p) => p.blocks.length);\n const changed =\n oldDist.length !== newDist.length ||\n oldDist.some((count, i) => count !== newDist[i]);\n\n if (changed) {\n isRePaginatingRef.current = true;\n pendingCursorRef.current = cursor;\n pagesRef.current = newPages;\n setPages(newPages);\n onPaginationChange?.(result);\n }\n }, [css, layoutEngine, onPaginationChange]);\n\n // Keep a stable ref so the MutationObserver closure always calls the latest version\n const rePaginateFromDOMRef = useRef(rePaginateFromDOM);\n rePaginateFromDOMRef.current = rePaginateFromDOM;\n\n // ----------------------------------------------------------\n // Pagination — runs on initial load and config changes\n // ----------------------------------------------------------\n\n const runPagination = useCallback(() => {\n // Parse the LLM-authored HTML.\n // An LLM may produce a full document (<!DOCTYPE html><html><head>\n // <style>…</style></head><body>…</body></html>) or a plain fragment.\n // DOMParser handles both: for fragments it wraps in html/body;\n // for full documents it parses normally. We then move any <head>\n // styles/links into the body so they participate in pagination\n // as zero-height blocks and their styles apply to the content.\n const parsed = new DOMParser().parseFromString(html, 'text/html');\n\n // Rescue <style> and <link rel=\"stylesheet\"> from <head>\n parsed.head\n .querySelectorAll('style, link[rel=\"stylesheet\"]')\n .forEach((el) => {\n parsed.body.insertBefore(el, parsed.body.firstChild);\n });\n\n paginateHTML(parsed.body.innerHTML);\n }, [html, paginateHTML]);\n\n // Run pagination when html or pageConfig changes\n useEffect(() => {\n runPagination();\n }, [runPagination]);\n\n // ----------------------------------------------------------\n // Block management — add / delete / edit HTML\n // ----------------------------------------------------------\n\n /** Collect all block outerHTMLs from the live DOM */\n const collectBlocksFromDOM = useCallback((): string[] => {\n if (!pagesContainerRef.current) return [];\n const contentDivs = pagesContainerRef.current.querySelectorAll(\n '.dopecanvas-block-content'\n );\n const blocks: string[] = [];\n contentDivs.forEach((div) => {\n const child = div.firstElementChild as HTMLElement;\n if (child) blocks.push(child.outerHTML);\n });\n return blocks;\n }, []);\n\n /** Add a new empty block below the given global index */\n const handleAddBlock = useCallback(\n (globalIndex: number) => {\n const blocks = collectBlocksFromDOM();\n blocks.splice(\n globalIndex + 1,\n 0,\n '<p style=\"min-height: 1.5em; line-height: 1.6;\">&nbsp;</p>'\n );\n setHoveredBlockIndex(null);\n paginateHTML(blocks.join('\\n'));\n },\n [collectBlocksFromDOM, paginateHTML]\n );\n\n /** Delete the block at the given global index */\n const handleDeleteBlock = useCallback(\n (globalIndex: number) => {\n const blocks = collectBlocksFromDOM();\n if (blocks.length <= 1) return; // keep at least one block\n blocks.splice(globalIndex, 1);\n setHoveredBlockIndex(null);\n paginateHTML(blocks.join('\\n'));\n },\n [collectBlocksFromDOM, paginateHTML]\n );\n\n /** Open the HTML source editor for the given block */\n const handleOpenEditor = useCallback(\n (globalIndex: number) => {\n const blocks = collectBlocksFromDOM();\n if (globalIndex < blocks.length) {\n setEditingBlockIndex(globalIndex);\n setEditingHTML(blocks[globalIndex]);\n }\n },\n [collectBlocksFromDOM]\n );\n\n /** Save edited HTML and re-paginate */\n const handleSaveHTML = useCallback(\n (newHTML: string) => {\n if (editingBlockIndex === null) return;\n const blocks = collectBlocksFromDOM();\n if (editingBlockIndex < blocks.length) {\n blocks[editingBlockIndex] = newHTML;\n }\n setEditingBlockIndex(null);\n setEditingHTML('');\n setHoveredBlockIndex(null);\n paginateHTML(blocks.join('\\n'));\n },\n [editingBlockIndex, collectBlocksFromDOM, paginateHTML]\n );\n\n /** Cancel the HTML editor */\n const handleCancelEditor = useCallback(() => {\n setEditingBlockIndex(null);\n setEditingHTML('');\n }, []);\n\n // ----------------------------------------------------------\n // After pages render: make editable + observe changes\n // ----------------------------------------------------------\n\n useEffect(() => {\n const container = pagesContainerRef.current;\n if (!container) return;\n\n // Disconnect previous observer\n if (mutationObserverRef.current) {\n mutationObserverRef.current.disconnect();\n }\n\n // Make table cells individually editable.\n // Non-table blocks get contentEditable from their React prop;\n // tables need cell-level editability so users can't break table structure.\n const blockContents = container.querySelectorAll('.dopecanvas-block-content');\n blockContents.forEach((contentDiv) => {\n const child = contentDiv.firstElementChild as HTMLElement;\n if (!child) return;\n\n if (child.tagName === 'TABLE') {\n const cells = child.querySelectorAll('td, th');\n cells.forEach((cell) => {\n (cell as HTMLElement).contentEditable = 'true';\n });\n }\n });\n\n // Execute <script> tags embedded in the LLM-authored HTML.\n // This must run AFTER contentEditable setup so scripts can override\n // editability on specific cells (e.g. formula cells).\n const activatedScripts = activateScripts(container);\n\n // Set up MutationObserver — collects HTML and re-paginates when needed\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n const observer = new MutationObserver(() => {\n if (isRePaginatingRef.current) return;\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => {\n collectHTMLFromDOM();\n rePaginateFromDOMRef.current();\n }, 300);\n });\n\n observer.observe(container, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: false,\n });\n\n mutationObserverRef.current = observer;\n\n // Restore cursor after a re-pagination re-render\n if (pendingCursorRef.current) {\n requestAnimationFrame(() => {\n if (pendingCursorRef.current && pagesContainerRef.current) {\n restoreCursorPosition(\n pagesContainerRef.current,\n pendingCursorRef.current\n );\n pendingCursorRef.current = null;\n }\n isRePaginatingRef.current = false;\n });\n } else {\n isRePaginatingRef.current = false;\n }\n\n return () => {\n observer.disconnect();\n activatedScripts.forEach((s) => s.remove());\n if (debounceTimer) clearTimeout(debounceTimer);\n };\n }, [pages, collectHTMLFromDOM]);\n\n // ----------------------------------------------------------\n // Render\n // ----------------------------------------------------------\n\n return (\n <div className=\"dopecanvas-paged-view\" style={scrollContainerStyle}>\n {/* Hidden measurement container */}\n <div ref={measureRef} aria-hidden=\"true\" />\n\n {/* Visible pages */}\n <div ref={pagesContainerRef} style={pagesWrapperStyle}>\n {css && <style dangerouslySetInnerHTML={{ __html: css }} />}\n {pages.map((pageData, pageIndex) => {\n // Compute this page's starting global block index\n const pageStartIdx = pages\n .slice(0, pageIndex)\n .reduce((sum, p) => sum + p.blocks.length, 0);\n\n return (\n <Page\n key={pageIndex}\n dimensions={dimensions}\n margins={pageConfig.margins}\n pageNumber={pageIndex + 1}\n totalPages={pages.length}\n >\n {pageData.blocks.map((blockHTML, blockIndex) => {\n const globalIdx = pageStartIdx + blockIndex;\n const lower = blockHTML.trim().toLowerCase();\n const isEditable =\n !lower.startsWith('<script') && !lower.startsWith('<style');\n\n const isTable = lower.startsWith('<table');\n\n return (\n <div\n key={`${pageIndex}-${blockIndex}`}\n className=\"dopecanvas-block-wrapper\"\n style={{ position: 'relative' }}\n onMouseEnter={() => {\n if (!isEditable) return;\n if (hideTimeoutRef.current) {\n clearTimeout(hideTimeoutRef.current);\n hideTimeoutRef.current = null;\n }\n setHoveredBlockIndex(globalIdx);\n }}\n onMouseLeave={() => {\n hideTimeoutRef.current = setTimeout(() => {\n setHoveredBlockIndex((prev) =>\n prev === globalIdx ? null : prev\n );\n }, 250);\n }}\n >\n <MemoizedBlockContent\n html={blockHTML}\n isEditable={isEditable}\n isTable={isTable}\n />\n {isEditable && (\n <BlockToolbar\n visible={hoveredBlockIndex === globalIdx}\n onAddBelow={() => handleAddBlock(globalIdx)}\n onEditHTML={() => handleOpenEditor(globalIdx)}\n onDelete={() => handleDeleteBlock(globalIdx)}\n />\n )}\n </div>\n );\n })}\n </Page>\n );\n })}\n\n {/* Show at least one empty page if no content */}\n {pages.length === 0 && (\n <Page\n dimensions={dimensions}\n margins={pageConfig.margins}\n pageNumber={1}\n totalPages={1}\n >\n <div\n contentEditable=\"true\"\n style={{ minHeight: '1em', outline: 'none' }}\n data-placeholder=\"Start typing...\"\n />\n </Page>\n )}\n </div>\n\n {/* HTML Editor Modal */}\n {editingBlockIndex !== null && (\n <HTMLEditorModal\n html={editingHTML}\n onSave={handleSaveHTML}\n onCancel={handleCancelEditor}\n />\n )}\n </div>\n );\n};\n\n// ----------------------------------------------------------\n// Styles\n// ----------------------------------------------------------\n\nconst scrollContainerStyle: React.CSSProperties = {\n flex: 1,\n overflow: 'auto',\n backgroundColor: '#e8e8e8',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n};\n\nconst pagesWrapperStyle: React.CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '24px',\n padding: '24px 0',\n};\n","// ============================================================\n// PageLayoutEngine — Pagination algorithm\n// ============================================================\n// Pure TypeScript class with no React dependency.\n// Takes a container of block elements, measures them, and\n// distributes them across fixed-size pages.\n// ============================================================\n\nimport type {\n PageConfig,\n PageDimensions,\n PageSizeName,\n PaginationResult,\n BlockMeasurement,\n} from './types';\nimport {\n PAGE_SIZE_PRESETS,\n DEFAULT_PAGE_CONFIG,\n} from './types';\n\nexport class PageLayoutEngine {\n private config: PageConfig;\n\n constructor(config: PageConfig = DEFAULT_PAGE_CONFIG) {\n this.config = { ...config };\n }\n\n // ----------------------------------------------------------\n // Config accessors\n // ----------------------------------------------------------\n\n getConfig(): PageConfig {\n return { ...this.config };\n }\n\n setConfig(config: Partial<PageConfig>): void {\n if (config.size !== undefined) {\n this.config.size = config.size;\n }\n if (config.margins !== undefined) {\n this.config.margins = { ...config.margins };\n }\n }\n\n /** Resolve page size name to pixel dimensions */\n getPageDimensions(): PageDimensions {\n if (typeof this.config.size === 'string') {\n return PAGE_SIZE_PRESETS[this.config.size as PageSizeName];\n }\n return this.config.size;\n }\n\n /** Usable content area height (page height minus top+bottom margins) */\n getContentAreaHeight(): number {\n const dims = this.getPageDimensions();\n return dims.height - this.config.margins.top - this.config.margins.bottom;\n }\n\n /** Usable content area width (page width minus left+right margins) */\n getContentAreaWidth(): number {\n const dims = this.getPageDimensions();\n return dims.width - this.config.margins.left - this.config.margins.right;\n }\n\n // ----------------------------------------------------------\n // Measurement\n // ----------------------------------------------------------\n\n /**\n * Measure all direct child block elements of the container.\n * The container should be styled to match the content area width\n * so that measurements reflect actual rendered heights.\n */\n measureBlocks(container: HTMLElement): BlockMeasurement[] {\n const children = Array.from(container.children) as HTMLElement[];\n const measurements: BlockMeasurement[] = [];\n\n for (let i = 0; i < children.length; i++) {\n const el = children[i];\n const style = window.getComputedStyle(el);\n\n // Check for CSS break-before / break-after\n const breakBefore =\n style.getPropertyValue('break-before') === 'page' ||\n style.getPropertyValue('page-break-before') === 'always';\n const breakAfter =\n style.getPropertyValue('break-after') === 'page' ||\n style.getPropertyValue('page-break-after') === 'always';\n\n // Use getBoundingClientRect for precise measurement including margins\n const rect = el.getBoundingClientRect();\n const marginTop = parseFloat(style.marginTop) || 0;\n const marginBottom = parseFloat(style.marginBottom) || 0;\n const totalHeight = rect.height + marginTop + marginBottom;\n\n measurements.push({\n index: i,\n height: totalHeight,\n element: el,\n breakBefore,\n breakAfter,\n });\n }\n\n return measurements;\n }\n\n // ----------------------------------------------------------\n // Pagination\n // ----------------------------------------------------------\n\n /**\n * Paginate: distribute measured blocks across pages.\n * \n * Algorithm:\n * 1. Walk blocks sequentially\n * 2. Accumulate height on current page\n * 3. When a block would overflow, start a new page\n * 4. Respect break-before / break-after CSS\n * 5. If a single block is taller than a page, give it its own page\n */\n paginate(measurements: BlockMeasurement[]): PaginationResult {\n if (measurements.length === 0) {\n return { pages: [{ blockIndices: [] }], pageCount: 1 };\n }\n\n const contentHeight = this.getContentAreaHeight();\n const pages: { blockIndices: number[] }[] = [];\n let currentPage: number[] = [];\n let currentHeight = 0;\n\n for (let i = 0; i < measurements.length; i++) {\n const block = measurements[i];\n\n // Force a new page if break-before is set (and current page has content)\n if (block.breakBefore && currentPage.length > 0) {\n pages.push({ blockIndices: currentPage });\n currentPage = [];\n currentHeight = 0;\n }\n\n // Check if adding this block would overflow the current page\n if (currentHeight + block.height > contentHeight && currentPage.length > 0) {\n // Current page is full — start a new one\n pages.push({ blockIndices: currentPage });\n currentPage = [];\n currentHeight = 0;\n }\n\n // Add block to current page\n currentPage.push(block.index);\n currentHeight += block.height;\n\n // Force a new page after this block if break-after is set\n if (block.breakAfter) {\n pages.push({ blockIndices: currentPage });\n currentPage = [];\n currentHeight = 0;\n }\n }\n\n // Push the last page if it has content\n if (currentPage.length > 0) {\n pages.push({ blockIndices: currentPage });\n }\n\n // Ensure at least one page\n if (pages.length === 0) {\n pages.push({ blockIndices: [] });\n }\n\n return {\n pages,\n pageCount: pages.length,\n };\n }\n}\n","// ============================================================\n// EditableManager — contentEditable integration\n// ============================================================\n// Manages making block elements editable, tracking changes\n// via MutationObserver, and providing undo/redo.\n// ============================================================\n\nimport type { UndoSnapshot, Unsubscribe, ToolbarContext } from './types';\n\nexport type ChangeCallback = () => void;\nexport type ContextChangeCallback = (context: ToolbarContext) => void;\n\nexport class EditableManager {\n private observer: MutationObserver | null = null;\n private changeCallbacks: Set<ChangeCallback> = new Set();\n private contextCallbacks: Set<ContextChangeCallback> = new Set();\n private undoStack: UndoSnapshot[] = [];\n private redoStack: UndoSnapshot[] = [];\n private container: HTMLElement | null = null;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private selectionHandler: (() => void) | null = null;\n private currentContext: ToolbarContext = 'none';\n\n private static readonly MAX_UNDO_STACK = 100;\n private static readonly DEBOUNCE_MS = 150;\n\n // ----------------------------------------------------------\n // Lifecycle\n // ----------------------------------------------------------\n\n /**\n * Attach to a container element. Sets up contentEditable on\n * all direct child blocks and starts observing changes.\n */\n attach(container: HTMLElement): void {\n this.detach(); // Clean up any previous attachment\n this.container = container;\n\n // Make all direct children editable\n this.makeChildrenEditable(container);\n\n // Take initial snapshot for undo\n this.pushUndoSnapshot();\n\n // Start observing mutations\n this.observer = new MutationObserver(this.handleMutations);\n this.observer.observe(container, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: ['style', 'class'],\n });\n\n // Listen for selection changes to detect context\n this.selectionHandler = this.handleSelectionChange.bind(this);\n document.addEventListener('selectionchange', this.selectionHandler);\n }\n\n /**\n * Detach from the container. Stop observing and clean up.\n */\n detach(): void {\n if (this.observer) {\n this.observer.disconnect();\n this.observer = null;\n }\n if (this.selectionHandler) {\n document.removeEventListener('selectionchange', this.selectionHandler);\n this.selectionHandler = null;\n }\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n this.container = null;\n }\n\n // ----------------------------------------------------------\n // Make elements editable\n // ----------------------------------------------------------\n\n /**\n * Set contentEditable on all direct children of the container.\n * Table cells get individual editability; other blocks are editable as wholes.\n */\n makeChildrenEditable(container: HTMLElement): void {\n const children = Array.from(container.children) as HTMLElement[];\n for (const child of children) {\n if (child.tagName === 'TABLE') {\n // For tables, make individual cells editable (not the table itself)\n this.makeTableCellsEditable(child);\n } else {\n child.contentEditable = 'true';\n }\n }\n }\n\n private makeTableCellsEditable(table: HTMLElement): void {\n const cells = table.querySelectorAll('td, th');\n cells.forEach((cell) => {\n (cell as HTMLElement).contentEditable = 'true';\n });\n }\n\n // ----------------------------------------------------------\n // Mutation handling\n // ----------------------------------------------------------\n\n private handleMutations = (_mutations: MutationRecord[]): void => {\n // Debounce to avoid excessive re-pagination\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n this.debounceTimer = setTimeout(() => {\n this.pushUndoSnapshot();\n this.notifyChange();\n }, EditableManager.DEBOUNCE_MS);\n };\n\n // ----------------------------------------------------------\n // Selection / context detection\n // ----------------------------------------------------------\n\n private handleSelectionChange(): void {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0 || !this.container) {\n this.setContext('none');\n return;\n }\n\n const range = selection.getRangeAt(0);\n const node = range.startContainer;\n\n // Walk up from the selection to find context\n let current: Node | null = node;\n while (current && current !== this.container) {\n if (current instanceof HTMLElement) {\n const tag = current.tagName;\n if (tag === 'TD' || tag === 'TH' || tag === 'TABLE') {\n this.setContext('table');\n return;\n }\n if (tag === 'IMG') {\n this.setContext('image');\n return;\n }\n if (current.dataset?.dopecanvasChart) {\n this.setContext('chart');\n return;\n }\n }\n current = current.parentNode;\n }\n\n // Default to text context if inside our container\n if (this.container.contains(node)) {\n this.setContext('text');\n } else {\n this.setContext('none');\n }\n }\n\n private setContext(ctx: ToolbarContext): void {\n if (ctx !== this.currentContext) {\n this.currentContext = ctx;\n this.contextCallbacks.forEach((cb) => cb(ctx));\n }\n }\n\n getContext(): ToolbarContext {\n return this.currentContext;\n }\n\n // ----------------------------------------------------------\n // Undo / Redo\n // ----------------------------------------------------------\n\n private pushUndoSnapshot(): void {\n if (!this.container) return;\n const html = this.container.innerHTML;\n const last = this.undoStack[this.undoStack.length - 1];\n // Don't push duplicates\n if (last && last.html === html) return;\n\n this.undoStack.push({ html, timestamp: Date.now() });\n // Clear redo stack on new change\n this.redoStack = [];\n // Limit stack size\n if (this.undoStack.length > EditableManager.MAX_UNDO_STACK) {\n this.undoStack.shift();\n }\n }\n\n undo(): boolean {\n if (!this.container || this.undoStack.length <= 1) return false;\n\n // Pop current state to redo stack\n const current = this.undoStack.pop()!;\n this.redoStack.push(current);\n\n // Restore previous state\n const previous = this.undoStack[this.undoStack.length - 1];\n this.pauseObserver(() => {\n this.container!.innerHTML = previous.html;\n this.makeChildrenEditable(this.container!);\n });\n this.notifyChange();\n return true;\n }\n\n redo(): boolean {\n if (!this.container || this.redoStack.length === 0) return false;\n\n const next = this.redoStack.pop()!;\n this.undoStack.push(next);\n\n this.pauseObserver(() => {\n this.container!.innerHTML = next.html;\n this.makeChildrenEditable(this.container!);\n });\n this.notifyChange();\n return true;\n }\n\n /** Temporarily disconnect observer to avoid feedback loops */\n private pauseObserver(fn: () => void): void {\n if (this.observer) {\n this.observer.disconnect();\n }\n fn();\n if (this.observer && this.container) {\n this.observer.observe(this.container, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: ['style', 'class'],\n });\n }\n }\n\n // ----------------------------------------------------------\n // Event callbacks\n // ----------------------------------------------------------\n\n onChange(callback: ChangeCallback): Unsubscribe {\n this.changeCallbacks.add(callback);\n return () => {\n this.changeCallbacks.delete(callback);\n };\n }\n\n onContextChange(callback: ContextChangeCallback): Unsubscribe {\n this.contextCallbacks.add(callback);\n return () => {\n this.contextCallbacks.delete(callback);\n };\n }\n\n private notifyChange(): void {\n this.changeCallbacks.forEach((cb) => cb());\n }\n\n // ----------------------------------------------------------\n // Formatting commands\n // ----------------------------------------------------------\n\n /**\n * Execute a formatting command on the current selection.\n * Uses document.execCommand for broad browser support.\n */\n execCommand(command: string, value?: string): boolean {\n return document.execCommand(command, false, value);\n }\n\n /** Check if a command is active for the current selection */\n queryCommandState(command: string): boolean {\n return document.queryCommandState(command);\n }\n\n /** Get the value of a command for the current selection */\n queryCommandValue(command: string): string {\n return document.queryCommandValue(command);\n }\n\n // ----------------------------------------------------------\n // Content access\n // ----------------------------------------------------------\n\n getHTML(): string {\n if (!this.container) return '';\n return this.container.innerHTML;\n }\n\n getPlainText(): string {\n if (!this.container) return '';\n return this.container.innerText || this.container.textContent || '';\n }\n}\n","// ============================================================\n// DopeCanvas — Main canvas component\n// ============================================================\n// The top-level React component that composes the paged view\n// and document engine together.\n//\n// The toolbar is NOT rendered by default. Instead, all toolbar\n// actions are exposed via a ref-based API (DopeCanvasHandle).\n// Consumers can build their own toolbar UI or use the provided\n// Toolbar components separately.\n//\n// CRITICAL DESIGN: Content edits from the user update a ref,\n// NOT state. This prevents React from re-rendering (and thus\n// destroying) the live editable DOM. Only page config changes\n// or external HTML loads trigger re-pagination.\n// ============================================================\n\nimport React, { useMemo, useCallback, useState, useRef, useEffect, useImperativeHandle, forwardRef } from 'react';\nimport { PagedView } from './PagedView';\nimport { PageLayoutEngine } from '../core/PageLayoutEngine';\nimport { EditableManager } from '../core/EditableManager';\nimport type {\n PageConfig,\n PaginationResult,\n} from '../core/types';\nimport { DEFAULT_PAGE_CONFIG } from '../core/types';\n\n// ----------------------------------------------------------\n// Public API handle exposed via ref\n// ----------------------------------------------------------\n\nexport interface DopeCanvasHandle {\n // Text formatting\n /** Execute a formatting command (e.g. 'bold', 'italic', 'fontSize') */\n execCommand: (command: string, value?: string) => boolean;\n /** Check if a command is active for the current selection */\n queryCommandState: (command: string) => boolean;\n /** Get the value of a command for the current selection */\n queryCommandValue: (command: string) => string;\n\n // Page configuration\n /** Get the current page configuration */\n getPageConfig: () => PageConfig;\n /** Update page configuration (size, margins). Triggers re-pagination. */\n setPageConfig: (config: Partial<PageConfig>) => void;\n /** Get the current number of pages */\n getPageCount: () => number;\n\n // Content access\n /** Get the current document HTML (reflects user edits) */\n getHTML: () => string;\n /** Get the document content as plain text */\n getPlainText: () => string;\n\n // Undo / Redo\n /** Undo the last edit. Returns false if nothing to undo. */\n undo: () => boolean;\n /** Redo the last undone edit. Returns false if nothing to redo. */\n redo: () => boolean;\n}\n\n// ----------------------------------------------------------\n// Component props\n// ----------------------------------------------------------\n\nexport interface DopeCanvasProps {\n /** Initial HTML content to load */\n html?: string;\n /** Optional CSS to inject alongside the HTML */\n css?: string;\n /** Page configuration */\n pageConfig?: PageConfig;\n /** Callback when content changes */\n onContentChange?: (html: string) => void;\n /** Callback when page config changes */\n onPageConfigChange?: (config: PageConfig) => void;\n /** Style overrides for the root container */\n style?: React.CSSProperties;\n}\n\nexport const DopeCanvas = forwardRef<DopeCanvasHandle, DopeCanvasProps>(({\n html = '',\n css,\n pageConfig: externalPageConfig,\n onContentChange,\n onPageConfigChange,\n style,\n}, ref) => {\n const [internalPageConfig, setInternalPageConfig] = useState<PageConfig>(\n externalPageConfig || DEFAULT_PAGE_CONFIG\n );\n const [paginationResult, setPaginationResult] = useState<PaginationResult>({\n pages: [],\n pageCount: 0,\n });\n // Store the latest HTML in a ref — edits update this without triggering re-render\n const currentHTMLRef = useRef(html);\n // Root container ref — used to read live DOM content in getHTML()\n const rootRef = useRef<HTMLDivElement>(null);\n\n // Stable callback ref for onContentChange so PagedView doesn't re-render\n const onContentChangeRef = useRef(onContentChange);\n onContentChangeRef.current = onContentChange;\n\n // Use external config if provided, otherwise internal\n const pageConfig = externalPageConfig || internalPageConfig;\n\n // Create engine instances (stable across renders)\n const layoutEngine = useMemo(() => new PageLayoutEngine(pageConfig), []);\n const editableManager = useMemo(() => new EditableManager(), []);\n\n // Update layout engine when config changes\n useEffect(() => {\n layoutEngine.setConfig(pageConfig);\n }, [pageConfig, layoutEngine]);\n\n // Handle content changes from editing — update ref only, no state\n const handleContentChange = useCallback(\n (newHTML: string) => {\n currentHTMLRef.current = newHTML;\n onContentChangeRef.current?.(newHTML);\n },\n []\n );\n\n // Handle page config changes\n const handlePageConfigChange = useCallback(\n (newConfig: Partial<PageConfig>) => {\n const updated = {\n ...pageConfig,\n ...newConfig,\n margins: {\n ...pageConfig.margins,\n ...(newConfig.margins || {}),\n },\n };\n setInternalPageConfig(updated);\n layoutEngine.setConfig(updated);\n onPageConfigChange?.(updated);\n },\n [pageConfig, layoutEngine, onPageConfigChange]\n );\n\n // Handle pagination updates\n const handlePaginationChange = useCallback((result: PaginationResult) => {\n setPaginationResult(result);\n }, []);\n\n // ----------------------------------------------------------\n // Expose API via ref\n // ----------------------------------------------------------\n\n useImperativeHandle(ref, () => ({\n execCommand: (command: string, value?: string) => {\n return editableManager.execCommand(command, value);\n },\n queryCommandState: (command: string) => {\n return editableManager.queryCommandState(command);\n },\n queryCommandValue: (command: string) => {\n return editableManager.queryCommandValue(command);\n },\n getPageConfig: () => ({ ...pageConfig }),\n setPageConfig: (config: Partial<PageConfig>) => {\n handlePageConfigChange(config);\n },\n getPageCount: () => paginationResult.pageCount,\n getHTML: () => {\n // Read directly from the live DOM so edits are never missed\n // (the MutationObserver in PagedView debounces updates to the ref,\n // so the ref can be stale if getHTML is called right after an edit)\n if (rootRef.current) {\n const contentDivs = rootRef.current.querySelectorAll(\n '.dopecanvas-block-content'\n );\n if (contentDivs.length > 0) {\n const parts: string[] = [];\n contentDivs.forEach((div) => {\n const child = div.firstElementChild as HTMLElement;\n if (child) parts.push(child.outerHTML);\n });\n if (parts.length > 0) {\n const freshHTML = parts.join('\\n');\n currentHTMLRef.current = freshHTML; // keep ref in sync\n return freshHTML;\n }\n }\n }\n return currentHTMLRef.current;\n },\n getPlainText: () => {\n // Also read from live DOM for consistency\n const liveHTML = rootRef.current\n ? (() => {\n const divs = rootRef.current!.querySelectorAll('.dopecanvas-block-content');\n const parts: string[] = [];\n divs.forEach((d) => {\n const child = d.firstElementChild as HTMLElement;\n if (child) parts.push(child.outerHTML);\n });\n return parts.length > 0 ? parts.join('\\n') : currentHTMLRef.current;\n })()\n : currentHTMLRef.current;\n const tmp = document.createElement('div');\n tmp.innerHTML = liveHTML;\n return tmp.innerText || tmp.textContent || '';\n },\n undo: () => editableManager.undo(),\n redo: () => editableManager.redo(),\n }), [editableManager, pageConfig, paginationResult.pageCount, handlePageConfigChange]);\n\n return (\n <div\n ref={rootRef}\n className=\"dopecanvas-root\"\n style={{\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n width: '100%',\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, sans-serif',\n ...style,\n }}\n >\n {/* Paged document view */}\n <PagedView\n html={html}\n css={css}\n pageConfig={pageConfig}\n layoutEngine={layoutEngine}\n editableManager={editableManager}\n onContentChange={handleContentChange}\n onPaginationChange={handlePaginationChange}\n />\n </div>\n );\n});\n","// ============================================================\n// DocumentEngine — Core orchestrator\n// ============================================================\n// Ties PageLayoutEngine and EditableManager together.\n// Manages the lifecycle: load → parse → paginate → edit → re-paginate\n// ============================================================\n\nimport { PageLayoutEngine } from './PageLayoutEngine';\nimport { EditableManager } from './EditableManager';\nimport type {\n PageConfig,\n PaginationResult,\n BlockMeasurement,\n Unsubscribe,\n} from './types';\nimport { DEFAULT_PAGE_CONFIG } from './types';\n\nexport class DocumentEngine {\n private layoutEngine: PageLayoutEngine;\n private editableManager: EditableManager;\n private sourceHTML: string = '';\n private sourceCSS: string = '';\n private measureContainer: HTMLElement | null = null;\n private contentContainer: HTMLElement | null = null;\n private paginationResult: PaginationResult = { pages: [], pageCount: 0 };\n private paginationCallbacks: Set<(result: PaginationResult) => void> = new Set();\n private changeCallbacks: Set<(html: string) => void> = new Set();\n\n constructor(config: PageConfig = DEFAULT_PAGE_CONFIG) {\n this.layoutEngine = new PageLayoutEngine(config);\n this.editableManager = new EditableManager();\n }\n\n // ----------------------------------------------------------\n // Accessors\n // ----------------------------------------------------------\n\n getLayoutEngine(): PageLayoutEngine {\n return this.layoutEngine;\n }\n\n getEditableManager(): EditableManager {\n return this.editableManager;\n }\n\n getPaginationResult(): PaginationResult {\n return this.paginationResult;\n }\n\n getSourceHTML(): string {\n return this.sourceHTML;\n }\n\n getPageConfig(): PageConfig {\n return this.layoutEngine.getConfig();\n }\n\n // ----------------------------------------------------------\n // Load HTML content\n // ----------------------------------------------------------\n\n /**\n * Load LLM-generated HTML (and optional CSS) into the engine.\n * This parses the HTML and prepares it for pagination.\n */\n loadHTML(html: string, css?: string): void {\n this.sourceHTML = html;\n this.sourceCSS = css || '';\n }\n\n // ----------------------------------------------------------\n // Attach to DOM containers\n // ----------------------------------------------------------\n\n /**\n * Set the measurement container — a hidden container styled\n * to match the content area width. Used for measuring block heights.\n */\n setMeasureContainer(el: HTMLElement): void {\n this.measureContainer = el;\n }\n\n /**\n * Set the content container — the visible container where\n * editable blocks live. The EditableManager attaches here.\n */\n setContentContainer(el: HTMLElement): void {\n if (this.contentContainer) {\n this.editableManager.detach();\n }\n this.contentContainer = el;\n }\n\n // ----------------------------------------------------------\n // Pagination cycle\n // ----------------------------------------------------------\n\n /**\n * Run the full pagination cycle:\n * 1. Inject HTML into measure container\n * 2. Inject CSS (via <style> tag)\n * 3. Measure all blocks\n * 4. Run pagination algorithm\n * 5. Return result for rendering\n */\n runPagination(): { result: PaginationResult; measurements: BlockMeasurement[] } {\n if (!this.measureContainer) {\n return {\n result: { pages: [{ blockIndices: [] }], pageCount: 1 },\n measurements: [],\n };\n }\n\n // Set up the measure container width to match content area\n const contentWidth = this.layoutEngine.getContentAreaWidth();\n this.measureContainer.style.width = `${contentWidth}px`;\n this.measureContainer.style.position = 'absolute';\n this.measureContainer.style.left = '-9999px';\n this.measureContainer.style.top = '0';\n this.measureContainer.style.visibility = 'hidden';\n\n // Inject CSS if provided\n let styleEl: HTMLStyleElement | null = null;\n if (this.sourceCSS) {\n styleEl = document.createElement('style');\n styleEl.textContent = this.sourceCSS;\n this.measureContainer.appendChild(styleEl);\n }\n\n // Inject HTML content\n const contentWrapper = document.createElement('div');\n contentWrapper.innerHTML = this.sourceHTML;\n this.measureContainer.appendChild(contentWrapper);\n\n // Measure blocks\n const measurements = this.layoutEngine.measureBlocks(contentWrapper);\n\n // Paginate\n this.paginationResult = this.layoutEngine.paginate(measurements);\n\n // Clean up measure container\n this.measureContainer.innerHTML = '';\n\n // Notify listeners\n this.paginationCallbacks.forEach((cb) => cb(this.paginationResult));\n\n return { result: this.paginationResult, measurements };\n }\n\n /**\n * Re-paginate using the current content container's live DOM.\n * Called after user edits.\n */\n rePaginate(): PaginationResult {\n if (!this.contentContainer) {\n return this.paginationResult;\n }\n\n // Measure from the live content\n const measurements = this.layoutEngine.measureBlocks(this.contentContainer);\n this.paginationResult = this.layoutEngine.paginate(measurements);\n\n // Notify\n this.paginationCallbacks.forEach((cb) => cb(this.paginationResult));\n return this.paginationResult;\n }\n\n // ----------------------------------------------------------\n // Attach editing\n // ----------------------------------------------------------\n\n /**\n * Attach the editable manager to the content container\n * and set up change listener for re-pagination.\n */\n attachEditing(container: HTMLElement): void {\n this.contentContainer = container;\n this.editableManager.attach(container);\n\n // Re-paginate on content change\n this.editableManager.onChange(() => {\n // Update source HTML from live DOM\n this.sourceHTML = container.innerHTML;\n this.changeCallbacks.forEach((cb) => cb(this.sourceHTML));\n });\n }\n\n // ----------------------------------------------------------\n // Page config\n // ----------------------------------------------------------\n\n setPageConfig(config: Partial<PageConfig>): void {\n this.layoutEngine.setConfig(config);\n }\n\n // ----------------------------------------------------------\n // Event listeners\n // ----------------------------------------------------------\n\n onPagination(callback: (result: PaginationResult) => void): Unsubscribe {\n this.paginationCallbacks.add(callback);\n return () => {\n this.paginationCallbacks.delete(callback);\n };\n }\n\n onChange(callback: (html: string) => void): Unsubscribe {\n this.changeCallbacks.add(callback);\n return () => {\n this.changeCallbacks.delete(callback);\n };\n }\n\n // ----------------------------------------------------------\n // Content access\n // ----------------------------------------------------------\n\n getHTML(): string {\n if (this.contentContainer) {\n return this.contentContainer.innerHTML;\n }\n return this.sourceHTML;\n }\n\n getPlainText(): string {\n if (this.contentContainer) {\n return this.contentContainer.innerText || this.contentContainer.textContent || '';\n }\n return '';\n }\n\n // ----------------------------------------------------------\n // Cleanup\n // ----------------------------------------------------------\n\n destroy(): void {\n this.editableManager.detach();\n this.paginationCallbacks.clear();\n this.changeCallbacks.clear();\n this.measureContainer = null;\n this.contentContainer = null;\n }\n}\n","// ============================================================\n// DocumentAPI — External programmatic interface\n// ============================================================\n// This class provides a clean API for external systems\n// (LLMs, database sync, parent applications) to interact\n// with a DopeCanvas document.\n// ============================================================\n\nimport type { PageConfig, PaginationResult, Unsubscribe } from '../core/types';\n\n/**\n * DocumentAPI provides a programmatic interface to the DopeCanvas\n * document. It wraps the internal state management and exposes\n * methods for loading, reading, and modifying document content.\n *\n * Usage:\n * const api = new DocumentAPI();\n * // Connect to a DopeCanvas instance (done internally by DopeCanvas component)\n * api.loadHTML('<h1>Hello</h1><p>World</p>');\n * api.onChange((html) => console.log('Content changed:', html));\n */\nexport class DocumentAPI {\n private _html: string = '';\n private _css: string = '';\n private _pageConfig: PageConfig | null = null;\n private _paginationResult: PaginationResult = { pages: [], pageCount: 0 };\n\n // Callbacks\n private _changeCallbacks: Set<(html: string) => void> = new Set();\n private _loadCallbacks: Set<(html: string, css?: string) => void> = new Set();\n private _pageConfigCallbacks: Set<(config: PageConfig) => void> = new Set();\n\n // Connector functions set by DopeCanvas component\n private _getHTMLFn: (() => string) | null = null;\n private _getPlainTextFn: (() => string) | null = null;\n\n // ----------------------------------------------------------\n // Content loading\n // ----------------------------------------------------------\n\n /**\n * Load HTML content into the canvas.\n * Optionally provide CSS to inject alongside.\n */\n loadHTML(html: string, css?: string): void {\n this._html = html;\n this._css = css || '';\n this._loadCallbacks.forEach((cb) => cb(html, css));\n }\n\n /**\n * Get the current document HTML content.\n * Reflects any user edits.\n */\n getHTML(): string {\n if (this._getHTMLFn) {\n return this._getHTMLFn();\n }\n return this._html;\n }\n\n /**\n * Get the document content as plain text.\n */\n getPlainText(): string {\n if (this._getPlainTextFn) {\n return this._getPlainTextFn();\n }\n // Fallback: strip HTML tags\n const tmp = document.createElement('div');\n tmp.innerHTML = this._html;\n return tmp.innerText || tmp.textContent || '';\n }\n\n // ----------------------------------------------------------\n // Event listeners\n // ----------------------------------------------------------\n\n /**\n * Listen for content changes (triggered by user edits).\n * Returns an unsubscribe function.\n */\n onChange(callback: (html: string) => void): Unsubscribe {\n this._changeCallbacks.add(callback);\n return () => {\n this._changeCallbacks.delete(callback);\n };\n }\n\n /**\n * Listen for load events (when loadHTML is called).\n */\n onLoad(callback: (html: string, css?: string) => void): Unsubscribe {\n this._loadCallbacks.add(callback);\n return () => {\n this._loadCallbacks.delete(callback);\n };\n }\n\n /**\n * Listen for page config changes.\n */\n onPageConfigChange(callback: (config: PageConfig) => void): Unsubscribe {\n this._pageConfigCallbacks.add(callback);\n return () => {\n this._pageConfigCallbacks.delete(callback);\n };\n }\n\n // ----------------------------------------------------------\n // Page operations\n // ----------------------------------------------------------\n\n /**\n * Get the current number of pages.\n */\n getPageCount(): number {\n return this._paginationResult.pageCount;\n }\n\n /**\n * Get the current page configuration.\n */\n getPageConfig(): PageConfig | null {\n return this._pageConfig;\n }\n\n /**\n * Set page configuration (size, margins).\n * Triggers re-pagination.\n */\n setPageConfig(config: Partial<PageConfig>): void {\n if (this._pageConfig) {\n this._pageConfig = {\n ...this._pageConfig,\n ...config,\n margins: {\n ...this._pageConfig.margins,\n ...(config.margins || {}),\n },\n };\n this._pageConfigCallbacks.forEach((cb) => cb(this._pageConfig!));\n }\n }\n\n // ----------------------------------------------------------\n // Element access (for future DB sync)\n // ----------------------------------------------------------\n\n /**\n * Query elements within the document by CSS selector.\n * Useful for targeting specific sections for database sync.\n */\n querySelectorAll(selector: string): Element[] {\n const tmp = document.createElement('div');\n tmp.innerHTML = this.getHTML();\n return Array.from(tmp.querySelectorAll(selector));\n }\n\n /**\n * Get the innerHTML of a specific element by its ID.\n */\n getElementContent(id: string): string | null {\n const tmp = document.createElement('div');\n tmp.innerHTML = this.getHTML();\n const el = tmp.querySelector(`#${id}`);\n return el ? el.innerHTML : null;\n }\n\n /**\n * Set the innerHTML of a specific element by its ID.\n * Re-loads the full document with the modification.\n */\n setElementContent(id: string, html: string): void {\n const tmp = document.createElement('div');\n tmp.innerHTML = this.getHTML();\n const el = tmp.querySelector(`#${id}`);\n if (el) {\n el.innerHTML = html;\n this.loadHTML(tmp.innerHTML, this._css);\n }\n }\n\n // ----------------------------------------------------------\n // Internal connectors (used by DopeCanvas component)\n // ----------------------------------------------------------\n\n /** @internal Called by DopeCanvas to wire up live content access */\n _connectGetHTML(fn: () => string): void {\n this._getHTMLFn = fn;\n }\n\n /** @internal Called by DopeCanvas to wire up plain text access */\n _connectGetPlainText(fn: () => string): void {\n this._getPlainTextFn = fn;\n }\n\n /** @internal Called by DopeCanvas when content changes */\n _notifyChange(html: string): void {\n this._html = html;\n this._changeCallbacks.forEach((cb) => cb(html));\n }\n\n /** @internal Called by DopeCanvas when pagination runs */\n _updatePagination(result: PaginationResult): void {\n this._paginationResult = result;\n }\n\n /** @internal Called by DopeCanvas when page config changes */\n _updatePageConfig(config: PageConfig): void {\n this._pageConfig = config;\n }\n}\n","// ============================================================\n// useSelectionContext — Track what element type is selected\n// ============================================================\n\nimport { useState, useEffect, useCallback } from 'react';\nimport type { ToolbarContext } from '../core/types';\nimport type { EditableManager } from '../core/EditableManager';\n\nexport function useSelectionContext(\n editableManager: EditableManager | null\n): ToolbarContext {\n const [context, setContext] = useState<ToolbarContext>('none');\n\n useEffect(() => {\n if (!editableManager) return;\n\n const unsub = editableManager.onContextChange((ctx) => {\n setContext(ctx);\n });\n\n return unsub;\n }, [editableManager]);\n\n return context;\n}\n\n/**\n * Hook to query the current formatting state (bold, italic, etc.)\n * from the browser's selection.\n */\nexport function useFormattingState() {\n const [state, setState] = useState({\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n justifyLeft: false,\n justifyCenter: false,\n justifyRight: false,\n justifyFull: false,\n });\n\n const updateState = useCallback(() => {\n setState({\n bold: document.queryCommandState('bold'),\n italic: document.queryCommandState('italic'),\n underline: document.queryCommandState('underline'),\n strikethrough: document.queryCommandState('strikethrough'),\n justifyLeft: document.queryCommandState('justifyLeft'),\n justifyCenter: document.queryCommandState('justifyCenter'),\n justifyRight: document.queryCommandState('justifyRight'),\n justifyFull: document.queryCommandState('justifyFull'),\n });\n }, []);\n\n useEffect(() => {\n document.addEventListener('selectionchange', updateState);\n return () => {\n document.removeEventListener('selectionchange', updateState);\n };\n }, [updateState]);\n\n return state;\n}\n","// ============================================================\n// TextToolbar — Text formatting tools\n// ============================================================\n\nimport React, { useCallback, useRef } from 'react';\nimport { useFormattingState } from '../../hooks/useSelectionContext';\n\ninterface TextToolbarProps {\n onExecCommand: (command: string, value?: string) => void;\n}\n\nexport const TextToolbar: React.FC<TextToolbarProps> = ({ onExecCommand }) => {\n const formatState = useFormattingState();\n\n // ----------------------------------------------------------\n // Selection save / restore\n // ----------------------------------------------------------\n // Toolbar controls (selects, color pickers) steal focus from\n // the contentEditable area, clearing the browser selection.\n // We save the range on mouseDown (before focus moves) and\n // restore it before executing the formatting command.\n // ----------------------------------------------------------\n\n const savedRangeRef = useRef<Range | null>(null);\n\n const saveSelection = useCallback(() => {\n const sel = window.getSelection();\n if (sel && sel.rangeCount > 0) {\n savedRangeRef.current = sel.getRangeAt(0).cloneRange();\n }\n }, []);\n\n const restoreSelection = useCallback(() => {\n const range = savedRangeRef.current;\n if (!range) return;\n const sel = window.getSelection();\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(range);\n }\n }, []);\n\n const handleCommand = useCallback(\n (command: string, value?: string) => (e: React.MouseEvent) => {\n e.preventDefault(); // Don't steal focus from content\n onExecCommand(command, value);\n },\n [onExecCommand]\n );\n\n const handleFontSize = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n restoreSelection();\n onExecCommand('fontSize', e.target.value);\n },\n [onExecCommand, restoreSelection]\n );\n\n const handleHeading = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n restoreSelection();\n const value = e.target.value;\n if (value === 'p') {\n onExecCommand('formatBlock', 'p');\n } else {\n onExecCommand('formatBlock', value);\n }\n },\n [onExecCommand, restoreSelection]\n );\n\n const handleForeColor = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n restoreSelection();\n onExecCommand('foreColor', e.target.value);\n },\n [onExecCommand, restoreSelection]\n );\n\n const handleBackColor = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n restoreSelection();\n onExecCommand('hiliteColor', e.target.value);\n },\n [onExecCommand, restoreSelection]\n );\n\n return (\n <div style={toolbarSectionStyle}>\n {/* Block format */}\n <select\n onChange={handleHeading}\n defaultValue=\"p\"\n style={selectStyle}\n title=\"Block Format\"\n onMouseDown={saveSelection}\n >\n <option value=\"p\">Paragraph</option>\n <option value=\"h1\">Heading 1</option>\n <option value=\"h2\">Heading 2</option>\n <option value=\"h3\">Heading 3</option>\n <option value=\"h4\">Heading 4</option>\n <option value=\"h5\">Heading 5</option>\n <option value=\"h6\">Heading 6</option>\n </select>\n\n <div style={dividerStyle} />\n\n {/* Font size */}\n <select\n onChange={handleFontSize}\n defaultValue=\"3\"\n style={selectStyle}\n title=\"Font Size\"\n onMouseDown={saveSelection}\n >\n <option value=\"1\">8pt</option>\n <option value=\"2\">10pt</option>\n <option value=\"3\">12pt</option>\n <option value=\"4\">14pt</option>\n <option value=\"5\">18pt</option>\n <option value=\"6\">24pt</option>\n <option value=\"7\">36pt</option>\n </select>\n\n <div style={dividerStyle} />\n\n {/* Inline formatting */}\n <ToolbarButton\n icon=\"B\"\n title=\"Bold (Ctrl+B)\"\n active={formatState.bold}\n onMouseDown={handleCommand('bold')}\n extraStyle={{ fontWeight: 'bold' }}\n />\n <ToolbarButton\n icon=\"I\"\n title=\"Italic (Ctrl+I)\"\n active={formatState.italic}\n onMouseDown={handleCommand('italic')}\n extraStyle={{ fontStyle: 'italic' }}\n />\n\n <div style={dividerStyle} />\n\n {/* Colors */}\n <label style={colorLabelStyle} title=\"Text Color\" onMouseDown={saveSelection}>\n A\n <input\n type=\"color\"\n defaultValue=\"#000000\"\n onChange={handleForeColor}\n style={colorInputStyle}\n />\n </label>\n <label style={colorLabelStyle} title=\"Highlight Color\" onMouseDown={saveSelection}>\n <span style={{ backgroundColor: '#ffff00', padding: '0 2px' }}>A</span>\n <input\n type=\"color\"\n defaultValue=\"#ffff00\"\n onChange={handleBackColor}\n style={colorInputStyle}\n />\n </label>\n </div>\n );\n};\n\n// ----------------------------------------------------------\n// ToolbarButton sub-component\n// ----------------------------------------------------------\n\ninterface ToolbarButtonProps {\n icon: string;\n title: string;\n active?: boolean;\n onMouseDown: (e: React.MouseEvent) => void;\n extraStyle?: React.CSSProperties;\n}\n\nconst ToolbarButton: React.FC<ToolbarButtonProps> = ({\n icon,\n title,\n active,\n onMouseDown,\n extraStyle,\n}) => {\n return (\n <button\n type=\"button\"\n title={title}\n onMouseDown={onMouseDown}\n style={{\n width: '28px',\n height: '28px',\n borderWidth: '1px',\n borderStyle: 'solid',\n borderColor: active ? '#b0b5bd' : 'transparent',\n borderRadius: '3px',\n backgroundColor: active ? '#d0d5dd' : 'transparent',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '13px',\n color: '#333',\n padding: 0,\n fontFamily: 'inherit',\n ...extraStyle,\n }}\n dangerouslySetInnerHTML={{ __html: icon }}\n />\n );\n};\n\n// ----------------------------------------------------------\n// Styles\n// ----------------------------------------------------------\n\nconst toolbarSectionStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '2px',\n flexWrap: 'wrap',\n};\n\nconst selectStyle: React.CSSProperties = {\n height: '28px',\n borderWidth: '1px',\n borderStyle: 'solid',\n borderColor: '#ccc',\n borderRadius: '3px',\n fontSize: '12px',\n padding: '0 4px',\n cursor: 'pointer',\n backgroundColor: '#fff',\n};\n\nconst dividerStyle: React.CSSProperties = {\n width: '1px',\n height: '20px',\n backgroundColor: '#ddd',\n margin: '0 4px',\n};\n\nconst colorLabelStyle: React.CSSProperties = {\n position: 'relative',\n width: '28px',\n height: '28px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n fontSize: '13px',\n fontWeight: 'bold',\n};\n\nconst colorInputStyle: React.CSSProperties = {\n position: 'absolute',\n bottom: 0,\n left: 0,\n width: '100%',\n height: '4px',\n padding: 0,\n borderWidth: 0,\n borderStyle: 'none',\n cursor: 'pointer',\n};\n","// ============================================================\n// PageSetupToolbar — Page size and margin controls\n// ============================================================\n\nimport React, { useCallback } from 'react';\nimport type { PageConfig, PageSizeName } from '../../core/types';\n\ninterface PageSetupToolbarProps {\n pageConfig: PageConfig;\n pageCount: number;\n onPageConfigChange: (config: Partial<PageConfig>) => void;\n}\n\nexport const PageSetupToolbar: React.FC<PageSetupToolbarProps> = ({\n pageConfig,\n pageCount,\n onPageConfigChange,\n}) => {\n const handleSizeChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n const value = e.target.value as PageSizeName;\n onPageConfigChange({ size: value });\n },\n [onPageConfigChange]\n );\n\n const handleMarginChange = useCallback(\n (side: keyof typeof pageConfig.margins) =>\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = Math.max(0, parseInt(e.target.value) || 0);\n onPageConfigChange({\n margins: {\n ...pageConfig.margins,\n [side]: value,\n },\n });\n },\n [pageConfig.margins, onPageConfigChange]\n );\n\n const currentSize =\n typeof pageConfig.size === 'string' ? pageConfig.size : 'custom';\n\n return (\n <div style={sectionStyle}>\n {/* Page size */}\n <label style={labelStyle}>\n Page:\n <select\n value={currentSize}\n onChange={handleSizeChange}\n style={selectStyle}\n >\n <option value=\"letter\">Letter (8.5 x 11)</option>\n <option value=\"a4\">A4 (210 x 297mm)</option>\n <option value=\"legal\">Legal (8.5 x 14)</option>\n </select>\n </label>\n\n <div style={dividerStyle} />\n\n {/* Margins */}\n <span style={{ fontSize: '12px', color: '#666' }}>Margins (px):</span>\n <MarginInput\n label=\"T\"\n value={pageConfig.margins.top}\n onChange={handleMarginChange('top')}\n />\n <MarginInput\n label=\"R\"\n value={pageConfig.margins.right}\n onChange={handleMarginChange('right')}\n />\n <MarginInput\n label=\"B\"\n value={pageConfig.margins.bottom}\n onChange={handleMarginChange('bottom')}\n />\n <MarginInput\n label=\"L\"\n value={pageConfig.margins.left}\n onChange={handleMarginChange('left')}\n />\n\n <div style={dividerStyle} />\n\n {/* Page count */}\n <span style={{ fontSize: '12px', color: '#666' }}>\n {pageCount} {pageCount === 1 ? 'page' : 'pages'}\n </span>\n </div>\n );\n};\n\n// ----------------------------------------------------------\n// MarginInput sub-component\n// ----------------------------------------------------------\n\ninterface MarginInputProps {\n label: string;\n value: number;\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\nconst MarginInput: React.FC<MarginInputProps> = ({ label, value, onChange }) => (\n <label style={marginLabelStyle} title={`${label} margin`}>\n {label}:\n <input\n type=\"number\"\n value={value}\n onChange={onChange}\n style={marginInputStyle}\n min={0}\n max={300}\n step={12}\n />\n </label>\n);\n\n// ----------------------------------------------------------\n// Styles\n// ----------------------------------------------------------\n\nconst sectionStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n flexWrap: 'wrap',\n};\n\nconst labelStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n fontSize: '12px',\n color: '#666',\n};\n\nconst selectStyle: React.CSSProperties = {\n height: '26px',\n borderWidth: '1px',\n borderStyle: 'solid',\n borderColor: '#ccc',\n borderRadius: '3px',\n fontSize: '12px',\n padding: '0 4px',\n cursor: 'pointer',\n backgroundColor: '#fff',\n};\n\nconst dividerStyle: React.CSSProperties = {\n width: '1px',\n height: '20px',\n backgroundColor: '#ddd',\n margin: '0 4px',\n};\n\nconst marginLabelStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '2px',\n fontSize: '11px',\n color: '#666',\n};\n\nconst marginInputStyle: React.CSSProperties = {\n width: '44px',\n height: '24px',\n borderWidth: '1px',\n borderStyle: 'solid',\n borderColor: '#ccc',\n borderRadius: '3px',\n fontSize: '11px',\n textAlign: 'center',\n padding: '0 2px',\n};\n","// ============================================================\n// Toolbar — Main toolbar container with context switching\n// ============================================================\n\nimport React from 'react';\nimport { TextToolbar } from './TextToolbar';\nimport { PageSetupToolbar } from './PageSetupToolbar';\nimport type { PageConfig } from '../../core/types';\n\ninterface ToolbarProps {\n pageConfig: PageConfig;\n pageCount: number;\n onExecCommand: (command: string, value?: string) => void;\n onPageConfigChange: (config: Partial<PageConfig>) => void;\n}\n\nexport const Toolbar: React.FC<ToolbarProps> = ({\n pageConfig,\n pageCount,\n onExecCommand,\n onPageConfigChange,\n}) => {\n return (\n <div style={toolbarContainerStyle}>\n {/* Top row: Text formatting */}\n <div style={toolbarRowStyle}>\n <TextToolbar onExecCommand={onExecCommand} />\n </div>\n\n {/* Bottom row: Page setup */}\n <div style={toolbarRowStyle}>\n <PageSetupToolbar\n pageConfig={pageConfig}\n pageCount={pageCount}\n onPageConfigChange={onPageConfigChange}\n />\n </div>\n </div>\n );\n};\n\n// ----------------------------------------------------------\n// Styles\n// ----------------------------------------------------------\n\nconst toolbarContainerStyle: React.CSSProperties = {\n borderBottomWidth: '1px',\n borderBottomStyle: 'solid',\n borderBottomColor: '#d0d0d0',\n backgroundColor: '#f8f8f8',\n padding: '4px 8px',\n display: 'flex',\n flexDirection: 'column',\n gap: '4px',\n flexShrink: 0,\n zIndex: 10,\n};\n\nconst toolbarRowStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n minHeight: '32px',\n};\n","// ============================================================\n// useDocumentEngine — React hook wrapping DocumentEngine\n// ============================================================\n\nimport { useRef, useState, useCallback, useEffect } from 'react';\nimport { DocumentEngine } from '../core/DocumentEngine';\nimport type { PageConfig, PaginationResult } from '../core/types';\nimport { DEFAULT_PAGE_CONFIG } from '../core/types';\n\ninterface UseDocumentEngineOptions {\n initialHTML?: string;\n initialCSS?: string;\n initialConfig?: PageConfig;\n}\n\ninterface UseDocumentEngineReturn {\n engine: DocumentEngine;\n paginationResult: PaginationResult;\n pageConfig: PageConfig;\n loadHTML: (html: string, css?: string) => void;\n setPageConfig: (config: Partial<PageConfig>) => void;\n triggerPagination: () => void;\n getHTML: () => string;\n getPlainText: () => string;\n}\n\nexport function useDocumentEngine(\n options: UseDocumentEngineOptions = {}\n): UseDocumentEngineReturn {\n const {\n initialHTML = '',\n initialCSS = '',\n initialConfig = DEFAULT_PAGE_CONFIG,\n } = options;\n\n const engineRef = useRef<DocumentEngine>(new DocumentEngine(initialConfig));\n const [paginationResult, setPaginationResult] = useState<PaginationResult>({\n pages: [{ blockIndices: [] }],\n pageCount: 1,\n });\n const [pageConfig, setPageConfigState] = useState<PageConfig>(initialConfig);\n\n // Load HTML into engine\n const loadHTML = useCallback((html: string, css?: string) => {\n engineRef.current.loadHTML(html, css);\n }, []);\n\n // Set page configuration\n const setPageConfig = useCallback((config: Partial<PageConfig>) => {\n engineRef.current.setPageConfig(config);\n setPageConfigState(engineRef.current.getPageConfig());\n }, []);\n\n // Trigger re-pagination\n const triggerPagination = useCallback(() => {\n const { result } = engineRef.current.runPagination();\n setPaginationResult(result);\n }, []);\n\n // Get current HTML content\n const getHTML = useCallback(() => {\n return engineRef.current.getHTML();\n }, []);\n\n // Get plain text\n const getPlainText = useCallback(() => {\n return engineRef.current.getPlainText();\n }, []);\n\n // Load initial HTML\n useEffect(() => {\n if (initialHTML) {\n engineRef.current.loadHTML(initialHTML, initialCSS);\n }\n }, [initialHTML, initialCSS]);\n\n // Subscribe to pagination events\n useEffect(() => {\n const unsub = engineRef.current.onPagination((result) => {\n setPaginationResult(result);\n });\n return unsub;\n }, []);\n\n // Cleanup\n useEffect(() => {\n return () => {\n engineRef.current.destroy();\n };\n }, []);\n\n return {\n engine: engineRef.current,\n paginationResult,\n pageConfig,\n loadHTML,\n setPageConfig,\n triggerPagination,\n getHTML,\n getPlainText,\n };\n}\n"],"names":["Page","dimensions","margins","pageNumber","totalPages","children","jsxs","jsx","BlockToolbar","visible","onAddBelow","onEditHTML","onDelete","toolbarStyle","e","Btn","PlusIcon","CodeIcon","TrashIcon","onClick","title","danger","hovered","setHovered","useState","btnStyle","HTMLEditorModal","html","onSave","onCancel","value","setValue","createPortal","overlayStyle","modalStyle","headerStyle","textareaStyle","ta","start","end","updated","footerStyle","cancelBtnStyle","saveBtnStyle","PAGE_SIZE_PRESETS","DEFAULT_MARGINS","DEFAULT_PAGE_CONFIG","activateScripts","container","activated","orig","fresh","attr","saveCursorPosition","sel","range","anchorNode","wrappers","blockIndex","w","preRange","textOffset","restoreCursorPosition","state","wrapper","walker","remaining","textNode","MemoizedBlockContent","React","isEditable","isTable","PagedView","css","pageConfig","layoutEngine","_editableManager","onContentChange","onPaginationChange","measureRef","useRef","pagesContainerRef","mutationObserverRef","onContentChangeRef","pages","setPages","pendingCursorRef","isRePaginatingRef","pagesRef","hoveredBlockIndex","setHoveredBlockIndex","editingBlockIndex","setEditingBlockIndex","editingHTML","setEditingHTML","hideTimeoutRef","collectHTMLFromDOM","useCallback","contentDivs","htmlParts","contentDiv","content","updatedHTML","paginateHTML","htmlContent","mc","styleEl","measurements","blockHTMLs","m","result","pageData","page","idx","rePaginateFromDOM","cursor","div","contentWidth","measureWrapper","measuredHTMLs","newPages","p","oldDist","newDist","count","i","rePaginateFromDOMRef","runPagination","parsed","el","useEffect","collectBlocksFromDOM","blocks","child","handleAddBlock","globalIndex","handleDeleteBlock","handleOpenEditor","handleSaveHTML","newHTML","handleCancelEditor","cell","activatedScripts","debounceTimer","observer","s","scrollContainerStyle","pagesWrapperStyle","pageIndex","pageStartIdx","sum","blockHTML","globalIdx","lower","prev","PageLayoutEngine","config","style","breakBefore","breakAfter","rect","marginTop","marginBottom","totalHeight","contentHeight","currentPage","currentHeight","block","EditableManager","table","_mutations","selection","node","current","tag","ctx","cb","last","previous","next","fn","callback","command","DopeCanvas","forwardRef","externalPageConfig","onPageConfigChange","ref","internalPageConfig","setInternalPageConfig","paginationResult","setPaginationResult","currentHTMLRef","rootRef","useMemo","editableManager","handleContentChange","handlePageConfigChange","newConfig","handlePaginationChange","useImperativeHandle","parts","freshHTML","liveHTML","divs","d","tmp","DocumentEngine","contentWrapper","DocumentAPI","selector","id","useSelectionContext","context","setContext","useFormattingState","setState","updateState","TextToolbar","onExecCommand","formatState","savedRangeRef","saveSelection","restoreSelection","handleCommand","handleFontSize","handleHeading","handleForeColor","handleBackColor","toolbarSectionStyle","selectStyle","dividerStyle","ToolbarButton","colorLabelStyle","colorInputStyle","icon","active","onMouseDown","extraStyle","PageSetupToolbar","pageCount","handleSizeChange","handleMarginChange","side","currentSize","sectionStyle","labelStyle","MarginInput","label","onChange","marginLabelStyle","marginInputStyle","Toolbar","toolbarContainerStyle","toolbarRowStyle","useDocumentEngine","options","initialHTML","initialCSS","initialConfig","engineRef","setPageConfigState","loadHTML","setPageConfig","triggerPagination","getHTML","getPlainText"],"mappings":"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"}