@one2x/medeo-rte 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/embed/code.ts","../src/embed/image.ts","../src/model/markers.ts","../src/model/blocks.ts","../src/model/types.ts","../src/model/virtualBlock.ts","../src/layout/measure.ts","../src/layout/refMetrics.ts","../src/layout/style.ts","../src/layout/wrap.ts","../src/layout/engine.ts","../src/paint/decorations.ts","../src/embed/ref.ts","../src/embed/slot.ts","../src/embed/video.ts","../src/embed/host.ts","../src/embed/registry.ts","../src/embed/index.ts","../src/mutations/types.ts","../src/mutations/apply.ts","../src/model/fragment.ts","../src/mutations/invert.ts","../src/mutations/ranges.ts","../src/mutations/transform.ts","../src/mutations/selection.ts","../src/edits/editResult.ts","../src/operations/context.ts","../src/operations/resolve.ts","../src/operations/primitives.ts","../src/operations/style.ts","../src/convert/markdown.ts","../src/model/document.ts","../src/operations/entity.ts","../src/operations/virtualBlock.ts","../src/operations/text.ts","../src/operations/table.ts","../src/convert/mdPaste.ts","../src/operations/slice.ts","../src/edits/transaction.ts","../src/edits/undoStack.ts","../src/input/ime.ts","../src/commands/shortcuts.ts","../src/input/keyboard.ts","../src/perf.ts","../src/input/caretMotion.ts","../src/convert/clipboard.ts","../src/paint/canvasPainter.ts","../src/paint/htmlPainter.ts","../src/editor.ts"],"sourcesContent":["import { EmbedEntity } from '../model/types';\nimport { EmbedBox, EmbedPlugin, emitEmbedChange } from './types';\n\nexport const CODE_LANGUAGES = ['plain', 'javascript', 'typescript', 'python', 'json', 'html', 'css'] as const;\nconst BAR_H = 28;\nconst LINE_H = 18;\nconst PAD = 12;\n\nexport function measureCode(entity: EmbedEntity, contentWidth: number): { width: number; height: number } {\n const lines = Math.max(1, (entity.code ?? '').split('\\n').length);\n const width = Math.max(160, entity.width || contentWidth);\n return { width, height: BAR_H + PAD * 2 + lines * LINE_H };\n}\n\nexport const codePlugin: EmbedPlugin = {\n kind: 'code',\n keepAspectRatio: false,\n interactive: true,\n overlayOnCanvas: true,\n measure: measureCode,\n create(box) {\n const root = document.createElement('div');\n root.className = 'mini-embed mini-code mini-embed-interactive';\n const bar = document.createElement('div');\n bar.className = 'mini-code-bar';\n const sel = document.createElement('select');\n sel.className = 'mini-code-lang';\n for (const lang of CODE_LANGUAGES) {\n const opt = document.createElement('option');\n opt.value = lang;\n opt.textContent = lang;\n sel.appendChild(opt);\n }\n bar.appendChild(sel);\n const input = document.createElement('textarea');\n input.className = 'mini-code-input';\n input.spellcheck = false;\n input.value = box.entity.code ?? '';\n sel.value = box.entity.language ?? 'plain';\n root.append(bar, input);\n\n sel.addEventListener('change', () => {\n emitEmbedChange(root, { id: box.entity.id, patch: { language: sel.value } }, true);\n });\n input.addEventListener('input', () => {\n emitEmbedChange(root, { id: box.entity.id, patch: { code: input.value } });\n });\n input.addEventListener('blur', () => {\n emitEmbedChange(root, { id: box.entity.id, patch: { code: input.value } }, true);\n });\n return root;\n },\n update(el, box) {\n const sel = el.querySelector<HTMLSelectElement>('.mini-code-lang');\n const input = el.querySelector<HTMLTextAreaElement>('.mini-code-input');\n if (sel && document.activeElement !== sel) sel.value = box.entity.language ?? 'plain';\n if (input && document.activeElement !== input) input.value = box.entity.code ?? '';\n },\n paintCanvasBackdrop(ctx, box) {\n ctx.fillStyle = '#f4f6f8';\n ctx.fillRect(box.x, box.y, box.w, box.h);\n }\n};\n","import { EmbedBox, EmbedPlugin } from './types';\n\nexport const imagePlugin: EmbedPlugin = {\n kind: 'image',\n keepAspectRatio: true,\n interactive: false,\n overlayOnCanvas: false,\n measure(entity) {\n return { width: entity.width, height: entity.height };\n },\n create(box) {\n const node = document.createElement('img');\n node.className = 'mini-embed mini-image';\n node.draggable = false;\n node.src = box.entity.src ?? '';\n return node;\n },\n update(el, box) {\n const img = el as HTMLImageElement;\n if (box.entity.src && img.src !== box.entity.src) img.src = box.entity.src;\n el.classList.toggle('is-inline', box.h <= 32);\n },\n paintCanvasBackdrop(ctx, box, imageOf) {\n const src = box.entity.src;\n if (!src) return;\n const node = imageOf(src);\n if (!node.complete || node.naturalWidth <= 0) return;\n if (box.h <= 32) {\n ctx.save();\n ctx.beginPath();\n ctx.roundRect(box.x, box.y, box.w, box.h, 6);\n ctx.clip();\n ctx.drawImage(node, box.x, box.y, box.w, box.h);\n ctx.restore();\n return;\n }\n ctx.drawImage(node, box.x, box.y, box.w, box.h);\n }\n};\n","/** 文档流里的结构标记:每个标记占一个下标,和普通字符一样参与排版与选区。 */\nexport const MARKERS = {\n PARAGRAPH: '\\n',\n IMAGE: '*',\n TABLE_START: '\\u0010',\n TABLE_END: '\\u0011',\n TABLE_ROW: '\\u0012',\n TABLE_CELL: '\\u001c'\n} as const;\n\nexport function isTableMarker(ch: string): boolean {\n return (\n ch === MARKERS.TABLE_START ||\n ch === MARKERS.TABLE_END ||\n ch === MARKERS.TABLE_ROW ||\n ch === MARKERS.TABLE_CELL\n );\n}\n\nexport function isStructuralMarker(ch: string): boolean {\n return ch === MARKERS.PARAGRAPH || isTableMarker(ch);\n}\n\nexport function prevCodePointLen(text: string, index: number): number {\n if (index <= 0) return 0;\n const c = text.charCodeAt(index - 1);\n if (c >= 0xdc00 && c <= 0xdfff && index >= 2) {\n const p = text.charCodeAt(index - 2);\n if (p >= 0xd800 && p <= 0xdbff) return 2;\n }\n return 1;\n}\n\nexport function nextCodePointLen(text: string, index: number): number {\n if (index >= text.length) return 0;\n const c = text.charCodeAt(index);\n if (c >= 0xd800 && c <= 0xdbff && index + 1 < text.length) {\n const n = text.charCodeAt(index + 1);\n if (n >= 0xdc00 && n <= 0xdfff) return 2;\n }\n return 1;\n}\n","import { isTableMarker, MARKERS } from './markers';\nimport type { ParagraphProps } from './types';\n\nexport interface ParaRange {\n start: number;\n end: number;\n}\n\nexport interface TableCellBlock {\n marker: number;\n start: number;\n end: number;\n paragraphs: ParaRange[];\n}\n\nexport interface TableRowBlock {\n marker: number;\n start: number;\n end: number;\n cells: TableCellBlock[];\n}\n\nexport interface ParagraphBlock {\n kind: 'paragraph';\n start: number;\n end: number;\n}\n\nexport interface TableBlock {\n kind: 'table';\n start: number;\n end: number;\n rows: TableRowBlock[];\n}\n\nexport type Block = ParagraphBlock | TableBlock;\n\n/**\n * parseBlocks 结果缓存。spacers 是不可变字符串,内容一样块结构就一样;一次按键里\n * 排版、工具栏、状态栏、操作层会把全文解析十几次,长文档下每次都是毫秒级。\n * 只留最近两份(当前文档 + 片段/临时文档交替时不互相挤掉)。返回值视为只读。\n */\nconst blockCache: { spacers: string; blocks: Block[] }[] = [];\n\nexport function parseBlocks(spacers: string): Block[] {\n for (const c of blockCache) {\n if (c.spacers === spacers) return c.blocks;\n }\n const blocks = parseBlocksUncached(spacers);\n blockCache.unshift({ spacers, blocks });\n if (blockCache.length > 2) blockCache.pop();\n return blocks;\n}\n\nfunction parseBlocksUncached(spacers: string): Block[] {\n const blocks: Block[] = [];\n let i = 0;\n while (i < spacers.length) {\n if (spacers[i] === MARKERS.TABLE_START) {\n const table = parseTable(spacers, i);\n blocks.push(table);\n i = table.end;\n } else {\n let j = i;\n while (j < spacers.length && spacers[j] !== MARKERS.PARAGRAPH && spacers[j] !== MARKERS.TABLE_START) {\n j++;\n }\n if (j < spacers.length && spacers[j] === MARKERS.PARAGRAPH) {\n j++;\n }\n if (j === i) {\n i++;\n continue;\n }\n blocks.push({ kind: 'paragraph', start: i, end: j });\n i = j;\n }\n }\n return blocks;\n}\n\nfunction parseTable(spacers: string, start: number): TableBlock {\n let i = start + 1;\n const rows: TableRowBlock[] = [];\n while (i < spacers.length && spacers[i] !== MARKERS.TABLE_END) {\n if (spacers[i] !== MARKERS.TABLE_ROW) {\n i++;\n continue;\n }\n const rowMarker = i;\n i += 1;\n const cells: TableCellBlock[] = [];\n while (i < spacers.length && spacers[i] === MARKERS.TABLE_CELL) {\n const cellMarker = i;\n i += 1;\n const paragraphs: ParaRange[] = [];\n let paraStart = i;\n while (i < spacers.length && !isTableMarker(spacers[i])) {\n if (spacers[i] === MARKERS.PARAGRAPH) {\n paragraphs.push({ start: paraStart, end: i + 1 });\n paraStart = i + 1;\n }\n i++;\n }\n if (paraStart < i) {\n paragraphs.push({ start: paraStart, end: i });\n }\n if (paragraphs.length === 0) {\n paragraphs.push({ start: i, end: i });\n }\n cells.push({ marker: cellMarker, start: cellMarker, end: i, paragraphs });\n }\n rows.push({ marker: rowMarker, start: rowMarker, end: i, cells });\n }\n let end = i;\n if (i < spacers.length && spacers[i] === MARKERS.TABLE_END) {\n end = i + 1;\n }\n return { kind: 'table', start, end, rows };\n}\n\nexport function findTableAt(spacers: string, index: number): TableBlock | null {\n for (const block of parseBlocks(spacers)) {\n if (block.kind === 'table' && index >= block.start && index < block.end) {\n return block;\n }\n }\n return null;\n}\n\nexport function isEmptyParagraph(spacers: string, para: ParaRange): boolean {\n const contentEnd = spacers[para.end - 1] === MARKERS.PARAGRAPH ? para.end - 1 : para.end;\n return contentEnd <= para.start;\n}\n\n/** 列表标记 / 标题画在段落样式上,不进 spacer;有它们时占位符不能当空文档。 */\nexport function isVisuallyEmptyDoc(doc: {\n spacers: string;\n entities: { size: number };\n paragraphPropsAt: (index: number) => ParagraphProps;\n}): boolean {\n if (doc.entities.size > 0) return false;\n for (const ch of doc.spacers) {\n if (ch !== MARKERS.PARAGRAPH) return false;\n }\n for (const block of parseBlocks(doc.spacers)) {\n if (block.kind !== 'paragraph') return false;\n const props = doc.paragraphPropsAt(block.start);\n if ((props.list ?? 'none') !== 'none') return false;\n if ((props.heading ?? 0) > 0) return false;\n if ((props.indent ?? 0) > 0) return false;\n }\n return true;\n}\n\nexport function findParagraphAt(spacers: string, index: number): ParaRange | null {\n const clamped = Math.max(0, Math.min(index, spacers.length));\n for (const block of parseBlocks(spacers)) {\n if (block.kind === 'paragraph' && clamped >= block.start && clamped <= block.end) {\n if (clamped === block.end && clamped < spacers.length) continue;\n return { start: block.start, end: block.end };\n }\n if (block.kind === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const para of cell.paragraphs) {\n if (clamped >= para.start && clamped <= para.end) {\n if (clamped === para.end && clamped < cell.end) continue;\n return para;\n }\n }\n }\n }\n }\n }\n if (spacers.length === 0) return { start: 0, end: 0 };\n return null;\n}\n\nexport function paragraphsIntersecting(spacers: string, start: number, end: number): ParaRange[] {\n const from = Math.min(start, end);\n const to = Math.max(start, end);\n if (from === to) {\n const para = findParagraphAt(spacers, from);\n return para ? [para] : [];\n }\n const out: ParaRange[] = [];\n for (const block of parseBlocks(spacers)) {\n if (block.kind === 'paragraph') {\n if (block.end > from && block.start < to) out.push(block);\n } else {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const para of cell.paragraphs) {\n if (para.end > from && para.start < to) out.push(para);\n }\n }\n }\n }\n }\n return uniqueRanges(out);\n}\n\nfunction uniqueRanges(ranges: ParaRange[]): ParaRange[] {\n const seen = new Set<string>();\n const out: ParaRange[] = [];\n for (const r of ranges) {\n const k = `${r.start}:${r.end}`;\n if (!seen.has(k)) {\n seen.add(k);\n out.push(r);\n }\n }\n return out;\n}\n\nexport function cellAt(spacers: string, index: number): { table: TableBlock; row: number; col: number; cell: TableCellBlock } | null {\n const table = findTableAt(spacers, index);\n if (!table) return null;\n for (let r = 0; r < table.rows.length; r++) {\n const row = table.rows[r];\n for (let c = 0; c < row.cells.length; c++) {\n const cell = row.cells[c];\n if (index >= cell.start && index < cell.end) {\n return { table, row: r, col: c, cell };\n }\n if (index === cell.end && c === row.cells.length - 1 && r === table.rows.length - 1) {\n return { table, row: r, col: c, cell };\n }\n }\n }\n return null;\n}\n\n/** 把下标吸附到最近的安全落点,避开表格结构标记 */\nexport function nearestSafeIndex(spacers: string, index: number): number {\n const i = Math.max(0, Math.min(index, spacers.length));\n const ch = spacers[i];\n if (ch === MARKERS.TABLE_CELL) return i + 1;\n if (ch === MARKERS.TABLE_ROW) return i + 2;\n if (ch === MARKERS.TABLE_START) return i + 3;\n if (ch === MARKERS.TABLE_END) return Math.max(0, i - 1);\n return i;\n}\n\nexport function cellContentRange(cell: TableCellBlock): { start: number; end: number } {\n return {\n start: cell.paragraphs[0]?.start ?? cell.start + 1,\n end: cell.end\n };\n}\n\nexport function isLastTableCell(hit: { table: TableBlock; row: number; col: number }): boolean {\n const lastRow = hit.table.rows.length - 1;\n const lastCol = hit.table.rows[lastRow].cells.length - 1;\n return hit.row === lastRow && hit.col === lastCol;\n}\n\nexport function nextCellIndex(spacers: string, index: number, dir: 1 | -1): number | null {\n const here = cellAt(spacers, index);\n if (!here) return null;\n const { table, row, col } = here;\n let r = row;\n let c = col + dir;\n if (c >= table.rows[r].cells.length) {\n r += 1;\n c = 0;\n } else if (c < 0) {\n r -= 1;\n if (r >= 0) c = table.rows[r].cells.length - 1;\n }\n if (r < 0 || r >= table.rows.length) return null;\n const target = table.rows[r].cells[c];\n return target.paragraphs[0]?.start ?? target.start + 1;\n}\n\nexport function expandRangeOverStructures(spacers: string, start: number, end: number): { start: number; end: number } {\n let from = Math.min(start, end);\n let to = Math.max(start, end);\n if (from === to) return { start: from, end: to };\n for (const block of parseBlocks(spacers)) {\n if (block.kind !== 'table') continue;\n const overlaps = from < block.end && to > block.start;\n if (!overlaps) continue;\n const slice = spacers.slice(Math.max(from, block.start), Math.min(to, block.end));\n const touchesEdge = slice.includes(MARKERS.TABLE_START) || slice.includes(MARKERS.TABLE_END) || from <= block.start || to >= block.end;\n if (touchesEdge) {\n from = Math.min(from, block.start);\n to = Math.max(to, block.end);\n }\n }\n return { start: from, end: to };\n}\n\nexport function emptyTableSpacers(rows: number, cols: number): string {\n let s = MARKERS.TABLE_START;\n for (let r = 0; r < rows; r++) {\n s += MARKERS.TABLE_ROW;\n for (let c = 0; c < cols; c++) {\n s += MARKERS.TABLE_CELL + MARKERS.PARAGRAPH;\n }\n }\n s += MARKERS.TABLE_END;\n return s;\n}\n","export type HeadingLevel = 0 | 1 | 2 | 3;\nexport type Align = 'left' | 'center' | 'right';\nexport type ListKind = 'none' | 'ul' | 'ol';\nexport type StyleType = 'text' | 'paragraph' | 'table' | 'cell' | 'image' | 'link';\n\nexport type UnderlineStyle = 'single' | 'double' | 'wavy' | 'dotted' | 'marker';\nexport type TextFill = 'solid' | 'rainbow' | 'sunset';\n\nexport interface TextProps {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n underlineStyle?: UnderlineStyle;\n strikethrough?: boolean;\n fontSize?: number;\n /**\n * CSS font-family 栈。须具名或宿主 CSS 变量(如 `var(--Body-Medium-Font, Manrope)`)。\n * 测宽会在挂载后改用 getComputedStyle 解析后的值。不要用 `system-ui`。\n */\n fontFamily?: string;\n /** 字重,默认 400。`bold: true` 时仍为 700。 */\n fontWeight?: number;\n color?: string;\n fill?: TextFill;\n}\n\nexport interface ParagraphProps {\n heading?: HeadingLevel;\n align?: Align;\n list?: ListKind;\n indent?: number;\n /** 非空时此段属于同一分组;末段末尾回车新段不再继承。空串表示无分组。 */\n groupId?: string;\n}\n\nexport interface TableProps {\n colWidths?: number[];\n}\n\nexport interface CellProps {\n background?: string;\n}\n\nexport interface ImageProps {\n entityId: string;\n}\n\nexport interface LinkProps {\n url: string;\n}\n\nexport type StyleProps = TextProps | ParagraphProps | TableProps | CellProps | ImageProps | LinkProps;\n\n/** 外链默认色 */\nexport const LINK_COLOR = '#2374d1';\n\nexport interface StyleSpan {\n start: number;\n end: number;\n type: StyleType;\n props: StyleProps;\n}\n\n/** 行内嵌入对象:挂在 `*` 占位符上的实体类型 */\n/** `internalSlot` = SDK 内置芯片;`hostSlot` = 宿主自绘芯片。 */\nexport type EmbedKind = 'image' | 'video' | 'code' | 'formula' | 'internalSlot' | 'ref' | 'hostSlot';\nexport type SlotKind = 'text' | 'image' | 'select';\nexport type MediaKind = EmbedKind;\n\nexport interface EmbedEntity {\n id: string;\n kind?: EmbedKind;\n width: number;\n height: number;\n src?: string;\n language?: string;\n code?: string;\n latex?: string;\n displayMode?: boolean;\n slotKind?: SlotKind;\n label?: string;\n slotValue?: string;\n slotOptions?: string[];\n float?: 'left' | 'right';\n fragmentId?: string;\n /**\n * 宿主渲染型嵌入对象(kind:'hostSlot')承载的业务数据。SDK 不解释其内容,只负责\n * 存取、随实体序列化、在数据变化时通知宿主渲染器重渲。宿主通常在此存业务对象\n * 的引用 id(引用式承载),完整数据由宿主自己的 store 解析。\n */\n data?: unknown;\n /** host 型嵌入对象的类型标识(如 'objectRef'),由宿主定义,SDK 原样透传给渲染器。 */\n hostType?: string;\n}\n\nexport interface Fragment {\n id: string;\n title?: string;\n slice: Slice;\n}\n\n/** @deprecated 使用 EmbedEntity;保留别名以免切片/布局大面积改名 */\nexport type ImageEntity = EmbedEntity;\n\n/** 视频默认宽高比 */\nexport const VIDEO_ASPECT = 1920 / 1080;\n\n/**\n * 虚拟块种类:\n * - `region`:一层皮,整体选中/进出,文字不可直接编辑;\n * - `virtualSlot`:最内层文本槽,像输入框(placeholder、选中、进出);\n * - `mark`:纯样式区间,只给文本流加背景/边框/文字缺省,交互与普通文本完全一致。\n * 不参与区间树(parentId 恒为 null)、不进选中/编辑状态机,可与其它块任意叠放。\n */\nexport type VirtualBlockKind = 'region' | 'virtualSlot' | 'mark';\n\n/**\n * 虚拟块的皮和文字缺省。块皮(底、边、圆角、内边距)只能放这里;\n * 文字字段与 {@link TextProps} 对齐,作排版期 fallback,不是 applyStyle 轨道。\n */\nexport interface VirtualBlockChrome {\n background?: string;\n /** 仅 mark:鼠标悬停在该区间上时用这个底色替换 background(整段、含折行各行) */\n hoverBackground?: string;\n borderColor?: string;\n borderWidth?: number;\n radius?: number;\n /** 水平内边距:只外扩底色/边框(行首行尾也外扩),不影响排版。编辑器 padding.x 小于它时,边缘处会被裁 */\n paddingX?: number;\n color?: string;\n fontSize?: number;\n fontFamily?: string;\n fontWeight?: number;\n bold?: boolean;\n italic?: boolean;\n /** 仅 slot:empty 时用这个色画 placeholder */\n placeholderColor?: string;\n}\n\n/**\n * 盖在同一条 spacers 上的可嵌套区间。不占额外字符,不是实体、不是 fragment。\n * 坐标是模型半开区间 [start, end)。\n */\nexport interface VirtualBlock {\n id: string;\n parentId: string | null;\n kind: VirtualBlockKind;\n start: number;\n end: number;\n chrome: VirtualBlockChrome;\n placeholder?: string;\n empty?: boolean;\n}\n\nexport interface Slice {\n text: string;\n styles: StyleSpan[];\n entities: ImageEntity[];\n fragments?: Fragment[];\n virtualBlocks?: VirtualBlock[];\n}\n\nexport interface Selection {\n anchor: number;\n focus: number;\n}\n\nexport function selStart(sel: Selection): number {\n return Math.min(sel.anchor, sel.focus);\n}\n\nexport function selEnd(sel: Selection): number {\n return Math.max(sel.anchor, sel.focus);\n}\n\nexport function isCollapsed(sel: Selection): boolean {\n return sel.anchor === sel.focus;\n}\n\nexport const DEFAULT_TEXT: Required<Pick<TextProps, 'fontSize' | 'color'>> & TextProps = {\n fontSize: 16,\n color: '#1f2329',\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false\n};\n\nexport const DEFAULT_PARAGRAPH: Required<ParagraphProps> = {\n heading: 0,\n align: 'left',\n list: 'none',\n indent: 0,\n groupId: ''\n};\n\n/** 列表最大嵌套层级 */\nexport const MAX_LIST_INDENT = 8;\n\nexport const HEADING_TEXT: Record<HeadingLevel, TextProps> = {\n 0: { fontSize: 16, bold: false },\n 1: { fontSize: 28, bold: true },\n 2: { fontSize: 22, bold: true },\n 3: { fontSize: 18, bold: true }\n};\n\nexport function hasTextProps(props: TextProps): boolean {\n return (\n props.bold !== undefined ||\n props.italic !== undefined ||\n props.underline !== undefined ||\n props.underlineStyle !== undefined ||\n props.strikethrough !== undefined ||\n props.fontSize !== undefined ||\n props.fontFamily !== undefined ||\n props.fontWeight !== undefined ||\n props.color !== undefined ||\n props.fill !== undefined\n );\n}\n\nexport function textPropsEqual(a: TextProps, b: TextProps): boolean {\n return (\n a.bold === b.bold &&\n a.italic === b.italic &&\n a.underline === b.underline &&\n a.underlineStyle === b.underlineStyle &&\n a.strikethrough === b.strikethrough &&\n a.fontSize === b.fontSize &&\n a.fontFamily === b.fontFamily &&\n a.fontWeight === b.fontWeight &&\n a.color === b.color &&\n a.fill === b.fill\n );\n}\n\nexport function underlineKind(style: TextProps): UnderlineStyle | 'none' {\n if (style.underline === false) return 'none';\n if (style.underlineStyle) return style.underlineStyle;\n if (style.underline) return 'single';\n return 'none';\n}\n\nexport function paraPropsEqual(a: ParagraphProps, b: ParagraphProps): boolean {\n return (\n a.heading === b.heading &&\n a.align === b.align &&\n a.list === b.list &&\n a.indent === b.indent &&\n (a.groupId ?? '') === (b.groupId ?? '')\n );\n}\n\nexport function cloneStyle(span: StyleSpan): StyleSpan {\n return { start: span.start, end: span.end, type: span.type, props: { ...span.props } };\n}\n\nexport function cloneEntity(entity: ImageEntity): ImageEntity {\n return { ...entity };\n}\n\nexport function cloneVirtualBlock(block: VirtualBlock): VirtualBlock {\n return { ...block, chrome: { ...block.chrome } };\n}\n\n/** 虚拟块 chrome 上与 TextProps 对齐的文字缺省。 */\nexport function chromeTextProps(chrome: VirtualBlockChrome): TextProps {\n const props: TextProps = {};\n if (chrome.bold !== undefined) props.bold = chrome.bold;\n if (chrome.italic !== undefined) props.italic = chrome.italic;\n if (chrome.fontSize !== undefined) props.fontSize = chrome.fontSize;\n if (chrome.fontFamily !== undefined) props.fontFamily = chrome.fontFamily;\n if (chrome.fontWeight !== undefined) props.fontWeight = chrome.fontWeight;\n if (chrome.color !== undefined) props.color = chrome.color;\n return props;\n}\n","/**\n * 虚拟块区间表的机械运算:挪坐标、裁切、包含判定。\n *\n * 合法性(不交叉、slot 是叶子)由 Operation 保证。这里只做和 style 同类的\n * 闭开区间算术,以及 Slice 裁切时的平移。\n */\nimport { cloneVirtualBlock, VirtualBlock } from './types';\n\nexport function shiftVirtualBlocksOnInsert(\n blocks: Iterable<VirtualBlock>,\n index: number,\n len: number\n): VirtualBlock[] {\n if (!len) return [...blocks].map(cloneVirtualBlock);\n return [...blocks].map((b) => {\n if (b.end <= index) return cloneVirtualBlock(b);\n if (b.start >= index) return cloneVirtualBlock({ ...b, start: b.start + len, end: b.end + len });\n return cloneVirtualBlock({ ...b, end: b.end + len });\n });\n}\n\nexport function shiftVirtualBlocksOnDelete(\n blocks: Iterable<VirtualBlock>,\n start: number,\n end: number\n): VirtualBlock[] {\n const len = end - start;\n if (len <= 0) return [...blocks].map(cloneVirtualBlock);\n const out: VirtualBlock[] = [];\n for (const b of blocks) {\n if (b.end <= start) {\n out.push(cloneVirtualBlock(b));\n } else if (b.start >= end) {\n out.push(cloneVirtualBlock({ ...b, start: b.start - len, end: b.end - len }));\n } else if (b.start < start && b.end > end) {\n out.push(cloneVirtualBlock({ ...b, end: b.end - len }));\n } else if (b.start < start) {\n if (start > b.start) out.push(cloneVirtualBlock({ ...b, end: start }));\n } else if (b.end > end) {\n out.push(cloneVirtualBlock({ ...b, start, end: b.end - len }));\n }\n }\n return out.filter((b) => b.end > b.start);\n}\n\n/** 半开区间是否相交(相邻不算)。 */\nexport function rangesOverlap(a: { start: number; end: number }, b: { start: number; end: number }): boolean {\n return a.start < b.end && b.start < a.end;\n}\n\n/** 是否交叉:相交但谁也不包含谁。 */\nexport function rangesCross(a: { start: number; end: number }, b: { start: number; end: number }): boolean {\n return rangesOverlap(a, b) && !rangeContains(a, b) && !rangeContains(b, a);\n}\n\n/** a 是否包含 b(相等也算包含)。 */\nexport function rangeContains(a: { start: number; end: number }, b: { start: number; end: number }): boolean {\n return a.start <= b.start && a.end >= b.end;\n}\n\nexport function depthOf(block: VirtualBlock, byId: Map<string, VirtualBlock>): number {\n let d = 0;\n let id = block.parentId;\n const seen = new Set<string>([block.id]);\n while (id && !seen.has(id)) {\n seen.add(id);\n const parent = byId.get(id);\n if (!parent) break;\n d += 1;\n id = parent.parentId;\n }\n return d;\n}\n\n/** 外层在前:覆盖更长的、同长则更浅的排前面。 */\nexport function sortOuterToInner(blocks: VirtualBlock[], byId?: Map<string, VirtualBlock>): VirtualBlock[] {\n const map = byId ?? new Map(blocks.map((b) => [b.id, b]));\n return [...blocks].sort((a, b) => {\n const la = a.end - a.start;\n const lb = b.end - b.start;\n if (la !== lb) return lb - la;\n return depthOf(a, map) - depthOf(b, map);\n });\n}\n\nexport function ancestorChain(block: VirtualBlock, byId: Map<string, VirtualBlock>): VirtualBlock[] {\n const chain: VirtualBlock[] = [];\n let cur: VirtualBlock | undefined = block;\n const seen = new Set<string>();\n while (cur && !seen.has(cur.id)) {\n seen.add(cur.id);\n chain.unshift(cloneVirtualBlock(cur));\n cur = cur.parentId ? byId.get(cur.parentId) : undefined;\n }\n return chain;\n}\n\n/**\n * 裁到半开区间 [from, to) 并平移到以 0 为原点。\n * 父块若没被裁进来,parentId 置 null。\n */\nexport function clipVirtualBlocks(\n blocks: Iterable<VirtualBlock>,\n from: number,\n to: number\n): VirtualBlock[] {\n const hits: VirtualBlock[] = [];\n for (const b of blocks) {\n const start = Math.max(b.start, from);\n const end = Math.min(b.end, to);\n if (end <= start) continue;\n hits.push(\n cloneVirtualBlock({\n ...b,\n start: start - from,\n end: end - from\n })\n );\n }\n const ids = new Set(hits.map((b) => b.id));\n for (const b of hits) {\n if (b.parentId && !ids.has(b.parentId)) b.parentId = null;\n }\n return hits;\n}\n\nexport function offsetVirtualBlocks(blocks: Iterable<VirtualBlock>, offset: number): VirtualBlock[] {\n if (!offset) return [...blocks].map(cloneVirtualBlock);\n return [...blocks].map((b) => cloneVirtualBlock({ ...b, start: b.start + offset, end: b.end + offset }));\n}\n","import { measureNaturalWidth, prepareWithSegments, setLocale } from '@chenglou/pretext';\nimport { DEFAULT_TEXT, TextProps } from '../model/types';\n\n/**\n * 默认测量/绘制字体。具名字体,避免 system-ui 在 canvas 与 DOM 上解析不一致。\n *\n * 宿主可通过 `textDefaults.fontFamily` / 文字 span 覆盖。\n * `.mini-editor` 的 `--mini-font-family` 必须与当前测量字体一致。\n */\nexport const FONT_FAMILY = '\"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif';\n\nexport const LINE_HEIGHT = 1.6;\nexport const PAGE_CONTENT_WIDTH = 680;\nexport const PAGE_PADDING_X = 72;\nexport const PAGE_PADDING_Y = 56;\nexport const LIST_MARKER_WIDTH = 28;\nexport const INDENT_STEP = 24;\nexport const CELL_PAD = 8;\n/** 列宽下限(约 18pt,这里用 px) */\nexport const MIN_COL_WIDTH = 36;\nexport const COL_BORDER_HIT = 4;\n\nconst widthCache = new Map<string, number>();\nlet localeReady = false;\n\nexport function ensureLocale() {\n if (localeReady) return;\n setLocale('zh-CN');\n localeReady = true;\n}\n\nexport function fontFamilyOf(props?: TextProps | null): string {\n const raw = props?.fontFamily?.trim();\n // canvas / pretext 不能解析 CSS 变量;测宽应使用 getComputedStyle 解析后的栈。\n if (!raw || /\\bvar\\s*\\(/i.test(raw)) return FONT_FAMILY;\n return raw;\n}\n\nexport function resolveFont(props: TextProps): { size: number; weight: string; style: string; family: string } {\n return {\n size: props.fontSize ?? DEFAULT_TEXT.fontSize,\n weight: props.bold ? '700' : String(props.fontWeight ?? 400),\n style: props.italic ? 'italic' : 'normal',\n family: fontFamilyOf(props)\n };\n}\n\n/** canvas / pretext 用的 font 字符串,需与绘制层 CSS 一致。 */\nexport function canvasFont(props: TextProps): string {\n const font = resolveFont(props);\n return `${font.style} ${font.weight} ${font.size}px ${font.family}`;\n}\n\n/**\n * 宽度测量走 pretext:canvas measureText + 分段缓存,不读 DOM、不触发布局回流。\n * 同一 font+text 只 prepare 一次。\n */\nexport function measureWidth(text: string, props: TextProps): number {\n if (!text) return 0;\n ensureLocale();\n const font = canvasFont(props);\n const key = `${font}\\0${text}`;\n const hit = widthCache.get(key);\n if (hit !== undefined) return hit;\n const prepared = prepareWithSegments(text, font, { whiteSpace: 'pre-wrap' });\n const w = measureNaturalWidth(prepared);\n widthCache.set(key, w);\n return w;\n}\n\nconst glyphCache = new Map<string, number[]>();\nconst GLYPH_CACHE_MAX = 4000;\n\nfunction naturalWidth(text: string, font: string): number {\n if (!text) return 0;\n return measureNaturalWidth(prepareWithSegments(text, font, { whiteSpace: 'pre-wrap' }));\n}\n\n/**\n * 一段文字里每个 UTF-16 单元的前进宽度,用于摆字(glyph.x / caret stop)。\n *\n * 折行用的是整串测宽(带字距调整,如 `Te` 比两个字单独相加窄)。如果摆字改用\n * 「每个字单独测宽再累加」,同一行的实际宽度会比折行时认为的宽,最后一个字就会\n * 越过版心被裁掉。所以这里取前缀宽度之差:`w[k] = width(text[0..k]) - width(text[0..k-1])`,\n * 一整段的宽度之和与 {@link measureWidth}(text) 严格相等。\n *\n * 代理对:高位单元带整个码点的宽度,低位单元为 0,保持 `text.length` 个元素。\n */\nexport function measureGlyphWidths(text: string, props: TextProps): number[] {\n if (!text) return [];\n ensureLocale();\n const font = canvasFont(props);\n const key = `${font}\\0${text}`;\n const hit = glyphCache.get(key);\n if (hit) return hit;\n\n const widths = new Array<number>(text.length).fill(0);\n let prevWidth = 0;\n let k = 0;\n while (k < text.length) {\n const cp = text.codePointAt(k) ?? 0;\n const end = k + (cp > 0xffff ? 2 : 1);\n const width = end === text.length ? measureWidth(text, props) : naturalWidth(text.slice(0, end), font);\n widths[k] = Math.max(0, width - prevWidth);\n prevWidth = width;\n k = end;\n }\n\n if (glyphCache.size >= GLYPH_CACHE_MAX) glyphCache.clear();\n glyphCache.set(key, widths);\n return widths;\n}\n\nexport function lineHeightOf(props: TextProps): number {\n return Math.round((props.fontSize ?? DEFAULT_TEXT.fontSize) * LINE_HEIGHT);\n}\n\nexport function isCjk(ch: string): boolean {\n const c = ch.charCodeAt(0);\n return (\n (c >= 0x4e00 && c <= 0x9fff) ||\n (c >= 0x3400 && c <= 0x4dbf) ||\n (c >= 0x3000 && c <= 0x303f) ||\n (c >= 0xff00 && c <= 0xffef)\n );\n}\n\nexport function canBreakAfter(ch: string): boolean {\n if (!ch) return false;\n if (/\\s/.test(ch)) return true;\n return isCjk(ch);\n}\n","/** 与正文对齐,不再为轨或标题栏留空。 */\nexport const REF_PAD = 0;\nexport const REF_HEAD = 0;\n\nexport function refInnerWidth(boxW: number): number {\n return Math.max(40, boxW - REF_PAD);\n}\n","import { DocumentModel } from '../model/document';\nimport { DEFAULT_TEXT, HEADING_TEXT, LINK_COLOR, LinkProps, ParagraphProps, TextProps, VirtualBlock } from '../model/types';\n\nfunction chromeFallback(doc: DocumentModel, index: number): TextProps {\n const chain = doc.blocksAt(index);\n const t: TextProps = {};\n for (const b of chain) {\n const c = b.chrome;\n if (c.bold !== undefined) t.bold = c.bold;\n if (c.italic !== undefined) t.italic = c.italic;\n if (c.fontSize !== undefined) t.fontSize = c.fontSize;\n if (c.fontFamily !== undefined) t.fontFamily = c.fontFamily;\n if (c.fontWeight !== undefined) t.fontWeight = c.fontWeight;\n if (c.color !== undefined) t.color = c.color;\n }\n const inner = innermostEmptySlot(chain);\n if (inner?.chrome.placeholderColor) t.color = inner.chrome.placeholderColor;\n return t;\n}\n\nfunction innermostEmptySlot(chain: VirtualBlock[]): VirtualBlock | null {\n for (let i = chain.length - 1; i >= 0; i--) {\n if (chain[i].kind === 'virtualSlot' && chain[i].empty) return chain[i];\n }\n return null;\n}\n\nexport function resolvedTextStyle(doc: DocumentModel, index: number, para: ParagraphProps): TextProps {\n const heading = HEADING_TEXT[para.heading ?? 0];\n const span = doc.styles.find((s) => s.type === 'text' && s.start <= index && index < s.end);\n const link = doc.styles.find((s) => s.type === 'link' && s.start <= index && index < s.end);\n const t = span ? (span.props as TextProps) : {};\n const chrome = chromeFallback(doc, index);\n const href = link ? (link.props as LinkProps).url : '';\n return {\n bold: t.bold ?? chrome.bold ?? heading.bold ?? false,\n italic: t.italic ?? chrome.italic ?? false,\n underline: t.underline ?? (href ? true : false),\n underlineStyle: t.underlineStyle,\n strikethrough: t.strikethrough ?? false,\n fontSize:\n t.fontSize ??\n chrome.fontSize ??\n ((para.heading ?? 0) > 0 ? heading.fontSize : undefined) ??\n doc.textDefaults?.fontSize ??\n DEFAULT_TEXT.fontSize,\n fontFamily: t.fontFamily ?? chrome.fontFamily ?? doc.textDefaults?.fontFamily,\n fontWeight: t.fontWeight ?? chrome.fontWeight ?? doc.textDefaults?.fontWeight,\n color: t.color ?? chrome.color ?? (href ? LINK_COLOR : doc.textDefaults?.color ?? DEFAULT_TEXT.color),\n fill: t.fill\n };\n}\n","import { layoutNextLine, prepareWithSegments, type PreparedTextWithSegments } from '@chenglou/pretext';\nimport { DocumentModel } from '../model/document';\nimport { isTableMarker, MARKERS } from '../model/markers';\nimport { ImageEntity, ParagraphProps, TextProps, textPropsEqual } from '../model/types';\nimport { canvasFont, ensureLocale, measureWidth } from './measure';\nimport { resolvedTextStyle } from './style';\n\nexport type WrapItem =\n | { kind: 'text'; index: number; length: number; text: string; style: TextProps }\n | { kind: 'image'; index: number; length: 1; entity: ImageEntity };\n\n/** 与 host 插件 FALLBACK 一致:未回传测宽前不要按 0 排版,否则后随文字会叠进胶囊。 */\nconst HOST_FALLBACK_W = 120;\nconst HOST_FALLBACK_H = 24;\n\nexport function embedLayoutSize(entity: ImageEntity, maxWidth?: number): { width: number; height: number } {\n const host = entity.kind === 'hostSlot';\n let width = entity.width > 0 ? entity.width : host ? HOST_FALLBACK_W : 0;\n const height = entity.height > 0 ? entity.height : host ? HOST_FALLBACK_H : entity.height;\n if (maxWidth != null && maxWidth > 0 && width > maxWidth) width = maxWidth;\n return { width, height };\n}\n\n/** 测宽达到行宽则独占一行。芯片 host 按 kind 行内折,不走高度阈值;代码块/视频仍按高度独占。 */\nexport function embedOccupiesLine(entity: ImageEntity, maxWidth: number): boolean {\n if (entity.float) return false;\n const raw = entity.width > 0 ? entity.width : entity.kind === 'hostSlot' ? HOST_FALLBACK_W : 0;\n if (raw >= maxWidth - 0.5) return true;\n if (entity.kind === 'hostSlot') return false;\n const height = entity.height > 0 ? entity.height : entity.height;\n return height > 36;\n}\n\nexport type WrappedLine = { items: WrapItem[]; start: number; end: number };\n\nconst preparedCache = new Map<string, PreparedTextWithSegments>();\n\nfunction preparedFor(text: string, style: TextProps): PreparedTextWithSegments {\n ensureLocale();\n const font = canvasFont(style);\n const key = `${font}\\0${text}`;\n const hit = preparedCache.get(key);\n if (hit) return hit;\n const prepared = prepareWithSegments(text, font, { whiteSpace: 'pre-wrap' });\n preparedCache.set(key, prepared);\n return prepared;\n}\n\nexport type SourceRun =\n | { kind: 'text'; index: number; text: string; style: TextProps; prepared: PreparedTextWithSegments }\n | { kind: 'image'; index: number; entity: ImageEntity };\n\nfunction collectRuns(doc: DocumentModel, start: number, end: number, para: ParagraphProps): SourceRun[] {\n const runs: SourceRun[] = [];\n let i = start;\n while (i < end) {\n const ch = doc.spacers[i];\n if (ch === MARKERS.PARAGRAPH || isTableMarker(ch)) {\n i += 1;\n continue;\n }\n if (ch === MARKERS.IMAGE) {\n const entity = doc.imageAt(i);\n if (entity) {\n runs.push({ kind: 'image', index: i, entity });\n i += 1;\n continue;\n }\n }\n const style = resolvedTextStyle(doc, i, para);\n let j = i + 1;\n while (j < end) {\n const n = doc.spacers[j];\n if (n === MARKERS.PARAGRAPH || n === MARKERS.IMAGE || isTableMarker(n)) break;\n const ns = resolvedTextStyle(doc, j, para);\n if (!textPropsEqual(style, ns)) break;\n j += 1;\n }\n const text = doc.spacers.slice(i, j);\n runs.push({ kind: 'text', index: i, text, style, prepared: preparedFor(text, style) });\n i = j;\n }\n return runs;\n}\n\nfunction fitPrefix(text: string, style: TextProps, maxWidth: number): string {\n if (!text) return '';\n if (measureWidth(text, style) <= maxWidth) return text;\n let lo = 1;\n let hi = text.length;\n let best = 1;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n if (measureWidth(text.slice(0, mid), style) <= maxWidth) {\n best = mid;\n lo = mid + 1;\n } else {\n hi = mid - 1;\n }\n }\n return text.slice(0, best);\n}\n\n/**\n * 断行走 pretext 的 prepareWithSegments + layoutNextLine(pre-wrap)。\n * 嵌入对象(图/视频/代码/公式)保持原子盒,不交给 pretext。\n */\nexport function wrapParagraph(\n doc: DocumentModel,\n start: number,\n end: number,\n para: ParagraphProps,\n maxWidth: number\n): WrappedLine[] {\n const runs = collectRuns(doc, start, end, para);\n const lines: WrappedLine[] = [];\n let items: WrapItem[] = [];\n let lineW = 0;\n let lineStart = start;\n\n const flush = (lineEnd: number) => {\n lines.push({ items, start: lineStart, end: lineEnd });\n items = [];\n lineW = 0;\n lineStart = lineEnd;\n };\n\n for (const run of runs) {\n if (run.kind === 'image') {\n const isolated = embedOccupiesLine(run.entity, maxWidth);\n const w = embedLayoutSize(run.entity, maxWidth).width;\n if (isolated) {\n if (items.length > 0) flush(run.index);\n items.push({ kind: 'image', index: run.index, length: 1, entity: run.entity });\n flush(run.index + 1);\n continue;\n }\n if (items.length > 0 && lineW + w > maxWidth) flush(run.index);\n items.push({ kind: 'image', index: run.index, length: 1, entity: run.entity });\n lineW += w;\n continue;\n }\n\n let rest = run.text;\n let restIndex = run.index;\n let restPrepared = run.prepared;\n while (rest.length) {\n const remain = maxWidth - lineW;\n if (items.length > 0 && remain <= 0) {\n flush(restIndex);\n continue;\n }\n const widthForLine = items.length > 0 ? Math.max(1, remain) : Math.max(1, maxWidth);\n const line = layoutNextLine(restPrepared, { segmentIndex: 0, graphemeIndex: 0 }, widthForLine);\n let text = line?.text ? rest.slice(0, Math.min(line.text.length, rest.length)) : rest;\n text = fitPrefix(text, run.style, widthForLine);\n if (!text) {\n text = rest[0] ?? '';\n }\n if (items.length > 0 && measureWidth(text, run.style) > remain + 0.5 && remain < maxWidth) {\n flush(restIndex);\n continue;\n }\n const w = measureWidth(text, run.style);\n items.push({\n kind: 'text',\n index: restIndex,\n length: text.length,\n text,\n style: run.style\n });\n lineW += w;\n rest = rest.slice(text.length);\n restIndex += text.length;\n restPrepared = rest ? preparedFor(rest, run.style) : restPrepared;\n if (rest) flush(restIndex);\n }\n }\n\n if (items.length > 0 || lines.length === 0) {\n flush(end);\n }\n return lines;\n}\n\nexport type FlowObstacle = { x: number; y: number; w: number; h: number; side: 'left' | 'right' };\n\nexport function bandSlot(\n contentX: number,\n contentW: number,\n bandTop: number,\n bandH: number,\n obstacles: FlowObstacle[],\n gap = 14\n): { x: number; w: number } {\n let left = contentX;\n let right = contentX + contentW;\n for (const f of obstacles) {\n if (f.y + f.h <= bandTop + 0.5 || f.y >= bandTop + bandH - 0.5) continue;\n if (f.side === 'left') left = Math.max(left, f.x + f.w + gap);\n else right = Math.min(right, f.x - gap);\n }\n return { x: left, w: Math.max(48, right - left) };\n}\n\nexport type RunCursor = { runs: SourceRun[]; i: number; off: number };\n\nfunction cursorIndex(cur: RunCursor, fallback: number): number {\n const run = cur.runs[cur.i];\n if (!run) return fallback;\n return run.kind === 'text' ? run.index + cur.off : run.index;\n}\n\nexport function createWrapCursor(doc: DocumentModel, start: number, end: number, para: ParagraphProps, skipFloats = true): RunCursor {\n const runs = collectRuns(doc, start, end, para).filter((r) => !(skipFloats && r.kind === 'image' && r.entity.float));\n return { runs, i: 0, off: 0 };\n}\n\nexport function wrapCursorDone(cur: RunCursor): boolean {\n return cur.i >= cur.runs.length;\n}\n\nexport function wrapCursorIndex(cur: RunCursor, fallback: number): number {\n return cursorIndex(cur, fallback);\n}\n\nexport function wrapCursorPeek(cur: RunCursor): SourceRun | undefined {\n return cur.runs[cur.i];\n}\n\nexport function wrapCursorSkip(cur: RunCursor) {\n cur.i += 1;\n cur.off = 0;\n}\n\nexport function consumeWrapLine(cur: RunCursor, maxWidth: number): WrapItem[] {\n const items: WrapItem[] = [];\n let lineW = 0;\n while (!wrapCursorDone(cur)) {\n const run = cur.runs[cur.i];\n const remain = maxWidth - lineW;\n if (run.kind === 'image') {\n if (run.entity.float) break;\n const isolated = embedOccupiesLine(run.entity, maxWidth);\n const w = embedLayoutSize(run.entity, maxWidth).width;\n if (isolated) {\n if (items.length > 0) break;\n items.push({ kind: 'image', index: run.index, length: 1, entity: run.entity });\n cur.i += 1;\n break;\n }\n if (items.length > 0 && w > remain) break;\n items.push({ kind: 'image', index: run.index, length: 1, entity: run.entity });\n lineW += w;\n cur.i += 1;\n continue;\n }\n const rest = run.text.slice(cur.off);\n if (!rest) {\n cur.i += 1;\n cur.off = 0;\n continue;\n }\n if (items.length > 0 && remain <= 0) break;\n const widthForLine = items.length > 0 ? Math.max(1, remain) : Math.max(1, maxWidth);\n const prepared = preparedFor(rest, run.style);\n const line = layoutNextLine(prepared, { segmentIndex: 0, graphemeIndex: 0 }, widthForLine);\n let text = line?.text ? rest.slice(0, Math.min(line.text.length, rest.length)) : rest;\n text = fitPrefix(text, run.style, widthForLine);\n if (!text) text = rest[0] ?? '';\n if (items.length > 0 && measureWidth(text, run.style) > remain + 0.5 && remain < maxWidth) break;\n const w = measureWidth(text, run.style);\n items.push({ kind: 'text', index: run.index + cur.off, length: text.length, text, style: run.style });\n lineW += w;\n cur.off += text.length;\n if (cur.off >= run.text.length) {\n cur.i += 1;\n cur.off = 0;\n }\n if (cur.off > 0) break;\n }\n return items;\n}\n","import { parseBlocks, TableBlock } from '../model/blocks';\nimport { DocumentModel } from '../model/document';\nimport { MARKERS } from '../model/markers';\nimport {\n DEFAULT_PARAGRAPH,\n ParagraphProps,\n StyleSpan,\n Selection,\n selEnd,\n selStart\n} from '../model/types';\nimport { depthOf, sortOuterToInner } from '../model/virtualBlock';\nimport { CELL_PAD, COL_BORDER_HIT, INDENT_STEP, lineHeightOf, LIST_MARKER_WIDTH, measureGlyphWidths, measureWidth, PAGE_CONTENT_WIDTH, PAGE_PADDING_X, PAGE_PADDING_Y } from './measure';\nimport { refInnerWidth } from './refMetrics';\nimport { resolvedTextStyle } from './style';\nimport { CaretPos, CaretStop, CellLayout, DocLayout, GlyphBox, ImageBox, LineBox, ParagraphLayout, SelRect, TableLayout, VBlockFragment } from './types';\nimport { bandSlot, consumeWrapLine, createWrapCursor, embedLayoutSize, FlowObstacle, wrapCursorDone, wrapCursorIndex, wrapCursorPeek, wrapCursorSkip, wrapParagraph, WrapItem } from './wrap';\n\nexport { resolvedTextStyle } from './style';\n\nconst UL_MARKERS = ['•', '◦', '▪'];\n\nfunction listMarkerText(para: ParagraphProps, olIndex: number): string {\n if (para.list === 'ul') return UL_MARKERS[(para.indent ?? 0) % UL_MARKERS.length];\n if (para.list === 'ol') return `${olIndex}.`;\n return '';\n}\n\nfunction layoutParagraph(\n doc: DocumentModel,\n start: number,\n end: number,\n x: number,\n y: number,\n maxWidth: number,\n olIndex: number,\n obstacles: FlowObstacle[] = [],\n paraProps?: ParagraphProps\n): ParagraphLayout {\n const props: ParagraphProps = { ...DEFAULT_PARAGRAPH, ...(paraProps ?? doc.paragraphPropsAt(start)) };\n const indent = (props.indent ?? 0) * INDENT_STEP;\n const markerText = listMarkerText(props, olIndex);\n const markerW = props.list && props.list !== 'none' ? LIST_MARKER_WIDTH : 0;\n const contentX = x + indent + markerW;\n const contentW = Math.max(80, maxWidth - indent - markerW);\n const align = props.align ?? 'left';\n const floats: ImageBox[] = [];\n const allObstacles = [...obstacles];\n const useFlow = allObstacles.length > 0 || paragraphHasFloat(doc, start, end);\n const lines: LineBox[] = [];\n let lineY = y;\n\n if (!useFlow) {\n const wrapped = wrapParagraph(doc, start, end, props, contentW);\n for (let i = 0; i < wrapped.length; i++) {\n const row = wrapped[i];\n const line = buildLine(\n doc,\n props,\n row.items,\n contentX,\n lineY,\n contentW,\n align,\n start,\n row.start,\n row.end,\n markerText && i === 0 ? markerText : '',\n x + indent\n );\n lines.push(line);\n lineY += line.h;\n }\n } else {\n const cur = createWrapCursor(doc, start, end, props, false);\n let i = 0;\n do {\n const peek = wrapCursorPeek(cur);\n if (peek?.kind === 'image' && peek.entity.float) {\n const side = peek.entity.float;\n const size = embedLayoutSize(peek.entity, maxWidth);\n const fx = side === 'left' ? x : x + maxWidth - size.width;\n const box: ImageBox = { index: peek.index, x: fx, y: lineY, w: size.width, h: size.height, entity: peek.entity };\n floats.push(box);\n allObstacles.push({ x: box.x, y: box.y, w: box.w, h: box.h, side });\n wrapCursorSkip(cur);\n continue;\n }\n const slot = bandSlot(contentX, contentW, lineY, 28, allObstacles);\n const lineStart = wrapCursorIndex(cur, start);\n const items = wrapCursorDone(cur) ? [] : consumeWrapLine(cur, slot.w);\n const lineEnd = wrapCursorDone(cur) ? end : wrapCursorIndex(cur, end);\n const line = buildLine(\n doc,\n props,\n items,\n slot.x,\n lineY,\n slot.w,\n align,\n start,\n lineStart,\n items.length ? lineEnd : end,\n markerText && i === 0 ? markerText : '',\n x + indent\n );\n lines.push(line);\n lineY += line.h;\n i += 1;\n } while (!wrapCursorDone(cur));\n }\n\n return {\n start,\n end,\n x,\n y,\n w: maxWidth,\n h: Math.max(0, lineY - y),\n props,\n lines,\n floats\n };\n}\n\nfunction paragraphHasFloat(doc: DocumentModel, start: number, end: number): boolean {\n for (let i = start; i < end; i++) {\n if (doc.spacers[i] === MARKERS.IMAGE && doc.imageAt(i)?.float) return true;\n }\n return false;\n}\n\nfunction nextOl(counter: Map<number, number>, props: ParagraphProps): number {\n if (props.list !== 'ol') {\n if (props.list === 'none') counter.clear();\n return 1;\n }\n const key = props.indent ?? 0;\n const n = (counter.get(key) ?? 0) + 1;\n counter.set(key, n);\n for (const k of [...counter.keys()]) {\n if (k > key) counter.delete(k);\n }\n return n;\n}\n\nfunction buildLine(\n doc: DocumentModel,\n para: ParagraphProps,\n items: WrapItem[],\n x: number,\n y: number,\n maxW: number,\n align: ParagraphProps['align'],\n paraStart: number,\n lineStart: number,\n lineEnd: number,\n markerText: string,\n markerX: number\n): LineBox {\n let contentW = 0;\n let contentH = 20;\n for (const item of items) {\n if (item.kind === 'image') {\n const size = embedLayoutSize(item.entity, maxW);\n contentW += size.width;\n contentH = Math.max(contentH, size.height);\n } else {\n contentW += measureWidth(item.text, item.style);\n contentH = Math.max(contentH, lineHeightOf(item.style));\n }\n }\n if (items.length === 0) {\n const emptyStyle = resolvedTextStyle(doc, lineStart, para);\n contentH = lineHeightOf(emptyStyle);\n }\n\n let dx = 0;\n if (align === 'center') dx = Math.max(0, (maxW - contentW) / 2);\n if (align === 'right') dx = Math.max(0, maxW - contentW);\n\n const glyphs: GlyphBox[] = [];\n const images: ImageBox[] = [];\n const caretStops: CaretStop[] = [{ index: lineStart, x: x + dx }];\n let cx = x + dx;\n\n for (const item of items) {\n if (item.kind === 'image') {\n const size = embedLayoutSize(item.entity, maxW);\n images.push({\n index: item.index,\n x: cx,\n y: y + Math.max(0, (contentH - size.height) / 2),\n w: size.width,\n h: size.height,\n entity: item.entity\n });\n cx += size.width;\n caretStops.push({ index: item.index + 1, x: cx });\n } else {\n let local = cx;\n // 摆字宽度取前缀宽度之差,与折行时的整串测宽口径一致,否则带字距调整的字体\n // (如 Manrope 的 `Te`)逐字累加会比折行预算宽,行尾字会越过版心。\n const widths = measureGlyphWidths(item.text, item.style);\n for (let k = 0; k < item.text.length; k++) {\n const ch = item.text[k];\n const w = widths[k];\n glyphs.push({\n index: item.index + k,\n x: local,\n y,\n w,\n h: contentH,\n text: ch,\n style: item.style\n });\n local += w;\n caretStops.push({ index: item.index + k + 1, x: local });\n }\n cx = local;\n }\n }\n\n if (caretStops[caretStops.length - 1].index !== lineEnd) {\n caretStops.push({ index: lineEnd, x: cx });\n }\n\n const marker = markerText\n ? {\n x: markerX,\n y,\n w: LIST_MARKER_WIDTH,\n h: contentH,\n text: markerText,\n kind: para.list ?? 'none'\n }\n : undefined;\n\n return {\n paragraphStart: paraStart,\n start: lineStart,\n end: lineEnd,\n x,\n y,\n w: maxW,\n h: contentH,\n ascent: contentH,\n align: align ?? 'left',\n glyphs,\n images,\n marker,\n caretStops,\n vblocks: vblockFragments(doc, lineStart, lineEnd, y, contentH, glyphs, images, !align || align === 'left' ? x + maxW : null)\n };\n}\n\nfunction vblockFragments(\n doc: DocumentModel,\n lineStart: number,\n lineEnd: number,\n y: number,\n lineH: number,\n glyphs: GlyphBox[],\n images: ImageBox[],\n fillRight: number | null\n): VBlockFragment[] {\n const hits = doc.virtualBlocksOverlapping(lineStart, lineEnd);\n if (!hits.length) return [];\n const sorted = sortOuterToInner(hits, doc.virtualBlocks);\n const out: VBlockFragment[] = [];\n for (const b of sorted) {\n const boxes: { x: number; y: number; w: number; h: number }[] = [];\n for (const g of glyphs) {\n if (g.index >= b.start && g.index < b.end) boxes.push(g);\n }\n for (const im of images) {\n if (im.index >= b.start && im.index < b.end) boxes.push(im);\n }\n if (!boxes.length) continue;\n const left = Math.min(...boxes.map((box) => box.x));\n const right = Math.max(...boxes.map((box) => box.x + box.w));\n const top = Math.min(...boxes.map((box) => box.y));\n const bottom = Math.max(...boxes.map((box) => box.y + box.h));\n // 只支持水平内边距:底色左右各外扩 padX(行首行尾也外扩)。\n // 它只影响绘制,不参与排版:字形位置、折行、行高都不变。\n const padX = b.chrome.paddingX ?? 0;\n // 区间还延续到后面的行(折行或跨段)时,这一行铺满到内容区右缘,各行连成一个整体;\n // 只有最后一行按文字实际宽度。仅左对齐行这样处理,居中/右对齐保持按内容宽度。\n const continues = b.end > lineEnd && /[^\\n]/.test(doc.spacers.slice(lineEnd, b.end));\n const boxLeft = left - padX;\n const boxRight = continues && fillRight != null ? Math.max(right, fillRight) + padX : right + padX;\n out.push({\n id: b.id,\n kind: b.kind,\n depth: depthOf(b, doc.virtualBlocks),\n x: boxLeft,\n y: Math.min(top, y),\n w: Math.max(0, boxRight - boxLeft),\n h: Math.max(lineH, bottom - top),\n chrome: { ...b.chrome },\n empty: b.empty,\n first: b.start >= lineStart,\n last: !continues\n });\n }\n return out.sort((a, b) => a.depth - b.depth);\n}\n\nfunction layoutTable(doc: DocumentModel, table: TableBlock, x: number, y: number, maxWidth: number, paraIndex: ParagraphPropsIndex): TableLayout {\n const cols = Math.max(1, ...table.rows.map((r) => r.cells.length));\n const stored = doc.tablePropsAt(table.start).colWidths ?? [];\n const even = Math.floor(maxWidth / cols);\n const hasStored = stored.length >= cols && stored.slice(0, cols).every((w) => w > 0);\n const colWidths = hasStored\n ? stored.slice(0, cols)\n : Array.from({ length: cols }, (_, i) => (stored[i] && stored[i] > 0 ? stored[i] : even));\n if (!hasStored) {\n const sum = colWidths.reduce((a, b) => a + b, 0);\n if (sum !== maxWidth) colWidths[cols - 1] += maxWidth - sum;\n }\n\n const cells: CellLayout[] = [];\n let cy = y;\n for (let r = 0; r < table.rows.length; r++) {\n const row = table.rows[r];\n const rowCells: CellLayout[] = [];\n let maxH = 32;\n let cx = x;\n for (let c = 0; c < cols; c++) {\n const cell = row.cells[c];\n const w = colWidths[c];\n const innerW = Math.max(1, w - CELL_PAD * 2);\n const paras: ParagraphLayout[] = [];\n let py = cy + CELL_PAD;\n const ol = new Map<number, number>();\n if (cell) {\n for (const para of cell.paragraphs) {\n const pp = paraIndex.at(para.start, para.end);\n const pl = layoutParagraph(doc, para.start, para.end, cx + CELL_PAD, py, innerW, nextOl(ol, pp), [], pp);\n paras.push(pl);\n py += pl.h;\n }\n }\n const h = Math.max(32, py - cy + CELL_PAD);\n maxH = Math.max(maxH, h);\n rowCells.push({\n row: r,\n col: c,\n start: cell?.start ?? table.start,\n end: cell?.end ?? table.start,\n x: cx,\n y: cy,\n w,\n h,\n paragraphs: paras\n });\n cx += w;\n }\n for (const cell of rowCells) cell.h = maxH;\n cells.push(...rowCells);\n cy += maxH;\n }\n\n return {\n start: table.start,\n end: table.end,\n x,\n y,\n w: colWidths.reduce((a, b) => a + b, 0),\n h: cy - y,\n colWidths,\n cells\n };\n}\n\nfunction fragmentFingerprint(doc: DocumentModel, fragmentId?: string): string {\n if (!fragmentId) return '';\n const fragment = doc.fragments.get(fragmentId);\n if (!fragment) return fragmentId;\n return `${fragment.slice.text}:${fragment.slice.styles.length}:${fragment.slice.entities.length}`;\n}\n\nfunction hostFingerprint(entity: { kind?: string; hostType?: string; data?: unknown }): string {\n if (entity.kind !== 'hostSlot') return '';\n try {\n return `${entity.hostType ?? ''}:${JSON.stringify(entity.data ?? null)}`;\n } catch {\n return entity.hostType ?? '';\n }\n}\n\nconst hasImagesCache = new WeakMap<DocumentModel, { spacers: string; has: boolean }>();\nfunction hasImages(doc: DocumentModel): boolean {\n const c = hasImagesCache.get(doc);\n if (c && c.spacers === doc.spacers) return c.has;\n const has = doc.spacers.includes(MARKERS.IMAGE);\n hasImagesCache.set(doc, { spacers: doc.spacers, has });\n return has;\n}\n\nfunction mediaFingerprint(doc: DocumentModel, start: number, end: number): string {\n // 全文没有嵌入对象是最常见的情况,直接跳过逐字扫描(indexOf 结果按文档缓存,见 hasImages)\n if (!hasImages(doc)) return '';\n const parts: string[] = [];\n for (let i = start; i < end; i++) {\n if (doc.spacers[i] !== MARKERS.IMAGE) continue;\n const e = doc.imageAt(i);\n if (e) {\n parts.push(\n `${e.id}:${e.kind ?? 'image'}:${hostFingerprint(e)}:${e.width}x${e.height}:${e.float ?? ''}:${e.code ?? ''}:${e.latex ?? ''}:${e.slotKind ?? ''}:${e.label ?? ''}:${e.slotValue ?? ''}:${e.src ?? ''}:${e.fragmentId ?? ''}:${fragmentFingerprint(doc, e.fragmentId)}:${(e.slotOptions ?? []).join('/')}`\n );\n }\n }\n return parts.join(',');\n}\n\n/**\n * 按块查样式区间的索引。\n *\n * 每排一次版就要给每个块算一次内容哈希,而哈希要知道「盖住这个块的样式区间」。\n * 直接在全表上筛是块数 × 区间数,长文档里这是排版的主要开销。\n *\n * 区间表本身按 `start` 有序(模型每次写完都会规范化),所以再存一列「前 i 个区间\n * 里最大的 end」—— 这一列必然单调,可以二分出第一个可能盖住本块的位置。它不要求\n * 区间互不相交,同一个下标上叠着文字、链接、图片好几层也照样对。\n */\nexport class StyleIndex {\n private spans: StyleSpan[];\n /** maxEnd[i] = spans[0..i] 里最大的 end,单调不减 */\n private maxEnd: number[];\n\n constructor(spans: StyleSpan[]) {\n this.spans = spans;\n this.maxEnd = [];\n let running = -Infinity;\n for (const s of spans) {\n running = Math.max(running, s.end);\n this.maxEnd.push(running);\n }\n }\n\n /** 第一个可能与 `start` 之后相交的区间下标。 */\n private lowerBound(start: number): number {\n let lo = 0;\n let hi = this.spans.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (this.maxEnd[mid] > start) hi = mid;\n else lo = mid + 1;\n }\n return lo;\n }\n\n /**\n * 块内的样式区间,端点相对块起点、并裁到块边界内。\n *\n * 相对化是缓存能跨编辑复用的前提:在文档中间插一个字,后面每个块的绝对下标都会\n * 平移,但它们的排版结果一模一样。裁剪是同一个道理 —— 一段样式伸到块外多远,不\n * 影响这个块怎么排。\n */\n key(start: number, end: number, types?: Set<string>): string {\n const parts: string[] = [];\n for (let i = this.lowerBound(start); i < this.spans.length; i++) {\n const s = this.spans[i];\n if (s.start >= end) break;\n if (s.end <= start) continue;\n if (types && !types.has(s.type)) continue;\n parts.push(\n `${s.type}:${Math.max(s.start, start) - start}:${Math.min(s.end, end) - start}:${JSON.stringify(s.props)}`\n );\n }\n return parts.join('|');\n }\n}\n\nconst INLINE_STYLES = new Set(['text', 'link', 'image']);\n\n/**\n * 段落属性查表。`doc.paragraphPropsAt` 每次都要 parseBlocks 扫全文来找段落边界,\n * 排版循环里已经知道每个块的 [start,end),再按位置扫一遍就是 段落数×全文长度 的平方开销\n * (8 万字 / 1000 段实测 1.7s)。这里一次性把段落样式区间收进 Map,按区间精确命中,\n * 命不中再退回重叠查找,语义与 paragraphPropsAt 一致。\n */\nclass ParagraphPropsIndex {\n private exact = new Map<string, StyleSpan>();\n private spans: StyleSpan[];\n\n constructor(doc: DocumentModel) {\n this.spans = doc.styles.filter((s) => s.type === 'paragraph');\n for (const s of this.spans) this.exact.set(`${s.start}:${s.end}`, s);\n }\n\n private keys = new WeakMap<StyleSpan, string>();\n private defaultKey = JSON.stringify(DEFAULT_PARAGRAPH);\n\n private spanFor(start: number, end: number): StyleSpan | undefined {\n return this.exact.get(`${start}:${end}`) ?? this.spans.find((s) => s.start < end && s.end > start);\n }\n\n at(start: number, end: number): ParagraphProps {\n return { ...DEFAULT_PARAGRAPH, ...(this.spanFor(start, end)?.props as ParagraphProps | undefined) };\n }\n\n /** 用于哈希的属性串:同一个样式区间只 stringify 一次 */\n key(start: number, end: number): string {\n const span = this.spanFor(start, end);\n if (!span) return this.defaultKey;\n let k = this.keys.get(span);\n if (!k) this.keys.set(span, (k = JSON.stringify({ ...DEFAULT_PARAGRAPH, ...span.props })));\n return k;\n }\n}\n\nfunction textDefaultsKey(doc: DocumentModel): string {\n return JSON.stringify({ f: doc.textDefaults?.fontFamily, w: doc.textDefaults?.fontWeight, s: doc.textDefaults?.fontSize });\n}\n\nfunction hashParagraph(doc: DocumentModel, styles: StyleIndex, start: number, end: number, width: number, olIndex: number, floatKey: string, propsKey: string, tdKey: string): string {\n return `p:${width}:${olIndex}:${floatKey}:${propsKey}:${doc.spacers.slice(start, end)}:${styles.key(start, end, INLINE_STYLES)}:${mediaFingerprint(doc, start, end)}:${vblockFingerprint(doc, start, end)}:td:${tdKey}`;\n}\n\nfunction vblockFingerprint(doc: DocumentModel, start: number, end: number): string {\n return doc\n .virtualBlocksOverlapping(start, end)\n // 区间相对段首:段落整体平移时哈希不变,才能命中缓存\n .map((b) => `${b.id}:${b.kind}:${b.parentId}:${b.start - start}:${b.end - start}:${b.empty ? 1 : 0}:${b.placeholder ?? ''}:${JSON.stringify(b.chrome)}`)\n .join(';');\n}\n\nfunction hashTable(doc: DocumentModel, styles: StyleIndex, table: TableBlock, width: number): string {\n return `t:${width}:${doc.spacers.slice(table.start, table.end)}:${styles.key(table.start, table.end)}:${mediaFingerprint(doc, table.start, table.end)}`;\n}\n\n/**\n * 把一份缓存的块布局搬到新位置:`dy` 是纵向位移,`di` 是下标位移。\n *\n * 下标必须跟着搬。布局里到处存着 spacer 下标(字形、图片、行的首尾、光标落点),\n * 命中测试和选区全靠它们 —— 只平移 y 会让复用的块指向错误的字符。\n *\n * 引用块的 `inner` 不动:它是片段自己坐标空间里的布局,和外层的下标无关。\n */\nfunction floatBoxes(paras: ParagraphLayout[]): ImageBox[] {\n return paras.flatMap((p) => p.floats ?? []);\n}\n\n/** 一个段落实际占的纵向范围:浮动图片可以探到段落之外。 */\nfunction paragraphBottom(p: ParagraphLayout): number {\n let bottom = p.y + p.h;\n for (const f of p.floats ?? []) bottom = Math.max(bottom, f.y + f.h);\n return bottom;\n}\n\nfunction moveParagraph(p: ParagraphLayout, dy: number, di: number, inPlace: boolean): ParagraphLayout {\n if (!dy && !di) return p;\n if (inPlace) return shiftParagraphInPlace(p, dy, di);\n return {\n ...p,\n y: p.y + dy,\n start: p.start + di,\n end: p.end + di,\n lines: p.lines.map((l) => ({\n ...l,\n y: l.y + dy,\n paragraphStart: l.paragraphStart + di,\n start: l.start + di,\n end: l.end + di,\n glyphs: l.glyphs.map((g) => ({ ...g, y: g.y + dy, index: g.index + di })),\n images: l.images.map((im) => ({ ...im, y: im.y + dy, index: im.index + di })),\n vblocks: l.vblocks?.map((v) => ({ ...v, y: v.y + dy })),\n marker: l.marker ? { ...l.marker, y: l.marker.y + dy } : undefined,\n caretStops: l.caretStops.map((c) => ({ ...c, index: c.index + di }))\n })),\n floats: p.floats?.map((f) => ({ ...f, y: f.y + dy, index: f.index + di }))\n };\n}\n\n/**\n * 就地平移。上一份布局在增量排版后就被丢弃(Editor 只保留最新一份),复用的块没必要\n * 深拷贝:8 万字文档在中间敲一个字,后面所有段落的下标都要加 1,拷贝 8 万个字形对象\n * 外加 GC 要二三十毫秒,就地改字段只要一两毫秒。\n */\nfunction shiftParagraphInPlace(p: ParagraphLayout, dy: number, di: number): ParagraphLayout {\n p.y += dy;\n p.start += di;\n p.end += di;\n for (const l of p.lines) {\n l.y += dy;\n l.paragraphStart += di;\n l.start += di;\n l.end += di;\n if (dy) {\n for (const g of l.glyphs) g.y += dy;\n for (const im of l.images) im.y += dy;\n if (l.vblocks) for (const v of l.vblocks) v.y += dy;\n if (l.marker) l.marker.y += dy;\n }\n if (di) {\n for (const g of l.glyphs) g.index += di;\n for (const im of l.images) im.index += di;\n for (const c of l.caretStops) c.index += di;\n }\n }\n if (p.floats) {\n for (const f of p.floats) {\n f.y += dy;\n f.index += di;\n }\n }\n return p;\n}\n\nfunction moveTable(t: TableLayout, dy: number, di: number, inPlace: boolean): TableLayout {\n if (!dy && !di) return t;\n if (inPlace) {\n t.y += dy;\n t.start += di;\n t.end += di;\n for (const c of t.cells) {\n c.y += dy;\n c.start += di;\n c.end += di;\n for (const p of c.paragraphs) moveParagraph(p, dy, di, true);\n }\n return t;\n }\n return {\n ...t,\n y: t.y + dy,\n start: t.start + di,\n end: t.end + di,\n cells: t.cells.map((c) => ({\n ...c,\n y: c.y + dy,\n start: c.start + di,\n end: c.end + di,\n paragraphs: c.paragraphs.map((p) => moveParagraph(p, dy, di, false))\n }))\n };\n}\n\n/**\n * 上一次排版复用了多少块、重排了多少块。\n *\n * 只为诊断和自检存在 —— 自检要能确认「确实复用了」,否则缓存整体失效也会静静\n * 通过。嵌套排版(引用块内部)累加进同一份计数,顶层调用时清零。\n */\nexport interface LayoutStats {\n reused: number;\n laidOut: number;\n}\n\nlet stats: LayoutStats = { reused: 0, laidOut: 0 };\n\nexport function lastLayoutStats(): LayoutStats {\n return { ...stats };\n}\n\nexport function layoutDocument(\n doc: DocumentModel,\n contentWidth = PAGE_CONTENT_WIDTH,\n prev?: DocLayout,\n insets: { x: number; y: number } = { x: PAGE_PADDING_X, y: PAGE_PADDING_Y },\n depth = 0\n): DocLayout {\n if (depth === 0) stats = { reused: 0, laidOut: 0 };\n const contentX = insets.x;\n const contentY = insets.y;\n const paragraphs: ParagraphLayout[] = [];\n const tables: TableLayout[] = [];\n let y = contentY;\n const topOl = new Map<number, number>();\n let activeFloats: FlowObstacle[] = [];\n\n // 脏区带:只有这个纵向区间里的像素变了,绘制层据此决定重画哪一段。\n // 判定规则很简单,也正因为简单才守得住:\n // 复用且没挪位置 → 像素一模一样,干净;\n // 复用但挪了位置 → 老位置和新位置都脏;\n // 重排的块 → 它自己那一段脏。\n // 一个块高度变了,它下面的块就会挪位置、跟着进脏区,所以「只标自己这一段」\n // 不会漏 —— 下面全都没挪,恰好说明这个块的高度没变。\n //\n // 挪位置的块连老位置一起标。理论上老位置会被下面的块顺带覆盖(块是竖直连续\n // 堆叠的),但那是个全局论证,一处不成立就花屏 —— 一个 Math.min 换掉这份心智\n // 负担,值得。\n //\n // 浮动图片是这套推理真正的例外:它能探出所在段落之外。所以段落占的像素高度按\n // max(段高, 浮动图底边) 算,而且循环之后还要拿上一份布局里的浮动图单独对一遍。\n let dirtyTop = Infinity;\n let dirtyBottom = -Infinity;\n const markDirty = (top: number, bottom: number) => {\n dirtyTop = Math.min(dirtyTop, top);\n dirtyBottom = Math.max(dirtyBottom, bottom);\n };\n // 没有上一份布局、或者宽度变了,一切都要重来\n if (!prev || prev.contentWidth !== contentWidth) markDirty(0, Infinity);\n\n const styleIndex = new StyleIndex(doc.styles);\n const paraIndex = new ParagraphPropsIndex(doc);\n const tdKey = textDefaultsKey(doc);\n // 同一哈希可能对应多个块(空行、重复段落很常见)。按哈希只留一个会让所有同款块都\n // 「命中」最后那一个,再被当成挪了位置:每次敲字都要深拷贝并标脏整篇。\n // 这里保留全部候选,优先取纵向位置相同的,其次取下标相同的。\n type Cached = ParagraphLayout | TableLayout;\n const prevByHash = new Map<string, { byY: Map<number, Cached>; byStart: Map<number, Cached>; first: Cached }>();\n if (prev) {\n for (const b of [...prev.paragraphs, ...prev.tables]) {\n if (!b.hash) continue;\n let entry = prevByHash.get(b.hash);\n if (!entry) prevByHash.set(b.hash, (entry = { byY: new Map(), byStart: new Map(), first: b }));\n entry.byY.set(Math.round(b.y), b);\n entry.byStart.set(b.start, b);\n }\n }\n // 就地平移的前提:prev 没被消费过(同一份布局只能喂一次),且同一个缓存块在本轮\n // 只被一个新块复用(同哈希多块时 first 兜底可能重复命中,重复的那次退回拷贝)。\n const inPlaceAllowed = !!prev && !prev.consumed;\n if (prev) prev.consumed = true;\n const shifted = new Set<Cached>();\n const canShiftInPlace = (c: Cached): boolean => {\n if (!inPlaceAllowed || shifted.has(c)) return false;\n shifted.add(c);\n return true;\n };\n const pickCached = (hash: string, y: number, start: number): Cached | undefined => {\n const entry = prevByHash.get(hash);\n if (!entry) return undefined;\n const ry = Math.round(y);\n return entry.byY.get(ry) ?? entry.byY.get(ry - 1) ?? entry.byY.get(ry + 1) ?? entry.byStart.get(start) ?? entry.first;\n };\n\n for (const block of parseBlocks(doc.spacers)) {\n if (block.kind === 'paragraph') {\n const props = paraIndex.at(block.start, block.end);\n const olIndex = nextOl(topOl, props);\n activeFloats = activeFloats.filter((f) => f.y + f.h > y + 0.5);\n const floatKey = activeFloats.map((f) => `${f.side}:${Math.round(f.w)}x${Math.round(Math.max(0, f.y + f.h - y))}`).join(',');\n const hash = hashParagraph(doc, styleIndex, block.start, block.end, contentWidth, olIndex, floatKey, paraIndex.key(block.start, block.end), tdKey);\n const cached = pickCached(hash, y, block.start);\n let p: ParagraphLayout;\n if (cached && 'lines' in cached && cached.hash === hash) {\n const oldY = cached.y;\n const oldBottom = paragraphBottom(cached);\n p = moveParagraph(cached, y - oldY, block.start - cached.start, canShiftInPlace(cached));\n p.hash = hash;\n stats.reused++;\n if (Math.abs(oldY - y) > 0.5) {\n markDirty(Math.min(oldY, y), Math.max(oldBottom, paragraphBottom(p)));\n }\n } else {\n p = layoutParagraph(doc, block.start, block.end, contentX, y, contentWidth, olIndex, activeFloats, props);\n p.hash = hash;\n stats.laidOut++;\n markDirty(y, paragraphBottom(p));\n }\n for (const f of p.floats ?? []) {\n if (f.entity.float) activeFloats.push({ x: f.x, y: f.y, w: f.w, h: f.h, side: f.entity.float });\n }\n paragraphs.push(p);\n y += p.h;\n } else {\n topOl.clear();\n const hash = hashTable(doc, styleIndex, block, contentWidth);\n const cached = pickCached(hash, y, block.start);\n let t: TableLayout;\n if (cached && 'cells' in cached && cached.hash === hash) {\n const oldY = cached.y;\n const oldH = cached.h;\n t = moveTable(cached, y - oldY, block.start - cached.start, canShiftInPlace(cached));\n t.hash = hash;\n stats.reused++;\n if (Math.abs(oldY - y) > 0.5) {\n markDirty(Math.min(oldY, y), Math.max(oldY + oldH, y + t.h));\n }\n } else {\n t = layoutTable(doc, block, contentX, y, contentWidth, paraIndex);\n t.hash = hash;\n stats.laidOut++;\n markDirty(y, y + t.h);\n }\n tables.push(t);\n y += t.h + 12;\n }\n }\n\n // 浮动图片探出段落之外,老位置推不出来 —— 直接比:位置或尺寸变了的,老位置也脏\n if (prev) {\n const now = new Map(floatBoxes(paragraphs).map((f) => [f.entity.id, f]));\n for (const old of floatBoxes(prev.paragraphs)) {\n const cur = now.get(old.entity.id);\n if (!cur || cur.x !== old.x || cur.y !== old.y || cur.w !== old.w || cur.h !== old.h) {\n markDirty(old.y, old.y + old.h);\n }\n }\n }\n\n const height = y + insets.y;\n // 文档高度变了说明尾部有内容进出,那一段也要重画(文档变短时得擦掉旧像素)\n if (prev && Math.abs(prev.height - height) > 0.5) {\n markDirty(Math.min(prev.height, height), Math.max(prev.height, height));\n }\n // 「全部重画」用 Infinity 表示,但不该漏进公开结构里,落地成实际画过的最大底边。\n // 注意不能拿文档高度去裁真实的脏区底边 —— 浮动图片可以探出文档底边之外。\n const dirty =\n dirtyTop < dirtyBottom\n ? {\n top: Math.max(0, dirtyTop),\n bottom: Number.isFinite(dirtyBottom) ? dirtyBottom : Math.max(height, prev?.height ?? 0)\n }\n : { top: 0, bottom: 0 };\n\n const lines: LineBox[] = [];\n const images: ImageBox[] = [];\n for (const p of paragraphs) {\n lines.push(...p.lines);\n for (const l of p.lines) {\n l.images = attachRefInners(doc, l.images, depth);\n images.push(...l.images);\n }\n if (p.floats) {\n p.floats = attachRefInners(doc, p.floats, depth);\n images.push(...p.floats);\n }\n }\n for (const t of tables) {\n for (const c of t.cells) {\n for (const p of c.paragraphs) {\n lines.push(...p.lines);\n for (const l of p.lines) {\n l.images = attachRefInners(doc, l.images, depth);\n images.push(...l.images);\n }\n }\n }\n }\n\n return {\n width: contentWidth + insets.x * 2,\n height,\n contentX,\n contentY,\n contentWidth,\n paragraphs,\n tables,\n lines,\n images,\n dirty\n };\n}\n\nfunction attachRefInners(doc: DocumentModel, boxes: ImageBox[], depth: number): ImageBox[] {\n if (depth > 0) return boxes;\n return boxes.map((box) => {\n if (box.entity.kind !== 'ref' || !box.entity.fragmentId) return box;\n const innerW = refInnerWidth(box.w);\n const model = doc.ensureFragmentModel(box.entity.fragmentId);\n return { ...box, inner: layoutDocument(model, innerW, undefined, { x: 0, y: 0 }, depth + 1) };\n });\n}\n\n/**\n * 按起始下标排好序的行,挂在 layout 上惰性建一次。`layout.lines` 是段落行在前、表格行\n * 在后,不保证全局有序,所以不能直接二分。\n */\nconst sortedLinesCache = new WeakMap<DocLayout, LineBox[]>();\nfunction sortedLines(layout: DocLayout): LineBox[] {\n let sorted = sortedLinesCache.get(layout);\n if (!sorted) {\n sorted = [...layout.lines].sort((a, b) => a.start - b.start || a.end - b.end);\n sortedLinesCache.set(layout, sorted);\n }\n return sorted;\n}\n\nexport function caretFromIndex(layout: DocLayout, index: number): CaretPos {\n // 先二分出包含该下标的几行(含前后各一行兜底),命中精确停靠点就不必扫全文:\n // 长文档里光标闪烁每帧都要调这里,全扫一遍 8 万个停靠点太贵。\n const sorted = sortedLines(layout);\n let lo = 0;\n let hi = sorted.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (sorted[mid].end < index) lo = mid + 1;\n else hi = mid;\n }\n let to = lo;\n while (to < sorted.length && sorted[to].start <= index) to++;\n const near = sorted.slice(Math.max(0, lo - 1), Math.min(sorted.length, to + 1));\n return caretFromIndexIn(layout, near, index) ?? caretFromIndexIn(layout, layout.lines, index, true)!;\n}\n\nfunction caretFromIndexIn(layout: DocLayout, lines: LineBox[], index: number, allowNearest = false): CaretPos | null {\n let bestLine: LineBox | null = null;\n let bestX = layout.contentX;\n let bestIndex = index;\n let bestDist = Infinity;\n const exact: { line: LineBox; x: number }[] = [];\n for (const line of lines) {\n for (const stop of line.caretStops) {\n if (stop.index === index) exact.push({ line, x: stop.x });\n const dist = Math.abs(stop.index - index);\n if (dist < bestDist || (dist === bestDist && stop.index <= index)) {\n bestDist = dist;\n bestLine = line;\n bestX = stop.x;\n bestIndex = stop.index;\n }\n }\n }\n if (bestDist !== 0 && !allowNearest) return null;\n // 默认同一下标取后一行(回车换行、普通折行)。仅当后一行是以该下标开头的嵌入对象\n // (文本槽折到下一行、光标在槽前)时,改用上一行行尾,避免光标画在槽行行首。\n if (exact.length >= 2) {\n const earlier = exact[0];\n const later = exact[exact.length - 1];\n const laterIsEmbedHead =\n later.line.caretStops[0]?.index === index &&\n later.line.images.some((img) => img.index === index);\n if (laterIsEmbedHead) {\n bestLine = earlier.line;\n bestX = earlier.x;\n bestIndex = index;\n }\n }\n if (!bestLine) return { x: layout.contentX, y: layout.contentY, h: 24, index };\n return { x: bestX, y: bestLine.y, h: bestLine.h, index: bestIndex };\n}\n\nexport function hitTestIndex(layout: DocLayout, localX: number, localY: number): number {\n for (const table of layout.tables) {\n if (localX < table.x || localX > table.x + table.w || localY < table.y || localY > table.y + table.h) {\n continue;\n }\n for (const cell of table.cells) {\n if (localX >= cell.x && localX < cell.x + cell.w && localY >= cell.y && localY < cell.y + cell.h) {\n const lines = cell.paragraphs.flatMap((p) => p.lines);\n if (lines.length) return closestCaretOnLines(lines, localX, localY);\n return cell.paragraphs[0]?.start ?? cell.start + 1;\n }\n }\n }\n return closestCaretOnLines(layout.lines, localX, localY);\n}\n\nfunction closestCaretOnLines(lines: LineBox[], localX: number, localY: number): number {\n if (lines.length === 0) return 0;\n let best = lines[0];\n let bestScore = Infinity;\n for (const line of lines) {\n const inY = localY >= line.y && localY < line.y + line.h;\n const inX = localX >= line.x && localX <= line.x + line.w;\n if (inY && inX) {\n best = line;\n break;\n }\n const dy = localY < line.y ? line.y - localY : localY >= line.y + line.h ? localY - (line.y + line.h) : 0;\n const dx = localX < line.x ? line.x - localX : localX > line.x + line.w ? localX - (line.x + line.w) : 0;\n const score = dy * 10000 + dx;\n if (score < bestScore) {\n bestScore = score;\n best = line;\n }\n }\n let stop = best.caretStops[0];\n let bestDist = Infinity;\n for (const s of best.caretStops) {\n const d = Math.abs(s.x - localX);\n if (d < bestDist) {\n bestDist = d;\n stop = s;\n }\n }\n return stop.index;\n}\n\nexport function selectionRects(layout: DocLayout, sel: Selection): SelRect[] {\n const from = selStart(sel);\n const to = selEnd(sel);\n if (from === to) return [];\n const cellRects = cellGridRects(layout, from, to);\n if (cellRects) return cellRects;\n const rects: SelRect[] = [];\n for (const line of layout.lines) {\n if (line.end <= from || line.start >= to) {\n const covers =\n line.caretStops.some((s) => s.index >= from && s.index < to) ||\n (from < line.end && to > line.start);\n if (!covers) continue;\n }\n const stops = line.caretStops;\n const left = stops.find((s) => s.index >= from) ?? stops[0];\n const rightCandidates = stops.filter((s) => s.index <= to);\n const right = rightCandidates[rightCandidates.length - 1] ?? stops[stops.length - 1];\n const x0 = Math.min(left.x, right.x);\n const x1 = Math.max(left.x, right.x);\n if (x1 > x0) {\n rects.push({ x: x0, y: line.y, w: x1 - x0, h: line.h });\n }\n }\n return punchEmbeds(rects, layout.images);\n}\n\nfunction punchEmbeds(rects: SelRect[], boxes: ImageBox[]): SelRect[] {\n let out = rects;\n for (const b of boxes) {\n const next: SelRect[] = [];\n for (const r of out) {\n const overlapY = r.y < b.y + b.h && r.y + r.h > b.y;\n const overlapX = r.x < b.x + b.w && r.x + r.w > b.x;\n if (!overlapY || !overlapX) {\n next.push(r);\n continue;\n }\n if (r.x < b.x - 1) next.push({ x: r.x, y: r.y, w: b.x - r.x - 2, h: r.h });\n if (r.x + r.w > b.x + b.w + 1) next.push({ x: b.x + b.w + 2, y: r.y, w: r.x + r.w - (b.x + b.w) - 2, h: r.h });\n }\n out = next.filter((r) => r.w > 2);\n }\n return out;\n}\n\nexport function imageBoxAt(layout: DocLayout, index: number): ImageBox | null {\n return layout.images.find((b) => b.index === index) ?? null;\n}\n\nfunction cellGridRects(layout: DocLayout, from: number, to: number): SelRect[] | null {\n let a: CellLayout | null = null;\n let b: CellLayout | null = null;\n for (const table of layout.tables) {\n for (const cell of table.cells) {\n if (from >= cell.start && from < cell.end) a = cell;\n if (to > cell.start && to <= cell.end) b = cell;\n if (from === cell.start) a = cell;\n if (to === cell.end) b = cell;\n }\n if (a && b && a !== b && table.cells.includes(a) && table.cells.includes(b)) {\n const r0 = Math.min(a.row, b.row);\n const r1 = Math.max(a.row, b.row);\n const c0 = Math.min(a.col, b.col);\n const c1 = Math.max(a.col, b.col);\n return table.cells\n .filter((c) => c.row >= r0 && c.row <= r1 && c.col >= c0 && c.col <= c1)\n .map((c) => ({ x: c.x, y: c.y, w: c.w, h: c.h }));\n }\n if (a && b && a === b && from <= a.start + 1 && to >= a.end) {\n return [{ x: a.x, y: a.y, w: a.w, h: a.h }];\n }\n a = null;\n b = null;\n }\n return null;\n}\n\nexport function hitColBorder(\n layout: DocLayout,\n x: number,\n y: number\n): { tableStart: number; col: number; widths: number[] } | null {\n for (const table of layout.tables) {\n if (y < table.y || y > table.y + table.h || x < table.x - COL_BORDER_HIT || x > table.x + table.w + COL_BORDER_HIT) {\n continue;\n }\n let cx = table.x;\n for (let i = 0; i < table.colWidths.length - 1; i++) {\n cx += table.colWidths[i];\n if (Math.abs(x - cx) <= COL_BORDER_HIT) {\n return { tableStart: table.start, col: i, widths: [...table.colWidths] };\n }\n }\n }\n return null;\n}\n","import { TextFill, TextProps, underlineKind } from '../model/types';\nimport { GlyphBox } from '../layout/types';\n\nexport function fillOf(style: TextProps): TextFill {\n return style.fill ?? 'solid';\n}\n\nexport function rainbowAt(index: number): string {\n const hue = (index * 37) % 360;\n return `hsl(${hue} 80% 46%)`;\n}\n\nexport function sunsetAt(t: number): string {\n const stops = ['#ff4d6d', '#ff8a4c', '#ffd166', '#06d6a0'];\n const x = Math.max(0, Math.min(0.999, t)) * (stops.length - 1);\n return stops[Math.floor(x)];\n}\n\nexport function cssFill(style: TextProps, runWidth: number): string {\n const fill = fillOf(style);\n if (fill === 'rainbow') {\n return `-webkit-background-clip:text;background-clip:text;color:transparent;background-image:linear-gradient(90deg,#ff4d6d,#ffd166,#06d6a0,#4cc9f0,#ff4d6d);background-size:${Math.max(120, runWidth)}px 100%;`;\n }\n if (fill === 'sunset') {\n return `-webkit-background-clip:text;background-clip:text;color:transparent;background-image:linear-gradient(90deg,#ff4d6d,#ff8a4c,#ffd166);`;\n }\n return '';\n}\n\nexport function canvasFill(style: TextProps, glyphIndex: number, runT = 0): string {\n const fill = fillOf(style);\n if (fill === 'rainbow') return rainbowAt(glyphIndex);\n if (fill === 'sunset') return sunsetAt(runT);\n return style.color ?? '#1f2329';\n}\n\nexport function paintCanvasUnderline(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n size: number,\n kind: ReturnType<typeof underlineKind>,\n color: string\n) {\n if (kind === 'none' || w <= 0) return;\n ctx.save();\n ctx.strokeStyle = color;\n ctx.fillStyle = color;\n const t = Math.max(1, size / 16);\n if (kind === 'marker') {\n ctx.globalAlpha = 0.35;\n ctx.strokeStyle = '#ffd166';\n ctx.lineWidth = Math.max(6, size * 0.28);\n ctx.lineCap = 'round';\n ctx.beginPath();\n ctx.moveTo(x, y - 1);\n ctx.quadraticCurveTo(x + w / 2, y + 3, x + w, y - 2);\n ctx.stroke();\n ctx.restore();\n return;\n }\n ctx.lineWidth = t;\n ctx.lineCap = 'round';\n if (kind === 'double') {\n ctx.fillRect(x, y, w, t);\n ctx.fillRect(x, y + t + 2, w, t);\n } else if (kind === 'dotted') {\n ctx.setLineDash([t * 1.6, t * 1.8]);\n ctx.beginPath();\n ctx.moveTo(x, y + t / 2);\n ctx.lineTo(x + w, y + t / 2);\n ctx.stroke();\n } else if (kind === 'wavy') {\n ctx.beginPath();\n const amp = Math.max(1.4, size * 0.08);\n const step = Math.max(4, size * 0.28);\n ctx.moveTo(x, y);\n for (let px = x; px <= x + w; px += step) {\n const up = ((px - x) / step) % 2 < 1;\n ctx.quadraticCurveTo(px + step / 2, y + (up ? -amp : amp), Math.min(x + w, px + step), y);\n }\n ctx.stroke();\n } else {\n ctx.fillRect(x, y, w, t);\n }\n ctx.restore();\n}\n\nexport function paintCanvasStrike(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, size: number, color: string) {\n ctx.fillStyle = color;\n ctx.fillRect(x, y, w, Math.max(1, size / 16));\n}\n\nexport function groupDecorationRuns(glyphs: GlyphBox[]): { x: number; y: number; w: number; size: number; kind: ReturnType<typeof underlineKind>; strike: boolean; color: string }[] {\n const out: { x: number; y: number; w: number; size: number; kind: ReturnType<typeof underlineKind>; strike: boolean; color: string }[] = [];\n let cur: (typeof out)[number] | null = null;\n for (const g of glyphs) {\n const kind = underlineKind(g.style);\n const strike = !!g.style.strikethrough;\n const size = g.style.fontSize ?? 16;\n const color = fillOf(g.style) === 'solid' ? g.style.color ?? '#1f2329' : rainbowAt(g.index);\n const baseline = g.y + g.h * 0.78;\n if (\n cur &&\n cur.kind === kind &&\n cur.strike === strike &&\n Math.abs(cur.y - baseline) < 1 &&\n Math.abs(cur.x + cur.w - g.x) < 0.6\n ) {\n cur.w += g.w;\n } else {\n if (cur) out.push(cur);\n cur = { x: g.x, y: baseline, w: g.w, size, kind, strike, color };\n }\n }\n if (cur) out.push(cur);\n return out;\n}\n","import { layoutDocument } from '../layout/engine';\nimport { canvasFont } from '../layout/measure';\nimport { REF_HEAD, REF_PAD, refInnerWidth } from '../layout/refMetrics';\nimport { DocLayout } from '../layout/types';\nimport { DocumentModel } from '../model/document';\nimport { underlineKind } from '../model/types';\nimport { cssFill, fillOf } from '../paint/decorations';\nimport { EmbedBox, EmbedPlugin } from './types';\n\nexport { REF_HEAD, REF_PAD, refInnerWidth } from '../layout/refMetrics';\nexport const REF_JUMP = 'mini-ref-jump';\nexport const REF_HIT = 'mini-ref-hit';\n\nexport interface RefJumpDetail {\n id: string;\n fragmentId: string;\n}\n\nexport interface RefHitDetail {\n id: string;\n fragmentId: string;\n localX: number;\n localY: number;\n}\n\nfunction innerUsedSize(layout: DocLayout): { width: number; height: number } {\n let right = layout.contentX;\n for (const line of layout.lines) {\n for (const g of line.glyphs) right = Math.max(right, g.x + g.w);\n for (const img of line.images) right = Math.max(right, img.x + img.w);\n for (const stop of line.caretStops) right = Math.max(right, stop.x);\n }\n for (const table of layout.tables) right = Math.max(right, table.x + table.w);\n return {\n width: Math.max(8, Math.ceil(right - layout.contentX)),\n height: Math.max(layout.height, 8)\n };\n}\n\nexport function measureRef(\n entity: { fragmentId?: string; width?: number },\n contentWidth: number,\n host?: DocumentModel\n): { width: number; height: number } {\n const maxW = Math.max(40, contentWidth);\n const innerW = refInnerWidth(maxW);\n const inner =\n entity.fragmentId && host\n ? layoutDocument(host.ensureFragmentModel(entity.fragmentId), innerW, undefined, { x: 0, y: 0 }, 1)\n : emptyInner(innerW);\n const used = innerUsedSize(inner);\n return { width: Math.min(maxW, used.width), height: used.height };\n}\n\nfunction emptyInner(width: number): DocLayout {\n return {\n width,\n height: 24,\n contentX: 0,\n contentY: 0,\n contentWidth: width,\n paragraphs: [],\n tables: [],\n lines: [],\n images: [],\n dirty: { top: 0, bottom: 0 }\n };\n}\n\nfunction countLabel(el: HTMLElement): string {\n const n = Number(el.dataset.refCount ?? 1);\n return n > 1 ? `引用 · ${n}` : '引用';\n}\n\nfunction paintInner(host: HTMLElement, layout: DocLayout | undefined) {\n host.replaceChildren();\n if (!layout) return;\n for (const line of layout.lines) {\n if (line.glyphs.length) host.appendChild(renderInnerLine(line));\n for (const img of line.images) {\n const hole = document.createElement('div');\n hole.className = 'mini-ref-hole';\n hole.style.cssText = `left:${img.x}px;top:${img.y}px;width:${img.w}px;height:${img.h}px;`;\n hole.textContent = img.entity.kind === 'image' ? '' : img.entity.kind ?? 'embed';\n if (img.entity.kind === 'image' && img.entity.src) {\n const pic = document.createElement('img');\n pic.src = img.entity.src;\n pic.alt = '';\n pic.style.cssText = 'width:100%;height:100%;object-fit:cover;border-radius:4px;';\n hole.replaceChildren(pic);\n }\n host.appendChild(hole);\n }\n }\n}\n\nfunction renderInnerLine(line: DocLayout['lines'][number]): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'mini-ref-line';\n let run: { text: string; style: (typeof line.glyphs)[0]['style']; x: number; y: number; h: number; w: number; start: number } | null = null;\n const flush = () => {\n if (!run) return;\n const span = document.createElement('span');\n span.className = `mini-run${fillOf(run.style) !== 'solid' ? ' is-fill' : ''}`;\n span.textContent = run.text;\n span.style.cssText = `left:${run.x}px;top:${run.y}px;height:${run.h}px;${innerCss(run.style, run.w)}`;\n wrap.appendChild(span);\n const deco = underlineKind(run.style);\n if (deco !== 'none' || run.style.strikethrough) {\n const bar = document.createElement('span');\n bar.className = `mini-deco mini-deco-${deco}${run.style.strikethrough ? ' is-strike' : ''}`;\n bar.style.cssText = `left:${run.x}px;top:${run.y}px;width:${run.w}px;height:${run.h}px;color:${run.style.color ?? '#1f2329'};`;\n wrap.appendChild(bar);\n }\n run = null;\n };\n for (const g of line.glyphs) {\n if (\n run &&\n run.style.bold === g.style.bold &&\n run.style.italic === g.style.italic &&\n run.style.underline === g.style.underline &&\n run.style.underlineStyle === g.style.underlineStyle &&\n run.style.strikethrough === g.style.strikethrough &&\n run.style.fontSize === g.style.fontSize &&\n run.style.color === g.style.color &&\n run.style.fill === g.style.fill &&\n run.start + run.text.length === g.index\n ) {\n run.text += g.text;\n run.w += g.w;\n } else {\n flush();\n run = { start: g.index, text: g.text, style: g.style, x: g.x, y: g.y, h: g.h, w: g.w };\n }\n }\n flush();\n return wrap;\n}\n\nfunction innerCss(style: DocLayout['lines'][number]['glyphs'][0]['style'], runW: number): string {\n const size = style.fontSize ?? 16;\n const weight = style.bold ? '700' : String(style.fontWeight ?? 400);\n const italic = style.italic ? 'italic' : 'normal';\n const color = style.color ?? '#1f2329';\n return `font-style:${italic};font-weight:${weight};font-size:${size}px;line-height:${size * 1.6}px;font-family:var(--mini-font-family);color:${color};text-decoration:none;${cssFill(style, runW)}`;\n}\n\nexport const refPlugin: EmbedPlugin = {\n kind: 'ref',\n keepAspectRatio: false,\n interactive: true,\n overlayOnCanvas: true,\n measure(entity, contentWidth, host) {\n return measureRef(entity, contentWidth, host);\n },\n create(box) {\n const root = document.createElement('div');\n root.className = 'mini-embed mini-ref mini-embed-interactive';\n const badge = document.createElement('span');\n badge.className = 'mini-ref-badge';\n badge.textContent = '引用';\n const body = document.createElement('div');\n body.className = 'mini-ref-body';\n root.append(badge, body);\n\n badge.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const fragmentId = root.dataset.fragmentId;\n if (!fragmentId) return;\n root.dispatchEvent(\n new CustomEvent<RefJumpDetail>(REF_JUMP, {\n bubbles: true,\n detail: { id: root.dataset.entity || box.entity.id, fragmentId }\n })\n );\n });\n paintChip(root, box);\n return root;\n },\n update(el, box) {\n paintChip(el, box);\n },\n paintCanvasBackdrop(ctx, box) {\n ctx.save();\n ctx.fillStyle = '#fff8dc';\n ctx.beginPath();\n ctx.roundRect(box.x, box.y, box.w, box.h, 3);\n ctx.fill();\n const inner = box.inner;\n if (inner) {\n ctx.translate(box.x + REF_PAD, box.y + REF_HEAD);\n for (const line of inner.lines) {\n for (const g of line.glyphs) {\n ctx.save();\n ctx.font = canvasFont(g.style);\n ctx.fillStyle = g.style.color ?? '#1f2329';\n ctx.textBaseline = 'top';\n ctx.fillText(g.text, g.x, g.y);\n ctx.restore();\n }\n }\n }\n ctx.restore();\n }\n};\n\nfunction paintChip(el: HTMLElement, box: EmbedBox) {\n const fragmentId = box.entity.fragmentId ?? '';\n el.dataset.fragmentId = fragmentId;\n el.dataset.refCount = el.dataset.refCount ?? '1';\n const badge = el.querySelector('.mini-ref-badge');\n if (badge) badge.textContent = countLabel(el);\n const body = el.querySelector<HTMLElement>('.mini-ref-body');\n if (body) {\n body.style.height = `${Math.max(24, box.h)}px`;\n paintInner(body, box.inner);\n }\n}\n\nexport function decorateRefEl(el: HTMLElement, count: number, title: string, editing: boolean, selected = false) {\n el.dataset.refCount = String(count);\n el.dataset.refTitle = title;\n el.classList.toggle('is-editing', editing);\n el.classList.toggle('is-selected', selected);\n const badge = el.querySelector('.mini-ref-badge');\n if (badge) badge.textContent = count > 1 ? `引用 · ${count}` : '引用';\n}\n","import { measureWidth } from '../layout/measure';\nimport { EmbedEntity, SlotKind } from '../model/types';\nimport { EMBED_EXIT_EDIT, EmbedPlugin, emitEmbedChange } from './types';\n\nexport const DEFAULT_SELECT_OPTIONS = ['小美', '阿力'] as const;\nconst FILLED_IMAGE = { width: 72, height: 40 };\n\nconst ICONS: Record<SlotKind, string> = {\n text:\n '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"M3 3.6h10M8 3.6v8.8M5.6 12.4h4.8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\"/></svg>',\n image:\n '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" aria-hidden=\"true\"><rect x=\"2.2\" y=\"3.2\" width=\"11.6\" height=\"9.6\" rx=\"1.6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\"/><path d=\"M3.4 11.2 6.1 8.2l2 1.7 2.4-3 2.1 4.3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/><circle cx=\"6\" cy=\"6.1\" r=\".9\" fill=\"currentColor\"/><path d=\"M11.2 4.6v2.4M10 5.8h2.4\" stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linecap=\"round\"/></svg>',\n select:\n '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"M4 6.2 8 10l4-3.8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>'\n};\n\nexport function defaultSlotLabel(kind: SlotKind): string {\n if (kind === 'image') return '上传图片';\n if (kind === 'select') return '请选择';\n return '输入文本';\n}\n\nexport function slotKindOf(entity: EmbedEntity): SlotKind {\n if (entity.slotKind === 'image' || entity.slotKind === 'select' || entity.slotKind === 'text') return entity.slotKind;\n return 'text';\n}\n\nexport function slotOptionsOf(entity: EmbedEntity): string[] {\n return entity.slotOptions?.length ? entity.slotOptions : [...DEFAULT_SELECT_OPTIONS];\n}\n\nexport function slotPlaceholder(entity: EmbedEntity): string {\n return entity.label || defaultSlotLabel(slotKindOf(entity));\n}\n\nexport function slotCaption(entity: EmbedEntity): string {\n return entity.slotValue?.trim() || slotPlaceholder(entity);\n}\n\nexport function slotFilled(entity: EmbedEntity): boolean {\n if (slotKindOf(entity) === 'image') return !!entity.src;\n return !!entity.slotValue?.trim();\n}\n\nexport function measureSlot(entity: EmbedEntity): { width: number; height: number } {\n if (slotKindOf(entity) === 'image' && entity.src) return { ...FILLED_IMAGE };\n const label = slotCaption(entity);\n const textW = typeof document === 'undefined' ? label.length * 13 : measureWidth(label, { fontSize: 13 });\n const extra = slotKindOf(entity) === 'select' ? 8 : 0;\n return { width: Math.ceil(28 + 16 + textW + 18 + extra), height: 28 };\n}\n\nfunction closeMenus(except?: HTMLElement) {\n for (const menu of document.querySelectorAll('.mini-slot-menu')) {\n if (menu === except) continue;\n menu.remove();\n }\n}\n\nfunction openSelectMenu(root: HTMLElement, entity: EmbedEntity) {\n closeMenus();\n const menu = document.createElement('div');\n menu.className = 'mini-slot-menu';\n const id = root.dataset.entity || entity.id;\n for (const name of slotOptionsOf(entity)) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = name;\n if (name === entity.slotValue) btn.classList.add('is-on');\n btn.addEventListener('mousedown', (e) => e.stopPropagation());\n btn.addEventListener('click', (e) => {\n e.stopPropagation();\n emitEmbedChange(root, { id, patch: { slotValue: name } }, true);\n menu.remove();\n });\n menu.appendChild(btn);\n }\n const clear = document.createElement('button');\n clear.type = 'button';\n clear.textContent = '清除';\n clear.addEventListener('mousedown', (e) => e.stopPropagation());\n clear.addEventListener('click', (e) => {\n e.stopPropagation();\n emitEmbedChange(root, { id, patch: { slotValue: '' } }, true);\n menu.remove();\n });\n menu.appendChild(clear);\n root.appendChild(menu);\n const onDoc = (e: MouseEvent) => {\n if (root.contains(e.target as Node)) return;\n menu.remove();\n document.removeEventListener('mousedown', onDoc);\n };\n document.addEventListener('mousedown', onDoc);\n}\n\nconst slotEntities = new WeakMap<HTMLElement, EmbedEntity>();\n\nfunction paintChip(el: HTMLElement, entity: EmbedEntity) {\n if (el.classList.contains('is-editing')) return;\n const kind = slotKindOf(entity);\n const filled = slotFilled(entity);\n const imageFilled = kind === 'image' && filled;\n el.className = `mini-embed mini-slot mini-embed-interactive${filled ? ' is-filled' : ''}${imageFilled ? ' is-image-filled' : ''}`;\n el.dataset.slotKind = kind;\n const icon = el.querySelector<HTMLElement>('.mini-slot-icon');\n const text = el.querySelector<HTMLElement>('.mini-slot-text');\n const thumb = el.querySelector<HTMLImageElement>('.mini-slot-thumb');\n const input = el.querySelector<HTMLInputElement>('.mini-slot-input');\n if (icon) {\n icon.hidden = imageFilled;\n icon.innerHTML = ICONS[kind];\n }\n if (text) {\n text.hidden = imageFilled;\n text.textContent = slotCaption(entity);\n }\n if (thumb) {\n thumb.hidden = !imageFilled;\n if (imageFilled && entity.src) thumb.src = entity.src;\n else thumb.removeAttribute('src');\n }\n if (input) input.hidden = true;\n}\n\nexport const slotPlugin: EmbedPlugin = {\n kind: 'internalSlot',\n keepAspectRatio: false,\n interactive: true,\n overlayOnCanvas: true,\n measure: measureSlot,\n create(box) {\n const root = document.createElement('span');\n const icon = document.createElement('span');\n icon.className = 'mini-slot-icon';\n const text = document.createElement('span');\n text.className = 'mini-slot-text';\n const thumb = document.createElement('img');\n thumb.className = 'mini-slot-thumb';\n thumb.alt = '';\n thumb.draggable = false;\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'mini-slot-input';\n input.hidden = true;\n const file = document.createElement('input');\n file.type = 'file';\n file.accept = 'image/*';\n file.className = 'mini-slot-file';\n root.append(icon, text, thumb, input, file);\n slotEntities.set(root, box.entity);\n\n let baseline = box.entity.slotValue ?? '';\n const current = () => slotEntities.get(root) ?? box.entity;\n const entityId = () => root.dataset.entity || current().id;\n\n const leaveEdit = () => {\n root.classList.remove('is-editing');\n input.hidden = true;\n icon.hidden = false;\n text.hidden = false;\n };\n\n const startTextEdit = () => {\n const entity = current();\n baseline = entity.slotValue ?? '';\n root.classList.add('is-editing');\n closeMenus();\n icon.hidden = true;\n text.hidden = true;\n thumb.hidden = true;\n input.hidden = false;\n input.value = baseline;\n input.placeholder = slotPlaceholder(entity);\n input.focus();\n input.select();\n };\n\n const commitText = () => {\n if (!root.classList.contains('is-editing')) return;\n const value = input.value;\n leaveEdit();\n emitEmbedChange(root, { id: entityId(), patch: { slotValue: value } }, true);\n };\n\n const cancelText = () => {\n if (!root.classList.contains('is-editing')) return;\n leaveEdit();\n emitEmbedChange(root, { id: entityId(), patch: { slotValue: baseline } }, true);\n };\n\n const activate = () => {\n const entity = current();\n const kind = slotKindOf(entity);\n if (kind === 'image') {\n file.click();\n return;\n }\n if (kind === 'select') {\n openSelectMenu(root, entity);\n return;\n }\n startTextEdit();\n };\n\n root.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).closest('.mini-slot-menu, .mini-slot-file, .mini-slot-input')) return;\n activate();\n });\n root.addEventListener('mini-slot-activate', activate);\n input.addEventListener('mousedown', (e) => e.stopPropagation());\n input.addEventListener('click', (e) => e.stopPropagation());\n input.addEventListener('input', () => {\n emitEmbedChange(root, { id: entityId(), patch: { slotValue: input.value } });\n });\n input.addEventListener('blur', () => {\n window.setTimeout(() => {\n if (root.contains(document.activeElement)) return;\n commitText();\n }, 0);\n });\n input.addEventListener('keydown', (e) => {\n e.stopPropagation();\n if (e.key === 'Enter') {\n e.preventDefault();\n commitText();\n return;\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n cancelText();\n return;\n }\n if (e.key === 'ArrowLeft' && input.selectionStart === 0 && input.selectionEnd === 0) {\n e.preventDefault();\n commitText();\n root.dispatchEvent(new CustomEvent(EMBED_EXIT_EDIT, { bubbles: true, detail: { id: entityId(), side: 'before' } }));\n return;\n }\n if (\n e.key === 'ArrowRight' &&\n input.selectionStart === input.value.length &&\n input.selectionEnd === input.value.length\n ) {\n e.preventDefault();\n commitText();\n root.dispatchEvent(new CustomEvent(EMBED_EXIT_EDIT, { bubbles: true, detail: { id: entityId(), side: 'after' } }));\n }\n });\n file.addEventListener('mousedown', (e) => e.stopPropagation());\n file.addEventListener('change', () => {\n const f = file.files?.[0];\n file.value = '';\n if (!f) return;\n emitEmbedChange(\n root,\n {\n id: entityId(),\n patch: { slotValue: '', src: URL.createObjectURL(f) }\n },\n true\n );\n });\n\n paintChip(root, box.entity);\n return root;\n },\n update(el, box) {\n slotEntities.set(el, box.entity);\n paintChip(el, box.entity);\n },\n paintCanvasBackdrop(ctx, box, imageOf) {\n const r = Math.min(12, box.h / 2);\n ctx.beginPath();\n ctx.roundRect(box.x, box.y, box.w, box.h, r);\n if (slotKindOf(box.entity) === 'image' && box.entity.src) {\n ctx.save();\n ctx.clip();\n try {\n ctx.drawImage(imageOf(box.entity.src), box.x, box.y, box.w, box.h);\n } catch {\n ctx.fillStyle = '#e9edf5';\n ctx.fill();\n }\n ctx.restore();\n return;\n }\n ctx.fillStyle = slotFilled(box.entity) ? '#e9edf5' : '#f2f4f7';\n ctx.fill();\n ctx.fillStyle = slotFilled(box.entity) ? '#1f2329' : '#98a2b3';\n ctx.font = '13px \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif';\n ctx.textBaseline = 'middle';\n ctx.fillText(slotCaption(box.entity), box.x + 34, box.y + box.h / 2);\n }\n};\n","import { EmbedBox, EmbedPlugin } from './types';\n\nfunction applyVideo(el: HTMLVideoElement, box: EmbedBox) {\n if (box.entity.src && el.src !== box.entity.src) el.src = box.entity.src;\n}\n\nexport const videoPlugin: EmbedPlugin = {\n kind: 'video',\n keepAspectRatio: true,\n interactive: true,\n overlayOnCanvas: true,\n measure(entity) {\n return { width: entity.width, height: entity.height };\n },\n create(box) {\n const node = document.createElement('video');\n node.className = 'mini-embed mini-image mini-video mini-embed-interactive';\n node.controls = true;\n node.preload = 'metadata';\n node.playsInline = true;\n node.draggable = false;\n applyVideo(node, box);\n return node;\n },\n update(el, box) {\n applyVideo(el as HTMLVideoElement, box);\n },\n paintCanvasBackdrop(ctx, box) {\n ctx.fillStyle = '#111827';\n ctx.fillRect(box.x, box.y, box.w, box.h);\n }\n};\n","import { EmbedEntity } from '../model/types';\nimport { EmbedBox, EmbedChangeDetail, EMBED_CHANGE, EMBED_COMMIT, EMBED_MEASURE, EmbedMeasureDetail, EmbedPlugin } from './types';\n\n/**\n * 宿主渲染型嵌入对象。\n *\n * 与内置的自绘型嵌入对象(image/slot/ref 等由 SDK 自己建 DOM、自己画)不同,\n * host 型把节点内部 DOM 的渲染权交给宿主:SDK 只负责在文本流里占一个字符位、\n * 用 measure 得到的尺寸给它绝对定位、并管理它的挂载/更新/卸载生命周期;节点里\n * 具体画什么由宿主提供的 {@link HostEmbedRenderer} 决定。宿主据此把自己框架\n * (axii / React 等)的业务组件 render 进 SDK 交出的容器里。\n *\n * 数据是引用式的:实体 {@link EmbedEntity.data} 里通常只存业务对象的引用 id,\n * 完整数据与状态由宿主自己的 store 维护、自行 resolve。数据变化经宿主回调写回\n * 实体(复用 EMBED_CHANGE / EMBED_COMMIT 事件回路),尺寸变化经 requestResize\n * 通知 SDK 重排。\n */\n\n/** SDK 交给宿主渲染器的上下文,随实体/选中态变化。 */\nexport interface HostEmbedContext {\n /** 当前实体(含 hostType / data 等业务字段)。 */\n entity: EmbedEntity;\n /** 该嵌入对象当前是否被选中(外层光标选区覆盖它)。 */\n selected: boolean;\n /**\n * 写回实体数据。commit=false 为预览(不进撤销栈),commit=true 落定(进撤销栈)。\n * patch 可含 data / width / height 等实体字段。\n */\n emitChange(patch: Partial<EmbedEntity>, commit?: boolean): void;\n /** 宿主渲染后尺寸确定/变化时调用,通知 SDK 用新尺寸重排。 */\n requestResize(width: number, height: number): void;\n}\n\n/**\n * 选中 host 后按键激活。引擎不解释业务 UI(下拉等),只问宿主要不要吞掉这次按键。\n * 返回 true:已处理,不再插段;false / 未实现:按默认换行。\n */\nexport interface HostActivateRequest {\n key: 'Enter';\n shift: boolean;\n}\n\n/** 一次 mount 返回的句柄,供 SDK 在实体/选中态变化和卸载时调用。 */\nexport interface HostEmbedHandle {\n /** 实体或选中态变化时,SDK 调它同步宿主渲染。 */\n update(ctx: HostEmbedContext): void;\n /** 节点从文档移除时,SDK 调它清理宿主侧资源(卸载组件、解绑等)。 */\n destroy(): void;\n /**\n * 整颗选中时的激活(对齐公式 Enter 进编辑)。省略则选中回车仍插段。\n */\n activate?(req: HostActivateRequest): boolean;\n}\n\n/** 宿主渲染器:把业务组件挂进 SDK 交出的容器。由构造 Editor 时通过 options 注入。 */\nexport interface HostEmbedRenderer {\n /**\n * 把业务组件渲染进 container。container 是 SDK 建好的空节点,已做好占位与定位。\n * 返回句柄供后续 update / destroy。\n */\n mount(container: HTMLElement, ctx: HostEmbedContext): HostEmbedHandle;\n}\n\n/** 当前 Editor 注入的渲染器。单例:一个运行时只有一个宿主渲染器。 */\nlet renderer: HostEmbedRenderer | null = null;\n\nexport function setHostEmbedRenderer(r: HostEmbedRenderer | null) {\n renderer = r;\n}\n\n/** host 型实体的默认兜底尺寸(宿主尚未回传测量前)。 */\nconst FALLBACK_SIZE = { width: 120, height: 24 };\n\n/** 每个容器 el 对应的宿主句柄、最近一次 box 与自动测尺观察器,供 update/卸载使用。 */\ntype HostRec = { el: HTMLElement; handle: HostEmbedHandle; box: EmbedBox; ro?: ResizeObserver; lastSize?: string };\n\nconst handles = new WeakMap<HTMLElement, HostRec>();\n/** 按实体 id 索引,光标移动时不经过 querySelector / data-entity,避免对不上。 */\nconst handlesById = new Map<string, HostRec>();\n\n/**\n * 把尺寸回报为 EMBED_MEASURE:只触发重排,不进撤销栈。\n *\n * 无论来自 SDK 的自动观察还是宿主手动调 requestResize,都走这里。延到微任务里\n * 派发有两个原因:宿主常在 mount 首帧就报,而此刻容器可能还没挂进文档树(create\n * 返回后 registry 才 appendChild),同步事件冒泡不到编辑器;且重排里再改 DOM 会\n * 触发 ResizeObserver 递归,延迟能断开这个同步链。\n */\nfunction emitMeasure(el: HTMLElement, id: string, width: number, height: number) {\n const detail: EmbedMeasureDetail = { id, width, height };\n queueMicrotask(() =>\n el.dispatchEvent(new CustomEvent(EMBED_MEASURE, { bubbles: true, detail }))\n );\n}\n\n/**\n * SDK 自动观察 host 块尺寸。宿主只管把组件画进容器,尺寸变化 SDK 自动感知并重排,\n * 宿主零负担、无需自己装 ResizeObserver 或调 requestResize。\n *\n * 观察的是内层 measure 节点 `inner`,不是外层 `el`:外层 el 会被 placeEmbed 按\n * 回填尺寸强制设宽高(用于占位定位),量它只会量到回填值、无法反映内容真实需求,\n * 形成自我印证;内层 inner 不设宽高、由宿主内容自然撑开,量到的才是内容真实占位。\n */\nfunction observeSize(inner: HTMLElement, id: string, rec: { ro?: ResizeObserver; lastSize?: string }) {\n if (typeof ResizeObserver === 'undefined') return;\n const ro = new ResizeObserver(() => {\n const width = Math.round(inner.offsetWidth);\n const height = Math.round(inner.offsetHeight);\n if (!width || !height) return;\n // 交接帧可能量到「一列字」的窄高盒子;写回会锁死排版,直到下次输入再撑开。\n if (width < 48 && height > width * 3) return;\n const key = `${width}x${height}`;\n // 去重:避免尺寸未变时反复触发重排。\n if (key === rec.lastSize) return;\n rec.lastSize = key;\n emitMeasure(inner, id, width, height);\n });\n ro.observe(inner);\n rec.ro = ro;\n}\n\n/**\n * 光标选中变化时打标并通知宿主。排版层不会每次重排,所以不能只靠 plugin.update。\n * 按实体 id 找句柄,并把 selected 直接写进 ctx,不依赖 data-entity 对得上。\n */\nexport function decorateHostEl(el: HTMLElement, selected: boolean) {\n const rec = handles.get(el) ?? handlesById.get(el.dataset.entity ?? '');\n if (!rec) {\n el.classList.toggle('is-selected', selected);\n return;\n }\n syncRecSelected(rec, selected);\n}\n\nexport function syncHostSelected(selectedId: string | null) {\n for (const rec of handlesById.values()) {\n syncRecSelected(rec, rec.box.entity.id === selectedId);\n }\n}\n\nfunction syncRecSelected(rec: HostRec, selected: boolean) {\n const prev = rec.el.classList.contains('is-selected');\n rec.el.classList.toggle('is-selected', selected);\n if (prev === selected) return;\n rec.handle.update({ ...contextOf(rec.el, rec.box), selected });\n}\n\nfunction contextOf(el: HTMLElement, box: EmbedBox): HostEmbedContext {\n const id = box.entity.id;\n return {\n entity: box.entity,\n // 选中态由编辑器通过 DOM class 标记(与自绘型一致),这里读回给宿主。\n selected: el.classList.contains('is-selected'),\n emitChange(patch, commit = false) {\n const detail: EmbedChangeDetail = { id, patch };\n el.dispatchEvent(new CustomEvent(commit ? EMBED_COMMIT : EMBED_CHANGE, { bubbles: true, detail }));\n },\n // 手动挡:SDK 默认已自动观察容器尺寸,宿主一般不用调这个;只有想自己精确\n // 控制回报时机的场景才用。走的是和自动观察同一条通道。\n requestResize(width, height) {\n emitMeasure(el, id, width, height);\n }\n };\n}\n\n/** 把宿主组件挂进内层节点,记录句柄并开启自动测尺。create/补挂共用。 */\nfunction mountInto(el: HTMLElement, inner: HTMLElement, box: EmbedBox) {\n const handle = renderer!.mount(inner, contextOf(el, box));\n const rec: HostRec = {\n el,\n handle,\n box\n };\n handles.set(el, rec);\n handlesById.set(box.entity.id, rec);\n observeSize(inner, box.entity.id, rec);\n}\n\nexport const hostEmbedPlugin: EmbedPlugin = {\n kind: 'hostSlot',\n keepAspectRatio: false,\n interactive: true,\n overlayOnCanvas: true,\n measure(entity) {\n // 宿主渲染型尺寸由宿主 render 后经 requestResize 回写到实体;此处用实体上已\n // 记录的尺寸,尚无则回退兜底值(首帧后宿主回传即触发重排修正)。\n const width = entity.width > 0 ? entity.width : FALLBACK_SIZE.width;\n const height = entity.height > 0 ? entity.height : FALLBACK_SIZE.height;\n return { width, height };\n },\n create(box) {\n const el = document.createElement('span');\n el.className = 'mini-embed mini-host mini-embed-interactive';\n // 标记 kind,供 syncEmbedLayer 移除时找到本插件调用 destroy 清理副作用。\n el.dataset.kind = 'hostSlot';\n // 内层 measure 节点:不设宽高、由宿主内容自然撑开,既是宿主的挂载点,\n // 也是 SDK 自动测尺的观察对象(见 observeSize)。\n const inner = document.createElement('span');\n inner.className = 'mini-host-inner';\n el.appendChild(inner);\n if (!renderer) {\n // 未注入渲染器:留一个占位容器,避免报错;宿主接入后应始终提供 renderer。\n return el;\n }\n mountInto(el, inner, box);\n return el;\n },\n update(el, box) {\n const rec = handles.get(el);\n if (rec) {\n rec.box = box;\n rec.el = el;\n handlesById.set(box.entity.id, rec);\n rec.handle.update({\n ...contextOf(el, box),\n selected: el.classList.contains('is-selected')\n });\n } else if (renderer) {\n // 容器已存在但尚未 mount(例如 create 时 renderer 未就绪):补挂。\n const inner = el.querySelector<HTMLElement>('.mini-host-inner') ?? el;\n mountInto(el, inner, box);\n }\n },\n paintCanvasBackdrop() {\n // 宿主渲染型只走 DOM 图层(overlayOnCanvas=true),canvas 后端不额外画底。\n }\n};\n\n/** 选中 host 按 Enter:转给该实体的 {@link HostEmbedHandle.activate}。 */\nexport function activateHostEmbed(id: string, req: HostActivateRequest): boolean {\n return handlesById.get(id)?.handle.activate?.(req) === true;\n}\n\n/** host 块从文档移除时清理:停掉自动测尺、卸载宿主组件、释放记录。 */\nexport function destroyHostEmbed(el: HTMLElement) {\n const rec = handles.get(el);\n if (rec) {\n rec.ro?.disconnect();\n rec.handle.destroy();\n handles.delete(el);\n handlesById.delete(rec.box.entity.id);\n }\n}\n","import { EmbedKind } from '../model/types';\nimport { EmbedBox, EmbedPlugin, placeEmbed } from './types';\n\nconst plugins = new Map<EmbedKind, EmbedPlugin>();\n\nexport function registerEmbed(plugin: EmbedPlugin) {\n plugins.set(plugin.kind, plugin);\n}\n\nexport function embedPlugin(kind: EmbedKind | undefined): EmbedPlugin {\n const hit = plugins.get(kind ?? 'image') ?? plugins.get('image');\n if (!hit) {\n throw new Error(\n `嵌入插件未注册:${kind ?? 'image'}。` +\n '请先 registerEmbed(...) 或构造 Editor 时传 plugins —— ' +\n '注意在构造 Editor 之前调用 embedPlugin 的代码(如预先构建文档)需要自己先注册。'\n );\n }\n return hit;\n}\n\nexport function syncEmbedLayer(\n host: HTMLElement,\n cache: Map<string, HTMLElement>,\n boxes: EmbedBox[],\n canvas: boolean\n) {\n const seen = new Set<string>();\n for (const box of boxes) {\n const plugin = embedPlugin(box.entity.kind);\n if (canvas && !plugin.overlayOnCanvas) continue;\n seen.add(box.entity.id);\n let el = cache.get(box.entity.id);\n if (!el) {\n el = plugin.create(box);\n host.appendChild(el);\n cache.set(box.entity.id, el);\n }\n plugin.update(el, box);\n placeEmbed(el, box);\n }\n for (const [id, el] of cache) {\n if (!seen.has(id)) {\n // 移除前给插件一次清理副作用的机会(观察器、外部组件等)。\n plugins.get((el.dataset.kind ?? '') as EmbedKind)?.destroy?.(el);\n el.remove();\n cache.delete(id);\n }\n }\n}\n","import { codePlugin } from './code';\nimport { imagePlugin } from './image';\nimport { refPlugin } from './ref';\nimport { slotPlugin } from './slot';\nimport { EmbedPlugin } from './types';\nimport { videoPlugin } from './video';\nimport { hostEmbedPlugin } from './host';\n\n/**\n * 默认内置插件。不含公式 —— 公式依赖 KaTeX / MathLive,体积很大,\n * 需要时从 `medeo-rte/formula` 单独引入再传给 Editor。\n */\nexport const builtinEmbedPlugins: EmbedPlugin[] = [\n imagePlugin,\n videoPlugin,\n codePlugin,\n slotPlugin,\n refPlugin\n];\n\nexport { codePlugin, imagePlugin, refPlugin, slotPlugin, videoPlugin };\nexport { hostEmbedPlugin, setHostEmbedRenderer, destroyHostEmbed, activateHostEmbed, decorateHostEl, syncHostSelected } from './host';\nexport type { HostEmbedRenderer, HostEmbedContext, HostEmbedHandle, HostActivateRequest } from './host';\nexport { embedPlugin, registerEmbed, syncEmbedLayer } from './registry';\nexport { measureCode } from './code';\nexport { decorateRefEl, measureRef, REF_HEAD, REF_HIT, REF_JUMP, REF_PAD, refInnerWidth } from './ref';\nexport { defaultSlotLabel, measureSlot } from './slot';\nexport { EMBED_CHANGE, EMBED_COMMIT, EMBED_EXIT_EDIT, EMBED_MEASURE, type EmbedBox, type EmbedChangeDetail, type EmbedExitDetail, type EmbedMeasureDetail, type EmbedPlugin } from './types';\n","/**\n * Mutation —— 文档变更的原子单元,也是 OT 变换的对象。\n *\n * 设计要点:\n * - Mutation 是**纯数据**,可直接 JSON 序列化后走网络。行为(应用、变换、求逆、\n * 合并)不挂在它身上,而是按 `type` 到注册表里查,见 registry.ts。\n * - 索引一律是**闭区间**语义,`deleteSpacers` 的 `[startIndex, endIndex]` 含两端。\n * 与文档模型半开区间的转换在 apply/invert 边界上做。\n * - 上层的一次用户操作(比如「按退格」)通常展开成多条 mutation,\n * 用 `multi` 打包成一步。\n */\nimport { EmbedEntity, Fragment, StyleProps, StyleType, VirtualBlock } from '../model/types';\n\n/** 在 insertBeforeIndex 之前插入这串 spacer。 */\nexport interface InsertSpacersMutation {\n type: 'insertSpacers';\n insertBeforeIndex: number;\n spacers: string;\n}\n\n/** 删除闭区间 [startIndex, endIndex]。 */\nexport interface DeleteSpacersMutation {\n type: 'deleteSpacers';\n startIndex: number;\n endIndex: number;\n}\n\n/** 给闭区间 [startIndex, endIndex] 覆盖一段样式。props 为 null 表示清除该类型。 */\nexport interface ApplyStyleMutation {\n type: 'applyStyle';\n styleType: StyleType;\n startIndex: number;\n endIndex: number;\n props: StyleProps | null;\n}\n\nexport interface AddEntityMutation {\n type: 'addEntity';\n entity: EmbedEntity;\n}\n\nexport interface UpdateEntityMutation {\n type: 'updateEntity';\n entityId: string;\n props: Partial<EmbedEntity>;\n}\n\nexport interface DeleteEntityMutation {\n type: 'deleteEntity';\n entityId: string;\n}\n\n/**\n * 新建一个同步块(fragment)。\n *\n * fragment 和 entity 一样按 id 寻址,不占主文档坐标空间,因此不参与下标变换。\n * 提取同步块(promoteRange)时发这条,撤销即删除它。\n */\nexport interface AddFragmentMutation {\n type: 'addFragment';\n fragment: Fragment;\n}\n\n/** 删除一个同步块。逆操作把整份 Fragment 原样加回来。 */\nexport interface DeleteFragmentMutation {\n type: 'deleteFragment';\n fragmentId: string;\n}\n\n/** 写入一个虚拟块。同 id 存在则整体替换。区间随字符插删由 applier 机械挪动。 */\nexport interface AddVirtualBlockMutation {\n type: 'addVirtualBlock';\n block: VirtualBlock;\n}\n\n/** 删除一个虚拟块。 */\nexport interface DeleteVirtualBlockMutation {\n type: 'deleteVirtualBlock';\n blockId: string;\n}\n\n/** 用完整值覆盖一个虚拟块(含区间与 chrome)。 */\nexport interface UpdateVirtualBlockMutation {\n type: 'updateVirtualBlock';\n blockId: string;\n block: VirtualBlock;\n}\n\n/** 变换后被完全抵消的操作。应用时什么都不做。 */\nexport interface NullMutation {\n type: 'null';\n}\n\n/** 一组按序执行的 mutation,构成一个不可分割的步骤。 */\nexport interface MultiMutation {\n type: 'multi';\n commands: Mutation[];\n}\n\n/**\n * 把一条 mutation 定向到某个片段(同步块)的坐标空间里去执行。\n *\n * 片段的内容是独立的一条字符流,下标和主文档不共享。用这层包装之后,\n * 片段内部的编辑和主文档编辑就是同一种东西了:进同一个撤销栈、走同一套变换。\n * 不同片段的操作天然不冲突,变换时直接原样放行。\n */\nexport interface ScopedMutation {\n type: 'scoped';\n fragmentId: string;\n inner: Mutation;\n}\n\nexport type Mutation =\n | InsertSpacersMutation\n | DeleteSpacersMutation\n | ApplyStyleMutation\n | AddEntityMutation\n | UpdateEntityMutation\n | DeleteEntityMutation\n | AddFragmentMutation\n | DeleteFragmentMutation\n | AddVirtualBlockMutation\n | DeleteVirtualBlockMutation\n | UpdateVirtualBlockMutation\n | NullMutation\n | MultiMutation\n | ScopedMutation;\n\nexport type MutationType = Mutation['type'];\n\n// ---- 构造 ----------------------------------------------------------------\n\nexport function insertSpacers(insertBeforeIndex: number, spacers: string): Mutation {\n return spacers ? { type: 'insertSpacers', insertBeforeIndex, spacers } : NULL_MUTATION;\n}\n\n/** 入参是闭区间。 */\nexport function deleteSpacers(startIndex: number, endIndex: number): Mutation {\n return endIndex >= startIndex ? { type: 'deleteSpacers', startIndex, endIndex } : NULL_MUTATION;\n}\n\n/** 从半开区间 [start, end) 构造,便于和文档模型对接。 */\nexport function deleteSpacersHalfOpen(start: number, end: number): Mutation {\n return deleteSpacers(start, end - 1);\n}\n\nexport function applyStyle(\n styleType: StyleType,\n startIndex: number,\n endIndex: number,\n props: StyleProps | null\n): Mutation {\n return endIndex >= startIndex\n ? { type: 'applyStyle', styleType, startIndex, endIndex, props }\n : NULL_MUTATION;\n}\n\nexport function addEntity(entity: EmbedEntity): Mutation {\n return { type: 'addEntity', entity };\n}\n\nexport function updateEntity(entityId: string, props: Partial<EmbedEntity>): Mutation {\n return { type: 'updateEntity', entityId, props };\n}\n\nexport function deleteEntity(entityId: string): Mutation {\n return { type: 'deleteEntity', entityId };\n}\n\nexport function addFragment(fragment: Fragment): Mutation {\n return { type: 'addFragment', fragment };\n}\n\nexport function deleteFragment(fragmentId: string): Mutation {\n return { type: 'deleteFragment', fragmentId };\n}\n\nexport function addVirtualBlock(block: VirtualBlock): Mutation {\n return { type: 'addVirtualBlock', block };\n}\n\nexport function deleteVirtualBlock(blockId: string): Mutation {\n return { type: 'deleteVirtualBlock', blockId };\n}\n\nexport function updateVirtualBlock(blockId: string, block: VirtualBlock): Mutation {\n return { type: 'updateVirtualBlock', blockId, block: { ...block, id: blockId } };\n}\n\nexport const NULL_MUTATION: NullMutation = { type: 'null' };\n\n/**\n * 把 inner 定向到某个片段。\n *\n * inner 是组合时会摊成「一串各自定向的单条」,这样 scoped 始终只包一条实操,\n * 逐条求逆和逐条变换才对得上。\n */\nexport function scoped(fragmentId: string, inner: Mutation): Mutation {\n if (inner.type === 'null') return NULL_MUTATION;\n if (inner.type === 'multi') return multi(unwrap(inner).map((m) => scoped(fragmentId, m)));\n return { type: 'scoped', fragmentId, inner };\n}\n\n/** 打包成一步。会摊平嵌套的 multi、滤掉 null;空则返回 null mutation。 */\nexport function multi(commands: Mutation[]): Mutation {\n const flat: Mutation[] = [];\n for (const c of commands) {\n if (c.type === 'null') continue;\n if (c.type === 'multi') flat.push(...unwrap(c));\n else flat.push(c);\n }\n if (flat.length === 0) return NULL_MUTATION;\n if (flat.length === 1) return flat[0];\n return { type: 'multi', commands: flat };\n}\n\n/** 摊平成一维列表,null 被滤掉。 */\nexport function unwrap(mutation: Mutation): Mutation[] {\n if (mutation.type === 'null') return [];\n if (mutation.type !== 'multi') return [mutation];\n const out: Mutation[] = [];\n for (const c of mutation.commands) out.push(...unwrap(c));\n return out;\n}\n\n/** multi 的逆序摊平。求逆时用:撤销一组操作要从最后一条倒着来。 */\nexport function reverse(mutations: Mutation[]): Mutation[] {\n return [...mutations].reverse();\n}\n","/**\n * 把 mutation 作用到文档模型上。\n *\n * 这一层是**机械写入**:不校验、不合并、不推导。所有语义判断都该在上层做完,\n * mutation 到这里时携带的已经是解析好的完整值。\n *\n * 区间语义在这里换挡:mutation 用闭区间 [start, end],\n * 文档模型用半开区间 [start, end),所以下面凡是调模型的地方都 +1。\n */\nimport { cloneEntity, StyleSpan } from '../model/types';\nimport { DocumentModel } from '../model/document';\nimport { Mutation, MutationType, unwrap } from './types';\n\nexport type ApplierFor<T extends MutationType> = (\n doc: DocumentModel,\n mutation: Extract<Mutation, { type: T }>\n) => void;\n\n/** 每种 mutation 一个 applier。少一种编译不过。 */\nexport type Appliers = { [T in MutationType]: ApplierFor<T> };\n\nexport const appliers: Appliers = {\n null: () => {},\n\n multi: (doc, mutation) => {\n for (const c of unwrap(mutation)) applyMutation(doc, c);\n },\n\n insertSpacers: (doc, mutation) => {\n doc.applyInsertSpacers(mutation.insertBeforeIndex, mutation.spacers);\n },\n\n deleteSpacers: (doc, mutation) => {\n doc.applyDeleteSpacers(mutation.startIndex, mutation.endIndex + 1);\n },\n\n applyStyle: (doc, mutation) => {\n const start = mutation.startIndex;\n const end = mutation.endIndex + 1;\n const next: StyleSpan[] = mutation.props\n ? [{ start, end, type: mutation.styleType, props: mutation.props }]\n : [];\n doc.applyStyleSpans(mutation.styleType, start, end, next);\n },\n\n addEntity: (doc, mutation) => {\n doc.entities.set(mutation.entity.id, cloneEntity(mutation.entity));\n },\n\n updateEntity: (doc, mutation) => {\n const cur = doc.entities.get(mutation.entityId);\n if (cur) doc.entities.set(mutation.entityId, cloneEntity({ ...cur, ...mutation.props }));\n },\n\n deleteEntity: (doc, mutation) => {\n doc.entities.delete(mutation.entityId);\n },\n\n addFragment: (doc, mutation) => {\n doc.applyAddFragment(mutation.fragment);\n },\n\n deleteFragment: (doc, mutation) => {\n doc.applyDeleteFragment(mutation.fragmentId);\n },\n\n addVirtualBlock: (doc, mutation) => {\n doc.applyAddVirtualBlock(mutation.block);\n },\n\n deleteVirtualBlock: (doc, mutation) => {\n doc.applyDeleteVirtualBlock(mutation.blockId);\n },\n\n updateVirtualBlock: (doc, mutation) => {\n doc.applyUpdateVirtualBlock(mutation.blockId, mutation.block);\n },\n\n // 路由到片段自己的模型上执行,然后把派生出来的 Slice 刷新一遍供引用处渲染。\n scoped: (doc, mutation) => {\n applyMutation(doc.ensureFragmentModel(mutation.fragmentId), mutation.inner);\n doc.syncFragment(mutation.fragmentId);\n }\n};\n\nexport function applyMutation(doc: DocumentModel, mutation: Mutation): void {\n // 单次转型:TS 无法把 appliers[m.type] 和 m 的类型关联起来,但查表本身是安全的。\n (appliers[mutation.type] as ApplierFor<MutationType>)(doc, mutation);\n}\n\n/** 依次应用一串 mutation。 */\nexport function applyMutations(doc: DocumentModel, mutations: Mutation[]): void {\n for (const m of mutations) applyMutation(doc, m);\n}\n","import { cloneEntity, cloneStyle, cloneVirtualBlock, Fragment, Slice } from './types';\nimport { MARKERS } from './markers';\n\nexport function cloneFragment(fragment: Fragment): Fragment {\n return {\n id: fragment.id,\n title: fragment.title,\n slice: cloneSlice(fragment.slice)\n };\n}\n\nexport function cloneSlice(slice: Slice): Slice {\n return {\n text: slice.text,\n styles: slice.styles.map(cloneStyle),\n entities: slice.entities.map(cloneEntity),\n fragments: slice.fragments?.map(cloneFragment),\n virtualBlocks: slice.virtualBlocks?.map(cloneVirtualBlock)\n };\n}\n\nexport function previewTitle(slice: Slice, max = 18): string {\n const text = slice.text.replace(/\\n+/g, ' ').replace(/\\*/g, '').trim();\n if (!text) return '未命名同步块';\n return text.length > max ? `${text.slice(0, max)}…` : text;\n}\n\nexport function normalizeFragmentSlice(slice: Slice): Slice {\n let text = slice.text;\n const styles = slice.styles.map(cloneStyle);\n if (!text.endsWith(MARKERS.PARAGRAPH)) text += MARKERS.PARAGRAPH;\n return {\n text,\n styles,\n entities: slice.entities.map(cloneEntity),\n virtualBlocks: slice.virtualBlocks?.map(cloneVirtualBlock)\n };\n}\n\nexport function sliceHasContent(slice: Slice): boolean {\n return slice.text.replace(/\\n/g, '').replace(/\\s/g, '').length > 0 || slice.entities.length > 0;\n}\n","/**\n * 求逆:给一条 mutation 算出能把它撤销掉的 mutation。\n *\n * 有的逆是纯算术(插入的逆就是删掉同样长度),有的必须先读文档\n * (删除的逆要把被删的内容原样记下来),所以求逆一律要在**应用之前**做。\n * 组合操作更要逐条交错:算第 n 条的逆 → 应用第 n 条 → 再算第 n+1 条的逆,\n * 否则后面几条的逆会建立在错误的状态上。用 applyAndInvert 就不会踩到。\n */\nimport { cloneEntity, cloneVirtualBlock, StyleSpan, StyleType } from '../model/types';\nimport { cloneFragment } from '../model/fragment';\nimport { DocumentModel } from '../model/document';\nimport { applyMutation } from './apply';\nimport {\n addEntity,\n addFragment,\n addVirtualBlock,\n applyStyle,\n deleteEntity,\n deleteFragment,\n deleteSpacers,\n deleteVirtualBlock,\n insertSpacers,\n Mutation,\n MutationType,\n multi,\n NULL_MUTATION,\n scoped,\n unwrap,\n updateEntity,\n updateVirtualBlock\n} from './types';\n\nconst STYLE_TYPES: StyleType[] = ['text', 'paragraph', 'table', 'cell', 'image', 'link'];\n\n/** 记录半开区间 [start, end) 上的全部样式,生成能原样恢复它们的 mutation。 */\nfunction restoreStyles(doc: DocumentModel, start: number, end: number): Mutation[] {\n const out: Mutation[] = [];\n for (const type of STYLE_TYPES) {\n const spans = doc.styleSpansOver(type, start, end);\n // 先清空整段,再逐段填回去 —— 否则残留的旧区间会和恢复的混在一起\n out.push(applyStyle(type, start, end - 1, null));\n for (const s of spans) out.push(applyStyle(type, s.start, s.end - 1, s.props));\n }\n return out;\n}\n\nexport type InverterFor<T extends MutationType> = (\n doc: DocumentModel,\n mutation: Extract<Mutation, { type: T }>\n) => Mutation;\n\n/** 每种 mutation 一个 inverter。少一种编译不过。 */\nexport type Inverters = { [T in MutationType]: InverterFor<T> };\n\nexport const inverters: Inverters = {\n null: () => NULL_MUTATION,\n\n multi: () => {\n throw new Error('组合操作要用 applyAndInvert 逐条交错求逆,不能整体求逆');\n },\n\n insertSpacers: (_doc, mutation) =>\n deleteSpacers(\n mutation.insertBeforeIndex,\n mutation.insertBeforeIndex + mutation.spacers.length - 1\n ),\n\n // 只管字符与样式。落在这段里的实体由 Operation 层显式发 deleteEntity,\n // 它们的逆(addEntity)自然排在这条前面,不需要在这里兜底。\n deleteSpacers: (doc, mutation) => {\n const start = mutation.startIndex;\n const end = mutation.endIndex + 1;\n const restoredBlocks = doc.virtualBlocksOverlapping(start, end).map((b) => addVirtualBlock(cloneVirtualBlock(b)));\n return multi([\n insertSpacers(start, doc.spacers.slice(start, end)),\n ...restoreStyles(doc, start, end),\n ...restoredBlocks\n ]);\n },\n\n applyStyle: (doc, mutation) =>\n multi(\n restoreStyles(doc, mutation.startIndex, mutation.endIndex + 1).filter(\n (m) => m.type === 'applyStyle' && m.styleType === mutation.styleType\n )\n ),\n\n addEntity: (doc, mutation) =>\n doc.entities.has(mutation.entity.id)\n ? updateEntity(mutation.entity.id, cloneEntity(doc.entities.get(mutation.entity.id)!))\n : deleteEntity(mutation.entity.id),\n\n updateEntity: (doc, mutation) => {\n const cur = doc.entities.get(mutation.entityId);\n if (!cur) return NULL_MUTATION;\n const before: Record<string, unknown> = {};\n for (const key of Object.keys(mutation.props)) {\n before[key] = (cur as unknown as Record<string, unknown>)[key];\n }\n return updateEntity(mutation.entityId, before as Partial<typeof cur>);\n },\n\n deleteEntity: (doc, mutation) => {\n const cur = doc.entities.get(mutation.entityId);\n return cur ? addEntity(cloneEntity(cur)) : NULL_MUTATION;\n },\n\n // 覆盖已有 id 时,逆是把旧 fragment 加回来;否则逆是删掉它。\n addFragment: (doc, mutation) => {\n const cur = doc.fragments.get(mutation.fragment.id);\n return cur ? addFragment(cloneFragment(cur)) : deleteFragment(mutation.fragment.id);\n },\n\n deleteFragment: (doc, mutation) => {\n const cur = doc.fragments.get(mutation.fragmentId);\n return cur ? addFragment(cloneFragment(cur)) : NULL_MUTATION;\n },\n\n addVirtualBlock: (doc, mutation) => {\n const cur = doc.blockById(mutation.block.id);\n return cur ? addVirtualBlock(cur) : deleteVirtualBlock(mutation.block.id);\n },\n\n updateVirtualBlock: (doc, mutation) => {\n const cur = doc.blockById(mutation.blockId);\n return cur ? updateVirtualBlock(mutation.blockId, cur) : NULL_MUTATION;\n },\n\n deleteVirtualBlock: (doc, mutation) => {\n const cur = doc.blockById(mutation.blockId);\n return cur ? addVirtualBlock(cur) : NULL_MUTATION;\n },\n\n // 在片段自己的模型上求逆,再包回同一个片段\n scoped: (doc, mutation) =>\n scoped(\n mutation.fragmentId,\n invertMutation(doc.ensureFragmentModel(mutation.fragmentId), mutation.inner)\n )\n};\n\n/**\n * 算出 mutation 的逆。必须在 mutation 被应用**之前**调用。\n * 组合操作请改用 {@link applyAndInvert}。\n */\nexport function invertMutation(doc: DocumentModel, mutation: Mutation): Mutation {\n return (inverters[mutation.type] as InverterFor<MutationType>)(doc, mutation);\n}\n\n/**\n * 应用 mutation,同时返回它的逆。\n * 组合操作会逐条交错处理,逆按相反顺序排列。\n */\nexport function applyAndInvert(doc: DocumentModel, mutation: Mutation): Mutation {\n const forward = unwrap(mutation);\n const inverses: Mutation[] = [];\n for (const m of forward) {\n inverses.unshift(invertMutation(doc, m));\n applyMutation(doc, m);\n }\n return multi(inverses);\n}\n","/**\n * 闭区间与索引变换。\n *\n * 注意区间语义:这一层全部用**闭区间** `[min, max]`,`min > max` 即为空。\n * 文档模型对外的 `deleteRange(start, end)` 用的是半开区间 `[start, end)`,\n * 两者在 mutation 的边界上转换(见 mutations.ts 的 deleteSpacers)。\n * 不要把两种语义混着用,差一位的 bug 都出在这里。\n */\n\nexport interface Range {\n min: number;\n max: number;\n}\n\n/** 空区间用 null 表示。 */\nexport type MaybeRange = Range | null;\n\nexport function newRange(min: number, max: number): MaybeRange {\n return min <= max ? { min, max } : null;\n}\n\nexport function rangeContains(range: Range, value: number): boolean {\n return value >= range.min && value <= range.max;\n}\n\nexport function rangeEquals(a: MaybeRange, b: MaybeRange): boolean {\n if (!a || !b) return a === b;\n return a.min === b.min && a.max === b.max;\n}\n\n/** 区间长度(闭区间,含两端)。 */\nexport function rangeLength(range: Range): number {\n return range.max - range.min + 1;\n}\n\n/** 把「位于 shiftPosition 及其之后」的坐标平移 offset。 */\nexport function shiftIndex(index: number, shiftPosition: number, offset: number): number {\n return index >= shiftPosition ? index + offset : index;\n}\n\n/**\n * 同上,但落在 shiftPosition 上的坐标**不动**。\n * 选区的起点要用这个:在光标处插入字符,光标不该被推走。\n */\nexport function shiftIndexExclusive(index: number, shiftPosition: number, offset: number): number {\n return index === shiftPosition ? index : shiftIndex(index, shiftPosition, offset);\n}\n\nexport function shiftRange(range: MaybeRange, shiftPosition: number, offset: number): MaybeRange {\n if (!range) return null;\n return newRange(\n shiftIndex(range.min, shiftPosition, offset),\n shiftIndex(range.max, shiftPosition, offset)\n );\n}\n\nexport function shiftRangeExclusive(range: MaybeRange, shiftPosition: number, offset: number): MaybeRange {\n if (!range) return null;\n return newRange(\n shiftIndexExclusive(range.min, shiftPosition, offset),\n shiftIndex(range.max, shiftPosition, offset)\n );\n}\n\n/** position 之前被删掉的长度。 */\nexport function leadingLength(position: number, range: Range): number {\n const leadEnd = Math.min(position - 1, range.max);\n return Math.max(0, leadEnd - range.min + 1);\n}\n\nexport function transformCoordinateAgainstDeletedRange(position: number, deleted: Range): number {\n return position - leadingLength(position, deleted);\n}\n\n/**\n * 把一个区间放到「deleted 已被删除」的坐标系里。整段被删则返回空。\n *\n * 一般情况只需把坐标减去它前面被删掉的长度;但如果端点本身落在被删范围内,\n * 这种平移不足以把它收回来,还要再多缩一位。\n */\nexport function transformRangeAgainstDeletedRange(range: MaybeRange, deleted: Range): MaybeRange {\n if (!range) return null;\n const newStart = transformCoordinateAgainstDeletedRange(range.min, deleted);\n const endpointDeleted = rangeContains(deleted, range.max);\n const newEnd = transformCoordinateAgainstDeletedRange(range.max, deleted) - (endpointDeleted ? 1 : 0);\n return newRange(newStart, newEnd);\n}\n","/**\n * OT 变换。\n *\n * `transform(a, b, aWins)` 的含义:b 已经被应用了,把 a 改写成能在「b 之后」\n * 正确执行的形式。`aWins` 是并列时的优先级 —— 两个插入落在同一个下标时,\n * 赢的一方留在原地,输的一方被推到后面。两端必须对同一对操作给出相反的\n * `aWins`,否则会各自算出不同的结果,文档就分叉了。\n */\nimport {\n ApplyStyleMutation,\n DeleteSpacersMutation,\n InsertSpacersMutation,\n Mutation,\n MutationType,\n NULL_MUTATION,\n multi,\n scoped,\n unwrap\n} from './types';\nimport {\n MaybeRange,\n newRange,\n rangeEquals,\n shiftIndex,\n shiftRange,\n transformRangeAgainstDeletedRange\n} from './ranges';\nimport { shiftVirtualBlocksOnDelete, shiftVirtualBlocksOnInsert } from '../model/virtualBlock';\n\n// ---- insert 对各类操作 ----------------------------------------------------\n\nfunction insertAgainstInsert(\n cmd: InsertSpacersMutation,\n other: InsertSpacersMutation,\n aWins: boolean\n): Mutation {\n // 并列插入:赢家不动\n if (other.insertBeforeIndex === cmd.insertBeforeIndex && aWins) return cmd;\n return {\n ...cmd,\n insertBeforeIndex: shiftIndex(cmd.insertBeforeIndex, other.insertBeforeIndex, other.spacers.length)\n };\n}\n\nfunction insertAgainstDelete(cmd: InsertSpacersMutation, other: DeleteSpacersMutation): Mutation {\n // 插入点落在被删掉的那段里 —— 锚点没了,这次插入作废\n if (other.startIndex < cmd.insertBeforeIndex && other.endIndex >= cmd.insertBeforeIndex) {\n return NULL_MUTATION;\n }\n const length = other.endIndex - other.startIndex + 1;\n return {\n ...cmd,\n insertBeforeIndex: shiftIndex(cmd.insertBeforeIndex, other.startIndex + 1, -length)\n };\n}\n\n// ---- delete 对各类操作 ----------------------------------------------------\n\nfunction deleteAgainstInsert(cmd: DeleteSpacersMutation, other: InsertSpacersMutation): Mutation {\n const shifted = shiftRange(\n newRange(cmd.startIndex, cmd.endIndex),\n other.insertBeforeIndex,\n other.spacers.length\n );\n return copyWithRange(cmd, shifted);\n}\n\nfunction deleteAgainstDelete(cmd: DeleteSpacersMutation, other: DeleteSpacersMutation): Mutation {\n const removed = transformRangeAgainstDeletedRange(newRange(cmd.startIndex, cmd.endIndex), {\n min: other.startIndex,\n max: other.endIndex\n });\n return copyWithRange(cmd, removed);\n}\n\nfunction copyWithRange(cmd: DeleteSpacersMutation, range: MaybeRange): Mutation {\n if (!range) return NULL_MUTATION;\n if (rangeEquals(range, newRange(cmd.startIndex, cmd.endIndex))) return cmd;\n return { ...cmd, startIndex: range.min, endIndex: range.max };\n}\n\n// ---- applyStyle 对各类操作 ------------------------------------------------\n// 样式区间跟着内容走,规则与 delete 的区间变换一致。\n\nfunction styleAgainstInsert(cmd: ApplyStyleMutation, other: InsertSpacersMutation): Mutation {\n const shifted = shiftRange(\n newRange(cmd.startIndex, cmd.endIndex),\n other.insertBeforeIndex,\n other.spacers.length\n );\n return copyStyleWithRange(cmd, shifted);\n}\n\nfunction styleAgainstDelete(cmd: ApplyStyleMutation, other: DeleteSpacersMutation): Mutation {\n const removed = transformRangeAgainstDeletedRange(newRange(cmd.startIndex, cmd.endIndex), {\n min: other.startIndex,\n max: other.endIndex\n });\n return copyStyleWithRange(cmd, removed);\n}\n\nfunction copyStyleWithRange(cmd: ApplyStyleMutation, range: MaybeRange): Mutation {\n if (!range) return NULL_MUTATION;\n if (rangeEquals(range, newRange(cmd.startIndex, cmd.endIndex))) return cmd;\n return { ...cmd, startIndex: range.min, endIndex: range.max };\n}\n\n// ---- 分发 ----------------------------------------------------------------\n\nexport type TransformerFor<T extends MutationType> = (\n cmd: Extract<Mutation, { type: T }>,\n other: Mutation,\n aWins: boolean\n) => Mutation;\n\n/** 每种 mutation 一个 transformer。少一种编译不过。 */\nexport type Transformers = { [T in MutationType]: TransformerFor<T> };\n\nexport const transformers: Transformers = {\n null: (cmd) => cmd,\n\n multi: (cmd, other, aWins) => multi(unwrap(cmd).map((c) => transform(c, other, aWins))),\n\n insertSpacers: (cmd, other, aWins) => {\n if (other.type === 'insertSpacers') return insertAgainstInsert(cmd, other, aWins);\n if (other.type === 'deleteSpacers') return insertAgainstDelete(cmd, other);\n return cmd;\n },\n\n deleteSpacers: (cmd, other) => {\n if (other.type === 'insertSpacers') return deleteAgainstInsert(cmd, other);\n if (other.type === 'deleteSpacers') return deleteAgainstDelete(cmd, other);\n return cmd;\n },\n\n applyStyle: (cmd, other) => {\n if (other.type === 'insertSpacers') return styleAgainstInsert(cmd, other);\n if (other.type === 'deleteSpacers') return styleAgainstDelete(cmd, other);\n return cmd;\n },\n\n // 实体操作按 id 寻址,不受下标变化影响\n addEntity: (cmd) => cmd,\n updateEntity: (cmd) => cmd,\n deleteEntity: (cmd) => cmd,\n\n // fragment 同样按 id 寻址,不占主文档坐标空间,原样放行\n addFragment: (cmd) => cmd,\n deleteFragment: (cmd) => cmd,\n\n addVirtualBlock: (cmd, other, aWins) => {\n if (other.type === 'insertSpacers') {\n const [shifted] = shiftVirtualBlocksOnInsert(\n [cmd.block],\n other.insertBeforeIndex,\n other.spacers.length\n );\n return shifted ? { ...cmd, block: shifted } : NULL_MUTATION;\n }\n if (other.type === 'deleteSpacers') {\n const shifted = shiftVirtualBlocksOnDelete([cmd.block], other.startIndex, other.endIndex + 1);\n return shifted[0] ? { ...cmd, block: shifted[0] } : NULL_MUTATION;\n }\n if (other.type === 'addVirtualBlock' && other.block.id === cmd.block.id) {\n return aWins ? cmd : other;\n }\n if (other.type === 'deleteVirtualBlock' && other.blockId === cmd.block.id) {\n return cmd;\n }\n if (other.type === 'updateVirtualBlock' && other.blockId === cmd.block.id) {\n return aWins ? cmd : { type: 'addVirtualBlock', block: other.block };\n }\n return cmd;\n },\n\n updateVirtualBlock: (cmd, other, aWins) => {\n if (other.type === 'insertSpacers') {\n const [shifted] = shiftVirtualBlocksOnInsert(\n [cmd.block],\n other.insertBeforeIndex,\n other.spacers.length\n );\n return shifted ? { ...cmd, block: shifted } : NULL_MUTATION;\n }\n if (other.type === 'deleteSpacers') {\n const shifted = shiftVirtualBlocksOnDelete([cmd.block], other.startIndex, other.endIndex + 1);\n return shifted[0] ? { ...cmd, blockId: cmd.blockId, block: shifted[0] } : NULL_MUTATION;\n }\n if (other.type === 'deleteVirtualBlock' && other.blockId === cmd.blockId) {\n return NULL_MUTATION;\n }\n if (other.type === 'updateVirtualBlock' && other.blockId === cmd.blockId) {\n return aWins ? cmd : other;\n }\n if (other.type === 'addVirtualBlock' && other.block.id === cmd.blockId) {\n return aWins ? cmd : { ...cmd, block: other.block };\n }\n return cmd;\n },\n\n deleteVirtualBlock: (cmd, other) => {\n if (other.type === 'deleteVirtualBlock' && other.blockId === cmd.blockId) return NULL_MUTATION;\n return cmd;\n },\n\n // 每个片段是独立的坐标空间。同一片段就往里递归,不同片段(或主文档的操作)\n // 天然不冲突,原样放行 —— 这是 scoped 这个设计最省事的地方。\n scoped: (cmd, other, aWins) => {\n if (other.type !== 'scoped' || other.fragmentId !== cmd.fragmentId) return cmd;\n return scoped(cmd.fragmentId, transform(cmd.inner, other.inner, aWins));\n }\n};\n\n/** 把 cmd 变换到「other 已应用」之后的坐标系里。 */\nexport function transform(cmd: Mutation, other: Mutation, aWins: boolean): Mutation {\n if (cmd.type === 'null' || other.type === 'null') return cmd;\n\n // other 是组合:把 cmd 逐条穿过去。这一步取决于 other 的类型,\n // 所以留在入口,不能塞进按 cmd.type 分派的表里。\n if (other.type === 'multi') {\n let out: Mutation = cmd;\n for (const o of unwrap(other)) out = transform(out, o, aWins);\n return out;\n }\n\n return (transformers[cmd.type] as TransformerFor<MutationType>)(cmd, other, aWins);\n}\n\n/**\n * 把一串操作变换到另一串之后。\n *\n * 关键在内层那次反向变换:a 列表里的第 i 条被 b[j] 变换的同时,b[j] 自己也要\n * 被变换后的 a[i] 推一把,否则 a 的第 i+1 条再对上 b[j] 时,b[j] 还停在旧坐标系里,\n * 结果就错了。\n */\nexport function transformCommands(a: Mutation[], b: Mutation[], aWins: boolean): Mutation[] {\n const others = [...b];\n const out: Mutation[] = [];\n for (let i = 0; i < a.length; i++) {\n let cur = a[i];\n for (let j = 0; j < others.length; j++) {\n const before = cur;\n cur = transform(before, others[j], aWins);\n others[j] = transform(others[j], before, !aWins);\n }\n out.push(cur);\n }\n return out;\n}\n\n/** 双向变换:同时得到 a'(在 b 之后执行)和 b'(在 a 之后执行)。 */\nexport function transformBoth(\n a: Mutation[],\n b: Mutation[],\n aWins = true\n): { a: Mutation[]; b: Mutation[] } {\n const others = [...b];\n const out: Mutation[] = [];\n for (let i = 0; i < a.length; i++) {\n let cur = a[i];\n for (let j = 0; j < others.length; j++) {\n const before = cur;\n cur = transform(before, others[j], aWins);\n others[j] = transform(others[j], before, !aWins);\n }\n out.push(cur);\n }\n return { a: out, b: others };\n}\n","/**\n * 选区 rebase:别人的操作落地后,把本地光标/选区挪到正确的新位置。\n *\n * 插入点正好等于光标位置时,光标推不推走由 `shiftedByInserts` 决定:\n * 本地刚敲下的字要跟着走(光标落在新字之后),而协作者在你光标处插入时\n * 你的光标应该原地不动。默认按后者。\n */\nimport { Selection } from '../model/types';\nimport { Mutation, unwrap } from './types';\nimport { shiftIndex, shiftIndexExclusive, transformCoordinateAgainstDeletedRange } from './ranges';\n\nexport function transformIndex(\n index: number,\n mutations: Mutation[],\n shiftedByInserts = false\n): number {\n let cur = index;\n for (const m of mutations) {\n if (m.type === 'insertSpacers') {\n cur = shiftedByInserts\n ? shiftIndex(cur, m.insertBeforeIndex, m.spacers.length)\n : shiftIndexExclusive(cur, m.insertBeforeIndex, m.spacers.length);\n } else if (m.type === 'deleteSpacers') {\n cur = transformCoordinateAgainstDeletedRange(cur, { min: m.startIndex, max: m.endIndex });\n } else if (m.type === 'multi') {\n cur = transformIndex(cur, unwrap(m), shiftedByInserts);\n }\n }\n return cur;\n}\n\nexport function transformSelection(\n sel: Selection,\n mutations: Mutation[],\n shiftedByInserts = false\n): Selection {\n const flat = mutations.flatMap((m) => unwrap(m));\n return {\n anchor: transformIndex(sel.anchor, flat, shiftedByInserts),\n focus: transformIndex(sel.focus, flat, shiftedByInserts)\n };\n}\n","/**\n * EditResult —— 一次用户操作的完整记录。\n *\n * 同时存**正向**和**逆向**两串 mutation:逆向是在应用正向的当时算出来的,\n * 因为很多逆操作(比如删除的逆)必须读到删之前的文档才能算。等到要撤销时\n * 再算就晚了。\n */\nimport { Selection } from '../model/types';\nimport { Mutation, reverse, unwrap } from '../mutations';\n\n/**\n * 编辑种类。新增一种编辑必须先在这里登记 —— 因为撤销的合并规则是按 kind 查的,\n * 漏登记会让新编辑落到默认的「不合并」上,症状很隐蔽。\n */\nexport type EditKind =\n | 'insert.text'\n | 'insert.paragraph'\n | 'insert.paste'\n | 'delete.backward'\n | 'delete.forward'\n | 'delete.selection'\n | 'style.text'\n | 'style.paragraph'\n | 'style.link'\n | 'embed.insert'\n | 'embed.update'\n | 'embed.resize'\n | 'embed.delete'\n | 'table.insert'\n | 'table.structure'\n | 'table.colWidth'\n | 'table.clearCells'\n | 'ref.promote'\n | 'ref.insert'\n | 'ref.unlink'\n | 'vblock.insert'\n | 'vblock.update'\n | 'vblock.remove';\n\n/**\n * 允许与相邻同类编辑合并成一步撤销的种类。\n *\n * 只有「连着做同一件事」才该合并:连续打字撤销时应该整段消失,而不是一个字\n * 一个字地退。别的都不合并 —— 尤其不能只看时间窗口,那会把「打几个字」和紧随\n * 其后的「点加粗」并成一步,撤销时文字和加粗一起没了。\n */\nconst MERGEABLE_KINDS = new Set<EditKind>([\n 'insert.text',\n 'delete.backward',\n 'delete.forward'\n]);\n\n/** 某个种类的默认合并键。同键才合并,null 表示永不合并。 */\nexport function mergeKeyFor(kind: EditKind, scope: string | null): string | null {\n if (!MERGEABLE_KINDS.has(kind)) return null;\n // 带上 scope:主文档里打字和片段里打字不是同一串输入\n return scope ? `${kind}@${scope}` : kind;\n}\n\nexport interface EditMeta {\n kind: EditKind;\n /** 相同且非 null 才允许与相邻一步合并成同一步撤销;null 表示永不合并。 */\n mergeKey: string | null;\n /** 本地产生的还是远端同步过来的。只有本地的才能被撤销。 */\n local: boolean;\n /** 是否占一步撤销。某些操作(如纯元数据变更)不占。 */\n undoable: boolean;\n /**\n * 这次编辑发生在哪个片段的坐标空间里,null 表示主文档。\n * 选区字段属于这个空间,撤销时要照它决定把选区还给谁。\n */\n scope: string | null;\n}\n\nexport interface EditResult {\n /** 正向操作 */\n mutations: Mutation[];\n /** 逆向操作,已按相反顺序排好,可直接依次执行 */\n inverse: Mutation[];\n selectionBefore: Selection;\n selectionAfter: Selection;\n meta: EditMeta;\n}\n\nexport function editMeta(init: Partial<EditMeta> & { kind: EditKind }): EditMeta {\n const scope = init.scope ?? null;\n return {\n kind: init.kind,\n mergeKey: init.mergeKey !== undefined ? init.mergeKey : mergeKeyFor(init.kind, scope),\n local: init.local ?? true,\n undoable: init.undoable ?? true,\n scope\n };\n}\n\nexport function editResult(init: {\n mutations: Mutation | Mutation[];\n inverse: Mutation | Mutation[];\n selectionBefore: Selection;\n selectionAfter: Selection;\n meta: Partial<EditMeta> & { kind: EditKind };\n}): EditResult {\n const flatten = (m: Mutation | Mutation[]) =>\n Array.isArray(m) ? m.flatMap(unwrap) : unwrap(m);\n return {\n mutations: flatten(init.mutations),\n inverse: flatten(init.inverse),\n selectionBefore: { ...init.selectionBefore },\n selectionAfter: { ...init.selectionAfter },\n meta: editMeta(init.meta)\n };\n}\n\nexport function isEmptyEdit(e: EditResult): boolean {\n return e.mutations.length === 0;\n}\n\n/**\n * 合并相邻两步(连续输入合成一步撤销)。\n *\n * 正向按时间顺序拼接;逆向要**倒过来**拼 —— 撤销一组操作得从最后一条开始退。\n * 选区取首尾:撤销后回到第一步之前的位置。\n */\nexport function mergeEdits(first: EditResult, second: EditResult): EditResult {\n return {\n mutations: [...first.mutations, ...second.mutations],\n inverse: [...second.inverse, ...first.inverse],\n selectionBefore: { ...first.selectionBefore },\n selectionAfter: { ...second.selectionAfter },\n meta: {\n ...first.meta,\n local: first.meta.local && second.meta.local,\n undoable: first.meta.undoable || second.meta.undoable\n }\n };\n}\n\n/** 交换正逆两串,得到「撤销这一步」本身作为一步操作。 */\nexport function invertEdit(e: EditResult): EditResult {\n return {\n mutations: e.inverse,\n inverse: reverse(e.mutations),\n selectionBefore: { ...e.selectionAfter },\n selectionAfter: { ...e.selectionBefore },\n meta: { ...e.meta }\n };\n}\n","/**\n * Operation 的执行上下文。\n *\n * Operation 通过 `emit` 改文档,通过 `doc` 读文档。`emit` 是**立即生效**的 ——\n * 发一条就写一条,所以同一个 Operation 里后续的读能看到前面的效果。复杂操作\n * 因此可以「读—写—再读」,比如先插入换行、再读出新的段落边界、再给新段落发样式。\n *\n * 逆操作在写入**之前**算出来(很多逆必须读到变更前的文档),正逆两串一起收集。\n */\nimport { DocumentModel } from '../model/document';\nimport { Selection } from '../model/types';\nimport { Mutation, applyMutation, invertMutation, scoped, unwrap } from '../mutations';\n\nexport interface OperationContext {\n /** 读文档。写只能走 emit */\n readonly doc: DocumentModel;\n /** 当前选区 */\n selection(): Selection;\n /** 移动选区。不产生 mutation */\n select(next: Selection): void;\n /** 发一条 mutation:先求逆、立即写入、正逆两串都收集 */\n emit(mutation: Mutation): void;\n}\n\n/** Operation 就是一个拿 context 的函数。组合就是传同一个 ctx 下去。 */\nexport type Operation<R = void> = (ctx: OperationContext) => R;\n\nexport interface OperationRun {\n /** 正向操作,按执行顺序 */\n forward: Mutation[];\n /** 逆向操作,已按相反顺序排好 */\n inverse: Mutation[];\n selectionBefore: Selection;\n selectionAfter: Selection;\n}\n\nclass Collector implements OperationContext {\n readonly forward: Mutation[] = [];\n readonly inverse: Mutation[] = [];\n private sel: Selection;\n\n constructor(readonly doc: DocumentModel, selection: Selection) {\n this.sel = { ...selection };\n }\n\n selection(): Selection {\n return { ...this.sel };\n }\n\n select(next: Selection) {\n this.sel = { ...next };\n }\n\n emit(mutation: Mutation) {\n // unwrap 把 multi 摊平、把 null 滤掉,所以下面只面对单条实操\n for (const one of unwrap(mutation)) {\n this.inverse.unshift(invertMutation(this.doc, one));\n applyMutation(this.doc, one);\n this.forward.push(one);\n }\n }\n}\n\n/**\n * 把上下文切到某个片段(同步块)的坐标空间。\n *\n * 片段有自己的一条字符流,下标从 0 起,和主文档不共享。切过去之后,所有\n * Operation 都能原样复用 —— 它们读到的是片段模型,发出的 mutation 自动包上\n * `scoped`,落进的还是外层那一份操作串。选区共用外层的格子,因为调用方一开始\n * 就是拿片段选区起的事务。\n */\nexport function scopeContext(outer: OperationContext, fragmentId: string): OperationContext {\n return {\n doc: outer.doc.ensureFragmentModel(fragmentId),\n selection: () => outer.selection(),\n select: (next) => outer.select(next),\n emit: (mutation) => outer.emit(scoped(fragmentId, mutation))\n };\n}\n\n/** 跑一个 Operation,拿到它产生的操作串与选区变化。 */\nexport function runOperation<R>(\n doc: DocumentModel,\n selection: Selection,\n op: Operation<R>\n): { run: OperationRun; result: R } {\n const ctx = new Collector(doc, selection);\n const result = op(ctx);\n return {\n run: {\n forward: ctx.forward,\n inverse: ctx.inverse,\n selectionBefore: { ...selection },\n selectionAfter: ctx.selection()\n },\n result\n };\n}\n","/**\n * 解析助手:Operation 层「读模型 → 判断」的那一半。\n *\n * mutation 携带的必须是完整解析过的值,不能是补丁。谁负责把「用户想加粗」\n * 变成「这段的完整文字属性是 {bold:true, size:16, color:'#111'}」?就是这里。\n * 这些函数只读文档,不写文档。\n */\nimport { parseBlocks } from '../model/blocks';\nimport { DocumentModel } from '../model/document';\nimport { isTableMarker, MARKERS } from '../model/markers';\nimport { DEFAULT_PARAGRAPH, ParagraphProps, StyleSpan, StyleType, TextProps } from '../model/types';\n\n/** 落在 index 处的完整文字属性。没有区间时是空对象,代表「未着色」。 */\nexport function resolveTextProps(doc: DocumentModel, index: number): TextProps {\n return doc.textPropsAt(index);\n}\n\n/** 落在 index 所属段落上的完整段落属性,缺省项补齐。 */\nexport function resolveParagraphProps(doc: DocumentModel, index: number): ParagraphProps {\n return doc.paragraphPropsAt(index);\n}\n\n/** 半开区间 [start, end) 内是否只有结构标记(段分隔、表格骨架、图片占位)。 */\nexport function rangeIsOnlyMarkers(doc: DocumentModel, start: number, end: number): boolean {\n for (let i = start; i < end; i++) {\n const ch = doc.spacers[i];\n if (ch === MARKERS.IMAGE) continue;\n if (ch !== MARKERS.PARAGRAPH && !isTableMarker(ch)) return false;\n }\n return true;\n}\n\n/** 一段文本里「真正是内容」的片段,用来给新插入的字上色时跳过结构标记。 */\nexport function contentRuns(text: string, base: number): [number, number][] {\n const runs: [number, number][] = [];\n let runStart = -1;\n for (let i = 0; i < text.length; i++) {\n const ch = text[i];\n const content = ch !== MARKERS.PARAGRAPH && !isTableMarker(ch);\n if (content && runStart < 0) runStart = base + i;\n if (!content && runStart >= 0) {\n runs.push([runStart, base + i]);\n runStart = -1;\n }\n }\n if (runStart >= 0) runs.push([runStart, base + text.length]);\n return runs;\n}\n\n/**\n * 把半开区间 [from, to) 按「已有 text 区间的边界」切成若干小段。\n * 每段要么整段落在某个已有区间里(带上它,属性要在它基础上合并),\n * 要么是空档(属性从零起)。这是文字上色能算出完整值的前提。\n */\nexport function textSegments(\n doc: DocumentModel,\n from: number,\n to: number\n): { start: number; end: number; existing: StyleSpan | null }[] {\n const points = new Set<number>([from, to]);\n for (const s of doc.styles) {\n if (s.type !== 'text' || s.end <= from || s.start >= to) continue;\n if (s.start > from && s.start < to) points.add(s.start);\n if (s.end > from && s.end < to) points.add(s.end);\n }\n const sorted = [...points].sort((a, b) => a - b);\n const out: { start: number; end: number; existing: StyleSpan | null }[] = [];\n for (let k = 0; k < sorted.length - 1; k++) {\n const start = sorted[k];\n const end = sorted[k + 1];\n if (start >= end) continue;\n const existing =\n doc.styles.find((s) => s.type === 'text' && s.start <= start && s.end >= end) ?? null;\n out.push({ start, end, existing });\n }\n return out;\n}\n\n/** 某一类样式里,完整覆盖 [start, end) 的那条区间。 */\nexport function spanCovering(\n doc: DocumentModel,\n type: StyleType,\n start: number,\n end: number\n): StyleSpan | null {\n return doc.styles.find((s) => s.type === type && s.start <= start && s.end >= end) ?? null;\n}\n\n/**\n * 按当前字符流算出「段落区间应该长什么样」。\n *\n * 段分隔符一插一删,段落的边界就变了。这里从块结构重新推导出该有的一组\n * paragraph 区间,属性尽量沿用原来落在同一位置的那条 —— 这就是回车后新段\n * 能继承缩进和列表状态的原因。\n */\nexport function expectedParagraphSpans(doc: DocumentModel): StyleSpan[] {\n const out: StyleSpan[] = [];\n const inherit = (start: number, end: number): StyleSpan => {\n const existing =\n doc.styles.find((s) => s.type === 'paragraph' && s.start === start && s.end === end) ??\n doc.styles.find(\n (s) => s.type === 'paragraph' && s.start < end && s.end > start && s.start >= start\n );\n return {\n start,\n end,\n type: 'paragraph',\n props: { ...DEFAULT_PARAGRAPH, ...(existing?.props as ParagraphProps | undefined) }\n };\n };\n for (const block of parseBlocks(doc.spacers)) {\n if (block.kind === 'paragraph') {\n out.push(inherit(block.start, block.end));\n } else {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const para of cell.paragraphs) {\n if (para.end > para.start) out.push(inherit(para.start, para.end));\n }\n }\n }\n }\n }\n return out.sort((a, b) => a.start - b.start || a.end - b.end);\n}\n","/**\n * Operation 层的低级发射助手。\n *\n * 这些不是 mutation,也不是完整的 Operation,而是介于两者之间的常用动作:\n * 「删一段字符流并顺手清掉附着的实体」「把段落区间重新对齐到块结构」之类。\n * 它们只通过 ctx.emit 改文档,所以每一步都进日志、都能被撤销和变换。\n */\nimport { Slice, StyleSpan, StyleType, TextProps } from '../model/types';\nimport {\n applyStyle,\n deleteEntity,\n deleteSpacers,\n insertSpacers,\n multi,\n Mutation\n} from '../mutations';\nimport { MARKERS } from '../model/markers';\nimport { OperationContext } from './context';\nimport { expectedParagraphSpans, rangeIsOnlyMarkers, textSegments } from './resolve';\n\nconst EMPTY_SLICE: Slice = { text: '', styles: [], entities: [] };\n\n/** 在 index 处插入原始 spacer 串。不做任何段落推导。 */\nexport function emitInsert(ctx: OperationContext, index: number, text: string): number {\n const i = ctx.doc.clamp(index);\n if (!text) return i;\n ctx.emit(insertSpacers(i, text));\n return i + text.length;\n}\n\n/**\n * 删掉半开区间 [start, end),返回被删内容。\n *\n * 落在区间里的实体会显式发一条 deleteEntity —— 让实体的消失也是一条 mutation,\n * 而不是删字符的隐式副作用,否则撤销和协同都对不上账。\n */\nexport function emitDelete(ctx: OperationContext, start: number, end: number): Slice {\n const from = ctx.doc.clamp(Math.min(start, end));\n const to = ctx.doc.clamp(Math.max(start, end));\n if (to <= from) return EMPTY_SLICE;\n const slice = ctx.doc.takeSlice(from, to);\n for (const e of slice.entities) ctx.emit(deleteEntity(e.id));\n ctx.emit(deleteSpacers(from, to - 1));\n return slice;\n}\n\n/** 给半开区间 [start, end) 覆盖一条样式区间。props 必须已解析完整。 */\nexport function emitStyle(\n ctx: OperationContext,\n type: StyleType,\n start: number,\n end: number,\n props: StyleSpan['props'] | null\n) {\n if (end <= start) return;\n ctx.emit(applyStyle(type, start, end - 1, props));\n}\n\n/**\n * 文字上色。把区间按已有区间边界切段,每段各自算出**合并后的完整属性**再发。\n * 纯结构标记的空档不上色,免得给段分隔符染上颜色。\n */\nexport function emitTextStyle(ctx: OperationContext, start: number, end: number, patch: TextProps) {\n const from = ctx.doc.clamp(Math.min(start, end));\n const to = ctx.doc.clamp(Math.max(start, end));\n if (from >= to) return;\n const out: Mutation[] = [];\n for (const seg of textSegments(ctx.doc, from, to)) {\n if (seg.existing) {\n out.push(applyStyle('text', seg.start, seg.end - 1, { ...(seg.existing.props as TextProps), ...patch }));\n } else if (!rangeIsOnlyMarkers(ctx.doc, seg.start, seg.end)) {\n out.push(applyStyle('text', seg.start, seg.end - 1, { ...patch }));\n }\n }\n ctx.emit(multi(out));\n}\n\n/**\n * 把 paragraph 区间重新对齐到当前块结构,只发实际有出入的那一段。\n *\n * 从前这是模型在删字符时偷偷做的,逆操作里没有记录,所以撤销要靠整篇比对样式。\n * 现在它是显式的 applyStyle,逆自然就跟着有了。\n */\nexport function normalizeParagraphs(ctx: OperationContext) {\n const doc = ctx.doc;\n // 全选删除会把最后一个段分隔符一并清掉,文档变成空串。之后再打字第一次回车\n // 只会补上这个收口符,视觉上仍是一行;必须在这里把空文档收成一段 `\\n`。\n if (!doc.spacers.endsWith(MARKERS.PARAGRAPH)) {\n emitInsert(ctx, doc.spacers.length, MARKERS.PARAGRAPH);\n }\n const needed = expectedParagraphSpans(doc);\n const current = doc.styles\n .filter((s) => s.type === 'paragraph')\n .sort((a, b) => a.start - b.start || a.end - b.end);\n\n const key = (s: StyleSpan) => `${s.start}:${s.end}:${JSON.stringify(s.props)}`;\n const needKeys = new Set(needed.map(key));\n const curKeys = new Set(current.map(key));\n const differing = [\n ...current.filter((s) => !needKeys.has(key(s))),\n ...needed.filter((s) => !curKeys.has(key(s)))\n ];\n if (differing.length === 0) return;\n\n // 清除范围要囊括每一条与之相交的目标区间,否则会把某段从中间切断。\n let from = Math.min(...differing.map((s) => s.start));\n let to = Math.max(...differing.map((s) => s.end));\n for (let guard = 0; guard < 8; guard++) {\n let grew = false;\n for (const s of needed) {\n if (s.start < to && s.end > from) {\n if (s.start < from) {\n from = s.start;\n grew = true;\n }\n if (s.end > to) {\n to = s.end;\n grew = true;\n }\n }\n }\n if (!grew) break;\n }\n\n const out: Mutation[] = [applyStyle('paragraph', from, to - 1, null)];\n for (const s of needed) {\n if (s.end <= from || s.start >= to) continue;\n out.push(applyStyle('paragraph', s.start, s.end - 1, s.props));\n }\n ctx.emit(multi(out));\n}\n\n/** 文档尾部必须有一个段分隔符收口,插表格之后要补。 */\nexport function ensureParagraphAfter(ctx: OperationContext, index: number) {\n if (index < ctx.doc.spacers.length) return;\n emitInsert(ctx, index, MARKERS.PARAGRAPH);\n}\n","/**\n * 样式类 Operation。\n *\n * 这一组最能说明 Operation 层存在的意义:用户表达的是补丁(「加粗」),\n * mutation 要求的是完整值(「这段的文字属性是 …」)。中间那步解析在这里做。\n */\nimport { paragraphsIntersecting } from '../model/blocks';\nimport { DEFAULT_TEXT, LINK_COLOR, ParagraphProps, TextProps } from '../model/types';\nimport { Operation } from './context';\nimport { emitStyle, emitTextStyle, normalizeParagraphs } from './primitives';\nimport { resolveParagraphProps } from './resolve';\n\n/** 给半开区间 [start, end) 打文字样式补丁。 */\nexport function applyTextStyle(start: number, end: number, patch: TextProps): Operation {\n return (ctx) => {\n emitTextStyle(ctx, start, end, patch);\n };\n}\n\n/**\n * 给区间套链接。\n *\n * 与之相交的旧链接要整条清掉(而不是只清重叠部分),否则会留下半截尾巴 ——\n * 所以清除范围先向外扩到覆盖所有相交的链接区间。\n */\nexport function applyLink(start: number, end: number, url: string): Operation {\n return (ctx) => {\n const from = ctx.doc.clamp(Math.min(start, end));\n const to = ctx.doc.clamp(Math.max(start, end));\n if (from >= to || !url) return;\n\n let clearFrom = from;\n let clearTo = to;\n for (const s of ctx.doc.styles) {\n if (s.type !== 'link' || s.start >= to || s.end <= from) continue;\n clearFrom = Math.min(clearFrom, s.start);\n clearTo = Math.max(clearTo, s.end);\n }\n emitStyle(ctx, 'link', clearFrom, clearTo, null);\n emitStyle(ctx, 'link', from, to, { url });\n emitTextStyle(ctx, from, to, { color: LINK_COLOR, underline: true });\n };\n}\n\n/** 摘掉落在 index 处的链接,顺带把链接色和下划线还原成默认。 */\nexport function removeLink(index: number): Operation {\n return (ctx) => {\n const span = ctx.doc.linkSpanAt(index);\n if (!span) return;\n const { start, end } = span;\n emitStyle(ctx, 'link', start, end, null);\n emitTextStyle(ctx, start, end, { color: DEFAULT_TEXT.color, underline: false });\n };\n}\n\n/**\n * 给区间覆盖到的每个段落打段落样式补丁。\n *\n * 段落属性是整段一个值,所以逐段读出现值、合并补丁、整段覆盖回去。\n */\nexport function applyParagraphStyle(start: number, end: number, patch: ParagraphProps): Operation {\n return (ctx) => {\n for (const para of paragraphsIntersecting(ctx.doc.spacers, start, end)) {\n const next = { ...resolveParagraphProps(ctx.doc, para.start), ...patch };\n emitStyle(ctx, 'paragraph', para.start, para.end, next);\n }\n normalizeParagraphs(ctx);\n };\n}\n","import { HeadingLevel, ListKind, TextProps } from '../model/types';\n\n/** 常用 Markdown 输入的即时识别规则。 */\nexport type MarkdownHit =\n | { kind: 'heading'; level: HeadingLevel; consume: number }\n | { kind: 'list'; list: ListKind; consume: number }\n | { kind: 'code-block'; consume: number; language: string }\n | { kind: 'formula'; matchStart: number; matchEnd: number; latex: string; displayMode: boolean }\n | {\n kind: 'text';\n style: TextProps;\n matchStart: number;\n matchEnd: number;\n inner: string;\n };\n\nconst RULES: Array<{ type: string; reg: RegExp }> = [\n { type: 'CODE_BLOCK', reg: /^```(\\w*)\\s$/ },\n { type: 'FORMULA_BLOCK', reg: /\\$\\$([^$]+)\\$\\$\\s$/ },\n { type: 'FORMULA', reg: /\\$([^$\\n]+)\\$\\s$/ },\n { type: 'BOLD', reg: /\\*{2}.+\\*{2}\\s$/ },\n { type: 'STRIKETHROUGH', reg: /[~~]{2}.+[~~]{2}\\s$/ },\n { type: 'UNDER_LINE', reg: /[~~].+[~~]\\s$/ },\n { type: 'HEADING3', reg: /^#{3}\\s$/ },\n { type: 'HEADING2', reg: /^#{2}\\s$/ },\n { type: 'HEADING1', reg: /^#\\s$/ },\n { type: 'NUMBERED_LIST', reg: /^\\d+\\.\\s$/ },\n { type: 'BULLETED_LIST', reg: /^(-|\\*|\\+)\\s$/ },\n { type: 'ITALIC', reg: /\\*.+\\*\\s$/ }\n];\n\nfunction lastMatch(text: string, reg: RegExp): RegExpMatchArray | null {\n const m = text.match(reg);\n return m && m[0] ? m : null;\n}\n\nexport function matchMarkdown(paraText: string): MarkdownHit | null {\n for (const rule of RULES) {\n const m = lastMatch(paraText, rule.reg);\n if (!m) continue;\n const full = m[0];\n const matchStart = paraText.lastIndexOf(full);\n const matchEnd = matchStart + full.length;\n\n if (rule.type === 'CODE_BLOCK') {\n return { kind: 'code-block', consume: full.length, language: (m[1] || 'plain').toLowerCase() };\n }\n if (rule.type === 'FORMULA_BLOCK') {\n return { kind: 'formula', matchStart, matchEnd, latex: m[1] ?? '', displayMode: true };\n }\n if (rule.type === 'FORMULA') {\n return { kind: 'formula', matchStart, matchEnd, latex: m[1] ?? '', displayMode: false };\n }\n if (rule.type === 'HEADING1') return { kind: 'heading', level: 1, consume: full.length };\n if (rule.type === 'HEADING2') return { kind: 'heading', level: 2, consume: full.length };\n if (rule.type === 'HEADING3') return { kind: 'heading', level: 3, consume: full.length };\n if (rule.type === 'NUMBERED_LIST') return { kind: 'list', list: 'ol', consume: full.length };\n if (rule.type === 'BULLETED_LIST') return { kind: 'list', list: 'ul', consume: full.length };\n\n if (rule.type === 'BOLD') {\n return { kind: 'text', style: { bold: true }, matchStart, matchEnd, inner: full.slice(2, full.length - 3) };\n }\n if (rule.type === 'ITALIC') {\n return { kind: 'text', style: { italic: true }, matchStart, matchEnd, inner: full.slice(1, full.length - 2) };\n }\n if (rule.type === 'UNDER_LINE') {\n return { kind: 'text', style: { underline: true }, matchStart, matchEnd, inner: full.slice(1, full.length - 2) };\n }\n if (rule.type === 'STRIKETHROUGH') {\n return {\n kind: 'text',\n style: { strikethrough: true },\n matchStart,\n matchEnd,\n inner: full.slice(2, full.length - 3)\n };\n }\n }\n return null;\n}\n\nexport function shouldTryMarkdown(inserted: string): boolean {\n if (!inserted) return false;\n const ch = inserted[inserted.length - 1];\n return ch === ' ' || ch === '-' || ch === '*' || ch === '`' || ch === '$';\n}\n","/**\n * 文档模型 —— 状态本身,不含任何编辑语义。\n *\n * 这一层只做两件事:\n * 1. **读**。给上层提供「index 处的文字属性是什么」「这段字符流长什么样」之类的查询。\n * 2. **落地 mutation**。四个 `apply*` 方法是 mutation applier 唯一的着陆点,\n * 它们是机械动作:挪坐标、写字段,不做判断、不推导、不补救。\n *\n * 「打字要继承左边的样式」「删掉段分隔符后段落边界要重算」这类判断一律不在这里,\n * 而在 Operation 层(src/operations/)。模型不偷偷改自己,是撤销和协同能对上账的前提。\n *\n * fragment(同步块)的增删也走 mutation:addFragment / deleteFragment 落到\n * applyAddFragment / applyDeleteFragment 上,和 entity 一样按 id 寻址、不占坐标空间。\n */\nimport { findParagraphAt, findTableAt, parseBlocks } from './blocks';\nimport { isTableMarker, MARKERS } from './markers';\nimport { cloneFragment, normalizeFragmentSlice, previewTitle } from './fragment';\nimport {\n cloneEntity,\n cloneStyle,\n cloneVirtualBlock,\n DEFAULT_PARAGRAPH,\n Fragment,\n ImageEntity,\n ImageProps,\n ParagraphProps,\n Selection,\n Slice,\n StyleSpan,\n StyleType,\n TableProps,\n TextProps,\n textPropsEqual,\n VirtualBlock\n} from './types';\nimport {\n clipVirtualBlocks,\n shiftVirtualBlocksOnDelete,\n shiftVirtualBlocksOnInsert,\n sortOuterToInner\n} from './virtualBlock';\n\nlet entitySeq = 1;\nlet fragmentSeq = 1;\nlet virtualBlockSeq = 1;\n\nexport function nextEntityId(): string {\n return `emb_${entitySeq++}`;\n}\n\nexport function nextFragmentId(): string {\n return `frag_${fragmentSeq++}`;\n}\n\nexport function nextVirtualBlockId(): string {\n return `vb_${virtualBlockSeq++}`;\n}\n\nexport type DocSnapshot = {\n spacers: string;\n styles: StyleSpan[];\n entities: ImageEntity[];\n fragments: Fragment[];\n virtualBlocks: VirtualBlock[];\n};\n\nexport class DocumentModel {\n spacers = '\\n';\n styles: StyleSpan[] = [{ start: 0, end: 1, type: 'paragraph', props: { ...DEFAULT_PARAGRAPH } }];\n entities = new Map<string, ImageEntity>();\n fragments = new Map<string, Fragment>();\n virtualBlocks = new Map<string, VirtualBlock>();\n private fragmentModels = new Map<string, DocumentModel>();\n\n constructor(initial?: {\n spacers: string;\n styles: StyleSpan[];\n entities?: ImageEntity[];\n fragments?: Fragment[];\n virtualBlocks?: VirtualBlock[];\n }) {\n if (initial) {\n this.spacers = initial.spacers;\n this.styles = initial.styles.map(cloneStyle);\n this.entities = new Map((initial.entities ?? []).map((e) => [e.id, cloneEntity(e)]));\n this.fragments = new Map((initial.fragments ?? []).map((f) => [f.id, cloneFragment(f)]));\n this.virtualBlocks = new Map((initial.virtualBlocks ?? []).map((b) => [b.id, cloneVirtualBlock(b)]));\n }\n }\n\n /** 未写 text span 时的默认字号/颜色。嵌入式输入框可覆盖文档编辑器的 16px 默认。 */\n textDefaults: TextProps | null = null;\n\n get length(): number {\n return this.spacers.length;\n }\n\n clamp(index: number): number {\n return Math.max(0, Math.min(index, this.spacers.length));\n }\n\n // ---- mutation 落地点 ----------------------------------------------------\n // 只给 mutation applier 用。别的地方要改文档,请发 mutation。\n\n /** insertSpacers 的落地:插入字符,已有样式区间跟着挪。 */\n applyInsertSpacers(index: number, text: string) {\n if (!text) return;\n const i = this.clamp(index);\n this.spacers = this.spacers.slice(0, i) + text + this.spacers.slice(i);\n this.styles = shiftStylesOnInsert(this.styles, i, text.length);\n this.replaceVirtualBlocks(shiftVirtualBlocksOnInsert(this.virtualBlocks.values(), i, text.length));\n }\n\n /** deleteSpacers 的落地(半开区间):删字符,样式区间跟着裁剪与前挪。 */\n applyDeleteSpacers(start: number, end: number) {\n const from = this.clamp(Math.min(start, end));\n const to = this.clamp(Math.max(start, end));\n if (to <= from) return;\n this.spacers = this.spacers.slice(0, from) + this.spacers.slice(to);\n this.styles = shiftStylesOnDelete(this.styles, from, to);\n this.replaceVirtualBlocks(shiftVirtualBlocksOnDelete(this.virtualBlocks.values(), from, to));\n }\n\n /** addVirtualBlock 的落地:同 id 则整体替换。 */\n applyAddVirtualBlock(block: VirtualBlock) {\n this.virtualBlocks.set(block.id, cloneVirtualBlock(block));\n }\n\n applyDeleteVirtualBlock(blockId: string) {\n this.virtualBlocks.delete(blockId);\n }\n\n applyUpdateVirtualBlock(blockId: string, block: VirtualBlock) {\n if (!this.virtualBlocks.has(blockId)) return;\n this.virtualBlocks.set(blockId, cloneVirtualBlock({ ...block, id: blockId }));\n }\n\n /**\n * applyStyle 的落地(半开区间):把某类样式在这段里整体换成给定的一组区间。\n * 语义是**覆盖**不是合并补丁,所以传进来的 props 必须已经解析完整。\n */\n /** addFragment 的落地:把整份 fragment 写入。已打开过的派生模型作废重建。 */\n applyAddFragment(fragment: Fragment) {\n this.fragments.set(fragment.id, cloneFragment(fragment));\n this.fragmentModels.delete(fragment.id);\n }\n\n /** deleteFragment 的落地:移除 fragment 及其派生模型。 */\n applyDeleteFragment(fragmentId: string) {\n this.fragments.delete(fragmentId);\n this.fragmentModels.delete(fragmentId);\n }\n\n applyStyleSpans(type: StyleType, start: number, end: number, next: StyleSpan[]) {\n // 横跨区间边界的区间要在边界处裁开保留两头,不能整条抹掉。\n const kept: StyleSpan[] = [];\n for (const s of this.styles) {\n if (s.type !== type || s.end <= start || s.start >= end) {\n kept.push(s);\n continue;\n }\n if (s.start < start) kept.push(cloneStyle({ ...s, start: s.start, end: start }));\n if (s.end > end) kept.push(cloneStyle({ ...s, start: end, end: s.end }));\n }\n this.styles = kept.concat(next.map(cloneStyle));\n this.mergeStyles();\n }\n\n // ---- 快照 --------------------------------------------------------------\n\n snapshot(): DocSnapshot {\n for (const id of this.fragmentModels.keys()) this.syncFragment(id);\n return {\n spacers: this.spacers,\n styles: this.styles.map(cloneStyle),\n entities: [...this.entities.values()].map(cloneEntity),\n fragments: [...this.fragments.values()].map(cloneFragment),\n virtualBlocks: this.listVirtualBlocks()\n };\n }\n\n restore(snap: DocSnapshot) {\n this.spacers = snap.spacers;\n this.styles = snap.styles.map(cloneStyle);\n this.entities = new Map(snap.entities.map((e) => [e.id, cloneEntity(e)]));\n this.fragments = new Map((snap.fragments ?? []).map((f) => [f.id, cloneFragment(f)]));\n this.virtualBlocks = new Map((snap.virtualBlocks ?? []).map((b) => [b.id, cloneVirtualBlock(b)]));\n this.fragmentModels.clear();\n }\n\n // ---- 读 ----------------------------------------------------------------\n\n /** 取半开区间 [start, end) 的内容副本,含落在里面的实体与它们引用的同步块。 */\n takeSlice(start: number, end: number): Slice {\n const from = this.clamp(Math.min(start, end));\n const to = this.clamp(Math.max(start, end));\n const text = this.spacers.slice(from, to);\n const styles = this.styles\n .filter((s) => s.end > from && s.start < to)\n .map((s) => ({\n ...cloneStyle(s),\n start: Math.max(0, s.start - from),\n end: Math.min(s.end, to) - from\n }))\n .filter((s) => s.end > s.start);\n const entities: ImageEntity[] = [];\n const fragmentIds = new Set<string>();\n for (const s of this.styles) {\n if (s.type === 'image' && s.start >= from && s.end <= to) {\n const id = (s.props as { entityId: string }).entityId;\n const e = this.entities.get(id);\n if (e) {\n entities.push(cloneEntity(e));\n if (e.kind === 'ref' && e.fragmentId) fragmentIds.add(e.fragmentId);\n }\n }\n }\n const fragments = [...fragmentIds]\n .map((id) => this.fragments.get(id))\n .filter((f): f is Fragment => !!f)\n .map(cloneFragment);\n const virtualBlocks = clipVirtualBlocks(this.virtualBlocks.values(), from, to);\n return { text, styles, entities, fragments, virtualBlocks };\n }\n\n /**\n * 读出某类样式在半开区间 [start, end) 内的分布,边缘按区间裁剪。\n * 求 applyStyle 的逆操作时用来记录「原来长什么样」。\n */\n styleSpansOver(type: StyleType, start: number, end: number): StyleSpan[] {\n return this.styles\n .filter((s) => s.type === type && s.start < end && s.end > start)\n .map((s) => cloneStyle({ ...s, start: Math.max(s.start, start), end: Math.min(s.end, end) }))\n .filter((s) => s.end > s.start)\n .sort((a, b) => a.start - b.start);\n }\n\n imageAt(index: number): ImageEntity | null {\n const span = this.imageSpanAt(index);\n if (!span) return null;\n return this.entities.get((span.props as { entityId: string }).entityId) ?? null;\n }\n\n imageSpanAt(index: number): StyleSpan | null {\n return this.styles.find((s) => s.type === 'image' && s.start <= index && index < s.end) ?? null;\n }\n\n textPropsAt(index: number): TextProps {\n const i = this.clamp(index);\n const probe = i > 0 ? i - 1 : i;\n const span = this.styles.find((s) => s.type === 'text' && s.start <= probe && probe < s.end);\n return span ? { ...(span.props as TextProps) } : {};\n }\n\n paragraphPropsAt(index: number): ParagraphProps {\n const para = findParagraphAt(this.spacers, index);\n if (!para) return { ...DEFAULT_PARAGRAPH };\n const span =\n this.styles.find((s) => s.type === 'paragraph' && s.start === para.start && s.end === para.end) ??\n this.styles.find((s) => s.type === 'paragraph' && s.start < para.end && s.end > para.start);\n return { ...DEFAULT_PARAGRAPH, ...(span?.props as ParagraphProps | undefined) };\n }\n\n linkSpanAt(index: number): StyleSpan | null {\n const i = this.clamp(index);\n const probe = i > 0 ? i - 1 : i;\n return this.styles.find((s) => s.type === 'link' && s.start <= probe && probe < s.end) ?? null;\n }\n\n linkUrlAt(index: number): string | null {\n const span = this.linkSpanAt(index);\n return span ? (span.props as { url: string }).url : null;\n }\n\n tablePropsAt(index: number): TableProps {\n const table = findTableAt(this.spacers, index);\n if (!table) return {};\n const span = this.styles.find((s) => s.type === 'table' && s.start <= table.start && s.end >= table.end);\n return { ...(span?.props as TableProps | undefined) };\n }\n\n /** 半开区间 [start, end) 的可读文本,结构标记被剔除,图片算一个空格。 */\n plainText(start: number, end: number): string {\n const from = this.clamp(Math.min(start, end));\n const to = this.clamp(Math.max(start, end));\n let out = '';\n for (let i = from; i < to; i++) {\n const ch = this.spacers[i];\n if (ch === MARKERS.IMAGE) out += ' ';\n else if (!isTableMarker(ch)) out += ch;\n }\n return out;\n }\n\n // ---- 同步块 ------------------------------------------------------------\n\n /**\n * 构造一份新的 fragment(分配 id、规范化 slice),但**不写模型**。\n * 落地由 addFragment mutation 完成,这样提取同步块能进撤销栈、走协同。\n */\n buildFragment(slice: Slice, title?: string): Fragment {\n const normalized = normalizeFragmentSlice(slice);\n return { id: nextFragmentId(), title: title || previewTitle(normalized), slice: normalized };\n }\n\n ensureFragmentModel(id: string): DocumentModel {\n let model = this.fragmentModels.get(id);\n if (model) return model;\n const fragment = this.fragments.get(id);\n model = documentFromSlice(fragment?.slice ?? { text: MARKERS.PARAGRAPH, styles: [], entities: [] });\n this.fragmentModels.set(id, model);\n return model;\n }\n\n syncFragment(id: string) {\n const model = this.fragmentModels.get(id);\n const fragment = this.fragments.get(id);\n if (!model || !fragment) return;\n fragment.slice = sliceFromDocument(model);\n fragment.title = previewTitle(fragment.slice);\n }\n\n listFragments(): Fragment[] {\n for (const id of this.fragmentModels.keys()) this.syncFragment(id);\n return [...this.fragments.values()].map(cloneFragment);\n }\n\n refIndices(fragmentId: string): number[] {\n const hits: number[] = [];\n for (let i = 0; i < this.spacers.length; i++) {\n if (this.spacers[i] !== MARKERS.IMAGE) continue;\n if (this.imageAt(i)?.fragmentId === fragmentId) hits.push(i);\n }\n return hits;\n }\n\n refCount(fragmentId: string): number {\n return this.refIndices(fragmentId).length;\n }\n\n rangeHasRef(start: number, end: number): boolean {\n const from = this.clamp(Math.min(start, end));\n const to = this.clamp(Math.max(start, end));\n for (let i = from; i < to; i++) {\n if (this.spacers[i] === MARKERS.IMAGE && this.imageAt(i)?.kind === 'ref') return true;\n }\n return false;\n }\n\n // ---- 虚拟块 ------------------------------------------------------------\n\n listVirtualBlocks(): VirtualBlock[] {\n return sortOuterToInner([...this.virtualBlocks.values()], this.virtualBlocks);\n }\n\n blockById(id: string): VirtualBlock | null {\n const block = this.virtualBlocks.get(id);\n return block ? cloneVirtualBlock(block) : null;\n }\n\n /** 覆盖下标 i 的虚拟块,外层在前。 */\n blocksAt(index: number): VirtualBlock[] {\n const i = this.clamp(index);\n const hits = [...this.virtualBlocks.values()].filter((b) => b.start <= i && i < b.end);\n return sortOuterToInner(hits, this.virtualBlocks).map(cloneVirtualBlock);\n }\n\n virtualBlocksOverlapping(start: number, end: number): VirtualBlock[] {\n const from = this.clamp(Math.min(start, end));\n const to = this.clamp(Math.max(start, end));\n return [...this.virtualBlocks.values()]\n .filter((b) => b.start < to && b.end > from)\n .map(cloneVirtualBlock);\n }\n\n innermostSlotAt(index: number): VirtualBlock | null {\n const hits = this.blocksAt(index);\n for (let i = hits.length - 1; i >= 0; i--) {\n if (hits[i].kind === 'virtualSlot') return hits[i];\n }\n return null;\n }\n\n /** 含槽尾光标:`start <= i <= end` 的最内层 slot。 */\n slotAtCaret(index: number): VirtualBlock | null {\n const i = this.clamp(index);\n const inside = this.innermostSlotAt(i);\n if (inside) return inside;\n const ending = [...this.virtualBlocks.values()].filter((b) => b.kind === 'virtualSlot' && b.end === i);\n if (!ending.length) return null;\n const sorted = sortOuterToInner(ending, this.virtualBlocks);\n return cloneVirtualBlock(sorted[sorted.length - 1]);\n }\n\n private replaceVirtualBlocks(next: VirtualBlock[]) {\n this.virtualBlocks = new Map(next.map((b) => [b.id, cloneVirtualBlock(b)]));\n }\n\n // ---- 构造期整理 ---------------------------------------------------------\n\n /**\n * 把 paragraph 区间对齐到块结构。\n *\n * 只在**构造**文档时用(从切片建模型、从磁盘读文档)。编辑过程中的对齐是\n * Operation 层的 normalizeParagraphs,走 mutation,因为它必须能被撤销。\n */\n normalize() {\n const needed: StyleSpan[] = [];\n const ensure = (start: number, end: number): StyleSpan => {\n const existing =\n this.styles.find((s) => s.type === 'paragraph' && s.start === start && s.end === end) ??\n this.styles.find((s) => s.type === 'paragraph' && s.start < end && s.end > start && s.start >= start);\n return {\n start,\n end,\n type: 'paragraph',\n props: { ...DEFAULT_PARAGRAPH, ...(existing?.props as ParagraphProps | undefined) }\n };\n };\n for (const block of parseBlocks(this.spacers)) {\n if (block.kind === 'paragraph') {\n needed.push(ensure(block.start, block.end));\n } else {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const para of cell.paragraphs) {\n if (para.end > para.start) needed.push(ensure(para.start, para.end));\n }\n }\n }\n }\n }\n this.styles = this.styles.filter((s) => s.type !== 'paragraph').concat(needed);\n this.mergeStyles();\n }\n\n /** 排序 + 合并相邻且属性相同的文字区间。纯粹的规范化,不改变可见结果。 */\n private mergeStyles() {\n this.styles.sort((a, b) => a.start - b.start || a.end - b.end || a.type.localeCompare(b.type));\n const merged: StyleSpan[] = [];\n for (const s of this.styles) {\n if (s.end <= s.start) continue;\n const last = merged[merged.length - 1];\n // 段落/表格/图片区间不能跨块合并,否则回车后精确匹配失败会掉回正文。\n if (\n last &&\n last.type === 'text' &&\n s.type === 'text' &&\n last.end === s.start &&\n textPropsEqual(last.props as TextProps, s.props as TextProps)\n ) {\n last.end = s.end;\n } else {\n merged.push(s);\n }\n }\n this.styles = merged;\n }\n}\n\nexport function shiftStylesOnInsert(styles: StyleSpan[], index: number, len: number): StyleSpan[] {\n return styles.map((s) => {\n if (s.end <= index) return s;\n if (s.start >= index) return { ...s, start: s.start + len, end: s.end + len };\n return { ...s, end: s.end + len };\n });\n}\n\nexport function shiftStylesOnDelete(styles: StyleSpan[], start: number, end: number): StyleSpan[] {\n const len = end - start;\n const out: StyleSpan[] = [];\n for (const s of styles) {\n if (s.end <= start) {\n out.push(s);\n } else if (s.start >= end) {\n out.push({ ...s, start: s.start - len, end: s.end - len });\n } else if (s.start < start && s.end > end) {\n out.push({ ...s, start: s.start, end: s.end - len });\n } else if (s.start < start) {\n if (start > s.start) out.push({ ...s, start: s.start, end: start });\n } else if (s.end > end) {\n out.push({ ...s, start, end: s.end - len });\n }\n }\n return out.filter((s) => s.end > s.start);\n}\n\nexport function collapsedSel(index: number): Selection {\n return { anchor: index, focus: index };\n}\n\nexport function documentFromSlice(slice: Slice): DocumentModel {\n const normalized = normalizeFragmentSlice(slice);\n const doc = new DocumentModel();\n doc.spacers = normalized.text || MARKERS.PARAGRAPH;\n doc.styles = normalized.styles.map(cloneStyle);\n doc.entities = new Map(normalized.entities.map((e) => [e.id, cloneEntity(e)]));\n doc.virtualBlocks = new Map((normalized.virtualBlocks ?? []).map((b) => [b.id, cloneVirtualBlock(b)]));\n if (!doc.styles.some((s) => s.type === 'paragraph')) {\n doc.styles.push({ start: 0, end: doc.spacers.length, type: 'paragraph', props: { ...DEFAULT_PARAGRAPH } });\n }\n doc.normalize();\n return doc;\n}\n\nexport function sliceFromDocument(doc: DocumentModel): Slice {\n return {\n text: doc.spacers,\n styles: doc.styles.map(cloneStyle),\n entities: [...doc.entities.values()].map(cloneEntity),\n virtualBlocks: doc.listVirtualBlocks()\n };\n}\n\n/** 去掉指定 groupId 的段落,留下其余内容。 */\nexport function sliceWithoutParagraphGroup(doc: DocumentModel, groupId: string): Slice {\n const id = groupId.trim();\n const keep: { start: number; end: number }[] = [];\n for (const block of parseBlocks(doc.spacers)) {\n if (block.kind === 'table') {\n keep.push({ start: block.start, end: block.end });\n continue;\n }\n if ((doc.paragraphPropsAt(block.start).groupId ?? '') !== id) {\n keep.push({ start: block.start, end: block.end });\n }\n }\n if (!keep.length) {\n return { text: MARKERS.PARAGRAPH, styles: [], entities: [] };\n }\n let text = '';\n const styles: StyleSpan[] = [];\n const entities: ImageEntity[] = [];\n for (const range of keep) {\n const offset = text.length;\n text += doc.spacers.slice(range.start, range.end);\n for (const span of doc.styles) {\n if (span.end <= range.start || span.start >= range.end) continue;\n const start = Math.max(span.start, range.start) - range.start + offset;\n const end = Math.min(span.end, range.end) - range.start + offset;\n if (end <= start) continue;\n if (span.type === 'image') {\n const entityId = (span.props as ImageProps).entityId;\n const entity = entityId ? doc.entities.get(entityId) : undefined;\n if (!entity) continue;\n const next = cloneEntity({ ...entity, id: nextEntityId() });\n entities.push(next);\n styles.push({ start, end, type: 'image', props: { entityId: next.id } });\n continue;\n }\n styles.push({ start, end, type: span.type, props: { ...span.props } });\n }\n }\n if (!text.endsWith(MARKERS.PARAGRAPH)) text += MARKERS.PARAGRAPH;\n return { text, styles, entities };\n}\n","/**\n * 实体类 Operation:图片、公式、代码块、槽位、同步块引用。\n *\n * 实体本身存在 id → 实体的表里,字符流上只留一个 IMAGE 占位符,\n * 由一条 image 样式区间把占位符和实体 id 绑起来。插一个实体因此是三条 mutation。\n */\nimport { cloneEntity, ImageEntity } from '../model/types';\nimport { MARKERS } from '../model/markers';\nimport { addEntity, updateEntity } from '../mutations';\nimport { nextEntityId } from '../model/document';\nimport { Operation } from './context';\nimport { emitInsert, emitStyle } from './primitives';\n\nexport type NewEntity = Omit<ImageEntity, 'id' | 'kind'> & { id?: string; kind?: ImageEntity['kind'] };\n\n/** 在 index 处插入一个实体,返回占位符之后的位置。 */\nexport function insertImage(index: number, entity: NewEntity): Operation<number> {\n return (ctx) => {\n const i = ctx.doc.clamp(index);\n const full = cloneEntity({\n ...entity,\n id: entity.id ?? nextEntityId(),\n kind: entity.kind ?? 'image'\n } as ImageEntity);\n ctx.emit(addEntity(full));\n emitInsert(ctx, i, MARKERS.IMAGE);\n emitStyle(ctx, 'image', i, i + 1, { entityId: full.id });\n return i + 1;\n };\n}\n\nexport type ImagePatch = Partial<\n Pick<\n ImageEntity,\n | 'width'\n | 'height'\n | 'code'\n | 'language'\n | 'latex'\n | 'src'\n | 'displayMode'\n | 'slotKind'\n | 'label'\n | 'slotValue'\n | 'slotOptions'\n | 'data'\n | 'hostType'\n >\n>;\n\n/** 改实体属性。undefined 的字段代表「不动」,在这里就剔掉,别让它盖掉原值。 */\nexport function updateImage(id: string, patch: ImagePatch): Operation {\n return (ctx) => {\n if (!ctx.doc.entities.has(id)) return;\n const props: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(patch)) {\n if (v !== undefined) props[k] = v;\n }\n if (!Object.keys(props).length) return;\n ctx.emit(updateEntity(id, props as ImagePatch));\n };\n}\n","/**\n * 虚拟块 Operation:套皮、拆皮、清槽、填槽、插入后盖住新字。\n *\n * 嵌套合法性在这里判断,通过才发 mutation。插删字符对区间的机械挪动在\n * applier 里,但清槽会把覆盖整段删掉(块被表里摘掉),所以这里要按快照补回。\n */\nimport { chromeTextProps, hasTextProps, TextProps, VirtualBlock, VirtualBlockChrome, VirtualBlockKind } from '../model/types';\nimport { ancestorChain, rangeContains, rangesCross, sortOuterToInner } from '../model/virtualBlock';\nimport { nextVirtualBlockId } from '../model/document';\nimport { addVirtualBlock, deleteVirtualBlock, updateVirtualBlock } from '../mutations';\nimport { Operation } from './context';\nimport { emitDelete, emitInsert, emitTextStyle } from './primitives';\nimport { resolveTextProps } from './resolve';\n\nexport interface VirtualBlockSpec {\n id?: string;\n parentId?: string | null;\n kind: VirtualBlockKind;\n start: number;\n end: number;\n chrome?: VirtualBlockChrome;\n placeholder?: string;\n empty?: boolean;\n}\n\nfunction blockMap(doc: { virtualBlocks: Map<string, VirtualBlock> }) {\n return doc.virtualBlocks;\n}\n\nexport function validateInsert(doc: { virtualBlocks: Map<string, VirtualBlock> }, block: VirtualBlock): string | null {\n if (block.end <= block.start) return 'empty-range';\n // mark 是纯样式叠层:不进区间树,也不受嵌套/交叉约束。\n if (block.kind === 'mark') return null;\n if (block.parentId) {\n const parent = doc.virtualBlocks.get(block.parentId);\n if (!parent) return 'missing-parent';\n if (!rangeContains(parent, block)) return 'outside-parent';\n if (parent.kind === 'virtualSlot') return 'virtualSlot-parent';\n }\n for (const other of doc.virtualBlocks.values()) {\n if (other.id === block.id || other.kind === 'mark') continue;\n if (rangesCross(block, other)) return 'cross';\n }\n if (block.kind === 'virtualSlot') {\n for (const other of doc.virtualBlocks.values()) {\n if (other.id === block.id || other.kind === 'mark') continue;\n if (other.parentId === block.id) return 'slot-child';\n if (rangeContains(block, other) && other.id !== block.parentId) return 'slot-child';\n }\n }\n return null;\n}\n\nfunction inferParentId(\n doc: { virtualBlocks: Map<string, VirtualBlock> },\n start: number,\n end: number,\n selfId?: string\n): string | null {\n const range = { start, end };\n let best: VirtualBlock | null = null;\n for (const b of doc.virtualBlocks.values()) {\n if (selfId && b.id === selfId) continue;\n if (b.kind === 'mark') continue;\n if (!rangeContains(b, range)) continue;\n if (!best || b.end - b.start < best.end - best.start) best = b;\n }\n return best?.id ?? null;\n}\n\n/**\n * 把 [start, end) 包成一层皮。不改字。\n * 完全落在新区间里的已有块会改挂到这一层下面。\n */\nexport function insertVirtualBlock(spec: VirtualBlockSpec): Operation<string | null> {\n return (ctx) => {\n const doc = ctx.doc;\n const start = doc.clamp(Math.min(spec.start, spec.end));\n const end = doc.clamp(Math.max(spec.start, spec.end));\n if (end <= start) return null;\n\n const id = spec.id && !doc.virtualBlocks.has(spec.id) ? spec.id : nextVirtualBlockId();\n const parentId =\n spec.kind === 'mark' ? null : spec.parentId !== undefined ? spec.parentId : inferParentId(doc, start, end, id);\n const placeholder =\n spec.kind === 'virtualSlot' ? spec.placeholder ?? doc.spacers.slice(start, end) : spec.placeholder;\n const empty =\n spec.kind === 'virtualSlot' ? spec.empty ?? (placeholder != null && doc.spacers.slice(start, end) === placeholder) : spec.empty;\n const block: VirtualBlock = {\n id,\n parentId,\n kind: spec.kind,\n start,\n end,\n chrome: { ...(spec.chrome ?? {}) },\n placeholder,\n empty\n };\n const err = validateInsert(doc, block);\n if (err) return null;\n\n ctx.emit(addVirtualBlock(block));\n for (const child of [...doc.virtualBlocks.values()]) {\n if (child.id === id || child.kind === 'mark' || block.kind === 'mark') continue;\n if (child.parentId === parentId && rangeContains(block, child) && child.id !== id) {\n ctx.emit(updateVirtualBlock(child.id, { ...child, parentId: id }));\n }\n }\n return id;\n };\n}\n\n/** 拆掉皮,字和胶囊留下。子块改挂到被拆掉那一层的父上。 */\nexport function removeVirtualBlock(id: string): Operation<boolean> {\n return (ctx) => {\n const block = ctx.doc.blockById(id);\n if (!block) return false;\n for (const child of ctx.doc.listVirtualBlocks()) {\n if (child.parentId === id) {\n ctx.emit(updateVirtualBlock(child.id, { ...child, parentId: block.parentId }));\n }\n }\n ctx.emit(deleteVirtualBlock(id));\n return true;\n };\n}\n\nexport function updateVirtualBlockChrome(id: string, chrome: VirtualBlockChrome): Operation<boolean> {\n return (ctx) => {\n const block = ctx.doc.blockById(id);\n if (!block) return false;\n ctx.emit(updateVirtualBlock(id, { ...block, chrome: { ...block.chrome, ...chrome } }));\n return true;\n };\n}\n\nfunction restoreChain(\n ctx: { doc: { blockById(id: string): VirtualBlock | null }; emit(m: import('../mutations').Mutation): void },\n snaps: VirtualBlock[],\n targetId: string,\n nextStart: number,\n nextEnd: number,\n empty: boolean\n) {\n for (const snap of snaps) {\n const isTarget = snap.id === targetId;\n const cur = ctx.doc.blockById(snap.id);\n let next: VirtualBlock;\n if (isTarget) {\n next = { ...snap, start: nextStart, end: nextEnd, empty };\n } else if (cur) {\n next = {\n ...cur,\n start: Math.min(cur.start, nextStart),\n end: Math.max(cur.end, nextEnd)\n };\n } else {\n next = { ...snap, start: nextStart, end: nextEnd };\n }\n if (cur) ctx.emit(updateVirtualBlock(snap.id, next));\n else ctx.emit(addVirtualBlock(next));\n }\n}\n\n/** 把槽内容换成 placeholder,empty=true。槽和父块都留下。 */\nexport function clearSlot(id: string): Operation<boolean> {\n return (ctx) => {\n const block = ctx.doc.blockById(id);\n if (!block || block.kind !== 'virtualSlot') return false;\n const placeholder = block.placeholder ?? '';\n if (!placeholder) return false;\n const from = block.start;\n const to = block.end;\n const snaps = ancestorChain(block, blockMap(ctx.doc));\n emitDelete(ctx, from, to);\n emitInsert(ctx, from, placeholder);\n restoreChain(ctx, snaps, id, from, from + placeholder.length, true);\n return true;\n };\n}\n\n/** 槽是行内区间:去掉尾部换行,中间的段分隔折成空格。 */\nexport function slotInlineText(text: string): string {\n return text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n').replace(/\\n+$/, '').replace(/\\n+/g, ' ');\n}\n\n/**\n * empty 时覆盖 placeholder;已填则整段替换。一次事务。\n * 返回新光标(槽尾)。槽内不进段分隔符。\n */\nexport function fillSlot(id: string, text: string, inherit?: TextProps): Operation<number | null> {\n return (ctx) => {\n const block = ctx.doc.blockById(id);\n if (!block || block.kind !== 'virtualSlot') return null;\n const safe = slotInlineText(text);\n const from = block.start;\n const to = block.end;\n const snaps = ancestorChain(block, blockMap(ctx.doc));\n const left = inherit ?? {\n ...resolveTextProps(ctx.doc, from),\n ...chromeTextProps(block.chrome)\n };\n emitDelete(ctx, from, to);\n if (safe) emitInsert(ctx, from, safe);\n const end = from + safe.length;\n const empty = safe.length === 0 || safe === (block.placeholder ?? '');\n restoreChain(ctx, snaps, id, from, end, empty && !!block.placeholder);\n if (safe && left && hasTextProps(left)) emitTextStyle(ctx, from, end, left);\n return end;\n };\n}\n\n/** 按 id 找到槽/块,连祖先一起撑开盖住 [start, end)。 */\nexport function coverAncestorsOf(id: string, start: number, end: number): Operation<void> {\n return (ctx) => {\n const block = ctx.doc.blockById(id);\n if (!block) return;\n const ids = [id];\n let pid = block.parentId;\n const seen = new Set(ids);\n while (pid && !seen.has(pid)) {\n seen.add(pid);\n ids.push(pid);\n pid = ctx.doc.blockById(pid)?.parentId ?? null;\n }\n coverVirtualBlocks(ids, start, end)(ctx);\n };\n}\n\n/** 插入后把指定块(及仍在的祖先)撑开盖住 [start, end)。 */\nexport function coverVirtualBlocks(ids: string[], start: number, end: number): Operation<void> {\n return (ctx) => {\n const unique = [...new Set(ids)];\n const blocks = unique\n .map((id) => ctx.doc.blockById(id))\n .filter((b): b is VirtualBlock => !!b);\n for (const b of sortOuterToInner(blocks, blockMap(ctx.doc))) {\n const next: VirtualBlock = {\n ...b,\n start: Math.min(b.start, start),\n end: Math.max(b.end, end),\n empty: b.kind === 'virtualSlot' ? false : b.empty\n };\n if (next.start !== b.start || next.end !== b.end || next.empty !== b.empty) {\n ctx.emit(updateVirtualBlock(b.id, next));\n }\n }\n };\n}\n\nexport function remapIncomingVirtualBlocks(\n blocks: VirtualBlock[],\n offset: number,\n occupied: Set<string>\n): VirtualBlock[] {\n if (!blocks.length) return [];\n const idMap = new Map<string, string>();\n for (const b of blocks) {\n let id = b.id;\n if (!id || occupied.has(id) || idMap.has(id)) {\n id = nextVirtualBlockId();\n }\n idMap.set(b.id, id);\n occupied.add(id);\n }\n const remapped = blocks.map((b) => ({\n ...b,\n id: idMap.get(b.id)!,\n parentId: b.parentId ? (idMap.get(b.parentId) ?? null) : null,\n start: b.start + offset,\n end: b.end + offset,\n chrome: { ...b.chrome }\n }));\n return sortOuterToInner(remapped, new Map(remapped.map((b) => [b.id, b])));\n}\n\n/**\n * 在 index 处插入了 text 之后,把「恰好在 index 结束」的 mark 向右撑开,\n * 让右边缘继续输入算区间内;遇到换行就断(只撑到第一个 \\n 之前)。\n * 插入本身已由调用方 emit,这里只补区间。\n */\nexport function extendMarksAtEnd(index: number, text: string): Operation<void> {\n return (ctx) => {\n if (!text || text.startsWith('\\n')) return;\n const nl = text.indexOf('\\n');\n const len = nl === -1 ? text.length : nl;\n for (const b of ctx.doc.listVirtualBlocks()) {\n if (b.kind !== 'mark' || b.end !== index) continue;\n ctx.emit(updateVirtualBlock(b.id, { ...b, end: b.end + len }));\n }\n };\n}\n","/**\n * 字符流类 Operation:打字、回车、退格、删除、Markdown 快捷输入。\n *\n * 这一组的共性是「插删字符会改变段落边界」,所以每个操作在动完字符流之后\n * 都要把段落区间重新对齐 —— 而且对齐动作本身也是 mutation,不是模型的暗箱。\n */\nimport { expandRangeOverStructures, findParagraphAt, findTableAt, isEmptyParagraph, parseBlocks } from '../model/blocks';\nimport { isTableMarker, MARKERS, nextCodePointLen, prevCodePointLen } from '../model/markers';\nimport { DEFAULT_PARAGRAPH, hasTextProps, ParagraphProps, Slice, TextProps } from '../model/types';\nimport { applyStyle, multi } from '../mutations';\nimport { matchMarkdown } from '../convert/markdown';\nimport { Operation, OperationContext } from './context';\nimport { emitDelete, emitInsert, emitTextStyle, normalizeParagraphs } from './primitives';\nimport { contentRuns, resolveParagraphProps, resolveTextProps } from './resolve';\nimport { applyParagraphStyle, applyTextStyle } from './style';\nimport { insertImage } from './entity';\nimport { coverAncestorsOf, extendMarksAtEnd, fillSlot } from './virtualBlock';\n\nconst EMPTY_SLICE: Slice = { text: '', styles: [], entities: [] };\n\nfunction isLastParagraphWithGroupId(\n doc: { spacers: string; paragraphPropsAt: (i: number) => ParagraphProps },\n paraStart: number,\n groupId: string\n): boolean {\n if (!groupId) return false;\n let last = -1;\n for (const block of parseBlocks(doc.spacers)) {\n if (block.kind !== 'paragraph') continue;\n if ((doc.paragraphPropsAt(block.start).groupId ?? '') === groupId) last = block.start;\n }\n return last === paraStart;\n}\n\n/**\n * 插入的文本里带换行时,被劈开的那个段落要变成两段,且两段都继承原属性。\n * 光靠 normalizeParagraphs 推不出来 —— 它只能让后半段回落到默认属性。\n */\nfunction splitParagraphSpans(ctx: OperationContext, index: number, text: string) {\n if (!text.includes('\\n')) return;\n let cursor = index;\n for (const ch of text) {\n if (ch === '\\n') {\n const para = findParagraphAt(ctx.doc.spacers, cursor);\n if (para && para.start < cursor + 1 && para.end > cursor + 1) {\n const props = resolveParagraphProps(ctx.doc, para.start);\n ctx.emit(\n multi([\n applyStyle('paragraph', para.start, para.end - 1, null),\n applyStyle('paragraph', para.start, cursor, { ...props }),\n applyStyle('paragraph', cursor + 1, para.end - 1, { ...props })\n ])\n );\n }\n }\n cursor += ch.length;\n }\n}\n\n/** 在 index 处插入文本,继承左侧文字样式(或调用方指定的样式)。返回新光标位置。 */\nexport function insertText(index: number, text: string, inherit?: TextProps): Operation<number> {\n return (ctx) => {\n if (!text) return ctx.doc.clamp(index);\n const safe = text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n const i = ctx.doc.clamp(index);\n const slot = ctx.doc.slotAtCaret(i);\n if (slot?.empty) {\n const end = fillSlot(slot.id, safe, inherit)(ctx);\n return end ?? i;\n }\n const left = inherit ?? resolveTextProps(ctx.doc, i);\n\n emitInsert(ctx, i, safe);\n extendMarksAtEnd(i, safe)(ctx);\n splitParagraphSpans(ctx, i, safe);\n if (left && hasTextProps(left)) {\n for (const [a, b] of contentRuns(safe, i)) emitTextStyle(ctx, a, b, left);\n }\n if (slot) coverAncestorsOf(slot.id, i, i + safe.length)(ctx);\n normalizeParagraphs(ctx);\n return i + safe.length;\n };\n}\n\n/** 回车。空列表项上先降缩进再退出列表;否则切段,两段各自继承合适的属性。 */\nexport function insertParagraph(index: number): Operation<number> {\n return (ctx) => {\n let i = ctx.doc.clamp(index);\n const slot = ctx.doc.slotAtCaret(i);\n // 槽不是多段容器:落在槽内时把回车挪到槽后,避免一个 slot 跨两段。\n if (slot && i > slot.start && i < slot.end) i = slot.end;\n const para = findParagraphAt(ctx.doc.spacers, i);\n const oldProps: ParagraphProps = para\n ? resolveParagraphProps(ctx.doc, para.start)\n : { ...DEFAULT_PARAGRAPH };\n const inList = (oldProps.list ?? 'none') !== 'none';\n\n if (para && inList && isEmptyParagraph(ctx.doc.spacers, para)) {\n const indent = oldProps.indent ?? 0;\n const patch: ParagraphProps = indent > 0 ? { indent: indent - 1 } : { list: 'none', indent: 0 };\n applyParagraphStyle(para.start, para.end, patch)(ctx);\n return i;\n }\n\n const paraEndContent =\n para && ctx.doc.spacers[para.end - 1] === MARKERS.PARAGRAPH ? para.end - 1 : para?.end ?? i;\n const atStart = !!para && i <= para.start;\n const atEnd = !!para && i >= paraEndContent;\n const groupId = String(oldProps.groupId ?? '');\n const exitGroup =\n !!para && !!groupId && atEnd && isLastParagraphWithGroupId(ctx.doc, para.start, groupId);\n\n emitInsert(ctx, i, MARKERS.PARAGRAPH);\n if (para) {\n const leftProps = { ...oldProps };\n const rightProps = { ...oldProps };\n const heading = oldProps.heading ?? 0;\n // 标题段在段尾回车时,新起的一段回落成正文;在段首回车则让上面那段是正文。\n if (heading && !inList && atEnd) rightProps.heading = 0;\n if (heading && !inList && atStart) leftProps.heading = 0;\n // 分组最后一段末尾回车:新段不再带 groupId。\n if (exitGroup) rightProps.groupId = '';\n ctx.emit(\n multi([\n applyStyle('paragraph', para.start, para.end, null),\n applyStyle('paragraph', para.start, i, leftProps),\n applyStyle('paragraph', i + 1, para.end, rightProps)\n ])\n );\n }\n normalizeParagraphs(ctx);\n return i + 1;\n };\n}\n\n/** 删掉一段区间,边界会向外扩到不切断表格等结构。 */\nexport function deleteRange(start: number, end: number): Operation<Slice> {\n return (ctx) => {\n const expanded = expandRangeOverStructures(\n ctx.doc.spacers,\n ctx.doc.clamp(start),\n ctx.doc.clamp(end)\n );\n if (expanded.start === expanded.end) return EMPTY_SLICE;\n const slice = emitDelete(ctx, expanded.start, expanded.end);\n normalizeParagraphs(ctx);\n return slice;\n };\n}\n\nexport type DeleteHit = { start: number; end: number; slice: Slice } | null;\n\n/** 退格。列表段首先去 bullet;删段分隔符时存活段继承上一段属性;表格骨架不动。 */\nexport function backspace(index: number): Operation<DeleteHit> {\n return (ctx) => {\n const doc = ctx.doc;\n const i = doc.clamp(index);\n const para = findParagraphAt(doc.spacers, i);\n const atStart = !!para && i === para.start;\n const props = para ? resolveParagraphProps(doc, para.start) : { ...DEFAULT_PARAGRAPH };\n\n if (atStart && (props.list ?? 'none') !== 'none') {\n applyParagraphStyle(para.start, para.end, { list: 'none', indent: 0 })(ctx);\n return { start: i, end: i, slice: EMPTY_SLICE };\n }\n if (i <= 0) return null;\n\n const prev = doc.spacers[i - 1];\n // 表格结构标记一律不删:TABLE_END 由编辑器侧改成选中整表。\n if (isTableMarker(prev)) return null;\n\n if (prev === MARKERS.PARAGRAPH) {\n const prevProps = resolveParagraphProps(doc, i - 1);\n const slice = emitDelete(ctx, i - 1, i);\n normalizeParagraphs(ctx);\n const merged = findParagraphAt(doc.spacers, i - 1);\n if (merged) applyParagraphStyle(merged.start, merged.end, prevProps)(ctx);\n return { start: i - 1, end: i, slice };\n }\n\n const len = prevCodePointLen(doc.spacers, i);\n const from = i - len;\n const span = doc.spacers[from] === MARKERS.IMAGE && doc.imageAt(from) ? 1 : len;\n const slice = emitDelete(ctx, from, from + span);\n normalizeParagraphs(ctx);\n return { start: from, end: from + span, slice };\n };\n}\n\n/** Delete 键。整表要整体删掉,其余按一个码点删。 */\nexport function deleteForward(index: number): Operation<DeleteHit> {\n return (ctx) => {\n const doc = ctx.doc;\n const i = doc.clamp(index);\n if (i >= doc.spacers.length) return null;\n const ch = doc.spacers[i];\n if (ch === MARKERS.TABLE_START) {\n const table = findTableAt(doc.spacers, i);\n if (table) {\n const slice = emitDelete(ctx, table.start, table.end);\n normalizeParagraphs(ctx);\n return { start: table.start, end: table.end, slice };\n }\n }\n if (isTableMarker(ch)) return null;\n const len = nextCodePointLen(doc.spacers, i);\n const slice = emitDelete(ctx, i, i + len);\n normalizeParagraphs(ctx);\n return { start: i, end: i + len, slice };\n };\n}\n\n/** 打完字后试着把 `# `、`- `、`**x**` 之类就地转成真正的样式或嵌入块。 */\nexport function applyMarkdownShortcut(caret: number): Operation<number> {\n return (ctx) => {\n const doc = ctx.doc;\n const i = doc.clamp(caret);\n const para = findParagraphAt(doc.spacers, i);\n if (!para) return i;\n const hit = matchMarkdown(doc.spacers.slice(para.start, i));\n if (!hit) return i;\n\n const restyleParagraph = (consume: number, patch: ParagraphProps) => {\n emitDelete(ctx, para.start, para.start + consume);\n normalizeParagraphs(ctx);\n const next = findParagraphAt(doc.spacers, para.start) ?? { start: para.start, end: para.start + 1 };\n applyParagraphStyle(next.start, next.end, patch)(ctx);\n return next.start;\n };\n\n if (hit.kind === 'heading') {\n return restyleParagraph(hit.consume, { heading: hit.level, list: 'none' });\n }\n if (hit.kind === 'list') {\n if (resolveParagraphProps(doc, para.start).list === hit.list) return i;\n return restyleParagraph(hit.consume, { list: hit.list, heading: 0 });\n }\n if (hit.kind === 'code-block') {\n emitDelete(ctx, para.start, para.start + hit.consume);\n normalizeParagraphs(ctx);\n return insertImage(para.start, {\n kind: 'code',\n width: 680,\n height: 80,\n language: hit.language || 'plain',\n code: ''\n })(ctx);\n }\n if (hit.kind === 'formula') {\n const from = para.start + hit.matchStart;\n emitDelete(ctx, from, para.start + hit.matchEnd);\n normalizeParagraphs(ctx);\n return insertImage(from, {\n kind: 'formula',\n width: 200,\n height: 48,\n latex: hit.latex,\n displayMode: hit.displayMode\n })(ctx);\n }\n\n const from = para.start + hit.matchStart;\n emitDelete(ctx, from, para.start + hit.matchEnd);\n normalizeParagraphs(ctx);\n emitInsert(ctx, from, `${hit.inner} `);\n if (hit.inner) applyTextStyle(from, from + hit.inner.length, hit.style)(ctx);\n normalizeParagraphs(ctx);\n return from + hit.inner.length + 1;\n };\n}","/**\n * 表格类 Operation。\n *\n * 表格在字符流里是一串结构标记,在样式里是一条覆盖整表的 table 区间(存列宽)。\n * 增删行列既要动字符流,也要同步列宽数组,两件事都得是显式 mutation。\n */\nimport { cellAt, emptyTableSpacers, findParagraphAt, findTableAt } from '../model/blocks';\nimport { MARKERS } from '../model/markers';\nimport { TableProps } from '../model/types';\nimport { Operation, OperationContext } from './context';\nimport { emitDelete, emitInsert, emitStyle, ensureParagraphAfter, normalizeParagraphs } from './primitives';\nimport { insertParagraph } from './text';\n\n/** 覆盖整表的那条 table 区间,找不到就返回 null。 */\nfunction tableSpan(ctx: OperationContext, start: number, end: number) {\n return ctx.doc.styles.find((s) => s.type === 'table' && s.start <= start && s.end >= end) ?? null;\n}\n\nfunction writeColWidths(ctx: OperationContext, tableStart: number, tableEnd: number, widths: number[]) {\n const span = tableSpan(ctx, tableStart, tableEnd);\n const props = { ...((span?.props as TableProps | undefined) ?? {}), colWidths: [...widths] };\n const from = span?.start ?? tableStart;\n const to = span?.end ?? tableEnd;\n emitStyle(ctx, 'table', from, to, props);\n}\n\n/** 插入空表。表格不能嵌在段落中间,所以必要时先把当前段切开。返回首格光标位置。 */\nexport function insertTable(index: number, rows = 2, cols = 2): Operation<number> {\n return (ctx) => {\n let i = ctx.doc.clamp(index);\n const para = findParagraphAt(ctx.doc.spacers, i);\n if (para && ctx.doc.spacers[para.end - 1] === '\\n' && i >= para.end - 1) {\n i = para.end;\n } else if (para && i > para.start && i < para.end) {\n i = insertParagraph(i)(ctx);\n }\n\n const table = emptyTableSpacers(rows, cols);\n emitInsert(ctx, i, table);\n emitStyle(ctx, 'table', i, i + table.length, {\n colWidths: Array.from({ length: cols }, () => 0)\n } satisfies TableProps);\n ensureParagraphAfter(ctx, i + table.length);\n normalizeParagraphs(ctx);\n return i + table.indexOf(MARKERS.TABLE_CELL) + 1;\n };\n}\n\n/** 在当前行下面插一行。 */\nexport function insertTableRow(index: number): Operation<boolean> {\n return (ctx) => {\n const hit = cellAt(ctx.doc.spacers, index);\n if (!hit) return false;\n const cols = Math.max(...hit.table.rows.map((r) => r.cells.length));\n let spacers = MARKERS.TABLE_ROW;\n for (let c = 0; c < cols; c++) spacers += MARKERS.TABLE_CELL + MARKERS.PARAGRAPH;\n emitInsert(ctx, hit.table.rows[hit.row].end, spacers);\n normalizeParagraphs(ctx);\n return true;\n };\n}\n\n/** 在当前列右边插一列。从下往上插,免得前面的插入把后面的坐标顶跑。 */\nexport function insertTableCol(index: number): Operation<boolean> {\n return (ctx) => {\n const hit = cellAt(ctx.doc.spacers, index);\n if (!hit) return false;\n const inserts: number[] = [];\n for (const row of [...hit.table.rows].reverse()) {\n inserts.push(row.cells[Math.min(hit.col, row.cells.length - 1)].end);\n }\n for (const at of inserts) emitInsert(ctx, at, MARKERS.TABLE_CELL + MARKERS.PARAGRAPH);\n\n const table = findTableAt(ctx.doc.spacers, index);\n if (table) {\n const span = tableSpan(ctx, table.start, table.end);\n const widths = [...(((span?.props as TableProps | undefined)?.colWidths) ?? [])];\n widths.splice(hit.col + 1, 0, 0);\n writeColWidths(ctx, table.start, table.end, widths);\n }\n normalizeParagraphs(ctx);\n return true;\n };\n}\n\n/** 删当前行。最后一行不给删。 */\nexport function deleteTableRow(index: number): Operation<boolean> {\n return (ctx) => {\n const hit = cellAt(ctx.doc.spacers, index);\n if (!hit || hit.table.rows.length <= 1) return false;\n const row = hit.table.rows[hit.row];\n emitDelete(ctx, row.start, row.end);\n normalizeParagraphs(ctx);\n return true;\n };\n}\n\n/** 删当前列。最后一列不给删。 */\nexport function deleteTableCol(index: number): Operation<boolean> {\n return (ctx) => {\n const hit = cellAt(ctx.doc.spacers, index);\n if (!hit) return false;\n if (Math.max(...hit.table.rows.map((r) => r.cells.length)) <= 1) return false;\n for (const row of [...hit.table.rows].reverse()) {\n const cell = row.cells[hit.col];\n if (cell) emitDelete(ctx, cell.start, cell.end);\n }\n const table = findTableAt(ctx.doc.spacers, hit.table.start);\n if (table) {\n const span = tableSpan(ctx, table.start, table.end);\n const widths = (span?.props as TableProps | undefined)?.colWidths;\n if (widths && widths.length > hit.col) {\n const next = [...widths];\n next.splice(hit.col, 1);\n writeColWidths(ctx, table.start, table.end, next);\n }\n }\n normalizeParagraphs(ctx);\n return true;\n };\n}\n\n/** 拖动列边界后落定列宽。 */\nexport function setTableColWidths(index: number, widths: number[]): Operation {\n return (ctx) => {\n const table = findTableAt(ctx.doc.spacers, index);\n if (!table) return;\n writeColWidths(ctx, table.start, table.end, widths);\n };\n}\n","import { MARKERS } from '../model/markers';\nimport { DEFAULT_PARAGRAPH, EmbedEntity, HeadingLevel, LINK_COLOR, ParagraphProps, Slice, StyleSpan, TextProps } from '../model/types';\n\n/**\n * 粘贴前的 Markdown 探测:先看标题/列表/链接,再看行内粗斜删除线。\n */\nexport function looksLikeMarkdown(text: string): boolean {\n const normalized = `\\n\\n${text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n')}\\n\\n`;\n return (\n /^(#{1,6})[ \\t]+.+/m.test(normalized) ||\n /(?:^|\\n) {0,3}([*+-]|\\d+\\.)[ \\t]+/.test(normalized) ||\n /\\[((?:\\[[^\\]]*]|[^\\[\\]])*)][ \\t]*\\([ \\t]?<?\\S+/.test(normalized) ||\n /\\*\\*[^*]+\\*\\*/.test(text) ||\n /(?<!\\*)\\*[^*\\n]+\\*(?!\\*)/.test(text) ||\n /~~.+~~/.test(text) ||\n /__[^_]+__/.test(text) ||\n /```/.test(text) ||\n /\\$\\$[\\s\\S]+\\$\\$/.test(text) ||\n /\\$[^$\\n]+\\$/.test(text)\n );\n}\n\ntype InlineTok = { text: string; style: TextProps; url?: string };\n\nfunction parseInline(input: string): InlineTok[] {\n const out: InlineTok[] = [];\n const re =\n /(\\*\\*\\*(.+?)\\*\\*\\*|\\*\\*(.+?)\\*\\*|\\*(.+?)\\*|~~(.+?)~~|__(.+?)__|\\[([^\\]]+)\\]\\(([^)]+)\\))/g;\n let last = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(input))) {\n if (m.index > last) out.push({ text: input.slice(last, m.index), style: {} });\n if (m[2] !== undefined) out.push({ text: m[2], style: { bold: true, italic: true } });\n else if (m[3] !== undefined) out.push({ text: m[3], style: { bold: true } });\n else if (m[4] !== undefined) out.push({ text: m[4], style: { italic: true } });\n else if (m[5] !== undefined) out.push({ text: m[5], style: { strikethrough: true } });\n else if (m[6] !== undefined) out.push({ text: m[6], style: { underline: true } });\n else if (m[7] !== undefined) {\n out.push({ text: m[7], style: { color: LINK_COLOR, underline: true }, url: m[8] });\n }\n last = m.index + m[0].length;\n }\n if (last < input.length) out.push({ text: input.slice(last), style: {} });\n return out.filter((t) => t.text.length > 0);\n}\n\nfunction blockProps(line: string): { rest: string; para: ParagraphProps } {\n const heading = line.match(/^(#{1,3})\\s+(.*)$/);\n if (heading) {\n return { rest: heading[2], para: { ...DEFAULT_PARAGRAPH, heading: heading[1].length as HeadingLevel } };\n }\n const ul = line.match(/^(\\s*)[-*+]\\s+(.*)$/);\n if (ul) {\n const indent = Math.min(8, Math.floor(ul[1].replace(/\\t/g, ' ').length / 2));\n return { rest: ul[2], para: { ...DEFAULT_PARAGRAPH, list: 'ul', indent } };\n }\n const ol = line.match(/^(\\s*)\\d+\\.\\s+(.*)$/);\n if (ol) {\n const indent = Math.min(8, Math.floor(ol[1].replace(/\\t/g, ' ').length / 2));\n return { rest: ol[2], para: { ...DEFAULT_PARAGRAPH, list: 'ol', indent } };\n }\n return { rest: line, para: { ...DEFAULT_PARAGRAPH } };\n}\n\n/** 支持的 Markdown 子集:标题/列表/粗斜下划删除线/链接/代码块/公式。 */\nexport function markdownToSlice(raw: string): Slice {\n const text = raw.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n const lines = text.split('\\n');\n let spacers = '';\n const styles: StyleSpan[] = [];\n const entities: EmbedEntity[] = [];\n\n const emitPara = (line: string) => {\n const { rest, para } = blockProps(line);\n const start = spacers.length;\n const tokens = parseInline(rest);\n for (const tok of tokens) {\n const a = spacers.length;\n spacers += tok.text;\n const b = spacers.length;\n if (Object.keys(tok.style).length) {\n styles.push({ start: a, end: b, type: 'text', props: { ...tok.style } });\n }\n if (tok.url) styles.push({ start: a, end: b, type: 'link', props: { url: tok.url } });\n }\n spacers += MARKERS.PARAGRAPH;\n styles.push({ start, end: spacers.length, type: 'paragraph', props: { ...para } });\n };\n\n const emitEmbed = (entity: EmbedEntity) => {\n const start = spacers.length;\n spacers += MARKERS.IMAGE;\n styles.push({ start, end: start + 1, type: 'image', props: { entityId: entity.id } });\n entities.push(entity);\n spacers += MARKERS.PARAGRAPH;\n styles.push({ start, end: spacers.length, type: 'paragraph', props: { ...DEFAULT_PARAGRAPH } });\n };\n\n let i = 0;\n if (lines.length === 0) emitPara('');\n while (i < lines.length) {\n const line = lines[i];\n const fence = line.match(/^```(\\w*)\\s*$/);\n if (fence) {\n const buf: string[] = [];\n i += 1;\n while (i < lines.length && !/^```\\s*$/.test(lines[i])) {\n buf.push(lines[i]);\n i += 1;\n }\n if (i < lines.length) i += 1;\n emitEmbed({\n id: `md_${entities.length}`,\n kind: 'code',\n width: 680,\n height: 80,\n language: fence[1] || 'plain',\n code: buf.join('\\n')\n });\n continue;\n }\n const oneLineMath = line.match(/^\\$\\$(.+)\\$\\$\\s*$/);\n if (oneLineMath) {\n emitEmbed({\n id: `md_${entities.length}`,\n kind: 'formula',\n width: 200,\n height: 48,\n latex: oneLineMath[1],\n displayMode: true\n });\n i += 1;\n continue;\n }\n if (line.trim() === '$$') {\n const buf: string[] = [];\n i += 1;\n while (i < lines.length && lines[i].trim() !== '$$') {\n buf.push(lines[i]);\n i += 1;\n }\n if (i < lines.length) i += 1;\n emitEmbed({\n id: `md_${entities.length}`,\n kind: 'formula',\n width: 200,\n height: 48,\n latex: buf.join('\\n'),\n displayMode: true\n });\n continue;\n }\n emitPara(line);\n i += 1;\n }\n\n return { text: spacers, styles, entities };\n}\n","/**\n * 切片类 Operation:粘贴、Markdown 整段导入、同步块的提取与展开。\n *\n * 切片自带实体,插入时 id 可能和文档里已有的撞车,所以先做一轮改名再落地。\n */\nimport { findParagraphAt } from '../model/blocks';\nimport { cloneFragment, cloneSlice, sliceHasContent } from '../model/fragment';\nimport { cloneEntity, Fragment, ImageEntity, Slice, StyleType, TextProps } from '../model/types';\nimport { MARKERS } from '../model/markers';\nimport {\n collapsedSel,\n DocumentModel,\n documentFromSlice,\n nextEntityId,\n sliceFromDocument\n} from '../model/document';\nimport { addEntity, addFragment } from '../mutations';\nimport { looksLikeMarkdown, markdownToSlice } from '../convert/mdPaste';\nimport { Operation, runOperation } from './context';\nimport { emitDelete, emitInsert, emitStyle, normalizeParagraphs } from './primitives';\nimport { insertImage } from './entity';\nimport { insertParagraph, insertText } from './text';\nimport { coverAncestorsOf, extendMarksAtEnd, fillSlot, insertVirtualBlock, remapIncomingVirtualBlocks, slotInlineText } from './virtualBlock';\nimport type { VirtualBlockSpec } from './virtualBlock';\n\n/**\n * 把切片里的同步块引用换成引用目标的实际内容。\n *\n * 跨文档粘贴不该带走一个指向源文档的悬空引用,所以复制粘贴前要先摊平。\n * 展开在一个临时文档上做,不碰真文档,因此不产生 mutation。\n */\nfunction materializeSlice(doc: DocumentModel, slice: Slice): Slice {\n if (!slice.entities.some((e) => e.kind === 'ref')) return cloneSlice(slice);\n const lookup = new Map(doc.fragments);\n for (const f of (slice.fragments ?? []) as Fragment[]) lookup.set(f.id, cloneFragment(f));\n\n const scratch = documentFromSlice(slice);\n // 从后往前换,免得前面的替换把后面引用的坐标顶跑。\n for (let i = scratch.spacers.length - 1; i >= 0; i--) {\n if (scratch.spacers[i] !== MARKERS.IMAGE) continue;\n const entity = scratch.imageAt(i);\n if (entity?.kind !== 'ref' || !entity.fragmentId) continue;\n const source = lookup.get(entity.fragmentId);\n runOperation(scratch, collapsedSel(i), (c) => {\n emitDelete(c, i, i + 1);\n normalizeParagraphs(c);\n if (source) insertSlice(i, cloneSlice(source.slice), false)(c);\n });\n }\n return sliceFromDocument(scratch);\n}\n\n/**\n * 把一个切片插到 index 处。\n *\n * asCopy 为真时先把切片里的同步块引用摊平成实际内容 —— 跨文档粘贴不该带走\n * 一个指向源文档的悬空引用。\n */\nexport function insertSlice(index: number, slice: Slice, asCopy = true): Operation<number> {\n return (ctx) => {\n const doc = ctx.doc;\n const incoming = asCopy ? materializeSlice(doc, slice) : cloneSlice(slice);\n const i = doc.clamp(index);\n const slot = doc.slotAtCaret(i);\n const nested =\n (incoming.virtualBlocks?.length ?? 0) > 0 || incoming.entities.length > 0;\n if (slot?.empty && !nested) {\n const text = slotInlineText(incoming.text);\n if (text) {\n const end = fillSlot(slot.id, text)(ctx);\n return end ?? i;\n }\n }\n\n const remap = new Map<string, string>();\n const entities = incoming.entities.map((e) => {\n if (!doc.entities.has(e.id)) return cloneEntity(e);\n const next = { ...cloneEntity(e), id: nextEntityId() };\n remap.set(e.id, next.id);\n return next;\n });\n\n emitInsert(ctx, i, incoming.text);\n extendMarksAtEnd(i, incoming.text)(ctx);\n for (const e of entities) ctx.emit(addEntity(e));\n for (const s of incoming.styles) {\n const props =\n s.type === 'image' && remap.size\n ? {\n ...(s.props as { entityId: string }),\n entityId:\n remap.get((s.props as { entityId: string }).entityId) ??\n (s.props as { entityId: string }).entityId\n }\n : { ...s.props };\n emitStyle(ctx, s.type as StyleType, s.start + i, s.end + i, props);\n }\n // 空槽插入模板:整段落在槽前(槽被机械推走),不要 cover 把树吞进槽里。\n if (slot && !slot.empty) {\n coverAncestorsOf(slot.id, i, i + incoming.text.length)(ctx);\n } else {\n const occupied = new Set(ctx.doc.virtualBlocks.keys());\n for (const block of remapIncomingVirtualBlocks(incoming.virtualBlocks ?? [], i, occupied)) {\n const spec: VirtualBlockSpec = {\n id: block.id,\n kind: block.kind,\n start: block.start,\n end: block.end,\n chrome: block.chrome,\n placeholder: block.placeholder,\n empty: block.empty\n };\n if (block.parentId) spec.parentId = block.parentId;\n insertVirtualBlock(spec)(ctx);\n }\n }\n normalizeParagraphs(ctx);\n return i + incoming.text.length;\n };\n}\n\n/** 把一段 Markdown 原文导入到 index 处。段落中间导入时先把段切开。 */\nexport function insertMarkdown(index: number, raw: string): Operation<number> {\n return (ctx) => {\n const doc = ctx.doc;\n const i = doc.clamp(index);\n const para = findParagraphAt(doc.spacers, i);\n const paraEnd =\n para && doc.spacers[para.end - 1] === MARKERS.PARAGRAPH ? para.end - 1 : para?.end ?? i;\n const at = para && i > para.start && i < paraEnd ? insertParagraph(i)(ctx) : i;\n\n const slice = markdownToSlice(raw);\n let text = slice.text;\n let styles = slice.styles;\n // 导入内容自带结尾段分隔符,而落点后面已经有一个了,去掉一个免得多出空行。\n if (text.endsWith(MARKERS.PARAGRAPH) && doc.spacers[at] === MARKERS.PARAGRAPH) {\n const cut = text.length - 1;\n text = text.slice(0, cut);\n styles = styles\n .map((s) => ({ ...s, start: Math.min(s.start, cut), end: Math.min(s.end, cut) }))\n .filter((s) => s.end > s.start);\n }\n insertSlice(at, { text, styles, entities: slice.entities })(ctx);\n return at + text.length;\n };\n}\n\n/** 粘贴纯文本。看起来像 Markdown 就走导入,否则当普通文字插入。 */\nexport function pasteText(index: number, raw: string, inherit?: TextProps): Operation<number> {\n return (ctx) =>\n looksLikeMarkdown(raw) ? insertMarkdown(index, raw)(ctx) : insertText(index, raw, inherit)(ctx);\n}\n\n/**\n * 把一段内容提取成同步块,原地换成一个引用。\n *\n * fragment 的新建走 addFragment mutation,和后续的删除、插入引用一起进操作串,\n * 因此整步可撤销、可协同。\n */\nexport function promoteRange(start: number, end: number): Operation<{ fragmentId: string; index: number } | null> {\n return (ctx) => {\n const doc = ctx.doc;\n const from = doc.clamp(Math.min(start, end));\n const to = doc.clamp(Math.max(start, end));\n if (from >= to || doc.rangeHasRef(from, to)) return null;\n const slice = doc.takeSlice(from, to);\n if (!sliceHasContent(slice)) return null;\n\n const fragment = doc.buildFragment(slice);\n ctx.emit(addFragment(fragment));\n emitDelete(ctx, from, to);\n normalizeParagraphs(ctx);\n const index = insertRef(from, fragment.id)(ctx);\n return { fragmentId: fragment.id, index };\n };\n}\n\n/** 在 index 处插一个指向同步块的引用,返回引用占位符自身的位置。 */\nexport function insertRef(index: number, fragmentId: string): Operation<number> {\n return (ctx) => {\n if (!ctx.doc.fragments.has(fragmentId)) return ctx.doc.clamp(index);\n const entity: Omit<ImageEntity, 'id'> = {\n kind: 'ref',\n fragmentId,\n width: 680,\n height: 80\n };\n return insertImage(index, entity)(ctx) - 1;\n };\n}\n\n/** 把引用就地展开成实际内容,引用本身消失。返回展开后的末尾位置。 */\nexport function unlinkRef(index: number): Operation<number | null> {\n return (ctx) => {\n const doc = ctx.doc;\n const i = doc.clamp(index);\n const entity = doc.imageAt(i);\n if (entity?.kind !== 'ref' || !entity.fragmentId) return null;\n const fragment = doc.fragments.get(entity.fragmentId);\n if (!fragment) return null;\n emitDelete(ctx, i, i + 1);\n normalizeParagraphs(ctx);\n return insertSlice(i, cloneSlice(fragment.slice), true)(ctx);\n };\n}\n","/**\n * 编辑事务 —— 一次用户操作的边界。\n *\n * 事务干的事:起一个 Operation 上下文、把里面产生的操作串收起来、包成一条\n * `EditResult` 交给撤销栈。它不碰 UI,也不决定要做什么编辑,所以宿主和自检\n * 能走同一条路径。\n *\n * 选区在事务期间归上下文管:Operation 用 `ctx.select` 落点,事务结束时一并交回。\n * 这样撤销栈拿到的「操作前/操作后选区」和操作串是同一份数据里配套的。\n */\nimport { DocumentModel } from '../model/document';\nimport { Selection } from '../model/types';\nimport { Operation, OperationContext, OperationRun, runOperation, scopeContext } from '../operations';\nimport { EditKind, EditMeta, EditResult, editResult } from './editResult';\n\nexport interface EditOutcome {\n /** 这次编辑的记录。没有产生任何变更时是 null,不该进撤销栈。 */\n edit: EditResult | null;\n /** 事务结束时的选区,属于 `meta.scope` 指定的坐标空间。 */\n selectionAfter: Selection;\n}\n\n/**\n * 在指定坐标空间里跑一段 Operation,不包装成编辑记录。\n *\n * `scope` 非空时上下文先切到该片段的坐标空间 —— Operation 原样复用,发出的\n * mutation 自动包上 `scoped`。拖拽预览这类不进撤销栈的改动直接用它。\n */\nexport function runScoped<R>(\n doc: DocumentModel,\n selection: Selection,\n scope: string | null,\n op: Operation<R>\n): { run: OperationRun; result: R } {\n return runOperation(doc, selection, (outer) => op(scope ? scopeContext(outer, scope) : outer));\n}\n\n/** 跑一次编辑事务,产出一条能进撤销栈的记录。 */\nexport function runEdit(\n doc: DocumentModel,\n selection: Selection,\n meta: Partial<EditMeta> & { kind: EditKind },\n run: (ctx: OperationContext) => void\n): EditOutcome {\n const { run: result } = runScoped(doc, selection, meta.scope ?? null, run);\n\n if (!result.forward.length) {\n return { edit: null, selectionAfter: result.selectionAfter };\n }\n return {\n edit: editResult({\n mutations: result.forward,\n inverse: result.inverse,\n selectionBefore: result.selectionBefore,\n selectionAfter: result.selectionAfter,\n meta\n }),\n selectionAfter: result.selectionAfter\n };\n}\n","/**\n * 撤销栈。\n *\n * 与「存整篇快照」的做法相比,这里存的是操作对,所以两件事成为可能:\n * 一是连续输入能在时间窗口内合并成一步;二是撤销时能把逆操作变换到\n * 「协作者的改动已经落地」之后的坐标系里,撤销自己的编辑不会误伤别人的。\n *\n * 栈顶是下标 0(最近一步),与遍历「比它更新的操作」的写法配合更自然。\n */\nimport { Selection } from '../model/types';\nimport { EditResult, invertEdit, isEmptyEdit, mergeEdits } from './editResult';\nimport { transformBoth, transformSelection } from '../mutations';\n\n/** 连续输入的合并窗口。超过这个间隔就另起一步。 */\nexport const UNDO_BATCH_MS = 2000;\n\nexport class UndoRedoStack {\n private undos: EditResult[] = [];\n private redos: EditResult[] = [];\n private lastPushAt = 0;\n private batchOpen = false;\n private now: () => number;\n\n constructor(now: () => number = () => Date.now()) {\n this.now = now;\n }\n\n get canUndo(): boolean {\n return this.undos.some((e) => e.meta.local && e.meta.undoable);\n }\n\n get canRedo(): boolean {\n return this.redos.length > 0;\n }\n\n clear() {\n this.undos = [];\n this.redos = [];\n this.batchOpen = false;\n }\n\n /** 选区被用户主动移动时调用,打断合并窗口。 */\n resetBatching() {\n this.batchOpen = false;\n }\n\n push(edit: EditResult) {\n if (isEmptyEdit(edit)) return;\n\n if (!edit.meta.local) {\n // 远端操作也要进栈:撤销本地操作时需要跨过它们做变换\n this.undos.unshift(edit);\n this.batchOpen = false;\n return;\n }\n\n // 合并要三个条件同时成立:在时间窗口内、批次没被打断、两步是同一串\n // 连续动作(mergeKey 相同且非 null)。少了最后一条,「打几个字」和紧随其后的\n // 「点加粗」会被并成一步,撤销时文字和加粗一起消失。\n const top = this.undos[0];\n const withinWindow = this.batchOpen && this.now() - this.lastPushAt < UNDO_BATCH_MS;\n const sameRun = !!edit.meta.mergeKey && top?.meta.mergeKey === edit.meta.mergeKey;\n if (withinWindow && sameRun && top?.meta.local && top.meta.undoable && edit.meta.undoable) {\n this.undos[0] = mergeEdits(top, edit);\n } else {\n this.undos.unshift(edit);\n this.batchOpen = true;\n }\n this.lastPushAt = this.now();\n this.redos = [];\n }\n\n /**\n * 取出下一步要撤销的操作,已变换到当前坐标系。\n *\n * 栈里可能夹着协作者的操作,所以不能直接弹栈顶:要找到最近一条本地可撤销的,\n * 把它的逆操作依次穿过它上面那些更新的操作,同时把那些操作也反向变换一遍\n * (它们的坐标系因为这次撤销也变了,留在栈里下次还要用)。\n */\n popForUndo(): EditResult | null {\n const index = this.undos.findIndex((e) => e.meta.local && e.meta.undoable);\n if (index < 0) return null;\n\n let target = this.undos[index];\n for (let i = index - 1; i >= 0; i--) {\n target = this.rebase(target, i);\n }\n this.undos.splice(index, 1);\n\n const undoStep = invertEdit(target);\n this.redos.unshift(target);\n this.batchOpen = false;\n return undoStep;\n }\n\n popForRedo(): EditResult | null {\n const target = this.redos.shift();\n if (!target) return null;\n this.undos.unshift(target);\n this.batchOpen = false;\n return target;\n }\n\n /**\n * 把 target 变换到「栈中第 i 条(更新的那条)已应用」之后,\n * 同时把第 i 条变换到「target 被撤销」之后。\n */\n private rebase(target: EditResult, i: number): EditResult {\n const intervening = this.undos[i];\n // 撤销时真正要跑的是逆操作,所以拿它去和中间操作对撞\n const pair = transformBoth(target.inverse, intervening.mutations, true);\n const forward = transformBoth(target.mutations, intervening.mutations, true);\n\n this.undos[i] = {\n ...intervening,\n mutations: pair.b,\n inverse: transformBoth(intervening.inverse, target.inverse, false).a\n };\n\n return {\n ...target,\n mutations: forward.a,\n inverse: pair.a,\n selectionBefore: transformSelection(target.selectionBefore, intervening.mutations),\n selectionAfter: transformSelection(target.selectionAfter, intervening.mutations)\n };\n }\n\n /** 远端操作落地后,把栈里所有本地操作变换到新坐标系。 */\n rebaseAgainstRemote(remote: EditResult) {\n for (let i = 0; i < this.undos.length; i++) {\n const e = this.undos[i];\n this.undos[i] = {\n ...e,\n mutations: transformBoth(e.mutations, remote.mutations, false).a,\n inverse: transformBoth(e.inverse, remote.mutations, false).a,\n selectionBefore: transformSelection(e.selectionBefore, remote.mutations),\n selectionAfter: transformSelection(e.selectionAfter, remote.mutations)\n };\n }\n for (let i = 0; i < this.redos.length; i++) {\n const e = this.redos[i];\n this.redos[i] = {\n ...e,\n mutations: transformBoth(e.mutations, remote.mutations, false).a,\n inverse: transformBoth(e.inverse, remote.mutations, false).a\n };\n }\n }\n\n /** 调试用:当前撤销栈里各步的操作条数。 */\n describe(): { undos: number[]; redos: number[] } {\n return {\n undos: this.undos.map((e) => e.mutations.length),\n redos: this.redos.map((e) => e.mutations.length)\n };\n }\n}\n\nexport type { EditResult, Selection };\n","export interface ImeHandler {\n onInsertText(text: string): void;\n onInsertParagraph(): void;\n onBackspace(): void;\n onDeleteForward(): void;\n onPaste(data: DataTransfer | null): void;\n onCompositionChange(active: boolean, text: string): void;\n}\n\nexport class ImeSurface {\n readonly el: HTMLDivElement;\n composing = false;\n private handler: ImeHandler;\n private keyConsumed = false;\n private ctxMenu = false;\n\n constructor(handler: ImeHandler) {\n this.handler = handler;\n this.el = document.createElement('div');\n this.el.className = 'mini-ime';\n this.el.contentEditable = 'true';\n this.el.spellcheck = false;\n this.el.setAttribute('role', 'textbox');\n this.el.setAttribute('aria-multiline', 'true');\n this.el.addEventListener('beforeinput', this.onBeforeInput);\n this.el.addEventListener('compositionstart', this.onCompStart);\n this.el.addEventListener('compositionupdate', this.onCompUpdate);\n this.el.addEventListener('compositionend', this.onCompEnd);\n this.el.addEventListener('paste', this.onPaste);\n this.el.addEventListener('keydown', this.onKeydownGuard);\n }\n\n focus() {\n if (document.activeElement !== this.el) this.el.focus({ preventScroll: true });\n }\n\n markKeyConsumed() {\n this.keyConsumed = true;\n }\n\n /**\n * 右键菜单:把隐藏的 contenteditable 临时挪到鼠标下并放入选中文字、全选。\n * 浏览器按 contextmenu 事件时鼠标下的元素决定菜单种类,落在 canvas 上会弹出\n * “存储图片”之类;落在可编辑文本上才是 剪切/拷贝/粘贴。复制/剪切/粘贴事件\n * 仍由编辑器接管,所以这里的文字只用来启用菜单项,不会被当作输入。\n */\n beginContextMenu(x: number, y: number, text: string) {\n if (this.composing) return;\n this.ctxMenu = true;\n this.el.classList.add('is-ctxmenu');\n this.el.style.left = `${x - 12}px`;\n this.el.style.top = `${y - 12}px`;\n this.el.style.width = '24px';\n this.el.style.height = '24px';\n this.el.textContent = text;\n this.focus();\n if (text) {\n const range = document.createRange();\n range.selectNodeContents(this.el);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n }\n }\n\n endContextMenu() {\n if (!this.ctxMenu) return;\n this.ctxMenu = false;\n this.el.classList.remove('is-ctxmenu');\n this.el.style.width = '';\n this.clear();\n }\n\n moveTo(x: number, y: number, h: number) {\n if (this.ctxMenu) return;\n this.el.style.left = `${x}px`;\n this.el.style.top = `${y}px`;\n this.el.style.height = `${Math.max(18, h)}px`;\n }\n\n clear() {\n this.el.textContent = '';\n }\n\n destroy() {\n this.el.removeEventListener('beforeinput', this.onBeforeInput);\n this.el.removeEventListener('compositionstart', this.onCompStart);\n this.el.removeEventListener('compositionupdate', this.onCompUpdate);\n this.el.removeEventListener('compositionend', this.onCompEnd);\n this.el.removeEventListener('paste', this.onPaste);\n this.el.removeEventListener('keydown', this.onKeydownGuard);\n this.el.remove();\n }\n\n private onCompStart = () => {\n this.composing = true;\n this.el.classList.add('is-composing');\n this.handler.onCompositionChange(true, '');\n };\n\n private onCompUpdate = (e: CompositionEvent) => {\n this.handler.onCompositionChange(true, e.data ?? this.el.textContent ?? '');\n };\n\n private onCompEnd = (e: CompositionEvent) => {\n this.composing = false;\n this.el.classList.remove('is-composing');\n const text = e.data || this.el.textContent || '';\n this.clear();\n this.handler.onCompositionChange(false, '');\n if (text) this.handler.onInsertText(text);\n };\n\n private onBeforeInput = (e: InputEvent) => {\n if (this.keyConsumed) {\n this.keyConsumed = false;\n // 快捷键在 keydown 里已经改过模型,这里只吞「同一次按键」带出来的默认输入\n // (退格/删除/换段)。keydown 若已 preventDefault,有的浏览器根本不会再派\n // 这次 beforeinput,标志会一直挂到下一键;绝不能把随后的 insertText 也挡掉,\n // 否则删除后再打的第一个字符会消失,第二次才进得去。\n const echo =\n e.inputType.startsWith('delete') ||\n e.inputType === 'insertParagraph' ||\n e.inputType === 'insertLineBreak';\n if (echo) {\n e.preventDefault();\n return;\n }\n }\n if (e.inputType === 'insertCompositionText') return;\n // 组合态里的一切输入(含删除候选串的 delete*)都交给浏览器在这个\n // contentEditable 内部消化。组合串的增删经 compositionupdate 镜像到模型,\n // 删除永远只作用在候选串上,绝不落到文档正文。\n if (this.composing) return;\n e.preventDefault();\n switch (e.inputType) {\n case 'insertText':\n case 'insertReplacementText':\n if (e.data) this.handler.onInsertText(e.data);\n break;\n case 'insertParagraph':\n case 'insertLineBreak':\n this.handler.onInsertParagraph();\n break;\n case 'deleteContentBackward':\n this.handler.onBackspace();\n break;\n case 'deleteContentForward':\n this.handler.onDeleteForward();\n break;\n case 'insertFromPaste':\n break;\n default:\n break;\n }\n };\n\n private onPaste = (e: ClipboardEvent) => {\n e.preventDefault();\n this.handler.onPaste(e.clipboardData);\n };\n\n private onKeydownGuard = (e: KeyboardEvent) => {\n if (e.key === 'Tab') e.preventDefault();\n };\n}\n","/**\n * 快捷键表。\n *\n * 一张纯数据表:按键组合 → 命令。它不认识 DOM 事件,也不认识编辑器 —— 匹配用的\n * 是 {@link KeyStroke} 这个最小结构,由输入源从事件里摘出来。这样这张表可以被\n * 直接断言,也可以将来换成宿主配置的。\n */\nimport { ArrowKey, CommandTable } from './types';\n\n/** 一次按键,从平台事件里摘出来的最小信息。 */\nexport interface KeyStroke {\n /** `KeyboardEvent.key`,大小写原样 */\n key: string;\n /** Cmd(mac)或 Ctrl */\n mod: boolean;\n shift: boolean;\n /** Option(mac)/ Alt */\n alt: boolean;\n /** 单独的 Cmd(mac)。省略时视为没按;`mod` 仍是 Cmd||Ctrl 的并集 */\n meta?: boolean;\n /** 单独的 Ctrl。省略时视为没按 */\n ctrl?: boolean;\n}\n\nexport interface Shortcut {\n /** 匹配的键名,单字母键写小写 */\n key: string;\n /** 是否要求按下 Cmd/Ctrl。省略等同 false —— 必须**没**按 */\n mod?: boolean;\n /** true 要求按 Shift,false 要求没按,省略则不管 */\n shift?: boolean;\n /**\n * true 要求按 Alt/Option,false 要求没按,省略则不管。\n *\n * 省略=不管(而不是像 `mod` 那样默认没按),是为了不改变既有行为:Option+方向键、\n * Option+Backspace 现在都落在无修饰键的条目上。需要区分时,把 `alt: true` 的条目\n * 排在无修饰键条目之前即可,与「带修饰键的排在前面」的顺序约定一致。\n */\n alt?: boolean;\n /**\n * 这个键本身会引发一次文本输入(beforeInput)。吞掉按键之后还得把那次输入一并\n * 压掉,否则内容会被写两遍。只有真正产生输入的键要标。\n *\n * 注意:keydown 里会 preventDefault,部分浏览器因此不再派 beforeinput。\n * IME 层只能按 inputType 吞删除/换段回声,不能无差别丢掉下一次 insertText。\n */\n suppressesInput?: boolean;\n /** 返回 false 表示这次没处理,事件不该被吞 */\n run(c: CommandTable, stroke: KeyStroke): void | boolean;\n}\n\nconst arrow = (key: ArrowKey): Shortcut => ({\n key,\n run: (c, s) => c.moveCaret(key, s.shift)\n});\n\n/**\n * 带修饰键的方向键 / Home / End。mac 和 Windows 的习惯不同,这里一起登记:\n * - Cmd+←→ 行首/行尾,Cmd+↑↓ 文首/文尾(mac)\n * - Option+←→ 按词,Option+↑↓ 按段(mac)\n * - Ctrl+←→ 按词,Ctrl+↑↓ 按段(Windows/Linux)\n * - Home/End 行首/行尾,Ctrl/Cmd+Home/End 文首/文尾\n * Shift 一律表示扩选。\n */\nconst modArrow = (key: ArrowKey): Shortcut => ({\n key,\n mod: true,\n run: (c, s) => {\n const dir = key === 'ArrowLeft' || key === 'ArrowUp' ? -1 : 1;\n const horizontal = key === 'ArrowLeft' || key === 'ArrowRight';\n // 没按 Cmd(只有 Ctrl)→ Windows 口径;按了 Cmd → mac 口径。\n if (!s.meta) return c.moveCaretBy(horizontal ? 'word' : 'paragraph', dir, s.shift);\n return c.moveCaretBy(horizontal ? 'line' : 'doc', dir, s.shift);\n }\n});\n\nconst altArrow = (key: ArrowKey): Shortcut => ({\n key,\n alt: true,\n run: (c, s) => {\n const dir = key === 'ArrowLeft' || key === 'ArrowUp' ? -1 : 1;\n const horizontal = key === 'ArrowLeft' || key === 'ArrowRight';\n return c.moveCaretBy(horizontal ? 'word' : 'paragraph', dir, s.shift);\n }\n});\n\nconst navKeys = (): Shortcut[] => [\n { key: 'Home', mod: true, run: (c, s) => c.moveCaretBy('doc', -1, s.shift) },\n { key: 'End', mod: true, run: (c, s) => c.moveCaretBy('doc', 1, s.shift) },\n { key: 'Home', run: (c, s) => c.moveCaretBy('line', -1, s.shift) },\n { key: 'End', run: (c, s) => c.moveCaretBy('line', 1, s.shift) },\n modArrow('ArrowLeft'),\n modArrow('ArrowRight'),\n modArrow('ArrowUp'),\n modArrow('ArrowDown'),\n altArrow('ArrowLeft'),\n altArrow('ArrowRight'),\n altArrow('ArrowUp'),\n altArrow('ArrowDown')\n];\n\n/**\n * 顺序有意义:从上往下取第一条匹配的。带修饰键的排在前面,免得被无修饰键的\n * 条目截住。\n */\nexport const SHORTCUTS: Shortcut[] = [\n { key: 'z', mod: true, shift: false, run: (c) => c.undo() },\n { key: 'z', mod: true, shift: true, run: (c) => c.redo() },\n { key: 'y', mod: true, run: (c) => c.redo() },\n { key: 'b', mod: true, run: (c) => c.toggleBold() },\n { key: 'i', mod: true, run: (c) => c.toggleItalic() },\n { key: 'u', mod: true, run: (c) => c.toggleUnderline() },\n { key: 'k', mod: true, run: (c) => c.toggleLink() },\n { key: 'a', mod: true, run: (c) => c.selectAll() },\n\n { key: 'Escape', run: (c) => c.exitFragment() },\n { key: 'Enter', suppressesInput: true, run: (c, s) => c.insertParagraph({ shift: s.shift }) },\n { key: 'Backspace', suppressesInput: true, run: (c) => c.backspace() },\n { key: 'Delete', suppressesInput: true, run: (c) => c.deleteForward() },\n { key: 'Tab', run: (c, s) => c.indentOrNextCell(s.shift ? -1 : 1) },\n\n ...navKeys(),\n arrow('ArrowLeft'),\n arrow('ArrowRight'),\n arrow('ArrowUp'),\n arrow('ArrowDown')\n];\n\n/**\n * 嵌入式输入框用的快捷键表:保留撤销/选区/删除/方向键,关掉加粗链接。\n * Enter 不在这张底表里,请用 {@link inputShortcuts} 补上换行,否则\n * keydown 不 preventDefault,contenteditable 的 beforeinput 仍会插段。\n */\nconst swallow: Shortcut['run'] = () => undefined;\n\nexport const INPUT_SHORTCUTS: Shortcut[] = [\n { key: 'z', mod: true, shift: false, run: (c) => c.undo() },\n { key: 'z', mod: true, shift: true, run: (c) => c.redo() },\n { key: 'y', mod: true, run: (c) => c.redo() },\n { key: 'b', mod: true, run: swallow },\n { key: 'i', mod: true, run: swallow },\n { key: 'u', mod: true, run: swallow },\n { key: 'k', mod: true, run: swallow },\n { key: 'a', mod: true, run: (c) => c.selectAll() },\n { key: 'Backspace', suppressesInput: true, run: (c) => c.backspace() },\n { key: 'Delete', suppressesInput: true, run: (c) => c.deleteForward() },\n ...navKeys(),\n arrow('ArrowLeft'),\n arrow('ArrowRight'),\n arrow('ArrowUp'),\n arrow('ArrowDown')\n];\n\n/**\n * 输入框快捷键。\n * - `newline`:Enter / Shift+Enter 都换行;Cmd/Ctrl+Enter 不登记,留给宿主提交。\n * - `enter` / `shift-enter`:旧口径(引擎仍提供,嵌入式输入框不要用)。\n */\nexport function inputShortcuts(\n submit: 'newline' | 'enter' | 'shift-enter' = 'newline'\n): Shortcut[] {\n if (submit === 'newline') {\n return [\n ...INPUT_SHORTCUTS,\n { key: 'Enter', suppressesInput: true, run: (c, s) => c.insertParagraph({ shift: s.shift }) }\n ];\n }\n const submitUsesShift = submit === 'shift-enter';\n return [\n ...INPUT_SHORTCUTS,\n { key: 'Enter', shift: submitUsesShift, suppressesInput: true, run: swallow },\n {\n key: 'Enter',\n shift: !submitUsesShift,\n suppressesInput: true,\n run: (c, s) => c.insertParagraph({ shift: s.shift })\n }\n ];\n}\n\nfunction matches(sc: Shortcut, stroke: KeyStroke): boolean {\n // 单字母键统一按小写比,这样 Cmd+Shift+Z 和 Cmd+Z 走同一套判断\n const key = sc.key.length === 1 ? stroke.key.toLowerCase() : stroke.key;\n if (key !== sc.key) return false;\n if (stroke.mod !== (sc.mod ?? false)) return false;\n if (sc.shift !== undefined && stroke.shift !== sc.shift) return false;\n if (sc.alt !== undefined && stroke.alt !== sc.alt) return false;\n return true;\n}\n\nexport function findShortcut(stroke: KeyStroke, table: Shortcut[] = SHORTCUTS): Shortcut | null {\n return table.find((sc) => matches(sc, stroke)) ?? null;\n}\n","/**\n * 键盘输入源:DOM 事件 → 命令。\n *\n * 这里只做三件事:判断该不该管这个事件、查表、跑命令。它不碰模型也不碰选区 ——\n * 所以「哪个键干什么」改起来只动 `commands/shortcuts.ts`,不用进这个文件。\n */\nimport { CommandTable, findShortcut, KeyStroke, Shortcut, SHORTCUTS } from '../commands';\n\n/**\n * 组合输入期间仍然放行的键。Enter 不在其列:组合态的回车是“确认候选”,由 IME 消化,\n * 绝不触发换行(否则中文输入选词按回车会错误插入段落)。\n */\nconst IME_PASSTHROUGH = new Set(['Backspace', 'Delete', 'Escape']);\n\nexport interface KeyboardHost {\n commands: CommandTable;\n /** 这个事件归不归本编辑器管(焦点、输入框内、嵌入对象里等) */\n accepts(e: KeyboardEvent): boolean;\n /** 组合输入是否进行中 */\n composing(): boolean;\n /** 吞掉了一个会引发文本输入的键,通知宿主连带压掉那次输入 */\n suppressInput(e: KeyboardEvent): void;\n shortcuts?: Shortcut[];\n}\n\nexport function strokeOf(e: KeyboardEvent): KeyStroke {\n return {\n key: e.key,\n mod: e.metaKey || e.ctrlKey,\n shift: e.shiftKey,\n alt: e.altKey,\n meta: e.metaKey,\n ctrl: e.ctrlKey\n };\n}\n\n/** 挂上 keydown 监听,返回解绑函数。 */\nexport function bindKeyboard(host: KeyboardHost): () => void {\n const table = host.shortcuts ?? SHORTCUTS;\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (!host.accepts(e)) return;\n // 组合输入进行中(中文候选框开着)时,回车/空格等键属于 IME 的“确认候选”动作,\n // 应交给 IME 消化,编辑器不得据此换行或插入。原生 isComposing 由浏览器在整个\n // 组合过程(含确认候选的那次按键)置真,比自维护状态更可靠,能覆盖 compositionend\n // 与 keydown 的时序竞态。keyCode 229 是同一语义在旧实现下的回退标志。\n if (e.isComposing || e.keyCode === 229) return;\n if (host.composing() && !IME_PASSTHROUGH.has(e.key)) return;\n\n const stroke = strokeOf(e);\n const sc = findShortcut(stroke, table);\n if (!sc) return;\n if (sc.run(host.commands, stroke) === false) return;\n\n e.preventDefault();\n if (sc.suppressesInput) host.suppressInput(e);\n };\n\n document.addEventListener('keydown', onKeyDown);\n return () => document.removeEventListener('keydown', onKeyDown);\n}\n","/**\n * 开发用性能探针。默认不开,开了之后才给 Editor 实例打补丁,不开时零开销。\n *\n * editor.perf.start() // 开始采样,同时开始监测帧间隔\n * ...连续打字 / 按住方向键 / 中文输入法连续上屏...\n * editor.perf.report() // console.table 输出并返回数据;editor.perf.stop() 停止并还原\n *\n * 口径:\n * - 各阶段耗时是 JS 同步耗时(ms),不含浏览器合成、光栅化。\n * - `→下一帧` 是从处理函数开始到下一次 requestAnimationFrame 回调开始的时间,\n * 近似“输入到上屏”的延迟;真正画完还要再加一帧里的合成时间。\n * - 表格里的 fps 列 = 1000 / 该项耗时,表示“如果每一帧都只做这件事,最高能跑多少帧”,上限显示 999;\n * 只有 `→下一帧` 行和底部的“帧”行接近真实体感帧率。\n * - 帧间隔取 requestAnimationFrame 相邻回调的间隔。注意光标闪烁本身每帧都在跑 rAF,\n * 所以空闲时也会有帧;有意义的是“操作期间”掉不掉帧。\n */\n\nexport interface PerfStat {\n count: number;\n avg: number;\n p95: number;\n max: number;\n}\n\ntype Patchable = Record<string, (...args: unknown[]) => unknown>;\n\n/** 要测的入口:用户一次操作的同步总耗时 */\nconst ENTRY = ['insertText', 'handleComposition', 'moveCaret', 'moveCaretBy', 'backspace', 'deleteForward', 'insertParagraph'];\n/** 要测的内部阶段 */\nconst STAGES = ['relayout', 'paintChrome', 'paintCaretLayer', 'scrollCaret', 'syncToolbar', 'syncStatus', 'afterCaretMove'];\n\nfunction stat(samples: number[]): PerfStat {\n if (!samples.length) return { count: 0, avg: 0, p95: 0, max: 0 };\n const sorted = [...samples].sort((a, b) => a - b);\n const sum = sorted.reduce((a, b) => a + b, 0);\n return {\n count: sorted.length,\n avg: sum / sorted.length,\n p95: sorted[Math.min(sorted.length - 1, Math.floor(sorted.length * 0.95))],\n max: sorted[sorted.length - 1]\n };\n}\n\nexport class PerfProbe {\n private target: Patchable;\n private getPainter: () => object;\n private painter: Patchable | null = null;\n private originals = new Map<string, () => unknown>();\n private painterOriginal: ((...args: unknown[]) => unknown) | null = null;\n private samples = new Map<string, number[]>();\n private frames: number[] = [];\n private raf = 0;\n private lastFrame = 0;\n private running = false;\n\n constructor(editor: object, getPainter: () => object) {\n this.target = editor as Patchable;\n this.getPainter = getPainter;\n }\n\n get active() {\n return this.running;\n }\n\n start() {\n if (this.running) return;\n this.running = true;\n this.reset();\n for (const name of [...ENTRY, ...STAGES]) this.patch(name, ENTRY.includes(name));\n // 画家可能被 setPaintMode 换掉:只给 start 时那一个打补丁,换了之后 paintDoc 不再计时\n const painter = this.getPainter() as Patchable;\n if (typeof painter.paintDoc === 'function') {\n const orig = painter.paintDoc.bind(painter);\n this.painter = painter;\n this.painterOriginal = painter.paintDoc;\n painter.paintDoc = (...args: unknown[]) => this.time('paintDoc', () => orig(...args));\n }\n this.lastFrame = 0;\n const tick = (now: number) => {\n if (this.lastFrame) this.frames.push(now - this.lastFrame);\n this.lastFrame = now;\n this.raf = requestAnimationFrame(tick);\n };\n this.raf = requestAnimationFrame(tick);\n }\n\n stop() {\n if (!this.running) return;\n this.running = false;\n cancelAnimationFrame(this.raf);\n for (const [name, orig] of this.originals) {\n // 实例上的补丁删掉即可回到原型方法\n delete (this.target as Record<string, unknown>)[name];\n void orig;\n }\n this.originals.clear();\n if (this.painter && this.painterOriginal) {\n // paintDoc 原先是原型方法,删掉实例补丁\n delete (this.painter as Record<string, unknown>).paintDoc;\n }\n this.painter = null;\n this.painterOriginal = null;\n }\n\n reset() {\n this.samples.clear();\n this.frames = [];\n }\n\n /** 汇总并输出到控制台,返回原始统计。 */\n report() {\n const rows: Record<string, PerfStat> = {};\n for (const [label, s] of this.samples) rows[label] = stat(s);\n // relayout 里去掉已单独统计的阶段,剩下的主要是排版本身\n const rl = this.samples.get('relayout');\n if (rl) {\n const inner = ['paintDoc', 'paintChrome', 'scrollCaret', 'syncToolbar', 'syncStatus'].map(\n (k) => this.samples.get(k) ?? []\n );\n const self = rl.map((v, i) => Math.max(0, v - inner.reduce((a, arr) => a + (arr[i] ?? 0), 0)));\n rows['relayout(排版自身,估算)'] = stat(self);\n }\n const fr = stat(this.frames);\n const frames = {\n 样本帧数: fr.count,\n 平均帧率: fr.avg ? +(1000 / fr.avg).toFixed(1) : 0,\n 帧间隔p95_ms: +fr.p95.toFixed(2),\n 最长帧_ms: +fr.max.toFixed(2),\n '超过16.7ms的帧': this.frames.filter((d) => d > 16.7).length,\n '超过33ms的帧': this.frames.filter((d) => d > 33).length\n };\n const table: Record<string, Record<string, number>> = {};\n for (const [label, s] of Object.entries(rows)) {\n const fps = (ms: number) => (ms > 0 ? Math.min(999, Math.round(1000 / ms)) : 999);\n table[label] = {\n 次数: s.count,\n 平均ms: +s.avg.toFixed(3),\n p95ms: +s.p95.toFixed(3),\n 最大ms: +s.max.toFixed(3),\n 平均fps: fps(s.avg),\n p95fps: fps(s.p95),\n 最差fps: fps(s.max)\n };\n }\n console.table(table);\n console.table({ 帧: frames });\n return { rows, frames };\n }\n\n private record(label: string, ms: number) {\n let arr = this.samples.get(label);\n if (!arr) this.samples.set(label, (arr = []));\n arr.push(ms);\n if (arr.length > 5000) arr.shift();\n }\n\n private time<T>(label: string, fn: () => T): T {\n const t = performance.now();\n try {\n return fn();\n } finally {\n this.record(label, performance.now() - t);\n }\n }\n\n private patch(name: string, entry: boolean) {\n const proto = this.target[name];\n if (typeof proto !== 'function') return;\n this.originals.set(name, proto as () => unknown);\n const self = this;\n (this.target as Record<string, unknown>)[name] = function patched(this: unknown, ...args: unknown[]) {\n const t = performance.now();\n try {\n return proto.apply(this, args);\n } finally {\n const dt = performance.now() - t;\n self.record(name, dt);\n if (entry) {\n requestAnimationFrame(() => self.record(`${name}→下一帧`, performance.now() - t));\n }\n }\n };\n }\n}\n","/**\n * 光标跳转目标的纯计算:按词 / 段落跳。\n *\n * 只吃字符流和下标,不碰选区与布局,便于直接断言。行首行尾、文首文尾依赖布局,\n * 由编辑器自己算。\n */\nimport { MARKERS } from '../model/markers';\n\n/** 方向键跳转的粒度 */\nexport type MoveUnit = 'word' | 'line' | 'paragraph' | 'doc';\n\nlet segmenter: Intl.Segmenter | null | undefined;\n\nfunction getSegmenter(): Intl.Segmenter | null {\n if (segmenter === undefined) {\n segmenter = typeof Intl !== 'undefined' && 'Segmenter' in Intl ? new Intl.Segmenter(undefined, { granularity: 'word' }) : null;\n }\n return segmenter;\n}\n\n/** 文档里允许放光标的最大下标:末尾那个段落符之后不是真实位置。 */\nexport function maxCaretIndex(spacers: string): number {\n return spacers.endsWith(MARKERS.PARAGRAPH) ? spacers.length - 1 : spacers.length;\n}\n\ninterface WordSpan {\n start: number;\n end: number;\n}\n\n/** 以“词”为单位切开字符流:词字符(含中文分词结果)和嵌入对象各算一个词。 */\nfunction wordSpans(spacers: string): WordSpan[] {\n const out: WordSpan[] = [];\n const seg = getSegmenter();\n if (seg) {\n for (const s of seg.segment(spacers)) {\n if (s.isWordLike || s.segment.includes(MARKERS.IMAGE)) {\n out.push({ start: s.index, end: s.index + s.segment.length });\n }\n }\n return out;\n }\n // 没有 Intl.Segmenter 的环境:按 \\w / 单个 CJK 字退化。\n const re = /[\\p{L}\\p{N}_]+|\\*/gu;\n let m: RegExpExecArray | null;\n while ((m = re.exec(spacers))) out.push({ start: m.index, end: m.index + m[0].length });\n return out;\n}\n\n/**\n * Option/Ctrl+←→ 的目标:向右到“下一个词的末尾”,向左到“上一个词的开头”。\n * 标点、空白、段落符都当作词间隔跳过。\n */\nexport function wordTarget(spacers: string, index: number, dir: 1 | -1): number {\n const spans = wordSpans(spacers);\n if (dir > 0) {\n for (const w of spans) if (w.end > index) return Math.min(w.end, maxCaretIndex(spacers));\n return maxCaretIndex(spacers);\n }\n for (let i = spans.length - 1; i >= 0; i--) if (spans[i].start < index) return spans[i].start;\n return 0;\n}\n\n/**\n * Option/Ctrl+↑↓ 的目标:向上到本段开头(已在开头则到上一段开头),\n * 向下到本段末尾(已在末尾则到下一段末尾)。\n */\nexport function paragraphTarget(spacers: string, index: number, dir: 1 | -1): number {\n const max = maxCaretIndex(spacers);\n if (dir < 0) {\n const start = index > 0 ? spacers.lastIndexOf(MARKERS.PARAGRAPH, index - 1) + 1 : 0;\n if (start < index) return start;\n if (index <= 0) return 0;\n return spacers.lastIndexOf(MARKERS.PARAGRAPH, index - 2) + 1;\n }\n const end = spacers.indexOf(MARKERS.PARAGRAPH, index);\n if (end === -1) return max;\n if (end > index) return Math.min(end, max);\n const next = spacers.indexOf(MARKERS.PARAGRAPH, index + 1);\n return next === -1 ? max : Math.min(next, max);\n}\n\n/**\n * 双击选词:返回 `index` 所在(或紧邻左侧)的词的范围;落在空白/标点上返回 null。\n * 光标恰在两词交界时取右边那个词,和原生一致。\n */\nexport function wordRangeAt(spacers: string, index: number): { start: number; end: number } | null {\n const spans = wordSpans(spacers);\n const hit = spans.find((w) => index >= w.start && index < w.end) ?? spans.find((w) => index === w.end);\n return hit ? { start: hit.start, end: hit.end } : null;\n}\n","import { ImageEntity, Slice, StyleSpan } from '../model/types';\n\n/** 自定义剪贴板 MIME:跨编辑器粘贴时保全样式与嵌入实体。 */\nexport const SLICE_MIME = 'text/x-mini-editor-slice';\n\nexport function serializeSlice(slice: Slice): string {\n return JSON.stringify(slice);\n}\n\nexport function parseSlice(raw: string): Slice | null {\n if (!raw) return null;\n try {\n const data = JSON.parse(raw) as Slice;\n if (!data || typeof data.text !== 'string' || !Array.isArray(data.styles)) return null;\n return {\n text: data.text,\n styles: (data.styles as StyleSpan[]).filter((s) => typeof s.start === 'number' && typeof s.end === 'number'),\n entities: Array.isArray(data.entities) ? (data.entities as ImageEntity[]) : [],\n virtualBlocks: Array.isArray(data.virtualBlocks) ? data.virtualBlocks : undefined\n };\n } catch {\n return null;\n }\n}\n\nexport function sliceFromClipboard(data: DataTransfer | null): Slice | null {\n if (!data) return null;\n return parseSlice(data.getData(SLICE_MIME));\n}\n","import { embedPlugin, syncEmbedLayer } from '../embed';\nimport { canvasFont, FONT_FAMILY } from '../layout/measure';\nimport { CaretPos, DocLayout, GlyphBox, SelRect } from '../layout/types';\nimport { canvasFill, groupDecorationRuns, paintCanvasStrike, paintCanvasUnderline } from './decorations';\nimport { PaintBackend } from './types';\n\n/**\n * 画布左右各比文档宽出这么多:mark 等块的 paddingX 外扩在行首行尾会画到内容区外,\n * 画布若恰好等宽就会被裁掉。画布整体左移 GUTTER 并平移绘制坐标,文字位置不变;\n * 配套的 style.css 给 .mini-page-wrap 左右各留同样宽度的可视区(负 margin 抵消)。\n */\nexport const CANVAS_GUTTER = 5;\n\n/**\n * 画布只覆盖可视区上下各这么多像素,而不是整篇文档。长文档(几万字)的整页画布\n * 会超过浏览器单张画布上限,而且每次光标闪烁都要清整张画布、每次换行都要重画全文。\n * 窗口外的内容滚进来时再按需重画。\n */\nconst VIEWPORT_MARGIN = 600;\n/**\n * 双指缩放(visualViewport.scale)不改 devicePixelRatio,位图被整体拉大就糊。这里把画布的\n * 像素密度乘上缩放倍数重画。倍数封顶,避免背包像素爆炸:放大 3 倍像素就是 9 倍。\n */\nconst MAX_ZOOM_SHARPNESS = 3;\n\nexport class CanvasPainter implements PaintBackend {\n private host: HTMLElement | null = null;\n private surface: HTMLElement | null = null;\n private canvas: HTMLCanvasElement | null = null;\n private chrome: HTMLCanvasElement | null = null;\n private ctx: CanvasRenderingContext2D | null = null;\n private chromeCtx: CanvasRenderingContext2D | null = null;\n private layout: DocLayout | null = null;\n private selRects: SelRect[] = [];\n private caret: CaretPos | null = null;\n private caretVisible = false;\n private caretTrails: CaretPos[] = [];\n private imageCache = new Map<string, HTMLImageElement>();\n private embeds: HTMLElement | null = null;\n private embedCache = new Map<string, HTMLElement>();\n private hasContent = false;\n private hoverId: string | null = null;\n /** 画布窗口在文档坐标里的顶部与高度(CSS px) */\n private winTop = 0;\n private winH = 0;\n private onScroll = () => this.followViewport();\n /** 上次重画用的像素密度(dpr × 缩放),变了就得整窗重画 */\n private lastScale = 0;\n private zoomRaf = 0;\n private zoomTimer = 0;\n private lastZoomPaint = 0;\n /** 缩放手势事件很密:节流到约 100ms 一次,手势停下后再精确补一次 */\n private onVisualViewport = () => {\n if (this.zoomRaf) return;\n this.zoomRaf = requestAnimationFrame(() => {\n this.zoomRaf = 0;\n const now = performance.now();\n if (now - this.lastZoomPaint >= 100) {\n this.lastZoomPaint = now;\n this.followViewport();\n }\n window.clearTimeout(this.zoomTimer);\n this.zoomTimer = window.setTimeout(() => this.followViewport(), 150);\n });\n };\n\n mount(host: HTMLElement) {\n this.destroy();\n this.host = host;\n this.surface = document.createElement('div');\n this.surface.className = 'mini-surface mini-surface-canvas';\n this.canvas = document.createElement('canvas');\n this.canvas.className = 'mini-canvas';\n this.chrome = document.createElement('canvas');\n this.chrome.className = 'mini-canvas mini-canvas-chrome';\n this.embeds = document.createElement('div');\n this.embeds.className = 'mini-layer mini-embeds';\n this.ctx = this.canvas.getContext('2d');\n this.chromeCtx = this.chrome.getContext('2d');\n this.surface.append(this.chrome, this.canvas, this.embeds);\n host.appendChild(this.surface);\n // 捕获阶段监听所有滚动(容器滚或窗口滚都算),只有可视区跑出画布窗口才重画\n document.addEventListener('scroll', this.onScroll, { capture: true, passive: true });\n window.addEventListener('resize', this.onScroll);\n // 双指缩放 / 缩放后平移只会动 visualViewport,不触发 document scroll\n window.visualViewport?.addEventListener('resize', this.onVisualViewport);\n window.visualViewport?.addEventListener('scroll', this.onVisualViewport);\n }\n\n /** 画布像素密度:dpr × 双指缩放倍数(封顶) */\n private pixelScale(): number {\n const dpr = window.devicePixelRatio || 1;\n const zoom = Math.min(MAX_ZOOM_SHARPNESS, Math.max(1, window.visualViewport?.scale ?? 1));\n return dpr * zoom;\n }\n\n getSurface(): HTMLElement {\n if (!this.surface) throw new Error('painter not mounted');\n return this.surface;\n }\n\n paintDoc(layout: DocLayout) {\n const prev = this.layout;\n this.layout = layout;\n const resized = this.resize(layout);\n // 画布尺寸或窗口位置一变,内容整块作废,只能全画(窗口范围内)\n const band =\n resized || !this.hasContent\n ? { top: 0, bottom: Math.max(layout.height, prev?.height ?? 0) }\n : layout.dirty;\n this.redrawContent(band);\n if (this.embeds) syncEmbedLayer(this.embeds, this.embedCache, layout.images, true);\n this.redrawChrome();\n }\n\n setHoverBlock(id: string | null) {\n if (id === this.hoverId) return;\n const prev = this.hoverId;\n this.hoverId = id;\n const layout = this.layout;\n if (!layout) return;\n for (const target of [prev, id]) {\n if (!target) continue;\n let top = Infinity;\n let bottom = -Infinity;\n for (const line of layout.lines) {\n for (const vb of line.vblocks ?? []) {\n if (vb.id !== target) continue;\n top = Math.min(top, vb.y, line.y);\n bottom = Math.max(bottom, vb.y + vb.h, line.y + line.h);\n }\n }\n if (top < bottom) this.redrawContent({ top: top - 1, bottom: bottom + 1 });\n }\n }\n\n paintSelection(rects: SelRect[]) {\n this.selRects = rects;\n this.redrawChrome();\n }\n\n paintCaret(caret: CaretPos | null, visible: boolean, trails: CaretPos[] = []) {\n this.caret = caret;\n this.caretVisible = visible;\n this.caretTrails = trails;\n this.redrawChrome();\n }\n\n destroy() {\n document.removeEventListener('scroll', this.onScroll, { capture: true });\n window.removeEventListener('resize', this.onScroll);\n window.visualViewport?.removeEventListener('resize', this.onVisualViewport);\n window.visualViewport?.removeEventListener('scroll', this.onVisualViewport);\n cancelAnimationFrame(this.zoomRaf);\n window.clearTimeout(this.zoomTimer);\n this.zoomRaf = 0;\n this.surface?.remove();\n this.host = null;\n this.surface = null;\n this.canvas = null;\n this.chrome = null;\n this.embeds = null;\n this.ctx = null;\n this.chromeCtx = null;\n this.layout = null;\n this.hasContent = false;\n this.imageCache.clear();\n for (const node of this.embedCache.values()) node.remove();\n this.embedCache.clear();\n }\n\n /** 可视区在文档坐标里的 [top, bottom]。找不到容器时就当整篇可见。 */\n private visibleRange(layout: DocLayout): { top: number; bottom: number } {\n if (!this.surface) return { top: 0, bottom: layout.height };\n const rect = this.surface.getBoundingClientRect();\n // 双指缩放后真正可见的只是布局视口的一部分:visualViewport 的 offsetTop / height\n // 都是布局视口 CSS 像素,与 getBoundingClientRect 同坐标系\n const vv = window.visualViewport;\n const viewTop = vv?.offsetTop ?? 0;\n // 个别环境(无头)visualViewport.height 给的是无意义的小数,退回 innerHeight / scale\n const vvH = vv && vv.height > 50 ? vv.height : (window.innerHeight || layout.height) / Math.max(1, vv?.scale ?? 1);\n const viewH = vvH || layout.height;\n // 浏览器窗口即最外层裁剪;容器滚动时 surface 的 rect 也会跟着变,因此一次 rect 读数就够\n return { top: Math.max(0, viewTop - rect.top), bottom: Math.min(layout.height, viewTop + viewH - rect.top) };\n }\n\n /** 按当前可视区决定画布窗口位置。返回是否挪了窗口。 */\n private placeWindow(layout: DocLayout, force: boolean): boolean {\n const vis = this.visibleRange(layout);\n const viewH = Math.max(1, vis.bottom - vis.top);\n const margin = VIEWPORT_MARGIN / Math.max(1, Math.min(MAX_ZOOM_SHARPNESS, window.visualViewport?.scale ?? 1));\n const wantH = Math.ceil(viewH + margin * 2);\n // 整篇都装得下:窗口就是整篇,位置固定为 0。短文档(业务里常见的几行输入框)必须走这条,\n // 否则残留的 winTop / winH 会让画布盖不住首行、或超出 surface 底部把容器撑出滚动条。\n if (wantH >= layout.height) {\n const changed = this.winTop !== 0 || this.winH !== layout.height;\n this.winTop = 0;\n this.winH = layout.height;\n return changed;\n }\n const maxTop = Math.max(0, layout.height - wantH);\n // 现有窗口仍然合法(没超出文档底部)且盖住了可视区,就不动\n const legal = this.winTop >= 0 && this.winTop <= maxTop && this.winTop + this.winH <= layout.height;\n const covers = vis.top >= this.winTop && vis.bottom <= this.winTop + this.winH;\n if (!force && legal && covers && this.winH >= wantH) return false;\n this.winTop = Math.min(maxTop, Math.max(0, Math.floor(vis.top - margin)));\n this.winH = wantH;\n return true;\n }\n\n /** 滚动/窗口尺寸变化:可视区离开画布窗口时挪窗口并整体重画 */\n private followViewport() {\n const layout = this.layout;\n if (!layout || !this.canvas) return;\n const scaleChanged = this.pixelScale() !== this.lastScale;\n if (!this.placeWindow(layout, scaleChanged) && !scaleChanged) return;\n this.resize(layout);\n this.redrawContent({ top: this.winTop, bottom: this.winTop + this.winH });\n this.redrawChrome();\n }\n\n private resize(layout: DocLayout): boolean {\n if (!this.surface || !this.canvas || !this.chrome || !this.ctx || !this.chromeCtx) return false;\n this.surface.style.width = `${layout.width}px`;\n this.surface.style.height = `${layout.height}px`;\n const moved = this.placeWindow(layout, false);\n const dpr = this.pixelScale();\n this.lastScale = dpr;\n const fullW = layout.width + CANVAS_GUTTER * 2;\n const w = Math.max(1, Math.round(fullW * dpr));\n const h = Math.max(1, Math.round(this.winH * dpr));\n const resized = this.canvas.width !== w || this.canvas.height !== h;\n if (resized) {\n for (const node of [this.canvas, this.chrome]) {\n node.width = w;\n node.height = h;\n node.style.width = `${fullW}px`;\n node.style.height = `${this.winH}px`;\n node.style.position = 'absolute';\n node.style.left = `${-CANVAS_GUTTER}px`;\n }\n }\n const topCss = `${this.winTop}px`;\n if (this.canvas.style.top !== topCss) {\n this.canvas.style.top = topCss;\n this.chrome.style.top = topCss;\n }\n // 绘制坐标仍是文档坐标:平移抵消窗口顶部\n this.ctx.setTransform(dpr, 0, 0, dpr, CANVAS_GUTTER * dpr, -this.winTop * dpr);\n this.chromeCtx.setTransform(dpr, 0, 0, dpr, CANVAS_GUTTER * dpr, -this.winTop * dpr);\n return resized || moved;\n }\n\n private redrawContent(band: { top: number; bottom: number }) {\n const ctx = this.ctx;\n const layout = this.layout;\n if (!ctx || !layout || !this.canvas) return;\n\n // 只画落在画布窗口里的那一段;窗口外的滚进来时由 followViewport 补画\n const top = Math.max(0, band.top, this.winTop);\n const bottom = Math.min(band.bottom, this.winTop + this.winH);\n if (top >= bottom) {\n this.hasContent = true;\n return;\n }\n const hits = (y: number, h: number) => y < bottom && y + h > top;\n ctx.save();\n ctx.beginPath();\n ctx.rect(-CANVAS_GUTTER, top, layout.width + CANVAS_GUTTER * 2, bottom - top);\n ctx.clip();\n const editorRoot = this.host?.closest('.mini-editor') as HTMLElement | null;\n // 文字画布始终透明:选区画在它下面,白底由 .mini-surface 的背景提供。\n ctx.clearRect(-CANVAS_GUTTER, top, layout.width + CANVAS_GUTTER * 2, bottom - top);\n\n ctx.strokeStyle = '#c9cdd4';\n ctx.lineWidth = 1;\n for (const table of layout.tables) {\n if (!hits(table.y, table.h)) continue;\n for (const cell of table.cells) {\n ctx.strokeRect(cell.x + 0.5, cell.y + 0.5, cell.w - 1, cell.h - 1);\n }\n }\n\n for (const line of layout.lines) {\n if (!hits(line.y, line.h)) continue;\n if (line.marker) {\n ctx.save();\n const family =\n (editorRoot ? getComputedStyle(editorRoot).fontFamily : '') || FONT_FAMILY;\n ctx.font = `400 16px ${family}`;\n ctx.fillStyle = '#667085';\n ctx.textAlign = 'right';\n ctx.textBaseline = 'top';\n const markerTop = line.marker.y + (line.marker.h - 16) / 2;\n ctx.fillText(line.marker.text, line.marker.x + line.marker.w - 8, markerTop);\n ctx.restore();\n }\n for (const vb of line.vblocks ?? []) this.paintVBlock(ctx, vb);\n for (const g of line.glyphs) this.paintGlyph(ctx, g);\n this.paintLineDeco(ctx, line.glyphs);\n for (const img of line.images) {\n embedPlugin(img.entity.kind).paintCanvasBackdrop(ctx, img, (src) => this.imageOf(src));\n }\n }\n for (const img of layout.images) {\n if (!img.entity.float || !hits(img.y, img.h)) continue;\n embedPlugin(img.entity.kind).paintCanvasBackdrop(ctx, img, (src) => this.imageOf(src));\n }\n ctx.restore();\n this.hasContent = true;\n }\n\n private redrawChrome() {\n const ctx = this.chromeCtx;\n const layout = this.layout;\n if (!ctx || !layout || !this.chrome) return;\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, this.chrome.width, this.chrome.height);\n ctx.restore();\n\n for (const r of this.selRects) {\n if (r.outline) this.strokeVBlockOutline(ctx, r);\n else this.fillSelectionRect(ctx, r);\n }\n\n for (const [i, t] of this.caretTrails.entries()) {\n this.drawCaret(ctx, t, 0.22 - i * 0.06);\n }\n if (this.caret && this.caretVisible) this.drawCaret(ctx, this.caret, this.caret.opacity ?? 1);\n }\n\n private fillSelectionRect(\n ctx: CanvasRenderingContext2D,\n r: { x: number; y: number; w: number; h: number }\n ) {\n const editorRoot = this.host?.closest('.mini-editor') as HTMLElement | null;\n const cs = editorRoot ? getComputedStyle(editorRoot) : null;\n const color = cs?.getPropertyValue('--mini-sel-color').trim() ?? '';\n const radius = cs ? parseFloat(cs.getPropertyValue('--mini-sel-radius')) || 0 : 0;\n const rainbow = editorRoot?.getAttribute('data-caret') === 'rainbow' && !color;\n ctx.beginPath();\n ctx.roundRect(r.x, r.y, r.w, r.h, radius);\n if (rainbow) {\n const grad = ctx.createLinearGradient(r.x, r.y, r.x + r.w, r.y);\n grad.addColorStop(0, 'rgba(255, 77, 109, 0.16)');\n grad.addColorStop(1, 'rgba(43, 108, 255, 0.22)');\n ctx.fillStyle = grad;\n } else {\n ctx.fillStyle = color || 'rgba(43, 108, 255, 0.22)';\n }\n ctx.fill();\n }\n\n private paintVBlock(\n ctx: CanvasRenderingContext2D,\n vb: { id: string; first: boolean; last: boolean; x: number; y: number; w: number; h: number; chrome: { background?: string; hoverBackground?: string; borderColor?: string; borderWidth?: number; radius?: number }; kind: string }\n ) {\n const c = vb.chrome;\n const fill = vb.id === this.hoverId && c.hoverBackground ? c.hoverBackground : c.background;\n const base = c.radius ?? (vb.kind === 'virtualSlot' ? 4 : vb.kind === 'mark' ? 3 : 6);\n // 首行上两角圆、末行下两角圆,其余角方;单行自然四角全圆。\n const top = vb.first ? base : 0;\n const bottom = vb.last ? base : 0;\n const radius: number[] = [top, top, bottom, bottom];\n if (fill) {\n ctx.beginPath();\n ctx.roundRect(vb.x, vb.y, vb.w, vb.h, radius);\n ctx.fillStyle = fill;\n ctx.fill();\n }\n if (c.borderWidth && c.borderColor) {\n ctx.beginPath();\n ctx.roundRect(vb.x + 0.5, vb.y + 0.5, Math.max(0, vb.w - 1), Math.max(0, vb.h - 1), radius);\n ctx.strokeStyle = c.borderColor;\n ctx.lineWidth = c.borderWidth;\n ctx.stroke();\n }\n }\n\n private strokeVBlockOutline(\n ctx: CanvasRenderingContext2D,\n r: { x: number; y: number; w: number; h: number; radius?: number }\n ) {\n const radius = r.radius ?? 6;\n ctx.beginPath();\n ctx.roundRect(r.x + 0.5, r.y + 0.5, Math.max(0, r.w - 1), Math.max(0, r.h - 1), radius);\n ctx.strokeStyle = '#2b6cff';\n ctx.lineWidth = 2;\n ctx.stroke();\n }\n\n private drawCaret(ctx: CanvasRenderingContext2D, caret: CaretPos, alpha: number) {\n const { x, y, h } = caret;\n const editorRoot = this.host?.closest('.mini-editor') as HTMLElement | null;\n const solid = editorRoot?.getAttribute('data-caret') !== 'rainbow';\n const caretW = editorRoot\n ? parseFloat(getComputedStyle(editorRoot).getPropertyValue('--mini-caret-width')) || 2\n : 2;\n const w = solid ? caretW : caret.bold ? 4.5 : 3;\n ctx.save();\n ctx.globalAlpha = Math.max(0, alpha);\n if (!solid && caret.italic) {\n ctx.translate(x, y + h);\n ctx.transform(1, 0, -0.25, 1, 0, 0);\n ctx.translate(-x, -(y + h));\n }\n const editorCs = editorRoot ? getComputedStyle(editorRoot) : null;\n if (solid) {\n ctx.fillStyle = editorCs?.getPropertyValue('--mini-caret-color').trim() || '#09090b';\n const glow = editorCs?.getPropertyValue('--mini-caret-glow').trim() ?? '';\n if (glow && glow !== 'none') {\n ctx.shadowColor = glow;\n ctx.shadowBlur = 6;\n }\n } else {\n const grad = ctx.createLinearGradient(x, y, x, y + h);\n grad.addColorStop(0, '#ff4d6d');\n grad.addColorStop(0.35, '#ffd166');\n grad.addColorStop(0.65, '#06d6a0');\n grad.addColorStop(1, '#4cc9f0');\n ctx.fillStyle = grad;\n }\n ctx.fillRect(x, y, w, h);\n ctx.restore();\n }\n\n private paintGlyph(ctx: CanvasRenderingContext2D, g: GlyphBox) {\n const size = g.style.fontSize ?? 16;\n ctx.font = canvasFont(g.style);\n ctx.fillStyle = canvasFill(g.style, g.index);\n ctx.textAlign = 'left';\n ctx.textBaseline = 'alphabetic';\n const metrics = ctx.measureText(g.text || '汉');\n const ascent = metrics.fontBoundingBoxAscent || size * 0.8;\n const descent = metrics.fontBoundingBoxDescent || size * 0.2;\n const fontH = ascent + descent;\n const boxTop = g.y + (g.h - fontH) / 2;\n const baseline = boxTop + ascent;\n ctx.fillText(g.text, g.x, baseline);\n }\n\n private paintLineDeco(ctx: CanvasRenderingContext2D, glyphs: GlyphBox[]) {\n for (const run of groupDecorationRuns(glyphs)) {\n const size = run.size;\n if (run.kind !== 'none') paintCanvasUnderline(ctx, run.x, run.y + Math.max(1, size * 0.06), run.w, size, run.kind, run.color);\n if (run.strike) paintCanvasStrike(ctx, run.x, run.y - size * 0.35, run.w, size, run.color);\n }\n }\n\n private imageOf(src: string): HTMLImageElement {\n let img = this.imageCache.get(src);\n if (img) return img;\n img = new Image();\n img.onload = () => {\n // 图片是异步到的,不知道它落在哪一段,整份重画\n if (this.layout) this.redrawContent({ top: 0, bottom: this.layout.height });\n };\n img.src = src;\n this.imageCache.set(src, img);\n return img;\n }\n}\n","import { underlineKind } from '../model/types';\nimport { syncEmbedLayer } from '../embed';\nimport { CaretPos, DocLayout, LineBox, SelRect, TableLayout, VBlockFragment } from '../layout/types';\nimport { cssFill, fillOf } from './decorations';\nimport { PaintBackend } from './types';\n\nfunction cssText(style: LineBox['glyphs'][0]['style'], runW: number): string {\n const size = style.fontSize ?? 16;\n const weight = style.bold ? '700' : String(style.fontWeight ?? 400);\n const italic = style.italic ? 'italic' : 'normal';\n const color = style.color ?? '#1f2329';\n const fill = cssFill(style, runW);\n return `font-style:${italic};font-weight:${weight};font-size:${size}px;font-family:var(--mini-font-family);color:${color};text-decoration:none;${fill}`;\n}\n\nexport class HtmlPainter implements PaintBackend {\n private host: HTMLElement | null = null;\n private surface: HTMLElement | null = null;\n private content: HTMLElement | null = null;\n private selection: HTMLElement | null = null;\n private caret: HTMLElement | null = null;\n private trails: HTMLElement[] = [];\n private embeds: HTMLElement | null = null;\n private embedCache = new Map<string, HTMLElement>();\n private hoverId: string | null = null;\n\n mount(host: HTMLElement) {\n this.destroy();\n this.host = host;\n this.surface = document.createElement('div');\n this.surface.className = 'mini-surface';\n this.selection = document.createElement('div');\n this.selection.className = 'mini-layer mini-selection';\n this.content = document.createElement('div');\n this.content.className = 'mini-layer mini-content';\n this.caret = document.createElement('div');\n this.caret.className = 'mini-caret';\n this.embeds = document.createElement('div');\n this.embeds.className = 'mini-layer mini-embeds';\n this.trails = [0, 1, 2].map(() => {\n const el = document.createElement('div');\n el.className = 'mini-caret mini-caret-trail';\n el.style.display = 'none';\n return el;\n });\n this.surface.append(this.selection, this.content, this.embeds, ...this.trails, this.caret);\n host.appendChild(this.surface);\n }\n\n getSurface(): HTMLElement {\n if (!this.surface) throw new Error('painter not mounted');\n return this.surface;\n }\n\n paintDoc(layout: DocLayout) {\n if (!this.surface || !this.content) return;\n this.surface.style.width = `${layout.width}px`;\n this.surface.style.height = `${layout.height}px`;\n // 只重建和脏区带相交的元素。元素都是绝对定位的,没动过的留在原地即可 ——\n // 连 DOM 顺序都不用管。\n const { top, bottom } = layout.dirty;\n // 空的、或者脏区带盖住了整页,就整块换掉:比逐个摘掉再补回来省事。\n // 脏区 {top:0,bottom:0} 表示「几何相对上一帧没变」,此处跳过子节点更新。\n // 调用方若整篇换了文档却仍传入空脏区,正文 DOM 会陈旧(见 Editor.setContent)。\n const full = !this.content.childElementCount || (top <= 0 && bottom >= layout.height);\n const hits = (y: number, h: number) => full || (y < bottom && y + h > top);\n\n if (full) {\n this.content.replaceChildren();\n } else {\n // 脏区带为空时 hits() 处处为假,下面几个循环自然什么都不做\n for (const child of [...this.content.children]) {\n const el = child as HTMLElement;\n if (hits(Number(el.dataset.y ?? 0), Number(el.dataset.h ?? 0))) el.remove();\n }\n }\n\n for (const table of layout.tables) {\n if (hits(table.y, table.h)) this.content.appendChild(renderTableChrome(table));\n }\n for (const line of layout.lines) {\n if (hits(line.y, line.h)) this.content.appendChild(renderLine(line));\n }\n // 嵌入对象是独立图层,自己按 id 做增删改,不受脏区带影响\n if (this.embeds) syncEmbedLayer(this.embeds, this.embedCache, layout.images, false);\n if (this.hoverId) this.applyHover();\n }\n\n setHoverBlock(id: string | null) {\n if (id === this.hoverId) return;\n this.hoverId = id;\n this.applyHover();\n }\n\n private applyHover() {\n if (!this.content) return;\n for (const node of this.content.querySelectorAll<HTMLElement>('.mini-vblock[data-hover-bg]')) {\n const on = node.dataset.id === this.hoverId;\n node.style.background = on ? node.dataset.hoverBg! : node.dataset.bg ?? 'transparent';\n }\n }\n\n paintSelection(rects: SelRect[]) {\n if (!this.selection) return;\n this.selection.replaceChildren();\n for (const r of rects) {\n const el = document.createElement('div');\n el.className = r.outline ? 'mini-vblock-outline' : 'mini-sel-rect';\n const radius = r.radius ?? 0;\n el.style.cssText = `left:${r.x}px;top:${r.y}px;width:${r.w}px;height:${r.h}px;${radius ? `border-radius:${radius}px;` : ''}`;\n this.selection.appendChild(el);\n }\n }\n\n paintCaret(caret: CaretPos | null, visible: boolean, trails: CaretPos[] = []) {\n if (!this.caret) return;\n placeCaret(this.caret, visible ? caret : null, 1);\n this.trails.forEach((el, i) => placeCaret(el, trails[i] ?? null, 0.28 - i * 0.08));\n }\n\n destroy() {\n this.surface?.remove();\n this.host = null;\n this.surface = null;\n this.content = null;\n this.selection = null;\n this.caret = null;\n this.trails = [];\n this.embeds = null;\n this.embedCache.clear();\n }\n}\n\nfunction placeCaret(el: HTMLElement, caret: CaretPos | null, fade: number) {\n if (!caret) {\n if (el.style.display !== 'none') el.style.display = 'none';\n return;\n }\n const width = caret.bold ? 4.5 : '';\n if (el.style.display !== 'block') el.style.display = 'block';\n // 光标移动时重启 CSS 闪烁动画,让它每次移动后都先亮(原生光标的表现)。\n // 不用 `void el.offsetWidth` 强制回流:长文档里一次回流要几十毫秒,而这里每帧都会跑。\n if (el.style.left !== `${caret.x}px` || el.style.top !== `${caret.y}px`) {\n for (const anim of el.getAnimations()) anim.currentTime = 0;\n }\n el.style.left = `${caret.x}px`;\n el.style.top = `${caret.y}px`;\n el.style.height = `${caret.h}px`;\n el.style.width = width === '' ? '' : `${width}px`;\n if (caret.opacity != null) el.style.opacity = String(caret.opacity * fade);\n else if (el.style.opacity) el.style.opacity = '';\n el.style.transform = caret.italic ? 'skewX(-14deg)' : 'none';\n el.classList.toggle('is-italic', !!caret.italic);\n}\n\nfunction renderLine(line: LineBox): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'mini-line';\n wrap.dataset.start = String(line.start);\n wrap.dataset.end = String(line.end);\n wrap.dataset.y = String(line.y);\n wrap.dataset.h = String(line.h);\n\n for (const vb of line.vblocks ?? []) {\n wrap.appendChild(renderVBlock(vb));\n }\n\n if (line.marker) {\n const m = document.createElement('span');\n m.className = 'mini-list-marker';\n m.textContent = line.marker.text;\n m.style.cssText = `left:${line.marker.x}px;top:${line.marker.y}px;width:${line.marker.w}px;height:${line.marker.h}px;`;\n wrap.appendChild(m);\n }\n\n if (line.glyphs.length > 0) {\n let run: { start: number; text: string; style: LineBox['glyphs'][0]['style']; x: number; y: number; h: number; w: number } | null = null;\n const flush = () => {\n if (!run) return;\n const span = document.createElement('span');\n span.className = `mini-run${fillOf(run.style) !== 'solid' ? ' is-fill' : ''}`;\n span.textContent = run.text;\n span.style.cssText = `left:${run.x}px;top:${run.y}px;width:${run.w}px;height:${run.h}px;line-height:${run.h}px;${cssText(run.style, run.w)}`;\n wrap.appendChild(span);\n const deco = underlineKind(run.style);\n if (deco !== 'none' || run.style.strikethrough) {\n const bar = document.createElement('span');\n bar.className = `mini-deco mini-deco-${deco}${run.style.strikethrough ? ' is-strike' : ''}`;\n bar.style.cssText = `left:${run.x}px;top:${run.y}px;width:${run.w}px;height:${run.h}px;color:${run.style.color ?? '#1f2329'};`;\n wrap.appendChild(bar);\n }\n run = null;\n };\n for (const g of line.glyphs) {\n if (\n run &&\n run.style.bold === g.style.bold &&\n run.style.italic === g.style.italic &&\n run.style.underline === g.style.underline &&\n run.style.underlineStyle === g.style.underlineStyle &&\n run.style.strikethrough === g.style.strikethrough &&\n run.style.fontSize === g.style.fontSize &&\n run.style.color === g.style.color &&\n run.style.fill === g.style.fill &&\n run.start + run.text.length === g.index\n ) {\n run.text += g.text;\n run.w += g.w;\n } else {\n flush();\n run = { start: g.index, text: g.text, style: g.style, x: g.x, y: g.y, h: g.h, w: g.w };\n }\n }\n flush();\n }\n\n return wrap;\n}\n\nfunction renderVBlock(vb: VBlockFragment): HTMLElement {\n const el = document.createElement('span');\n el.className = 'mini-vblock';\n el.dataset.id = vb.id;\n const c = vb.chrome;\n if (c.hoverBackground) {\n el.dataset.hoverBg = c.hoverBackground;\n el.dataset.bg = c.background ?? 'transparent';\n }\n const base = c.radius ?? (vb.kind === 'virtualSlot' ? 4 : vb.kind === 'mark' ? 3 : 6);\n // 首行上两角圆、末行下两角圆,其余角方;单行自然四角全圆。\n const top = vb.first ? base : 0;\n const bottom = vb.last ? base : 0;\n const radius = `${top}px ${top}px ${bottom}px ${bottom}px`;\n const border = c.borderWidth\n ? `${c.borderWidth}px solid ${c.borderColor ?? 'transparent'}`\n : 'none';\n el.style.cssText = [\n `left:${vb.x}px`,\n `top:${vb.y}px`,\n `width:${vb.w}px`,\n `height:${vb.h}px`,\n `background:${c.background ?? 'transparent'}`,\n `border:${border}`,\n `border-radius:${radius}`\n ].join(';');\n return el;\n}\n\nfunction renderTableChrome(table: TableLayout): HTMLElement {\n const box = document.createElement('div');\n box.className = 'mini-table';\n box.dataset.y = String(table.y);\n box.dataset.h = String(table.h);\n box.style.cssText = `left:${table.x}px;top:${table.y}px;width:${table.w}px;height:${table.h}px;`;\n for (const cell of table.cells) {\n const c = document.createElement('div');\n c.className = 'mini-cell';\n c.style.cssText = `left:${cell.x - table.x}px;top:${cell.y - table.y}px;width:${cell.w}px;height:${cell.h}px;`;\n box.appendChild(c);\n }\n return box;\n}\n","import { activateHostEmbed, builtinEmbedPlugins, decorateRefEl, defaultSlotLabel, EMBED_CHANGE, EMBED_COMMIT, EMBED_EXIT_EDIT, EMBED_MEASURE, EmbedChangeDetail, EmbedExitDetail, EmbedMeasureDetail, embedPlugin, hostEmbedPlugin, HostEmbedRenderer, measureRef, REF_HEAD, REF_JUMP, REF_PAD, refInnerWidth, registerEmbed, setHostEmbedRenderer, syncHostSelected } from './embed';\nimport { EmbedPlugin } from './embed/types';\nimport { RefJumpDetail } from './embed/ref';\nimport type { Shortcut } from './commands';\nimport { ArrowKey, CommandTable } from './commands';\nimport { EditKind, EditResult, runEdit, runScoped, UndoRedoStack } from './edits';\nimport { ImeSurface } from './input/ime';\nimport { bindKeyboard } from './input/keyboard';\nimport { caretFromIndex, hitColBorder, hitTestIndex, imageBoxAt, layoutDocument, resolvedTextStyle, selectionRects } from './layout/engine';\nimport { lineHeightOf, measureWidth, MIN_COL_WIDTH, PAGE_CONTENT_WIDTH, PAGE_PADDING_X, PAGE_PADDING_Y } from './layout/measure';\nimport { CaretPos, DocLayout, ImageBox, LineBox } from './layout/types';\nimport { PerfProbe } from './perf';\nimport { maxCaretIndex, MoveUnit, paragraphTarget, wordRangeAt, wordTarget } from './input/caretMotion';\nimport { SLICE_MIME, serializeSlice, sliceFromClipboard } from './convert/clipboard';\nimport { collapsedSel, DocumentModel, documentFromSlice, nextEntityId, sliceWithoutParagraphGroup } from './model/document';\nimport { cellAt, cellContentRange, findTableAt, isLastTableCell, isVisuallyEmptyDoc, nearestSafeIndex, nextCellIndex, parseBlocks } from './model/blocks';\nimport { applyMutations } from './mutations';\nimport * as ops from './operations';\nimport type { ImagePatch, Operation, OperationContext, VirtualBlockSpec } from './operations';\nimport { shouldTryMarkdown } from './convert/markdown';\nimport { MARKERS, nextCodePointLen, prevCodePointLen } from './model/markers';\nimport { cloneEntity, EmbedEntity, isCollapsed, MAX_LIST_INDENT, ParagraphProps, selEnd, selStart, Selection, Slice, SlotKind, TextProps, underlineKind, VIDEO_ASPECT, VirtualBlock, VirtualBlockChrome } from './model/types';\nimport { CanvasPainter } from './paint/canvasPainter';\nimport { HtmlPainter } from './paint/htmlPainter';\nimport { PaintBackend } from './paint/types';\n\nexport interface EditorOptions {\n /** 初始文档。不传则新建一个空文档。 */\n doc?: DocumentModel;\n /** 初始绘制后端,默认 `html`。 */\n paint?: 'html' | 'canvas';\n /**\n * 嵌入对象插件集,默认 {@link builtinEmbedPlugins}(图片/视频/代码块/插槽/同步块)。\n * 公式需从 `medeo-rte/formula` 单独引入后追加。\n */\n plugins?: EmbedPlugin[];\n /**\n * 内容宽度策略,默认 `'fill'`。\n * - `'fill'`:撑满宿主容器,并随容器尺寸变化自动重排(编辑器适应容器)。\n * - `number`:固定像素内容宽,行为与容器尺寸无关(适合需要确定版心的场景)。\n */\n width?: 'fill' | number;\n /**\n * 内容版心内边距(像素),默认 `{ x: 72, y: 56 }`(纸张/文档形态的版心留白)。\n * 决定内容行相对绘制表面的起始偏移与四周留白。嵌入式输入框等紧凑形态可传\n * `{ x: 0, y: 0 }`,把留白完全交给宿主 CSS 控制。\n */\n padding?: { x: number; y: number };\n /**\n * 宿主渲染器。提供后即启用 host 型嵌入对象:节点内部 DOM 由宿主用自己的框架\n * 组件渲染,SDK 只管占位、定位与生命周期。用于把业务卡片(如引用对象、插槽)\n * 挂进编辑器而不由 SDK 自绘。见 {@link HostEmbedRenderer}。\n */\n hostEmbed?: HostEmbedRenderer;\n /**\n * 空文档占位文案。由 SDK 画在首行位置,组合输入一开始就关掉(中间态已镜像进模型,\n * 宿主若只看 `change` 会误判仍为空)。之后可用 {@link Editor.setPlaceholder} 改。\n */\n placeholder?: string;\n /**\n * 未写 text span 时的默认文字属性。嵌入式输入框可传 14px 对齐业务输入。\n * `fontFamily` 须具名栈(不要 `system-ui`),会同时用于 pretext 测宽与绘制。\n * 不传则仍是文档编辑器默认 16px / `#1f2329` / 中文无衬线栈。\n */\n textDefaults?: TextProps;\n /**\n * 快捷键表。默认 {@link SHORTCUTS}(文档编辑:Enter 插段、Cmd+B 加粗等)。\n * 嵌入式输入框请传 {@link inputShortcuts}(默认 newline:Enter 换行)。\n */\n shortcuts?: Shortcut[];\n /**\n * 创建完成后是否把焦点放到 IME。默认 `true`(独立编辑器 / demo)。\n * 嵌入式输入框(如页面上的 Command Box)应传 `false`,避免抢走页面焦点。\n */\n autofocus?: boolean;\n /**\n * 光标 / 选区 / 空态占位的外观。不传则与常规编辑器一致:实心光标、扁平选区、无残影。\n * 彩虹光标 / 残影需显式 `caret: 'rainbow'`。\n */\n chrome?: EditorChrome;\n}\n\n/** 编辑器装饰外观(光标、选区、空态占位)。与正文字号/字体测量分开,避免宿主 CSS 盖绘制层。 */\nexport interface EditorChrome {\n /** 默认 `solid`。演示能力用 `rainbow`。 */\n caret?: 'rainbow' | 'solid';\n /** `solid` 时光标颜色,默认 `#09090b`。 */\n caretColor?: string;\n /** `solid` 时光标宽度,默认 2。 */\n caretWidth?: number;\n /** 是否画光标残影。默认关闭;`rainbow` 时可打开。 */\n caretTrail?: boolean;\n /**\n * 选区高亮色。默认接近浏览器原生选区:`rgba(43, 108, 255, 0.22)`。\n * 扁平填充,不再用彩虹渐变。`caret: 'rainbow'` 且未指定本项时,demo 仍用渐变选区。\n */\n selectionColor?: string;\n /** 选区圆角,像素。默认 0(和 `::selection` 一样是矩形)。 */\n selectionRadius?: number;\n /** 中文输入中间态下划线颜色。默认 `#1f2329`。 */\n composeUnderlineColor?: string;\n /** 中文输入中间态下划线粗细,默认 2。 */\n composeUnderlineWidth?: number;\n /** 空态占位颜色。 */\n placeholderColor?: string;\n /** 空态占位透明度 0–1。现网 Chat 为 0.2。 */\n placeholderOpacity?: number;\n /**\n * 绘制表面底色。默认纸张白(`var(--page)`)。\n * 嵌入式输入框应传 `transparent`,露出宿主输入框底,不要再铺一层白/灰。\n */\n surfaceBackground?: 'paper' | 'transparent';\n}\n\n/** 插入嵌入对象的落点:文档下标,或起/止/当前光标。 */\nexport type EmbedInsertAt = number | 'start' | 'end' | 'cursor';\n\n/** 编辑器当前状态,供宿主同步工具栏、状态栏等 UI。 */\nexport interface EditorState {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n fontSize: number;\n color: string;\n heading: 0 | 1 | 2 | 3;\n align: 'left' | 'center' | 'right';\n list: 'none' | 'ul' | 'ol';\n inTable: boolean;\n canUndo: boolean;\n canRedo: boolean;\n paintMode: 'html' | 'canvas';\n hasLink: boolean;\n canPromote: boolean;\n canInsertRef: boolean;\n canUnlink: boolean;\n /** 主文档选区 */\n selection: Selection;\n /** 主文档长度(spacer 数) */\n docLength: number;\n /** 是否正在同步块内部编辑 */\n inRefEdit: boolean;\n /** 同步块内部选区,仅 inRefEdit 为真时有意义 */\n refSelection: Selection;\n /** 虚拟块作用域栈,栈顶是当前选中/编辑的那一层 */\n vblockStack: { id: string; mode: 'selected' | 'editing' }[];\n}\n\n/**\n * - `change`:文档内容变化\n * - `selectionchange`:选区或光标移动\n * - `statechange`:{@link EditorState} 任一字段可能已变,用于同步工具栏\n * - `layoutchange`:重新排版完成,可从 {@link Editor.getLayout} 取新几何\n */\nexport type EditorEvent = 'change' | 'selectionchange' | 'statechange' | 'layoutchange';\n\nexport class Editor {\n /** 编辑器根节点,已挂载到构造时传入的容器下。 */\n readonly root: HTMLElement;\n /** 编辑命令集合,宿主自建工具栏时用。 */\n readonly commands: CommandTable;\n /** 开发用性能探针:`editor.perf.start()` … `editor.perf.report()`。默认关闭,零开销 */\n readonly perf: PerfProbe;\n /** 构造时传入的宿主容器。'fill' 模式下从它测量可用宽度。 */\n private parent: HTMLElement;\n /** 内容宽度策略,见 {@link EditorOptions.width}。 */\n private widthMode: 'fill' | number = 'fill';\n /** 内容版心内边距,见 {@link EditorOptions.padding}。所有主文档排版据此定位。 */\n private padding: { x: number; y: number } = { x: PAGE_PADDING_X, y: PAGE_PADDING_Y };\n /** 当前内容宽度(单一真相来源),所有主文档排版都读它。 */\n private contentWidth: number = PAGE_CONTENT_WIDTH;\n /** 'fill' 模式下监听宿主尺寸变化以重排;其它模式为 null。 */\n private resizeObserver: ResizeObserver | null = null;\n private page: HTMLElement;\n private pageInner: HTMLElement;\n private handle: HTMLElement;\n private embedFrame: HTMLElement;\n private imeBar: HTMLElement;\n private placeholderEl: HTMLElement;\n private placeholderText = '';\n private shortcutTable: Shortcut[] | undefined;\n private textDefaults: TextProps | null = null;\n /** 挂载后由 getComputedStyle 解析出的字体栈,专供测宽(canvas 读不懂 var())。 */\n private resolvedMeasureFamily: string | null = null;\n private chrome: EditorChrome = {};\n private disabled = false;\n private paintMode: 'html' | 'canvas' = 'html';\n private listeners: { [K in EditorEvent]: Set<() => void> } = {\n change: new Set(),\n selectionchange: new Set(),\n statechange: new Set(),\n layoutchange: new Set()\n };\n private doc: DocumentModel;\n private sel: Selection = collapsedSel(0);\n private undoStack = new UndoRedoStack();\n private layout: DocLayout;\n private painter: PaintBackend;\n private ime: ImeSurface;\n private typingStyle: TextProps | null = null;\n private keepTypingOnNextClick = false;\n private caretRaf = 0;\n private caretTrails: CaretPos[] = [];\n private lastCaretKey = '';\n /** 光标闪烁相位起点:每次光标移动/重置都从“亮”重新开始,和原生光标一致。 */\n private blinkEpoch = 0;\n private blinkPosKey = '';\n private composeText = '';\n /** 组合串镜像插入模型的起点;null 表示当前没有进行中的组合。 */\n private composeAnchor: number | null = null;\n /** 当前已镜像插入模型的组合串长度,用于下次幂等替换时删旧。 */\n private composeLen = 0;\n private refEdit: { entityId: string; fragmentId: string } | null = null;\n private fragSel: Selection = collapsedSel(0);\n private refDragging = false;\n private refDragAnchor = 0;\n private unbindKeyboard: (() => void) | null = null;\n private keysArmed = true;\n private dragging = false;\n private resizing: { id: string; startX: number; startW: number; startH: number } | null = null;\n private colResizing: { tableStart: number; col: number; startX: number; widths: number[] } | null = null;\n private embedEdit: { id: string; before: EmbedEntity } | null = null;\n private dragAnchor: number = 0;\n private vblockStack: { id: string; mode: 'selected' | 'editing' }[] = [];\n\n constructor(parent: HTMLElement, options: EditorOptions = {}) {\n for (const plugin of options.plugins ?? builtinEmbedPlugins) registerEmbed(plugin);\n // 提供了宿主渲染器才启用 host 型嵌入对象:注册插件并注入渲染器。\n if (options.hostEmbed) {\n registerEmbed(hostEmbedPlugin);\n setHostEmbedRenderer(options.hostEmbed);\n }\n\n this.parent = parent;\n this.widthMode = options.width ?? 'fill';\n this.padding = options.padding ?? { x: PAGE_PADDING_X, y: PAGE_PADDING_Y };\n this.shortcutTable = options.shortcuts;\n this.textDefaults = options.textDefaults ?? null;\n this.chrome = options.chrome ?? {};\n this.doc = options.doc ?? new DocumentModel();\n this.applyTextDefaults(this.doc);\n this.sel = collapsedSel(this.doc.length - 1);\n this.paintMode = options.paint ?? 'html';\n this.painter = this.createPainter();\n this.perf = new PerfProbe(this, () => this.painter);\n // 此刻尚未挂载到容器,'fill' 模式测不到宽度会回退默认值;挂载后 relayout() 修正。\n this.contentWidth = this.resolveContentWidth();\n this.layout = layoutDocument(this.doc, this.contentWidth, undefined, this.padding);\n\n this.root = document.createElement('div');\n this.root.className = 'mini-editor';\n this.root.dataset.paint = this.paintMode;\n this.applyChrome();\n this.commands = {\n toggleBold: () => this.toggleText('bold'),\n toggleItalic: () => this.toggleText('italic'),\n toggleUnderline: () => this.toggleText('underline'),\n toggleStrike: () => this.toggleText('strikethrough'),\n setFontSize: (size) => this.applyText({ fontSize: size }),\n setColor: (color) => this.applyText({ color }),\n setHeading: (level) => this.applyPara(level ? { heading: level, list: 'none' } : { heading: 0 }),\n setAlign: (align) => this.applyPara({ align }),\n toggleList: (kind) => this.toggleList(kind),\n indent: (delta) => this.changeIndent(delta),\n insertImage: (file) => this.insertMediaFile(file, 'image'),\n insertVideo: (file) => this.insertMediaFile(file, 'video'),\n insertCode: () => this.insertCodeBlock(),\n insertFormula: () => this.insertFormula(),\n insertSlot: (kind) => this.insertSlot(kind),\n insertHostEmbed: (hostType, data, size) => this.insertHostEmbed(hostType, data, size),\n insertTable: () => this.insertTable(),\n addRow: () => this.tableOp('row'),\n addCol: () => this.tableOp('col'),\n removeRow: () => this.tableOp('del-row'),\n removeCol: () => this.tableOp('del-col'),\n toggleLink: () => this.toggleLink(),\n promoteRef: () => this.promoteRef(),\n insertRef: () => this.insertExistingRef(),\n unlinkRef: () => this.unlinkSelectedRef(),\n undo: () => this.undo(),\n redo: () => this.redo(),\n insertParagraph: (opts) => this.insertParagraph(opts),\n backspace: () => this.backspace(),\n deleteForward: () => this.deleteForward(),\n selectAll: () => this.selectAll(),\n indentOrNextCell: (dir) => this.indentOrNextCell(dir),\n moveCaret: (key, extend) => this.moveCaret(key, extend),\n moveCaretBy: (unit, dir, extend) => this.moveCaretBy(unit, dir, extend),\n exitFragment: () => this.exitFragmentEdit()\n };\n\n this.page = document.createElement('div');\n this.page.className = 'mini-page-wrap';\n this.pageInner = document.createElement('div');\n this.pageInner.className = 'mini-page';\n this.painter.mount(this.pageInner);\n this.ime = new ImeSurface({\n onInsertText: (t) => this.insertText(t),\n onInsertParagraph: () => this.insertParagraph(),\n onBackspace: () => this.backspace(),\n onDeleteForward: () => this.deleteForward(),\n onPaste: (data) => this.pasteClipboard(data),\n onCompositionChange: (active, text) => this.handleComposition(active, text)\n });\n this.pageInner.appendChild(this.ime.el);\n\n this.handle = document.createElement('div');\n this.handle.className = 'mini-resize';\n this.embedFrame = document.createElement('div');\n this.embedFrame.className = 'mini-embed-frame';\n this.imeBar = document.createElement('div');\n this.imeBar.className = 'mini-ime-bar';\n this.placeholderText = options.placeholder ?? '';\n this.placeholderEl = document.createElement('div');\n this.placeholderEl.className = 'mini-placeholder';\n this.placeholderEl.hidden = true;\n this.placeholderEl.setAttribute('aria-hidden', 'true');\n this.pageInner.append(this.embedFrame, this.handle, this.imeBar, this.placeholderEl);\n\n this.page.appendChild(this.pageInner);\n this.root.append(this.page);\n parent.appendChild(this.root);\n\n this.bind();\n this.syncComputedFontForMeasure();\n this.relayout({ reuse: false });\n void document.fonts.ready.then(() => {\n if (!this.root.isConnected) return;\n this.syncComputedFontForMeasure();\n this.relayout({ reuse: false });\n });\n if (options.autofocus !== false) this.ime.focus();\n this.resetBlink();\n }\n\n setPaintMode(mode: 'html' | 'canvas') {\n if (mode === this.paintMode) return;\n this.unbindSurface();\n this.painter.destroy();\n this.paintMode = mode;\n this.painter = this.createPainter();\n this.painter.mount(this.pageInner);\n this.pageInner.append(this.ime.el, this.embedFrame, this.handle, this.imeBar);\n this.bindSurface();\n this.root.dataset.paint = mode;\n this.pageInner.classList.remove('is-flipping');\n void this.pageInner.offsetWidth;\n this.pageInner.classList.add('is-flipping');\n this.relayout();\n this.ime.focus();\n }\n\n // ---- 公共 API ----------------------------------------------------------\n\n /** 滚动容器。宿主要做小地图、滚动联动时用。 */\n get scroller(): HTMLElement {\n return this.page;\n }\n\n /**\n * 页面元素(内容画布所在的定位上下文)。\n * 宿主要往内容上叠东西(标尺、网格、水印、角标)时挂到这里。\n */\n get pageElement(): HTMLElement {\n return this.pageInner;\n }\n\n /** 当前绘制后端。 */\n get paint(): 'html' | 'canvas' {\n return this.paintMode;\n }\n\n /** 更新空态占位文案。传空字符串则不再显示。 */\n setPlaceholder(text: string) {\n this.placeholderText = text ?? '';\n this.syncPlaceholder();\n }\n\n /** 更新光标 / 选区等装饰外观,立即重绘 chrome。 */\n setChrome(patch: Partial<EditorChrome>) {\n this.chrome = { ...this.chrome, ...patch };\n this.applyChrome();\n this.paintChrome();\n }\n\n /**\n * 更新默认正文字号/颜色/字体。已写进 span 的同色文字会跟着改(给主题切换用),不进撤销。\n */\n setTextDefaults(patch: TextProps) {\n const prevColor = this.textDefaults?.color;\n this.textDefaults = { ...this.textDefaults, ...patch };\n this.applyTextDefaults(this.doc);\n const nextColor = this.textDefaults?.color;\n if (prevColor && nextColor && prevColor !== nextColor) {\n this.recolorMatchingText(prevColor, nextColor);\n }\n this.relayout({ reuse: false });\n }\n\n /** 把文档里等于 from 的文字色改成 to,不发 change、不进历史。 */\n private recolorMatchingText(from: string, to: string) {\n const match = (value?: string) => !!value && cssColorsEqual(value, from);\n for (const span of this.doc.styles) {\n if (span.type !== 'text') continue;\n const props = span.props as TextProps;\n if (match(props.color)) props.color = to;\n }\n if (this.typingStyle && match(this.typingStyle.color)) {\n this.typingStyle = { ...this.typingStyle, color: to };\n }\n }\n\n private applyTextDefaults(doc: DocumentModel) {\n if (!this.textDefaults && !this.resolvedMeasureFamily) {\n doc.textDefaults = null;\n return;\n }\n doc.textDefaults = {\n ...this.textDefaults,\n ...(this.resolvedMeasureFamily ? { fontFamily: this.resolvedMeasureFamily } : {}),\n };\n }\n\n private syncComputedFontForMeasure() {\n const computed = getComputedStyle(this.root).fontFamily?.trim();\n if (!computed) return;\n this.resolvedMeasureFamily = computed;\n this.applyTextDefaults(this.doc);\n }\n\n private createPainter(): PaintBackend {\n return this.paintMode === 'canvas' ? new CanvasPainter() : new HtmlPainter();\n }\n\n private caretIsSolid() {\n return this.chrome.caret !== 'rainbow';\n }\n\n private caretTrailEnabled() {\n return this.chrome.caretTrail === true;\n }\n\n private applyChrome() {\n this.root.dataset.caret = this.caretIsSolid() ? 'solid' : 'rainbow';\n this.root.dataset.surface =\n this.chrome.surfaceBackground === 'transparent' ? 'transparent' : 'paper';\n this.root.style.setProperty('--mini-caret-color', this.chrome.caretColor ?? '#09090b');\n this.root.style.setProperty(\n '--mini-caret-width',\n `${this.chrome.caretWidth ?? 2}px`\n );\n this.root.style.setProperty(\n '--mini-ime-underline-color',\n this.chrome.composeUnderlineColor ?? '#1f2329'\n );\n this.root.style.setProperty(\n '--mini-ime-underline-width',\n `${this.chrome.composeUnderlineWidth ?? 2}px`\n );\n const solid = this.caretIsSolid();\n const selColor = this.chrome.selectionColor;\n if (selColor) {\n this.root.style.setProperty('--mini-sel-color', selColor);\n } else if (solid) {\n this.root.style.setProperty('--mini-sel-color', 'rgba(43, 108, 255, 0.22)');\n } else {\n this.root.style.removeProperty('--mini-sel-color');\n }\n const selRadius =\n this.chrome.selectionRadius ?? (solid ? 0 : 6);\n this.root.style.setProperty('--mini-sel-radius', `${selRadius}px`);\n const cssFamily = this.textDefaults?.fontFamily?.trim();\n if (cssFamily) {\n this.root.style.setProperty('--mini-font-family', cssFamily);\n }\n const weight = this.textDefaults?.fontWeight;\n if (weight != null) {\n this.root.style.setProperty('--mini-font-weight', String(weight));\n }\n const contentW = this.layout?.contentWidth ?? this.contentWidth;\n this.root.style.setProperty('--mini-content-width', `${Math.max(0, contentW)}px`);\n }\n\n /** 当前排版结果(纯几何,只读)。宿主可据此画标尺、小地图、叠层。 */\n getLayout(): DocLayout {\n return this.layout;\n }\n\n /** 导出整篇内容,结果可 JSON 序列化。 */\n getContent(): Slice {\n return this.doc.takeSlice(0, this.doc.length);\n }\n\n /** 整篇替换内容,会清空撤销栈。 */\n setContent(slice: Slice) {\n this.doc = documentFromSlice(slice);\n this.applyTextDefaults(this.doc);\n this.refEdit = null;\n this.typingStyle = null;\n this.composeText = '';\n this.composeAnchor = null;\n this.composeLen = 0;\n this.ime.clear();\n this.undoStack.clear();\n this.vblockStack = [];\n this.sel = collapsedSel(Math.max(0, this.doc.length - 1));\n // 文档对象已经换掉,不能拿「刚冷排出来的新 layout」当增量 prev:\n // 那次冷排不会画到 DOM,紧接着的增量又会因哈希命中得到空脏区带,\n // painter 误以为画面已是最新,结果光标/选区跟着新几何走,正文还停在旧 DOM。\n this.relayout({ reuse: false });\n this.emit('change');\n }\n\n /** 直接拿文档模型。需要做批量操作或自定义命令时用。 */\n getDocument(): DocumentModel {\n return this.doc;\n }\n\n /**\n * 在当前选区(或 `at`)插入一份 Slice。模板混排(文案 + 槽 + 胶囊 + 虚拟块)走这条。\n */\n insertSlice(slice: Slice, at?: number) {\n if (at == null && this.selectedRegion()) return;\n this.runEdit('insert.paste', (ctx) => {\n const index = at ?? ctx.selection().focus;\n const nested = (slice.virtualBlocks?.length ?? 0) > 0 || slice.entities.length > 0;\n const slot = at == null ? this.slotToFill(ctx) : ctx.doc.slotAtCaret(index);\n if (!nested && slot && (slot.empty || (at == null && this.selectionCoversSlot(ctx, slot)))) {\n const text = ops.slotInlineText(slice.text);\n if (text) {\n const end = ops.fillSlot(slot.id, text)(ctx);\n if (end != null) ctx.select(collapsedSel(end));\n return;\n }\n }\n this.deleteSelectionIfNeeded(ctx);\n ctx.select(collapsedSel(ops.insertSlice(at ?? ctx.selection().focus, slice)(ctx)));\n });\n this.vblockStack = [];\n }\n\n /** 把指定范围(默认当前选区)包成一层虚拟块。 */\n insertVirtualBlock(spec: Omit<VirtualBlockSpec, 'start' | 'end'> & { start?: number; end?: number }): string | null {\n const start = spec.start ?? selStart(this.targetSel());\n const end = spec.end ?? selEnd(this.targetSel());\n if (end <= start) return null;\n let id: string | null = null;\n this.runEdit('vblock.insert', (ctx) => {\n id = ops.insertVirtualBlock({ ...spec, start, end })(ctx);\n const block = id ? ctx.doc.blockById(id) : null;\n // mark 是纯样式叠层:不改选区、不进选中态。\n if (block && block.kind !== 'mark') ctx.select({ anchor: block.start, focus: block.end });\n });\n if (id && spec.kind !== 'mark') this.selectVblock(id, 'selected');\n return id;\n }\n\n /**\n * 虚拟块当前在屏幕上的位置(clientX/Y 坐标,已含滚动),用来定位业务浮层。\n * `lines` 是每一行的片段(折行的块有多个);`left/top/width/height` 是它们的外接矩形。\n * 块不存在或还没排版出来时返回 null。滚动、重排之后需重新取。\n */\n getVirtualBlockRect(id: string): {\n left: number;\n top: number;\n width: number;\n height: number;\n lines: { left: number; top: number; width: number; height: number }[];\n } | null {\n const origin = this.painter.getSurface().getBoundingClientRect();\n const lines: { left: number; top: number; width: number; height: number }[] = [];\n for (const line of this.layout.lines) {\n for (const vb of line.vblocks ?? []) {\n if (vb.id !== id) continue;\n lines.push({ left: origin.left + vb.x, top: origin.top + vb.y, width: vb.w, height: vb.h });\n }\n }\n if (!lines.length) return null;\n const left = Math.min(...lines.map((r) => r.left));\n const top = Math.min(...lines.map((r) => r.top));\n const right = Math.max(...lines.map((r) => r.left + r.width));\n const bottom = Math.max(...lines.map((r) => r.top + r.height));\n return { left, top, width: right - left, height: bottom - top, lines };\n }\n\n updateVirtualBlock(id: string, chrome: VirtualBlockChrome) {\n this.runEdit('vblock.update', (ctx) => {\n ops.updateVirtualBlockChrome(id, chrome)(ctx);\n });\n }\n\n removeVirtualBlock(id: string) {\n this.runEdit('vblock.remove', (ctx) => {\n ops.removeVirtualBlock(id)(ctx);\n });\n this.vblockStack = this.vblockStack.filter((f) => f.id !== id);\n }\n\n /**\n * 在指定位置插入宿主渲染块。`at` 省略为当前光标(会先删掉非折叠选区)。\n * 插入后选中该占位符,便于缩放框/选中态;宿主若要把光标放到块后,自行折叠到 `focus`。\n */\n insertHostEmbed(\n hostType: string,\n data?: unknown,\n size?: { width: number; height: number },\n at: EmbedInsertAt = 'cursor'\n ) {\n this.insertEmbed(\n {\n id: nextEntityId(),\n kind: 'hostSlot',\n hostType,\n data,\n width: size?.width ?? 120,\n height: size?.height ?? 24\n },\n at\n );\n }\n\n /** 文档里所有嵌入对象(图片占位),按文档下标升序。 */\n listEmbeds(): { index: number; entity: EmbedEntity }[] {\n const out: { index: number; entity: EmbedEntity }[] = [];\n const { spacers } = this.doc;\n for (let i = 0; i < spacers.length; i++) {\n if (spacers[i] !== MARKERS.IMAGE) continue;\n const entity = this.doc.imageAt(i);\n if (entity) out.push({ index: i, entity });\n }\n return out;\n }\n\n /** 每个段落的分组 id,与块序一致;空串表示无分组。 */\n listParagraphGroupIds(): string[] {\n const ids: string[] = [];\n for (const block of parseBlocks(this.doc.spacers)) {\n if (block.kind !== 'paragraph') continue;\n ids.push(this.doc.paragraphPropsAt(block.start).groupId ?? '');\n }\n return ids;\n }\n\n /** 给前 `count` 个段落打上分组(省略则全部)。不进撤销栈。 */\n tagParagraphsWithGroup(groupId: string, count?: number) {\n const id = groupId.trim();\n if (!id) return;\n const paras = parseBlocks(this.doc.spacers).filter((block) => block.kind === 'paragraph');\n const n = count == null ? paras.length : Math.min(Math.max(0, count), paras.length);\n if (!n) return;\n this.applyNow((ctx) => {\n for (let i = 0; i < n; i++) {\n const para = paras[i]!;\n ops.applyParagraphStyle(para.start, para.end, { groupId: id })(ctx);\n }\n });\n this.relayout();\n }\n\n /** 去掉段落分组。传入 id 则只清该组,否则清全部。 */\n clearParagraphGroupIds(groupId?: string) {\n const id = groupId?.trim() ?? '';\n this.applyNow((ctx) => {\n for (const block of parseBlocks(this.doc.spacers)) {\n if (block.kind !== 'paragraph') continue;\n const current = this.doc.paragraphPropsAt(block.start).groupId ?? '';\n if (!current) continue;\n if (id && current !== id) continue;\n ops.applyParagraphStyle(block.start, block.end, { groupId: '' })(ctx);\n }\n });\n this.relayout();\n }\n\n /** 删除指定分组的段落,其余内容保留。会清空撤销栈。 */\n deleteParagraphsWithGroup(groupId: string) {\n const id = groupId.trim();\n if (!id) return;\n this.setContent(sliceWithoutParagraphGroup(this.doc, id));\n }\n\n /** 当前是否正好选中一颗嵌入对象(含 host)。 */\n selectedEmbed(): EmbedEntity | null {\n return this.selectedImage()?.entity ?? null;\n }\n\n /** 按谓词删除嵌入对象,从后往前以免下标错位。返回删除数量。 */\n deleteEmbeds(pred: (entity: EmbedEntity, index: number) => boolean): number {\n const hits = this.listEmbeds()\n .filter((x) => pred(x.entity, x.index))\n .map((x) => x.index)\n .sort((a, b) => b - a);\n if (!hits.length) return 0;\n const caret = hits[hits.length - 1]!;\n this.runEdit('embed.delete', (ctx) => {\n for (const i of hits) ops.deleteRange(i, i + 1)(ctx);\n ctx.select(collapsedSel(caret));\n });\n return hits.length;\n }\n\n /** 按谓词更新嵌入对象属性。`patchFor` 可按实体合并 data。返回更新数量。\n * `history: false` 不进撤销栈(生成中态这类 UI 过程)。 */\n updateEmbeds(\n pred: (entity: EmbedEntity, index: number) => boolean,\n patchFor: ImagePatch | ((entity: EmbedEntity, index: number) => ImagePatch),\n options?: { history?: boolean }\n ): number {\n const hits = this.listEmbeds().filter((x) => pred(x.entity, x.index));\n if (!hits.length) return 0;\n const patches = hits.map((h) => ({\n id: h.entity.id,\n patch: typeof patchFor === 'function' ? patchFor(h.entity, h.index) : patchFor,\n }));\n if (options?.history === false) {\n for (const item of patches) {\n this.applyNow(ops.updateImage(item.id, item.patch));\n }\n this.relayout();\n return hits.length;\n }\n this.runEdit('embed.update', (ctx) => {\n for (const item of patches) ops.updateImage(item.id, item.patch)(ctx);\n });\n return hits.length;\n }\n\n getSelection(): Selection {\n return { ...this.sel };\n }\n\n /** 屏幕坐标落到文档下标,供拖放落点。 */\n indexAtClientPoint(clientX: number, clientY: number): number {\n const { x, y } = this.localPoint({ clientX, clientY } as MouseEvent);\n return nearestSafeIndex(this.doc.spacers, hitTestIndex(this.layout, x, y));\n }\n\n setSelection(next: Selection) {\n this.sel = { ...next };\n this.afterCaretMove();\n }\n\n /** 当前状态快照,用于同步宿主 UI。 */\n getState(): EditorState {\n const text = this.currentTextStyle();\n const para = this.targetDoc().paragraphPropsAt(this.targetSel().focus);\n const embed = this.selectedImage();\n const canPromote =\n !this.refEdit &&\n !isCollapsed(this.sel) &&\n !(selEnd(this.sel) - selStart(this.sel) === 1 && embed?.entity.kind === 'ref');\n return {\n bold: !!text.bold,\n italic: !!text.italic,\n underline: underlineKind(text) !== 'none',\n strikethrough: !!text.strikethrough,\n fontSize: text.fontSize ?? 16,\n color: text.color ?? '#1f2329',\n heading: (para.heading ?? 0) as 0 | 1 | 2 | 3,\n align: para.align ?? 'left',\n list: para.list ?? 'none',\n inTable: !!cellAt(this.targetDoc().spacers, this.targetSel().focus),\n canUndo: this.undoStack.canUndo,\n canRedo: this.undoStack.canRedo,\n paintMode: this.paintMode,\n hasLink: !!this.targetDoc().linkUrlAt(this.targetSel().focus),\n canPromote,\n canInsertRef: !this.refEdit && this.doc.fragments.size > 0,\n canUnlink: !this.refEdit && embed?.entity.kind === 'ref',\n selection: { ...this.sel },\n docLength: this.doc.length,\n inRefEdit: !!this.refEdit,\n refSelection: { ...this.fragSel },\n vblockStack: this.vblockStack.map((f) => ({ ...f }))\n };\n }\n\n /** 订阅事件,返回取消订阅函数。 */\n on(event: EditorEvent, handler: () => void): () => void {\n this.listeners[event].add(handler);\n return () => this.listeners[event].delete(handler);\n }\n\n focus() {\n if (this.disabled) return;\n this.ime.focus();\n }\n\n /** 输入法组合是否进行中(含候选串已镜像进模型、尚未落定)。 */\n composing(): boolean {\n return this.ime.composing || this.composeAnchor !== null;\n }\n\n /** 禁用输入与快捷键。宿主 disabled 不能只靠 CSS pointer-events。 */\n setDisabled(disabled: boolean) {\n this.disabled = disabled;\n this.ime.el.contentEditable = disabled ? 'false' : 'true';\n }\n\n private emit(event: EditorEvent) {\n for (const handler of this.listeners[event]) handler();\n }\n\n // ------------------------------------------------------------------------\n\n private bindSurface() {\n this.painter.getSurface().addEventListener('mousedown', this.onMouseDown);\n this.painter.getSurface().addEventListener('mouseleave', this.onSurfaceLeave);\n }\n\n private unbindSurface() {\n this.painter.getSurface().removeEventListener('mousedown', this.onMouseDown);\n this.painter.getSurface().removeEventListener('mouseleave', this.onSurfaceLeave);\n }\n\n private hoverMarkId: string | null = null;\n\n private onSurfaceLeave = () => {\n this.setHoverMark(null);\n this.painter.getSurface().classList.remove('is-over-slot');\n };\n\n /** 鼠标是否在虚拟块文本槽(输入框)上。 */\n private overVirtualSlot(x: number, y: number): boolean {\n for (const line of this.layout.lines) {\n if (line.y > y) break;\n if (y >= line.y + line.h || !line.vblocks) continue;\n for (const vb of line.vblocks) {\n if (vb.kind === 'virtualSlot' && x >= vb.x && x <= vb.x + vb.w && y >= vb.y && y <= vb.y + vb.h) {\n return true;\n }\n }\n }\n return false;\n }\n\n private setHoverMark(id: string | null) {\n if (id === this.hoverMarkId) return;\n this.hoverMarkId = id;\n this.painter.setHoverBlock?.(id);\n }\n\n /** 鼠标下配置了 hoverBackground 的 mark(折行时命中任一行片段都算)。 */\n private markAt(x: number, y: number): string | null {\n let any = false;\n for (const b of this.doc.virtualBlocks.values()) {\n if (b.kind === 'mark' && b.chrome.hoverBackground) {\n any = true;\n break;\n }\n }\n if (!any) return null;\n for (const line of this.layout.lines) {\n if (line.y > y) break;\n if (y >= line.y + line.h || !line.vblocks) continue;\n for (let i = line.vblocks.length - 1; i >= 0; i--) {\n const vb = line.vblocks[i];\n if (vb.kind !== 'mark' || !vb.chrome.hoverBackground) continue;\n if (x >= vb.x && x <= vb.x + vb.w && y >= vb.y && y <= vb.y + vb.h) return vb.id;\n }\n }\n return null;\n }\n\n private bind() {\n this.bindSurface();\n window.addEventListener('mousemove', this.onMouseMove);\n this.root.addEventListener('contextmenu', this.onContextMenu);\n window.addEventListener('mouseup', this.onMouseUp);\n this.unbindKeyboard = bindKeyboard({\n commands: this.commands,\n accepts: (e) => this.acceptsKey(e),\n composing: () => this.composing(),\n suppressInput: (e) => {\n if (e.target === this.ime.el) this.ime.markKeyConsumed();\n },\n shortcuts: this.shortcutTable\n });\n document.addEventListener('mousedown', this.onDocMouseDown, true);\n this.root.addEventListener('mousedown', this.onRootMouseDown);\n this.parent.addEventListener('mousedown', this.onRootMouseDown);\n this.pageInner.addEventListener(EMBED_CHANGE, this.onEmbedChange);\n this.pageInner.addEventListener(EMBED_COMMIT, this.onEmbedCommit);\n this.pageInner.addEventListener(EMBED_MEASURE, this.onEmbedMeasure);\n this.pageInner.addEventListener(EMBED_EXIT_EDIT, this.onEmbedExitEdit);\n this.pageInner.addEventListener(REF_JUMP, this.onRefJump);\n this.pageInner.addEventListener('dblclick', this.onDoubleClick);\n this.root.addEventListener('focusin', this.onFocusChange);\n this.root.addEventListener('focusout', this.onFocusChange);\n this.handle.addEventListener('mousedown', this.onResizeStart);\n window.addEventListener('resize', this.onWindowResize);\n document.addEventListener('scroll', this.onAnyScroll, { capture: true, passive: true });\n window.addEventListener('resize', this.onAnyScroll);\n // 'fill' 模式:监听宿主容器尺寸变化重排。只观察 parent —— 它的宽度由外部布局决定,\n // 不受编辑器内部 surface 尺寸影响,不会形成重排循环。contentWidth 没变时 engine 增量复用。\n if (this.widthMode === 'fill' && typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this.relayout());\n this.resizeObserver.observe(this.parent);\n }\n document.addEventListener('copy', this.onCopy);\n document.addEventListener('cut', this.onCut);\n }\n\n destroy() {\n this.unbindKeyboard?.();\n document.removeEventListener('mousedown', this.onDocMouseDown, true);\n this.root.removeEventListener('mousedown', this.onRootMouseDown);\n this.parent.removeEventListener('mousedown', this.onRootMouseDown);\n this.root.removeEventListener('focusin', this.onFocusChange);\n this.root.removeEventListener('focusout', this.onFocusChange);\n window.removeEventListener('mousemove', this.onMouseMove);\n this.root.removeEventListener('contextmenu', this.onContextMenu);\n this.endContextMenu();\n window.removeEventListener('mouseup', this.onMouseUp);\n window.removeEventListener('resize', this.onWindowResize);\n document.removeEventListener('scroll', this.onAnyScroll, { capture: true });\n window.removeEventListener('resize', this.onAnyScroll);\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n document.removeEventListener('copy', this.onCopy);\n document.removeEventListener('cut', this.onCut);\n window.cancelAnimationFrame(this.caretRaf);\n this.unbindSurface();\n this.ime.destroy();\n this.painter.destroy();\n this.root.remove();\n }\n\n private onWindowResize = () => this.relayout();\n\n /**\n * 按当前 width 策略算出内容宽度。\n * - 固定像素:直接返回。\n * - 'fill':宿主容器可用宽减去左右版心内边距;容器尚未布局(宽度为 0)时回退默认值,\n * 避免首帧算出负数或零宽。\n */\n private resolveContentWidth(): number {\n if (typeof this.widthMode === 'number') return this.widthMode;\n const avail = this.parent.clientWidth - this.padding.x * 2;\n return avail > 0 ? avail : PAGE_CONTENT_WIDTH;\n }\n\n private commit(edit: EditResult) {\n this.undoStack.push(edit);\n this.typingStyle = null;\n this.keepTypingOnNextClick = false;\n this.relayout();\n // 一次编辑落定后通知外部:内容已变。预览态(applyNow)不走这里,所以\n // 组合中间态、拖拽缩放这类临时改动不会误报 change。\n this.emit('change');\n }\n\n private targetDoc(): DocumentModel {\n return this.refEdit ? this.doc.ensureFragmentModel(this.refEdit.fragmentId) : this.doc;\n }\n\n private targetSel(): Selection {\n return this.refEdit ? this.fragSel : this.sel;\n }\n\n private setTargetSel(next: Selection) {\n if (this.refEdit) this.fragSel = next;\n else this.sel = next;\n }\n\n private syncActiveFragment() {\n if (this.refEdit) this.doc.syncFragment(this.refEdit.fragmentId);\n }\n\n private activeRefBox(): ImageBox | null {\n if (!this.refEdit) return null;\n return this.layout.images.find((b) => b.entity.id === this.refEdit?.entityId) ?? null;\n }\n\n private refreshRefMetrics() {\n const width = this.layout?.contentWidth ?? PAGE_CONTENT_WIDTH;\n for (const entity of this.doc.entities.values()) {\n if (entity.kind !== 'ref') continue;\n const size = measureRef(entity, width, this.doc);\n entity.width = size.width;\n entity.height = size.height;\n }\n }\n\n /**\n * 一次用户操作的事务边界。事务本体在 Edit 层,这里只负责给它当前的选区和\n * 作用域,再把产出的记录送进撤销栈。\n *\n * 同步块内部编辑走的是同一条路,只是作用域换成片段 id —— 发出去的 mutation\n * 自动包上 `scoped`,进的还是同一个撤销栈。\n */\n private runEdit(kind: EditKind, run: (ctx: OperationContext) => void) {\n const scope = this.refEdit?.fragmentId ?? null;\n const { edit, selectionAfter } = runEdit(this.doc, this.targetSel(), { kind, scope }, run);\n this.setTargetSel(selectionAfter);\n if (!edit) {\n this.relayout();\n return;\n }\n this.commit(edit);\n }\n\n /** 立即落一次变更,不进撤销栈。拖拽预览这类「过程中」的改动用它。 */\n private applyNow<R>(op: Operation<R>): R {\n const scope = this.refEdit?.fragmentId ?? null;\n const { run, result } = runScoped(this.doc, this.targetSel(), scope, op);\n this.setTargetSel(run.selectionAfter);\n return result;\n }\n\n /**\n * 把已经预览生效的改动登记成一步可撤销的编辑。\n *\n * 拖拽缩放这类交互会先用 `applyNow` 实时改文档,松手时才落定。这里的做法是\n * 悄悄退回到起点、再用一次真正的编辑走到终点 —— 两步在同一帧内完成,用户看不\n * 出来,换来的是一条正常的、能重放能变换的操作记录,而不是一对手写的闭包。\n */\n private commitPreview(kind: EditKind, revert: Operation, settle: Operation) {\n this.applyNow(revert);\n this.runEdit(kind, (ctx) => settle(ctx));\n }\n\n private deleteSelectionIfNeeded(ctx: OperationContext) {\n const sel = ctx.selection();\n if (isCollapsed(sel)) return;\n const from = selStart(sel);\n const to = selEnd(sel);\n if (!this.refEdit && this.clearCellGrid(ctx, from, to)) {\n ctx.select(collapsedSel(nearestSafeIndex(this.doc.spacers, from)));\n return;\n }\n const selected = this.selectedVblock();\n if (!this.refEdit && this.stackTop()?.mode === 'selected' && selected?.kind === 'region') {\n return;\n }\n if (!this.refEdit && this.stackTop()?.mode === 'selected' && selected?.kind === 'virtualSlot') {\n ops.clearSlot(selected.id)(ctx);\n const next = ctx.doc.blockById(selected.id);\n ctx.select(next ? { anchor: next.start, focus: next.end } : collapsedSel(from));\n return;\n }\n const editing = this.editingSlotIn(ctx.doc);\n if (editing && from <= editing.start && to >= editing.end) {\n ops.clearSlot(editing.id)(ctx);\n const next = ctx.doc.blockById(editing.id);\n ctx.select(collapsedSel(next?.start ?? from));\n return;\n }\n ops.deleteRange(from, to)(ctx);\n ctx.select(collapsedSel(from));\n }\n\n private clearCellGrid(ctx: OperationContext, from: number, to: number): boolean {\n const a = cellAt(this.doc.spacers, from);\n const b = cellAt(this.doc.spacers, Math.max(from, to - 1));\n if (!a || !b || a.table.start !== b.table.start) return false;\n if (a.row === b.row && a.col === b.col && from > a.cell.start) return false;\n const r0 = Math.min(a.row, b.row);\n const r1 = Math.max(a.row, b.row);\n const c0 = Math.min(a.col, b.col);\n const c1 = Math.max(a.col, b.col);\n const cells = [];\n for (let r = r0; r <= r1; r++) {\n for (let c = c0; c <= c1; c++) {\n const cell = a.table.rows[r]?.cells[c];\n if (cell) cells.push(cell);\n }\n }\n if (!cells.length) return false;\n const minStart = Math.min(...cells.map((c) => c.start));\n const maxEnd = Math.max(...cells.map((c) => c.end));\n if (from > minStart + 1 || to < maxEnd) return false;\n for (const cell of [...cells].reverse()) {\n const range = cellContentRange(cell);\n if (range.end > range.start) ops.emitDelete(ctx, range.start, range.end);\n if (this.doc.spacers[range.start] !== MARKERS.PARAGRAPH) {\n ops.emitInsert(ctx, range.start, MARKERS.PARAGRAPH);\n }\n }\n ops.normalizeParagraphs(ctx);\n return true;\n }\n\n /**\n * 处理输入法组合态(拼音/候选的中间态)。\n *\n * 组合串镜像插入文档模型、参与真实排版 —— 每次变化都幂等地「删旧串 → 插新串」,\n * 光标后的内容因此靠正常重排让开,而不是被浮层盖住。整个组合过程用 applyNow\n * 落地、不进撤销栈;最终文字在 compositionend 后由 onInsertText 走一次正常插入\n * 落定成一步可撤销的编辑。组合区外观由白块 overlay 擦白,只留系统输入法的候选串。\n */\n private handleComposition(active: boolean, text: string) {\n if (active && this.composeAnchor === null) {\n // 组合开始:有选区先删掉,落点即组合串的锚点。\n if (!isCollapsed(this.targetSel())) {\n this.applyNow((ctx) => this.deleteSelectionIfNeeded(ctx));\n }\n this.composeAnchor = this.targetSel().focus;\n this.composeLen = 0;\n }\n\n if (active && this.composeAnchor !== null) {\n const anchor = this.composeAnchor;\n const inherit = this.typingStyle ?? this.targetDoc().textPropsAt(anchor);\n this.applyNow((ctx) => {\n const slot = this.editingSlotIn(ctx.doc) ?? ctx.doc.slotAtCaret(anchor);\n const covers =\n !!slot && this.composeLen > 0 && anchor <= slot.start && anchor + this.composeLen >= slot.end;\n if (slot && (slot.empty || covers)) {\n if (!text) {\n ops.clearSlot(slot.id)(ctx);\n const next = ctx.doc.blockById(slot.id);\n this.composeAnchor = next?.start ?? anchor;\n ctx.select(collapsedSel(this.composeAnchor));\n return;\n }\n const end = ops.fillSlot(slot.id, text, inherit)(ctx);\n const next = ctx.doc.blockById(slot.id);\n this.composeAnchor = next?.start ?? anchor;\n ctx.select(collapsedSel(end ?? anchor));\n return;\n }\n if (this.composeLen > 0) ops.deleteRange(anchor, anchor + this.composeLen)(ctx);\n const end = text ? ops.insertText(anchor, text, inherit)(ctx) : anchor;\n ctx.select(collapsedSel(end));\n });\n this.composeLen = text.length;\n } else if (!active && this.composeAnchor !== null) {\n // 组合结束:整槽预览用 clearSlot 留皮,最终文字由 onInsertText 走 fillSlot。\n const anchor = this.composeAnchor;\n const len = this.composeLen;\n this.applyNow((ctx) => {\n const slot = this.editingSlotIn(ctx.doc) ?? ctx.doc.slotAtCaret(anchor);\n const covers = !!slot && len > 0 && anchor <= slot.start && anchor + len >= slot.end;\n if (slot && (slot.empty || covers)) {\n ops.clearSlot(slot.id)(ctx);\n const next = ctx.doc.blockById(slot.id);\n ctx.select(collapsedSel(next?.start ?? slot.start));\n return;\n }\n if (len > 0) ops.deleteRange(anchor, anchor + len)(ctx);\n ctx.select(collapsedSel(anchor));\n });\n this.composeAnchor = null;\n this.composeLen = 0;\n }\n\n this.composeText = text;\n this.relayout();\n }\n\n insertText(text: string) {\n if (!text || this.disabled) return;\n const selected = this.selectedVblock();\n if (this.stackTop()?.mode === 'selected' && selected?.kind === 'region') return;\n this.runEdit('insert.text', (ctx) => {\n const selectedNow = ctx.doc.blockById(selected?.id ?? '');\n if (this.stackTop()?.mode === 'selected' && selectedNow?.kind === 'virtualSlot') {\n const end = ops.fillSlot(selectedNow.id, text)(ctx);\n if (end != null) ctx.select(collapsedSel(end));\n return;\n }\n const slot = this.editingSlotIn(ctx.doc);\n const sel = ctx.selection();\n const covers =\n !!slot && !isCollapsed(sel) && selStart(sel) <= slot.start && selEnd(sel) >= slot.end;\n if (slot && (slot.empty || covers)) {\n const end = ops.fillSlot(slot.id, text)(ctx);\n if (end != null) ctx.select(collapsedSel(end));\n return;\n }\n this.deleteSelectionIfNeeded(ctx);\n const inherit = this.typingStyle ?? ctx.doc.textPropsAt(ctx.selection().focus);\n const at = ctx.selection().focus;\n let next = ops.insertText(at, text, inherit)(ctx);\n if (!this.refEdit && shouldTryMarkdown(text)) next = ops.applyMarkdownShortcut(next)(ctx);\n ctx.select(collapsedSel(next));\n });\n if (this.stackTop()?.mode === 'selected' && selected?.kind === 'virtualSlot') {\n this.selectVblock(selected.id, 'editing');\n }\n }\n\n pasteText(text: string) {\n this.pasteClipboard(text ? fakePlainClipboard(text) : null);\n }\n\n pasteClipboard(data: DataTransfer | null) {\n if (this.selectedRegion()) return;\n const slice = sliceFromClipboard(data);\n const text = data?.getData('text/plain') ?? '';\n if (!slice && !text) return;\n this.runEdit('insert.paste', (ctx) => {\n const nested = (slice?.virtualBlocks?.length ?? 0) > 0 || (slice?.entities.length ?? 0) > 0;\n const payload = ops.slotInlineText(slice?.text ?? text);\n const slot = this.slotToFill(ctx);\n if (slot && payload && !nested) {\n const end = ops.fillSlot(slot.id, payload)(ctx);\n if (end != null) ctx.select(collapsedSel(end));\n return;\n }\n this.deleteSelectionIfNeeded(ctx);\n if (slice) {\n ctx.select(collapsedSel(ops.insertSlice(ctx.selection().focus, slice)(ctx)));\n return;\n }\n const inherit = this.typingStyle ?? ctx.doc.textPropsAt(ctx.selection().focus);\n const next = ops.pasteText(ctx.selection().focus, text, inherit)(ctx);\n ctx.select(collapsedSel(next));\n });\n if (this.stackTop()?.mode === 'selected' && this.selectedVblock()?.kind === 'virtualSlot') {\n const id = this.selectedVblock()?.id;\n if (id) this.selectVblock(id, 'editing');\n }\n }\n\n insertParagraph(opts?: { shift?: boolean }) {\n if (this.disabled) return;\n if (this.enterSelectedVblock()) return;\n if (this.selectedRegion()) return;\n const editing = this.editingSlot();\n const embed = this.selectedImage();\n if (embed?.entity.kind === 'formula' && this.beginFormulaEdit(embed.entity.id)) return;\n if (embed?.entity.kind === 'internalSlot' && this.beginSlotActivate(embed.entity.id)) return;\n if (embed?.entity.kind === 'ref' && this.beginRefEdit(embed.entity.id)) return;\n // 与现网 NodeSelection+Enter 开下拉对齐:仅普通 Enter 激活 host;Shift+Enter 仍在块后换行。\n if (\n embed?.entity.kind === 'hostSlot' &&\n !opts?.shift &&\n activateHostEmbed(embed.entity.id, { key: 'Enter', shift: false })\n ) {\n return;\n }\n const explicit = this.typingStyle ? { ...this.typingStyle } : null;\n const pending = { ...this.currentTextStyle() };\n const host = this.targetDoc();\n const fromHeading = host.paragraphPropsAt(this.targetSel().focus).heading ?? 0;\n this.runEdit('insert.paragraph', (ctx) => {\n if (embed && !this.refEdit) {\n ctx.select(collapsedSel(ops.insertParagraph(embed.index + 1)(ctx)));\n return;\n }\n if (editing) {\n const block = ctx.doc.blockById(editing.id);\n const at = block?.end ?? ctx.selection().focus;\n ctx.select(collapsedSel(ops.insertParagraph(at)(ctx)));\n return;\n }\n this.deleteSelectionIfNeeded(ctx);\n ctx.select(collapsedSel(ops.insertParagraph(ctx.selection().focus)(ctx)));\n });\n if (editing) this.vblockStack = [];\n this.typingStyle = this.inheritedTypingStyle(explicit, pending, fromHeading);\n this.keepTypingOnNextClick = !!this.typingStyle;\n this.syncToolbar();\n }\n\n private inheritedTypingStyle(explicit: TextProps | null, pending: TextProps, fromHeading: number): TextProps | null {\n const toHeading = this.targetDoc().paragraphPropsAt(this.targetSel().focus).heading ?? 0;\n if (fromHeading && toHeading === 0) return explicit;\n return explicit ?? pending;\n }\n\n private beginFormulaEdit(id: string): boolean {\n const node = this.pageInner.querySelector(`[data-entity=\"${CSS.escape(id)}\"]`);\n if (!node) return false;\n node.dispatchEvent(new Event('mini-formula-edit'));\n return true;\n }\n\n private beginSlotActivate(id: string): boolean {\n const node = this.pageInner.querySelector(`[data-entity=\"${CSS.escape(id)}\"]`);\n if (!node) return false;\n node.dispatchEvent(new Event('mini-slot-activate'));\n return true;\n }\n\n backspace() {\n if (this.handleVblockBackspace('backward')) return;\n if (this.deleteSelectedEmbed('backspace')) return;\n if (this.exitRefEditAtStart()) return;\n const sel = this.targetSel();\n const doc = this.targetDoc();\n if (isCollapsed(sel)) {\n const i = sel.focus;\n if (!this.refEdit && i > 0 && this.doc.spacers[i - 1] === MARKERS.TABLE_END) {\n const table = findTableAt(this.doc.spacers, i - 1);\n if (table) {\n this.sel = { anchor: table.start, focus: table.end };\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n return;\n }\n }\n }\n this.runEdit('delete.backward', (ctx) => {\n if (!isCollapsed(ctx.selection())) {\n this.deleteSelectionIfNeeded(ctx);\n return;\n }\n const res = ops.backspace(ctx.selection().focus)(ctx);\n if (res) ctx.select(collapsedSel(res.start));\n });\n }\n\n deleteForward() {\n if (this.handleVblockBackspace('forward')) return;\n if (this.deleteSelectedEmbed('forward')) return;\n this.runEdit('delete.forward', (ctx) => {\n if (!isCollapsed(ctx.selection())) {\n this.deleteSelectionIfNeeded(ctx);\n return;\n }\n ops.deleteForward(ctx.selection().focus)(ctx);\n });\n }\n\n private applyText(patch: TextProps) {\n if (isCollapsed(this.targetSel())) {\n this.typingStyle = { ...this.currentTextStyle(), ...patch };\n this.keepTypingOnNextClick = true;\n this.syncToolbar();\n this.ime.focus();\n return;\n }\n this.runEdit('style.text', (ctx) => {\n const sel = ctx.selection();\n ops.applyTextStyle(selStart(sel), selEnd(sel), patch)(ctx);\n });\n }\n\n private toggleText(key: 'bold' | 'italic' | 'underline' | 'strikethrough') {\n const cur = this.currentTextStyle();\n if (key === 'underline') {\n const on = underlineKind(cur) !== 'none';\n this.applyText(on ? { underline: false, underlineStyle: undefined } : { underline: true, underlineStyle: 'single' });\n return;\n }\n this.applyText({ [key]: !cur[key] });\n }\n\n private applyPara(patch: ParagraphProps) {\n this.runEdit('style.paragraph', (ctx) => {\n const sel = ctx.selection();\n ops.applyParagraphStyle(selStart(sel), selEnd(sel), patch)(ctx);\n });\n }\n\n private toggleLink() {\n const existing = this.targetDoc().linkSpanAt(this.targetSel().focus);\n if (isCollapsed(this.targetSel()) && existing) {\n const next = window.prompt('编辑链接,留空则移除', (existing.props as { url: string }).url);\n if (next === null) return;\n this.runEdit('style.link', (ctx) => {\n if (!next.trim()) ops.removeLink(ctx.selection().focus)(ctx);\n else ops.applyLink(existing.start, existing.end, next.trim())(ctx);\n });\n return;\n }\n const sel = this.targetSel();\n const from = selStart(sel);\n const to = selEnd(sel);\n const initial = existing ? (existing.props as { url: string }).url : 'https://';\n const url = window.prompt('输入链接', initial);\n if (url === null) return;\n const href = url.trim();\n if (!href) {\n if (existing) {\n this.runEdit('style.link', (ctx) => ops.removeLink(ctx.selection().focus)(ctx));\n }\n return;\n }\n this.runEdit('style.link', (ctx) => {\n if (from === to) {\n const next = ops.insertText(from, href)(ctx);\n ops.applyLink(from, next, href)(ctx);\n ctx.select({ anchor: from, focus: next });\n } else {\n ops.applyLink(from, to, href)(ctx);\n }\n });\n }\n\n private toggleList(kind: 'ul' | 'ol') {\n const cur = this.targetDoc().paragraphPropsAt(this.targetSel().focus);\n this.applyPara({ list: cur.list === kind ? 'none' : kind, heading: 0 });\n }\n\n private changeIndent(delta: number) {\n const cur = this.targetDoc().paragraphPropsAt(this.targetSel().focus);\n const next = Math.max(0, Math.min(MAX_LIST_INDENT, (cur.indent ?? 0) + delta));\n if (next === (cur.indent ?? 0)) return;\n this.applyPara({ indent: next });\n }\n\n private insertEmbed(entity: EmbedEntity, at: EmbedInsertAt = 'cursor') {\n if (this.refEdit && entity.kind === 'ref') return;\n if (at === 'cursor' && this.selectedRegion()) return;\n const host = this.targetDoc();\n const sized = { ...entity, ...embedPlugin(entity.kind).measure(entity, this.innerContentWidth(), host) };\n this.runEdit('embed.insert', (ctx) => {\n if (at === 'cursor') {\n this.deleteSelectionIfNeeded(ctx);\n } else {\n ctx.select(collapsedSel(this.resolveInsertIndex(at, ctx.doc)));\n }\n const next = ops.insertImage(ctx.selection().focus, sized)(ctx);\n ctx.select({ anchor: next - 1, focus: next });\n });\n }\n\n private resolveInsertIndex(at: EmbedInsertAt, doc = this.doc): number {\n if (at === 'start') return 0;\n if (at === 'end') return Math.max(0, doc.length - 1);\n if (at === 'cursor') return this.targetSel().focus;\n return doc.clamp(at);\n }\n\n private innerContentWidth(): number {\n if (this.refEdit) {\n const box = this.activeRefBox();\n return Math.max(80, refInnerWidth(box?.w ?? 400));\n }\n return this.layout.contentWidth;\n }\n\n private insertCodeBlock() {\n this.insertEmbed({\n id: nextEntityId(),\n kind: 'code',\n width: this.layout.contentWidth,\n height: 80,\n language: 'plain',\n code: ''\n });\n }\n\n private insertFormula() {\n this.insertEmbed({\n id: nextEntityId(),\n kind: 'formula',\n width: 240,\n height: 56,\n latex: '',\n displayMode: true\n });\n }\n\n private insertSlot(slotKind: SlotKind) {\n const id = nextEntityId();\n this.insertEmbed({\n id,\n kind: 'internalSlot',\n slotKind,\n label: defaultSlotLabel(slotKind),\n slotOptions: slotKind === 'select' ? ['小美', '阿力'] : undefined,\n width: 140,\n height: 28\n });\n queueMicrotask(() => this.beginSlotActivate(id));\n }\n\n private promoteRef() {\n if (this.refEdit) return;\n const from = selStart(this.sel);\n const to = selEnd(this.sel);\n if (from === to) return;\n if (to - from === 1 && this.doc.imageAt(from)?.kind === 'ref') return;\n this.runEdit('ref.promote', (ctx) => {\n const hit = ops.promoteRange(from, to)(ctx);\n if (!hit) return;\n ctx.select({ anchor: hit.index, focus: hit.index + 1 });\n });\n }\n\n private insertExistingRef() {\n if (this.refEdit) return;\n const fragments = this.doc.listFragments();\n if (!fragments.length) return;\n if (fragments.length === 1) {\n this.insertRefAtCaret(fragments[0].id);\n return;\n }\n const picked = window.prompt(\n fragments.map((f, i) => `${i + 1}. ${f.title ?? f.id}`).join('\\n') + '\\n\\n输入序号插入',\n '1'\n );\n const index = Number(picked) - 1;\n if (!Number.isInteger(index) || !fragments[index]) return;\n this.insertRefAtCaret(fragments[index].id);\n }\n\n private insertRefAtCaret(fragmentId: string) {\n if (this.selectedRegion()) return;\n this.runEdit('ref.insert', (ctx) => {\n this.deleteSelectionIfNeeded(ctx);\n const index = ops.insertRef(ctx.selection().focus, fragmentId)(ctx);\n ctx.select({ anchor: index, focus: index + 1 });\n });\n }\n\n private unlinkSelectedRef() {\n const embed = this.selectedImage();\n if (embed?.entity.kind !== 'ref') return;\n this.exitRefEdit();\n this.runEdit('ref.unlink', (ctx) => {\n const next = ops.unlinkRef(embed.index)(ctx);\n if (next !== null) ctx.select(collapsedSel(next));\n });\n }\n\n private selectedEmbedIndex(side: 'backspace' | 'forward'): number | null {\n if (this.refEdit) return null;\n const from = selStart(this.sel);\n const to = selEnd(this.sel);\n // 整块选中(蓝框 / 胶囊 selected)时,退格和 Delete 都删块。\n if (to - from === 1 && this.doc.spacers[from] === MARKERS.IMAGE) return from;\n if (from !== to) return null;\n // 折叠光标在块前:Delete 删块,Backspace 删光标前的字符。\n if (side === 'forward' && this.doc.spacers[from] === MARKERS.IMAGE) return from;\n // 折叠光标在块后:Backspace 删块。\n if (side === 'backspace' && from > 0 && this.doc.spacers[from - 1] === MARKERS.IMAGE) return from - 1;\n return null;\n }\n\n private deleteSelectedEmbed(side: 'backspace' | 'forward'): boolean {\n const index = this.selectedEmbedIndex(side);\n if (index === null) return false;\n this.runEdit('embed.delete', (ctx) => {\n ops.deleteRange(index, index + 1)(ctx);\n ctx.select(collapsedSel(index));\n });\n return true;\n }\n\n private exitRefEditAtStart(): boolean {\n if (!this.refEdit || !isCollapsed(this.fragSel) || this.fragSel.focus !== 0) return false;\n this.exitRefEdit();\n return true;\n }\n\n private refInnerLayout(box: ImageBox): DocLayout | null {\n if (box.inner) return box.inner;\n if (box.entity.kind !== 'ref' || !box.entity.fragmentId) return null;\n const innerW = refInnerWidth(box.w);\n return layoutDocument(this.doc.ensureFragmentModel(box.entity.fragmentId), innerW, undefined, { x: 0, y: 0 }, 1);\n }\n\n private hitRefIndex(box: ImageBox, x: number, y: number): number {\n const inner = this.refInnerLayout(box);\n if (!inner) return 0;\n return hitTestIndex(inner, x - box.x - REF_PAD, y - box.y - REF_HEAD);\n }\n\n private beginRefEdit(id: string, at?: number): boolean {\n const entity = this.doc.entities.get(id);\n if (entity?.kind !== 'ref' || !entity.fragmentId) return false;\n const model = this.doc.ensureFragmentModel(entity.fragmentId);\n this.refEdit = { entityId: id, fragmentId: entity.fragmentId };\n const fallback = Math.max(0, model.length - (model.spacers.endsWith('\\n') ? 1 : 0));\n this.fragSel = collapsedSel(at === undefined ? fallback : Math.max(0, Math.min(at, model.length)));\n this.relayout();\n this.ime.focus();\n return true;\n }\n\n private exitRefEdit(side?: 'before' | 'after') {\n if (!this.refEdit) return;\n const box = this.activeRefBox();\n const index = box?.index ?? selStart(this.sel);\n this.refEdit = null;\n if (side === 'before') this.sel = collapsedSel(index);\n else if (side === 'after') this.sel = collapsedSel(index + 1);\n else this.sel = { anchor: index, focus: index + 1 };\n this.relayout();\n this.ime.focus();\n }\n\n private onRefJump = (e: Event) => {\n const { fragmentId, id } = (e as CustomEvent<RefJumpDetail>).detail;\n const indices = this.doc.refIndices(fragmentId);\n if (indices.length < 2) return;\n const box = this.layout.images.find((b) => b.entity.id === id);\n const here = box?.index ?? -1;\n const pos = Math.max(0, indices.indexOf(here));\n const next = indices[(pos + 1) % indices.length];\n this.exitRefEdit();\n this.sel = { anchor: next, focus: next + 1 };\n this.afterCaretMove();\n };\n\n private onDoubleClick = (e: MouseEvent) => {\n const { x, y } = this.localPoint(e);\n const box = this.hitImage(x, y);\n if (box?.entity.kind !== 'ref') {\n this.selectWordAt(x, y);\n return;\n }\n e.preventDefault();\n this.beginRefEdit(box.entity.id, this.hitRefIndex(box, x, y));\n };\n\n /** 双击选词。点在嵌入对象上、空白或标点上时不处理,保留 mousedown 已定的光标。 */\n private selectWordAt(x: number, y: number) {\n if (!this.refEdit && this.hitImage(x, y)) return;\n const doc = this.targetDoc();\n let index: number;\n if (this.refEdit) {\n const box = this.activeRefBox();\n if (!box?.inner) return;\n index = hitTestIndex(box.inner, x - (box.x + REF_PAD), y - (box.y + REF_HEAD));\n } else {\n index = nearestSafeIndex(doc.spacers, hitTestIndex(this.layout, x, y));\n }\n const range = wordRangeAt(doc.spacers, index);\n if (!range) return;\n if (this.refEdit) {\n this.fragSel = { anchor: range.start, focus: range.end };\n } else {\n const editing = this.editingSlot();\n if (editing?.empty) return;\n const lo = editing ? Math.max(editing.start, range.start) : range.start;\n const hi = editing ? Math.min(editing.end, range.end) : range.end;\n if (lo >= hi) return;\n this.sel = { anchor: lo, focus: hi };\n }\n this.afterCaretMove();\n }\n\n private applyEmbedPatch(id: string, patch: Partial<EmbedEntity>) {\n this.applyNow(ops.updateImage(id, patch));\n const entity = this.doc.entities.get(id);\n if (!entity) return;\n const size = embedPlugin(entity.kind).measure(entity, this.layout.contentWidth);\n this.applyNow(ops.updateImage(id, size));\n this.layout = layoutDocument(this.doc, this.contentWidth, this.layout, this.padding);\n this.painter.paintDoc(this.layout);\n this.paintChrome();\n }\n\n private onEmbedMeasure = (e: Event) => {\n const { id, width, height } = (e as CustomEvent<EmbedMeasureDetail>).detail;\n const entity = this.doc.entities.get(id);\n if (!entity) return;\n // 尺寸没变就不重排;变了只更新布局,不进撤销栈、不开编辑事务。\n if (entity.width === width && entity.height === height) return;\n this.applyEmbedPatch(id, { width, height });\n };\n\n private onEmbedChange = (e: Event) => {\n const { id, patch } = (e as CustomEvent<EmbedChangeDetail>).detail;\n const entity = this.doc.entities.get(id);\n if (!entity) return;\n if (!this.embedEdit || this.embedEdit.id !== id) this.embedEdit = { id, before: cloneEntity(entity) };\n this.applyEmbedPatch(id, patch);\n };\n\n private onEmbedCommit = (e: Event) => {\n const { id, patch } = (e as CustomEvent<EmbedChangeDetail>).detail;\n const before = this.embedEdit?.id === id ? this.embedEdit.before : this.doc.entities.get(id);\n this.applyEmbedPatch(id, patch);\n const after = this.doc.entities.get(id);\n this.embedEdit = null;\n if (!before || !after) return;\n if (\n before.code === after.code &&\n before.latex === after.latex &&\n before.language === after.language &&\n before.width === after.width &&\n before.height === after.height &&\n before.slotValue === after.slotValue &&\n before.src === after.src &&\n before.label === after.label &&\n before.hostType === after.hostType &&\n before.data === after.data\n ) {\n return;\n }\n const prev = cloneEntity(before);\n const next = cloneEntity(after);\n this.commitPreview('embed.update', ops.updateImage(id, prev), ops.updateImage(id, next));\n };\n\n private onEmbedExitEdit = (e: Event) => {\n const { id, side } = (e as CustomEvent<EmbedExitDetail>).detail;\n const box = this.layout.images.find((b) => b.entity.id === id);\n if (!box) return;\n this.sel = collapsedSel(side === 'before' ? box.index : box.index + 1);\n this.afterCaretMove();\n this.ime.focus();\n };\n\n private insertMediaFile(file: File, kind: 'image' | 'video') {\n if (this.selectedRegion()) return;\n const src = URL.createObjectURL(file);\n const commit = (nw: number, nh: number) => {\n if (this.selectedRegion()) return;\n const max = 360;\n const w0 = nw > 0 ? nw : 360;\n const h0 = nh > 0 ? nh : Math.round(w0 / VIDEO_ASPECT);\n const scale = w0 > max ? max / w0 : 1;\n const entity = {\n id: nextEntityId(),\n src,\n width: Math.max(24, Math.round(w0 * scale)),\n height: Math.max(24, Math.round(h0 * scale)),\n kind\n };\n this.runEdit('embed.insert', (ctx) => {\n this.deleteSelectionIfNeeded(ctx);\n const next = ops.insertImage(ctx.selection().focus, entity)(ctx);\n ctx.select({ anchor: next - 1, focus: next });\n });\n };\n if (kind === 'video') {\n const video = document.createElement('video');\n video.preload = 'metadata';\n video.onloadedmetadata = () => commit(video.videoWidth, video.videoHeight);\n video.onerror = () => commit(360, Math.round(360 / VIDEO_ASPECT));\n video.src = src;\n return;\n }\n const img = new Image();\n img.onload = () => commit(img.width, img.height);\n img.onerror = () => commit(360, 360);\n img.src = src;\n }\n\n private insertTable() {\n if (this.selectedRegion()) return;\n this.runEdit('table.insert', (ctx) => {\n this.deleteSelectionIfNeeded(ctx);\n ctx.select(collapsedSel(ops.insertTable(ctx.selection().focus, 2, 2)(ctx)));\n });\n }\n\n private tableOp(op: 'row' | 'col' | 'del-row' | 'del-col') {\n this.runEdit('table.structure', (ctx) => {\n const focus = ctx.selection().focus;\n if (op === 'row') ops.insertTableRow(focus)(ctx);\n if (op === 'col') ops.insertTableCol(focus)(ctx);\n if (op === 'del-row') ops.deleteTableRow(focus)(ctx);\n if (op === 'del-col') ops.deleteTableCol(focus)(ctx);\n });\n }\n\n undo() {\n this.applyHistoryStep(this.undoStack.popForUndo());\n }\n\n redo() {\n this.applyHistoryStep(this.undoStack.popForRedo());\n }\n\n /**\n * 执行撤销栈交回来的一步。\n *\n * 栈给的是一条常规 EditResult:`mutations` 直接应用,选区取 `selectionAfter`。\n * 选区属于哪个坐标空间由 `meta.scope` 说了算 —— 片段里的编辑,撤销时该动的是\n * 片段选区。\n */\n private applyHistoryStep(step: EditResult | null) {\n if (!step) return;\n applyMutations(this.doc, step.mutations);\n if (step.meta.scope) this.fragSel = { ...step.selectionAfter };\n else this.sel = { ...step.selectionAfter };\n this.typingStyle = null;\n this.relayout();\n // 撤销/重做同样改变了文档内容,外部缓存需要随之刷新。\n this.emit('change');\n }\n\n private relayout(opts?: { reuse?: boolean }) {\n // 每次重排前按当前容器宽度更新内容宽度('fill' 模式下会随容器变化)。\n // contentWidth 未变时 engine 内部走增量复用,不会有额外重排开销。\n this.contentWidth = this.resolveContentWidth();\n this.syncActiveFragment();\n this.refreshRefMetrics();\n const prev = opts?.reuse === false ? undefined : this.layout;\n this.layout = layoutDocument(this.doc, this.contentWidth, prev, this.padding);\n this.root.style.setProperty('--mini-content-width', `${Math.max(0, this.layout.contentWidth)}px`);\n this.painter.paintDoc(this.layout);\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n this.scrollCaret();\n // 失焦后不要抢回 IME,否则点到页内其它控件还会看到光标。\n if (document.activeElement === this.ime.el) this.ime.focus();\n this.emit('layoutchange');\n }\n\n private paintChrome() {\n const embed = this.selectedImage();\n if (this.refEdit) {\n const box = this.activeRefBox();\n const origin = box ? { x: box.x + REF_PAD, y: box.y + REF_HEAD } : { x: 0, y: 0 };\n const rects = box?.inner\n ? selectionRects(box.inner, this.fragSel).map((r) => ({ ...r, x: r.x + origin.x, y: r.y + origin.y }))\n : [];\n this.painter.paintSelection(rects);\n } else {\n this.painter.paintSelection(embed ? [] : this.selectionPaintRects());\n }\n this.paintCaretLayer();\n this.updateEmbedChrome(embed);\n this.decorateRefNodes();\n this.decorateHostNodes();\n this.syncPlaceholder();\n }\n\n /**\n * 占位只在「看不见任何正文」时出现。组合一开始(哪怕候选串还是空的)就必须关掉:\n * 中间态走 applyNow,不发 change,宿主叠层会一直以为是空的。\n */\n private syncPlaceholder() {\n const composing = this.ime.composing || this.composeAnchor !== null;\n const show = !!this.placeholderText && !composing && isVisuallyEmptyDoc(this.doc);\n this.placeholderEl.hidden = !show;\n if (!show) return;\n this.placeholderEl.textContent = this.placeholderText;\n const line = this.layout.lines[0];\n const para = this.doc.paragraphPropsAt(0);\n const style = resolvedTextStyle(this.doc, 0, para);\n const size = style.fontSize ?? 16;\n const color = this.chrome.placeholderColor ?? '';\n const opacity =\n this.chrome.placeholderOpacity !== undefined ? String(this.chrome.placeholderOpacity) : '';\n this.placeholderEl.style.cssText = [\n `left:${this.layout.contentX}px`,\n `top:${line?.y ?? this.layout.contentY}px`,\n `max-width:${Math.max(0, this.layout.contentWidth)}px`,\n `font-size:${size}px`,\n `line-height:${line?.h ?? lineHeightOf(style)}px`,\n color ? `color:${color}` : '',\n opacity ? `opacity:${opacity}` : '',\n ]\n .filter(Boolean)\n .join(';');\n }\n\n private decorateHostNodes() {\n syncHostSelected(this.selectedImage()?.entity.id ?? null);\n }\n\n private decorateRefNodes() {\n const selectedId = this.selectedImage()?.entity.id;\n for (const node of this.pageInner.querySelectorAll<HTMLElement>('.mini-ref')) {\n const id = node.dataset.entity;\n const entity = id ? this.doc.entities.get(id) : undefined;\n if (!entity?.fragmentId) continue;\n const fragment = this.doc.fragments.get(entity.fragmentId);\n decorateRefEl(\n node,\n this.doc.refCount(entity.fragmentId),\n fragment?.title ?? '同步块',\n this.refEdit?.entityId === entity.id,\n selectedId === entity.id || this.refEdit?.entityId === entity.id\n );\n }\n }\n\n private paintCaretLayer() {\n const style = this.currentTextStyle();\n const mapped = this.refCaretPos();\n const demoCaret = this.chrome.caret === 'rainbow';\n const caret = {\n ...(mapped ?? caretFromIndex(this.layout, this.sel.focus)),\n italic: demoCaret && !!style.italic,\n bold: demoCaret && !!style.bold\n };\n if (demoCaret) {\n caret.opacity = 0.22 + 0.78 * (0.5 + 0.5 * Math.cos(performance.now() / 180));\n } else if (this.paintMode === 'canvas') {\n // 按墙钟闪,不要跟 rAF 帧数绑:CommandBox canvas 有 host 时帧率会掉,64 帧一圈会变得很慢。\n const period = 1060;\n const posKey = `${caret.x}:${caret.y}:${caret.h}`;\n const now = performance.now();\n if (posKey !== this.blinkPosKey) {\n this.blinkPosKey = posKey;\n this.blinkEpoch = now;\n }\n caret.opacity = (now - this.blinkEpoch) % period < period / 2 ? 1 : 0;\n }\n const key = `${Math.round(caret.x)}:${Math.round(caret.y)}:${Math.round(caret.h)}`;\n if (this.caretTrailEnabled() && key !== this.lastCaretKey) {\n if (this.lastCaretKey) this.caretTrails.unshift({ ...caret, opacity: 0.35 });\n this.caretTrails = this.caretTrails.slice(0, 3);\n this.lastCaretKey = key;\n }\n if (!this.caretTrailEnabled()) this.caretTrails = [];\n const showCaret =\n this.isFocused() &&\n !this.isEmbedChromeFocused() &&\n (this.refEdit ? isCollapsed(this.fragSel) : isCollapsed(this.sel));\n this.painter.paintCaret(\n showCaret ? caret : null,\n showCaret,\n this.caretTrailEnabled() ? this.caretTrails : []\n );\n const imeH = lineHeightOf(style);\n // 系统输入法靶子锚在组合起点,作为候选框的定位点;它本身透明、只占 1px,\n // 不再撑白块盖字(组合串的可见呈现完全交给模型正文)。\n const anchorPos = this.ime.composing ? this.composeCaret() : caret;\n const imeY = anchorPos.y + Math.max(0, (anchorPos.h - imeH) / 2);\n this.ime.moveTo(anchorPos.x, imeY, imeH);\n // 自绘的组合区下划线:从组合起点铺到组合串末尾。组合串在模型里,宽度与正文\n // 同度量,天然对齐。\n const composeW = this.ime.composing && this.composeText ? Math.max(12, measureWidth(this.composeText, style)) : 0;\n this.imeBar.style.display = composeW ? 'block' : 'none';\n if (composeW) {\n const underlineH = this.chrome.composeUnderlineWidth ?? 2;\n this.imeBar.style.left = `${anchorPos.x}px`;\n this.imeBar.style.top = `${anchorPos.y + anchorPos.h - underlineH}px`;\n this.imeBar.style.width = `${composeW}px`;\n }\n }\n\n /** 组合串起点(锚点)的屏幕坐标;主文档与片段内编辑都算对。 */\n private composeCaret(): CaretPos {\n const anchor = this.composeAnchor ?? this.targetSel().focus;\n if (this.refEdit) {\n const box = this.activeRefBox();\n if (box?.inner) {\n const c = caretFromIndex(box.inner, anchor);\n return { ...c, x: c.x + box.x + REF_PAD, y: c.y + box.y + REF_HEAD };\n }\n }\n return caretFromIndex(this.layout, anchor);\n }\n\n private refCaretPos(): CaretPos | null {\n if (!this.refEdit) return null;\n const box = this.activeRefBox();\n if (!box?.inner) return null;\n const caret = caretFromIndex(box.inner, this.fragSel.focus);\n return { ...caret, x: caret.x + box.x + REF_PAD, y: caret.y + box.y + REF_HEAD };\n }\n\n private currentTextStyle(): TextProps {\n const doc = this.targetDoc();\n const sel = this.targetSel();\n if (this.typingStyle) return { ...this.currentParaTextDefaults(), ...this.typingStyle };\n const para = doc.paragraphPropsAt(sel.focus);\n const idx = isCollapsed(sel) ? Math.max(0, sel.focus - 1) : selStart(sel);\n return resolvedTextStyle(doc, idx, para);\n }\n\n private currentParaTextDefaults(): TextProps {\n const doc = this.targetDoc();\n const sel = this.targetSel();\n return resolvedTextStyle(doc, sel.focus, doc.paragraphPropsAt(sel.focus));\n }\n\n private syncToolbar() {\n this.emit('statechange');\n }\n\n private syncStatus() {\n this.emit('selectionchange');\n }\n\n private resetBlink() {\n this.blinkEpoch = performance.now();\n window.cancelAnimationFrame(this.caretRaf);\n this.caretRaf = 0;\n this.paintCaretLayer();\n // HTML 实心光标靠 CSS 闪;每帧写 opacity/display 会把动画掐掉,看起来像闪得很慢。\n if (this.caretIsSolid() && this.paintMode !== 'canvas') return;\n const tick = () => {\n this.paintCaretLayer();\n this.caretRaf = window.requestAnimationFrame(tick);\n };\n this.caretRaf = window.requestAnimationFrame(tick);\n }\n\n /** 从内到外找出真正会滚动的祖先(编辑器自己的 page、宿主限高容器、整页)。 */\n /** scrollParents 结果缓存:祖先链上的 overflow 很少变,300ms 内复用,省掉每次按键的 getComputedStyle。 */\n private scrollParentsCache: { at: number; list: HTMLElement[] } | null = null;\n /**\n * 上次 scrollCaret 真正读到的几何:各滚动容器的可视区与 surface 顶部(client 坐标)。\n * 任何滚动 / 窗口尺寸变化都会清掉;用它先判断光标还在不在可视区里,在就不碰布局。\n */\n private viewGeom: { at: number; surfaceTop: number; views: { sc: HTMLElement; top: number; h: number }[] } | null = null;\n private onAnyScroll = () => {\n this.viewGeom = null;\n };\n\n private scrollParents(): HTMLElement[] {\n const now = performance.now();\n if (this.scrollParentsCache && now - this.scrollParentsCache.at < 300 && this.page.isConnected) {\n return this.scrollParentsCache.list;\n }\n const out: HTMLElement[] = [];\n let el: HTMLElement | null = this.page;\n while (el && el !== document.body && el !== document.documentElement) {\n const oy = getComputedStyle(el).overflowY;\n if ((oy === 'auto' || oy === 'scroll' || oy === 'overlay') && el.scrollHeight > el.clientHeight) {\n out.push(el);\n }\n el = el.parentElement;\n }\n const root = document.scrollingElement as HTMLElement | null;\n if (root && root.scrollHeight > root.clientHeight) out.push(root);\n this.scrollParentsCache = { at: now, list: out };\n return out;\n }\n\n private scrollCaret() {\n const caret = this.refCaretPos() ?? caretFromIndex(this.layout, this.sel.focus);\n const surface = this.painter.getSurface();\n const parents = this.scrollParents();\n const now = performance.now();\n // 快速路径:几何缓存还新鲜(没滚动、没改窗口、300ms 内),且光标按缓存算仍在每个\n // 可视区内,就不读布局。读 getBoundingClientRect 会强制回流,是这里主要的开销。\n const geom = this.viewGeom;\n if (geom && now - geom.at < 300 && geom.views.length === parents.length && geom.views.every((v, i) => v.sc === parents[i])) {\n const top = geom.surfaceTop + caret.y;\n const bottom = top + caret.h;\n const inside = geom.views.every((v) => {\n const margin = Math.max(0, Math.min(40, (v.h - caret.h) / 2));\n return top - margin >= v.top && bottom + margin <= v.top + v.h;\n });\n if (inside) return;\n }\n const views: { sc: HTMLElement; top: number; h: number }[] = [];\n for (const sc of parents) {\n const isRoot = sc === document.scrollingElement;\n const viewTop = isRoot ? 0 : sc.getBoundingClientRect().top;\n const viewH = isRoot ? window.innerHeight : sc.clientHeight;\n const margin = Math.max(0, Math.min(40, (viewH - caret.h) / 2));\n // 每轮重新量:内层滚动之后,外层看到的光标位置也变了。\n const top = surface.getBoundingClientRect().top + caret.y;\n const bottom = top + caret.h;\n if (top - margin < viewTop) sc.scrollTop += top - margin - viewTop;\n else if (bottom + margin > viewTop + viewH) sc.scrollTop += bottom + margin - (viewTop + viewH);\n views.push({ sc, top: viewTop, h: viewH });\n }\n // 滚完再量一次 surface 位置作为缓存基准。程序触发的 scroll 事件下一帧才到,会再清一次缓存,\n // 那只是多读一回,不影响正确性。\n this.viewGeom = { at: now, surfaceTop: surface.getBoundingClientRect().top, views };\n }\n\n private lastDragEvent: MouseEvent | null = null;\n private dragScrollRaf = 0;\n\n /** 拖选时鼠标停在视图外也要持续滚动并扩选,行为同原生。 */\n /** 上下键的目标列:x 是出发时的光标横坐标,focus 是上一次落点,用来判断 goal 是否仍有效 */\n private verticalGoal: { x: number; focus: number } | null = null;\n\n private dragScrollTick = () => {\n this.dragScrollRaf = 0;\n const e = this.lastDragEvent;\n if (!this.dragging || !e) return;\n const sc = this.scrollParents()[0];\n if (!sc) return;\n const r = sc.getBoundingClientRect();\n const edge = 24;\n let dy = 0;\n if (e.clientY < r.top + edge) dy = -Math.min(24, (r.top + edge - e.clientY) / 3 + 2);\n else if (e.clientY > r.bottom - edge) dy = Math.min(24, (e.clientY - (r.bottom - edge)) / 3 + 2);\n if (!dy) return;\n const before = sc.scrollTop;\n sc.scrollTop += dy;\n if (sc.scrollTop !== before) this.extendDragTo(e);\n this.dragScrollRaf = window.requestAnimationFrame(this.dragScrollTick);\n };\n\n private extendDragTo(e: MouseEvent) {\n // 鼠标在滚动视口外时按视口边缘取点,避免一下子选到文末/文首。\n const sc = this.scrollParents()[0];\n let cy = e.clientY;\n if (sc) {\n const r = sc.getBoundingClientRect();\n cy = Math.min(r.bottom - 1, Math.max(r.top + 1, cy));\n }\n const rect = this.painter.getSurface().getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = cy - rect.top;\n const focus = nearestSafeIndex(this.doc.spacers, hitTestIndex(this.layout, x, y));\n this.sel = this.expandSel(this.dragAnchor, this.snapIndexForDrag(this.dragAnchor, focus));\n this.paintChrome();\n this.syncStatus();\n }\n\n private localPoint(e: MouseEvent): { x: number; y: number } {\n const rect = this.painter.getSurface().getBoundingClientRect();\n return { x: e.clientX - rect.left, y: e.clientY - rect.top };\n }\n\n private ctxMenuOrigin: { x: number; y: number } | null = null;\n\n private endContextMenu = () => {\n if (!this.ctxMenuOrigin) return;\n this.ctxMenuOrigin = null;\n this.ime.endContextMenu();\n for (const type of ['mousedown', 'keydown', 'copy', 'cut', 'paste'] as const) {\n document.removeEventListener(type, this.endContextMenuSoon, true);\n }\n window.removeEventListener('mousemove', this.onCtxMenuMove, true);\n this.paintCaretLayer();\n };\n\n /** copy/cut/paste 事件还要送达编辑器自己的处理函数,等它们跑完再收。 */\n private endContextMenuSoon = () => {\n window.setTimeout(this.endContextMenu, 0);\n };\n\n private onCtxMenuMove = (e: MouseEvent) => {\n const o = this.ctxMenuOrigin;\n if (o && Math.hypot(e.clientX - o.x, e.clientY - o.y) > 12) this.endContextMenu();\n };\n\n /**\n * 右键菜单:canvas 上右键会得到“存储图片”菜单,这里改成原生的 剪切/拷贝/粘贴。\n * 嵌入控件里的输入框等保留浏览器默认菜单。\n */\n private onContextMenu = (e: MouseEvent) => {\n if (this.disabled) return;\n const target = e.target as HTMLElement;\n if (target.closest('textarea, input, select, video, math-field, .mini-embed-interactive [contenteditable=\"true\"]')) return;\n const { x, y } = this.localPoint(e);\n if (!this.refEdit) {\n // 右键点在选区外:先把光标挪过去(原生输入框的行为)。点在嵌入对象上不动选区。\n const hit = this.hitImage(x, y);\n if (!hit) {\n const index = nearestSafeIndex(this.doc.spacers, hitTestIndex(this.layout, x, y));\n const lo = Math.min(this.sel.anchor, this.sel.focus);\n const hi = Math.max(this.sel.anchor, this.sel.focus);\n if (isCollapsed(this.sel) || index < lo || index > hi) {\n this.setSel(collapsedSel(index));\n this.afterCaretMove();\n }\n }\n }\n const sel = this.targetSel();\n const from = selStart(sel);\n const to = selEnd(sel);\n const text = from < to ? this.targetDoc().plainText(from, to).slice(0, 2000) : '';\n this.ctxMenuOrigin = { x: e.clientX, y: e.clientY };\n this.ime.beginContextMenu(x, y, text);\n for (const type of ['mousedown', 'keydown', 'copy', 'cut', 'paste'] as const) {\n document.addEventListener(type, this.endContextMenuSoon, true);\n }\n window.addEventListener('mousemove', this.onCtxMenuMove, true);\n };\n\n private onDocMouseDown = (e: MouseEvent) => {\n const t = e.target as Node;\n // parent 是宿主挂载点:空文档时表面比外层 min-height 矮,点到宿主空白\n // 仍应算编辑器内,否则会先 blur,再点也聚焦不住。\n this.keysArmed = this.root.contains(t) || this.parent.contains(t);\n if (!this.keysArmed) {\n this.ime.el.blur();\n this.paintCaretLayer();\n }\n };\n\n private onRootMouseDown = (e: MouseEvent) => {\n if (this.disabled) return;\n const el = e.target as HTMLElement;\n if (el.closest('.mini-embed-interactive') || el.closest('.mini-resize')) return;\n // 点的是非可聚焦层(空表面、占位、页边空白)。不 preventDefault 的话,\n // 浏览器会在 mousedown 默认动作里把刚 focus 的 IME 再 blur 掉。\n e.preventDefault();\n this.ime.focus();\n };\n\n private onFocusChange = () => {\n queueMicrotask(() => this.paintCaretLayer());\n };\n\n private onMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n if ((e.target as HTMLElement).closest('.mini-resize')) return;\n const { x, y } = this.localPoint(e);\n const refBox = this.hitImage(x, y);\n if (!this.refEdit && refBox?.entity.kind === 'ref') {\n e.preventDefault();\n this.setSel({ anchor: refBox.index, focus: refBox.index + 1 });\n this.ime.focus();\n this.resetBlink();\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n return;\n }\n if (this.refEdit) {\n if (refBox?.entity.kind === 'ref' && refBox.entity.fragmentId === this.refEdit.fragmentId) {\n e.preventDefault();\n this.refEdit = { entityId: refBox.entity.id, fragmentId: refBox.entity.fragmentId };\n this.sel = { anchor: refBox.index, focus: refBox.index + 1 };\n const index = this.hitRefIndex(refBox, x, y);\n this.fragSel = e.shiftKey ? { ...this.fragSel, focus: index } : collapsedSel(index);\n this.refDragging = true;\n this.refDragAnchor = e.shiftKey ? this.fragSel.anchor : index;\n this.ime.focus();\n this.resetBlink();\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n return;\n }\n this.exitRefEdit();\n }\n const interactive = (e.target as HTMLElement).closest('.mini-embed-interactive') as HTMLElement | null;\n if (interactive) {\n // 点在 embed 内部的真实交互控件(输入框、下拉、视频、公式域等)上:把焦点\n // 交给该控件本身,编辑器完全不介入——不 preventDefault、不选中整块、不抢焦点。\n // 否则浏览器的默认聚焦被阻止,控件拿不到焦点,键盘输入会落回编辑器(表现为\n // “一输入就替换整块”)。\n const field = (e.target as HTMLElement).closest('textarea, input, select, video, math-field, [contenteditable=\"true\"]');\n if (field) {\n this.keepTypingOnNextClick = false;\n return;\n }\n // 点在 embed 的非交互区域(外框/背景):选中整块。\n e.preventDefault();\n this.keepTypingOnNextClick = false;\n const index = Number(interactive.dataset.index);\n if (Number.isFinite(index)) {\n this.dragging = false;\n this.setSel({ anchor: index, focus: index + 1 });\n this.resetBlink();\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n }\n this.ime.focus();\n return;\n }\n e.preventDefault();\n this.ime.focus();\n if (this.keepTypingOnNextClick && !e.shiftKey && !e.metaKey && !e.ctrlKey) {\n this.keepTypingOnNextClick = false;\n this.resetBlink();\n this.paintChrome();\n this.syncToolbar();\n return;\n }\n const border = hitColBorder(this.layout, x, y);\n if (border) {\n this.colResizing = { tableStart: border.tableStart, col: border.col, startX: e.clientX, widths: border.widths };\n return;\n }\n const index = nearestSafeIndex(this.doc.spacers, hitTestIndex(this.layout, x, y));\n if ((e.metaKey || e.ctrlKey) && !e.shiftKey) {\n const url = this.doc.linkUrlAt(index);\n if (url && openSafeUrl(url)) return;\n }\n const img = this.hitImage(x, y);\n if (img) {\n this.vblockStack = [];\n this.setSel({ anchor: img.index, focus: img.index + 1 });\n } else if (e.shiftKey) {\n this.setSel(this.expandSel(this.sel.anchor, this.snapIndexForDrag(this.sel.anchor, index)));\n } else if (this.hitVblockClick(index)) {\n // stack/selection already updated\n } else {\n this.vblockStack = [];\n this.setSel(collapsedSel(index));\n }\n this.dragAnchor = this.sel.anchor;\n this.dragging = true;\n this.resetBlink();\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n };\n\n private onMouseMove = (e: MouseEvent) => {\n const { x, y } = this.localPoint(e);\n if (this.refDragging && this.refEdit) {\n const box = this.activeRefBox();\n if (box) {\n const index = this.hitRefIndex(box, x, y);\n this.fragSel = { anchor: this.refDragAnchor, focus: index };\n this.paintChrome();\n this.syncStatus();\n }\n return;\n }\n if (this.colResizing) {\n this.applyColResize(e.clientX);\n return;\n }\n if (this.resizing) {\n const dx = e.clientX - this.resizing.startX;\n const w = Math.max(40, this.resizing.startW + dx);\n const entity = this.doc.entities.get(this.resizing.id);\n const plugin = embedPlugin(entity?.kind);\n if (plugin.keepAspectRatio) {\n const ratio = this.resizing.startH / this.resizing.startW;\n this.applyNow(ops.updateImage(this.resizing.id, { width: Math.round(w), height: Math.round(w * ratio) }));\n } else {\n this.applyNow(ops.updateImage(this.resizing.id, { width: Math.round(w) }));\n if (entity) {\n const size = plugin.measure({ ...entity, width: Math.round(w) }, this.layout.contentWidth);\n this.applyNow(ops.updateImage(this.resizing.id, size));\n }\n }\n this.layout = layoutDocument(this.doc, this.contentWidth, this.layout, this.padding);\n this.painter.paintDoc(this.layout);\n this.paintChrome();\n return;\n }\n if (!this.dragging) {\n this.painter.getSurface().classList.toggle('is-col-resize', !!hitColBorder(this.layout, x, y));\n this.setHoverMark(e.buttons ? null : this.markAt(x, y));\n this.painter.getSurface().classList.toggle('is-over-slot', this.overVirtualSlot(x, y));\n return;\n }\n this.setHoverMark(null);\n this.lastDragEvent = e;\n this.extendDragTo(e);\n if (!this.dragScrollRaf) this.dragScrollRaf = window.requestAnimationFrame(this.dragScrollTick);\n };\n\n private onMouseUp = () => {\n if (this.colResizing) {\n const { tableStart, widths } = this.colResizing;\n const next = this.doc.tablePropsAt(tableStart).colWidths ?? widths;\n this.colResizing = null;\n if (next.some((w, i) => w !== widths[i])) {\n this.commitPreview(\n 'table.colWidth',\n ops.setTableColWidths(tableStart, widths),\n ops.setTableColWidths(tableStart, next)\n );\n }\n }\n if (this.resizing) {\n const id = this.resizing.id;\n const entity = this.doc.entities.get(id);\n const startW = this.resizing.startW;\n const startH = this.resizing.startH;\n this.resizing = null;\n if (entity && (entity.width !== startW || entity.height !== startH)) {\n const w = entity.width;\n const h = entity.height;\n this.commitPreview(\n 'embed.resize',\n ops.updateImage(id, { width: startW, height: startH }),\n ops.updateImage(id, { width: w, height: h })\n );\n }\n }\n this.dragging = false;\n this.refDragging = false;\n this.lastDragEvent = null;\n window.cancelAnimationFrame(this.dragScrollRaf);\n this.dragScrollRaf = 0;\n };\n\n private onResizeStart = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n const img = this.selectedImage();\n if (!img || img.entity.kind === 'internalSlot' || img.entity.kind === 'ref') return;\n this.resizing = { id: img.entity.id, startX: e.clientX, startW: img.entity.width, startH: img.entity.height };\n };\n\n private hitImage(x: number, y: number) {\n const hits = this.layout.images.filter((b) => x >= b.x && x <= b.x + b.w && y >= b.y && y <= b.y + b.h);\n return hits.find((b) => b.entity.kind === 'ref') ?? hits[hits.length - 1] ?? null;\n }\n\n private selectedImage() {\n if (selEnd(this.sel) - selStart(this.sel) !== 1) return null;\n const i = selStart(this.sel);\n if (this.doc.spacers[i] !== MARKERS.IMAGE) return null;\n return imageBoxAt(this.layout, i);\n }\n\n private updateEmbedChrome(img = this.selectedImage()) {\n if (!img) {\n this.embedFrame.style.display = 'none';\n this.handle.style.display = 'none';\n return;\n }\n const isSlot = img.entity.kind === 'internalSlot';\n const isRef = img.entity.kind === 'ref';\n const isHost = img.entity.kind === 'hostSlot';\n this.embedFrame.classList.toggle('is-slot', isSlot);\n this.embedFrame.classList.toggle('is-ref', isRef);\n this.embedFrame.classList.toggle('is-image', isSlot && img.entity.slotKind === 'image');\n // host 选中态由宿主组件自己画(如 InlineButton data-selected),不叠 SDK 蓝框。\n this.embedFrame.style.display =\n this.refEdit || isHost ? 'none' : 'block';\n this.embedFrame.style.left = `${img.x}px`;\n this.embedFrame.style.top = `${img.y}px`;\n this.embedFrame.style.width = `${img.w}px`;\n this.embedFrame.style.height = `${img.h}px`;\n // 尺寸由宿主渲染回报决定的 host 块,和插槽/引用一样不提供拖拽缩放手柄。\n this.handle.style.display = isSlot || isRef || isHost ? 'none' : 'block';\n this.handle.style.left = `${img.x + img.w - 5}px`;\n this.handle.style.top = `${img.y + img.h - 5}px`;\n }\n\n private writeClipboard(data: DataTransfer | null) {\n if (!data) return;\n const doc = this.targetDoc();\n const from = selStart(this.targetSel());\n const to = selEnd(this.targetSel());\n const slice = doc.takeSlice(from, to);\n data.setData(SLICE_MIME, serializeSlice(slice));\n data.setData('text/plain', doc.plainText(from, to));\n data.setData('text/html', sliceToHtml(slice));\n }\n\n private onCopy = (e: ClipboardEvent) => {\n if (!this.isFocused() || this.isEmbedChromeFocused()) return;\n if (isCollapsed(this.sel)) return;\n e.preventDefault();\n this.writeClipboard(e.clipboardData);\n };\n\n private onCut = (e: ClipboardEvent) => {\n if (!this.isFocused() || this.isEmbedChromeFocused()) return;\n if (isCollapsed(this.sel)) return;\n if (this.selectedRegion()) {\n e.preventDefault();\n return;\n }\n e.preventDefault();\n this.writeClipboard(e.clipboardData);\n this.backspace();\n };\n\n private isFocused(): boolean {\n return this.root.contains(document.activeElement);\n }\n\n /** 焦点在公式/槽等嵌入控件内时不画外层光标。 */\n private isEmbedChromeFocused(): boolean {\n const el = document.activeElement;\n if (!el || el === this.ime.el) return false;\n return !!el.closest('.mini-embed-interactive');\n }\n\n /**\n * 这次按键归不归本编辑器管。\n *\n * 「哪个键干什么」在 commands/shortcuts.ts 里,门面只回答这一个问题 —— 焦点在\n * 别的输入框、编辑器没装备快捷键、焦点在嵌入对象的字段里,都不接。\n */\n private acceptsKey(e: KeyboardEvent): boolean {\n if (this.disabled) return false;\n const target = e.target as HTMLElement;\n if (target.closest('input, textarea, select, math-field')) return false;\n if (!this.keysArmed && !this.root.contains(target)) return false;\n return !this.isEmbedChromeFocused();\n }\n\n private selectAll() {\n const editing = this.editingSlot();\n if (editing) {\n this.sel = { anchor: editing.start, focus: editing.end };\n this.paintChrome();\n this.syncStatus();\n return;\n }\n const full = { anchor: 0, focus: this.targetDoc().length };\n if (this.refEdit) this.fragSel = full;\n else this.sel = full;\n this.paintChrome();\n this.syncStatus();\n }\n\n /** Escape:先弹出虚拟块一层,再退出同步块内部编辑。 */\n private exitFragmentEdit(): boolean {\n if (this.vblockStack.length) {\n this.popVblock();\n return true;\n }\n if (!this.refEdit) return false;\n this.exitRefEdit();\n return true;\n }\n\n /** Tab:在列表里改嵌套层级,否则在表格里跳到下一格。 */\n private indentOrNextCell(dir: 1 | -1) {\n const inList = this.doc.paragraphPropsAt(this.sel.focus).list !== 'none';\n if (!inList && this.moveTableCell(dir)) return;\n this.changeIndent(dir);\n }\n\n private moveTableCell(dir: 1 | -1): boolean {\n const here = cellAt(this.doc.spacers, this.sel.focus);\n if (!here) return false;\n if (dir > 0 && isLastTableCell(here)) {\n this.runEdit('table.structure', (ctx) => {\n ops.insertTableRow(ctx.selection().focus)(ctx);\n });\n }\n const next = nextCellIndex(this.doc.spacers, this.sel.focus, dir);\n if (next === null) return false;\n const hit = cellAt(this.doc.spacers, next);\n if (!hit) {\n this.sel = collapsedSel(next);\n } else {\n const range = cellContentRange(hit.cell);\n this.sel = { anchor: range.start, focus: range.end };\n }\n this.relayout();\n return true;\n }\n\n private expandSel(anchor: number, focus: number): Selection {\n const a = cellAt(this.doc.spacers, anchor);\n const b = cellAt(this.doc.spacers, focus);\n if (a && b && a.table.start === b.table.start && (a.row !== b.row || a.col !== b.col)) {\n const r0 = Math.min(a.row, b.row);\n const r1 = Math.max(a.row, b.row);\n const c0 = Math.min(a.col, b.col);\n const c1 = Math.max(a.col, b.col);\n let start = Infinity;\n let end = -Infinity;\n for (let r = r0; r <= r1; r++) {\n for (let c = c0; c <= c1; c++) {\n const cell = a.table.rows[r]?.cells[c];\n if (!cell) continue;\n start = Math.min(start, cell.start);\n end = Math.max(end, cell.end);\n }\n }\n if (start < end) return { anchor: start, focus: end };\n }\n return { anchor, focus };\n }\n\n private applyColResize(clientX: number) {\n if (!this.colResizing) return;\n const { tableStart, col, startX, widths } = this.colResizing;\n const next = [...widths];\n const sum = widths[col] + widths[col + 1];\n const w1 = Math.max(MIN_COL_WIDTH, Math.min(sum - MIN_COL_WIDTH, widths[col] + (clientX - startX)));\n next[col] = Math.round(w1);\n next[col + 1] = Math.round(sum - w1);\n this.applyNow(ops.setTableColWidths(tableStart, next));\n this.layout = layoutDocument(this.doc, this.contentWidth, this.layout, this.padding);\n this.painter.paintDoc(this.layout);\n this.paintChrome();\n }\n\n private moveCaret(key: ArrowKey, extend: boolean) {\n if (this.refEdit) {\n this.moveFragmentCaret(key, extend);\n return;\n }\n if (!extend && (key === 'ArrowLeft' || key === 'ArrowRight')) {\n const vnext = this.moveAcrossVblock(key === 'ArrowRight' ? 1 : -1);\n if (vnext) {\n this.sel = vnext;\n this.afterCaretMove();\n return;\n }\n const next = this.moveAcrossEmbed(key === 'ArrowRight' ? 1 : -1);\n if (next) {\n this.sel = next;\n this.afterCaretMove();\n return;\n }\n }\n let index = this.sel.focus;\n const vertical = key === 'ArrowUp' || key === 'ArrowDown';\n // 上下移动要记住\"目标列\":连续按上下键时始终用第一次出发的 x,不然每行吸附一次会越跑越偏。\n // 只要焦点被别的操作挪过(左右键、点击、输入),goal 的 focus 就对不上,自动作废。\n const goalX =\n vertical && this.verticalGoal?.focus === index ? this.verticalGoal.x : this.verticalStartX(index);\n if (key === 'ArrowLeft') index = this.stepIndex(index, -1);\n if (key === 'ArrowRight') index = this.stepIndex(index, 1);\n if (key === 'ArrowUp') index = this.verticalMove(index, -1, goalX);\n if (key === 'ArrowDown') index = this.verticalMove(index, 1, goalX);\n const remember = () => {\n this.verticalGoal = vertical ? { x: goalX, focus: this.sel.focus } : null;\n };\n if (!extend && this.doc.spacers[index] === MARKERS.IMAGE) {\n this.sel = { anchor: index, focus: index + 1 };\n } else if (extend) {\n this.sel = { ...this.sel, focus: this.snapIndexForDrag(this.sel.anchor, index) };\n } else {\n this.sel = collapsedSel(index);\n }\n const editing = this.editingSlot();\n if (editing) {\n const a = Math.min(editing.end, Math.max(editing.start, this.sel.anchor));\n const f = Math.min(editing.end, Math.max(editing.start, this.sel.focus));\n this.sel = editing.empty ? collapsedSel(editing.start) : { anchor: a, focus: f };\n } else if (!extend && (key === 'ArrowUp' || key === 'ArrowDown')) {\n const slot = this.doc.innermostSlotAt(this.sel.focus) ?? this.doc.slotAtCaret(this.sel.focus);\n if (slot) {\n this.selectVblock(slot.id, 'editing');\n remember();\n this.afterCaretMove();\n return;\n }\n }\n remember();\n this.afterCaretMove();\n }\n\n /** 光标所在的可视行(折行边界上的同一下标以光标实际画的那一行为准)。 */\n private lineAt(layout: DocLayout, index: number): LineBox | null {\n const y = caretFromIndex(layout, index).y;\n return (\n layout.lines.find((l) => Math.abs(l.y - y) < 1 && index >= l.start && index <= l.end) ??\n layout.lines.find((l) => index >= l.start && index <= l.end) ??\n null\n );\n }\n\n private motionTarget(unit: MoveUnit, dir: 1 | -1, index: number, doc: DocumentModel, layout: DocLayout): number {\n const spacers = doc.spacers;\n if (unit === 'doc') return dir < 0 ? 0 : maxCaretIndex(spacers);\n if (unit === 'word') return wordTarget(spacers, index, dir);\n if (unit === 'paragraph') return paragraphTarget(spacers, index, dir);\n const line = this.lineAt(layout, index);\n if (!line) return index;\n if (dir < 0) return line.start;\n // 段末那一行的 end 若含段落符,光标应停在它前面。\n return line.end > line.start && spacers[line.end - 1] === '\\n' ? line.end - 1 : line.end;\n }\n\n private moveCaretBy(unit: MoveUnit, dir: 1 | -1, extend: boolean) {\n if (this.refEdit) {\n const box = this.activeRefBox();\n const doc = this.targetDoc();\n if (!box?.inner) return;\n const index = nearestSafeIndex(doc.spacers, this.motionTarget(unit, dir, this.fragSel.focus, doc, box.inner));\n this.fragSel = extend ? { ...this.fragSel, focus: index } : collapsedSel(index);\n this.afterCaretMove();\n return;\n }\n const raw = this.motionTarget(unit, dir, this.sel.focus, this.doc, this.layout);\n const index = nearestSafeIndex(this.doc.spacers, raw);\n this.sel = extend\n ? { ...this.sel, focus: this.snapIndexForDrag(this.sel.anchor, index) }\n : collapsedSel(index);\n const editing = this.editingSlot();\n if (editing) {\n const a = Math.min(editing.end, Math.max(editing.start, this.sel.anchor));\n const f = Math.min(editing.end, Math.max(editing.start, this.sel.focus));\n this.sel = editing.empty ? collapsedSel(editing.start) : { anchor: a, focus: f };\n }\n this.afterCaretMove();\n }\n\n private moveFragmentCaret(key: ArrowKey, extend: boolean) {\n const doc = this.targetDoc();\n const box = this.activeRefBox();\n let index = this.fragSel.focus;\n if (!extend && isCollapsed(this.fragSel) && (key === 'ArrowLeft' || key === 'ArrowRight')) {\n if (key === 'ArrowLeft' && index <= 0) {\n this.exitRefEdit('before');\n return;\n }\n if (key === 'ArrowRight' && index >= Math.max(0, doc.length - (doc.spacers.endsWith('\\n') ? 1 : 0))) {\n this.exitRefEdit('after');\n return;\n }\n }\n if (key === 'ArrowLeft') index = Math.max(0, index - prevCodePointLen(doc.spacers, index));\n if (key === 'ArrowRight') index = Math.min(doc.length, index + nextCodePointLen(doc.spacers, index) || 1);\n if ((key === 'ArrowUp' || key === 'ArrowDown') && box?.inner) {\n const caret = caretFromIndex(box.inner, index);\n const y = caret.y + (key === 'ArrowDown' ? caret.h + 1 : -1);\n index = hitTestIndex(box.inner, caret.x, y);\n }\n this.fragSel = extend ? { ...this.fragSel, focus: index } : collapsedSel(index);\n this.afterCaretMove();\n }\n\n private stackTop(): { id: string; mode: 'selected' | 'editing' } | null {\n return this.vblockStack[this.vblockStack.length - 1] ?? null;\n }\n\n /** 参与选中/进出/吸附的块;mark 是纯样式叠层,交互上当作不存在。 */\n private interactiveBlocks(): VirtualBlock[] {\n return this.doc.listVirtualBlocks().filter((b) => b.kind !== 'mark');\n }\n\n private selectedVblock(): VirtualBlock | null {\n const top = this.stackTop();\n if (!top || top.mode !== 'selected') return null;\n return this.doc.blockById(top.id);\n }\n\n private selectedRegion(): VirtualBlock | null {\n const block = this.selectedVblock();\n return block?.kind === 'region' ? block : null;\n }\n\n private editingSlot(): VirtualBlock | null {\n const top = this.stackTop();\n if (!top || top.mode !== 'editing') return null;\n const block = this.doc.blockById(top.id);\n return block?.kind === 'virtualSlot' ? block : null;\n }\n\n private editingSlotIn(doc: DocumentModel): VirtualBlock | null {\n const top = this.stackTop();\n if (!top || top.mode !== 'editing') return null;\n const block = doc.blockById(top.id);\n return block?.kind === 'virtualSlot' ? block : null;\n }\n\n private selectionCoversSlot(ctx: OperationContext, slot: VirtualBlock): boolean {\n const sel = ctx.selection();\n return !isCollapsed(sel) && selStart(sel) <= slot.start && selEnd(sel) >= slot.end;\n }\n\n /** 选中槽、整槽选区、或空槽编辑:下一次写入应 fillSlot,不要先 clear 再插。 */\n private slotToFill(ctx: OperationContext): VirtualBlock | null {\n if (this.selectedRegion()) return null;\n const selected = ctx.doc.blockById(this.selectedVblock()?.id ?? '');\n if (this.stackTop()?.mode === 'selected' && selected?.kind === 'virtualSlot') return selected;\n const slot = this.editingSlotIn(ctx.doc);\n if (!slot) return null;\n if (slot.empty || this.selectionCoversSlot(ctx, slot)) return slot;\n return null;\n }\n\n private selectVblock(id: string, mode: 'selected' | 'editing') {\n const block = this.doc.blockById(id);\n if (!block) return;\n const chain: { id: string; mode: 'selected' | 'editing' }[] = [];\n const ids: string[] = [];\n let cur: VirtualBlock | null = block;\n const seen = new Set<string>();\n while (cur && !seen.has(cur.id)) {\n seen.add(cur.id);\n ids.unshift(cur.id);\n cur = cur.parentId ? this.doc.blockById(cur.parentId) : null;\n }\n for (let i = 0; i < ids.length; i++) {\n const last = i === ids.length - 1;\n chain.push({ id: ids[i], mode: last ? mode : 'selected' });\n }\n this.vblockStack = chain;\n if (mode === 'editing') {\n const i = Math.min(Math.max(this.sel.focus, block.start), block.end);\n this.setSel(collapsedSel(i));\n } else {\n this.setSel({ anchor: block.start, focus: block.end });\n }\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n }\n\n private popVblock() {\n const top = this.stackTop();\n if (!top) return;\n if (top.mode === 'editing') {\n this.selectVblock(top.id, 'selected');\n return;\n }\n this.vblockStack = this.vblockStack.slice(0, -1);\n const parent = this.stackTop();\n if (parent) {\n const block = this.doc.blockById(parent.id);\n if (block) this.setSel({ anchor: block.start, focus: block.end });\n } else {\n const block = this.doc.blockById(top.id);\n this.setSel(collapsedSel(block?.start ?? this.sel.anchor));\n }\n this.afterCaretMove();\n }\n\n private enterSelectedVblock(): boolean {\n const top = this.stackTop();\n const block = top ? this.doc.blockById(top.id) : null;\n if (!top || top.mode !== 'selected' || !block) return false;\n const children = this\n .interactiveBlocks()\n .filter((b) => b.parentId === block.id)\n .sort((a, b) => a.start - b.start);\n if (block.kind === 'virtualSlot') {\n this.selectVblock(block.id, 'editing');\n return true;\n }\n if (children[0]) {\n this.selectVblock(children[0].id, 'selected');\n return true;\n }\n return true;\n }\n\n private handleVblockBackspace(dir: 'backward' | 'forward'): boolean {\n const selected = this.selectedVblock();\n const top = this.stackTop();\n if (top?.mode === 'selected' && selected) {\n if (selected.kind === 'virtualSlot') {\n this.runEdit('delete.backward', (ctx) => {\n ops.clearSlot(selected.id)(ctx);\n const next = ctx.doc.blockById(selected.id);\n if (next) ctx.select({ anchor: next.start, focus: next.end });\n });\n return true;\n }\n return true;\n }\n const editing = this.editingSlot();\n if (!editing) return false;\n if (editing.empty) {\n this.selectVblock(editing.id, 'selected');\n return true;\n }\n const sel = this.targetSel();\n if (!isCollapsed(sel)) return false;\n const i = sel.focus;\n if (dir === 'backward' && i <= editing.start) {\n this.selectVblock(editing.id, 'selected');\n return true;\n }\n if (dir === 'forward' && i >= editing.end) {\n this.selectVblock(editing.id, 'selected');\n return true;\n }\n const from = dir === 'backward' ? i - prevCodePointLen(this.doc.spacers, i) : i;\n const to = dir === 'backward' ? i : i + nextCodePointLen(this.doc.spacers, i);\n if (from >= editing.start && to <= editing.end && editing.end - editing.start - (to - from) <= 0) {\n this.runEdit('delete.backward', (ctx) => {\n ops.clearSlot(editing.id)(ctx);\n const next = ctx.doc.blockById(editing.id);\n ctx.select(collapsedSel(next?.start ?? editing.start));\n });\n return true;\n }\n return false;\n }\n\n private moveAcrossVblock(dir: 1 | -1): Selection | null {\n const top = this.stackTop();\n const editing = this.editingSlot();\n if (editing) {\n const i = this.sel.focus;\n if (dir < 0 && isCollapsed(this.sel) && i <= editing.start) {\n this.selectVblock(editing.id, 'selected');\n return this.sel;\n }\n if (dir > 0 && isCollapsed(this.sel) && (i >= editing.end || editing.empty)) {\n this.selectVblock(editing.id, 'selected');\n return this.sel;\n }\n return null;\n }\n if (top?.mode === 'selected') {\n const block = this.doc.blockById(top.id);\n if (!block) return null;\n const children = this\n .interactiveBlocks()\n .filter((b) => b.parentId === block.id)\n .sort((a, b) => a.start - b.start);\n const inward = children.length > 0;\n if (inward) {\n const child = dir > 0 ? children[0] : children[children.length - 1];\n this.selectVblock(child.id, 'selected');\n return this.sel;\n }\n this.vblockStack = this.vblockStack.slice(0, -1);\n const parent = this.stackTop();\n if (parent) {\n const pb = this.doc.blockById(parent.id);\n if (pb) {\n this.setSel({ anchor: pb.start, focus: pb.end });\n return this.sel;\n }\n }\n return collapsedSel(dir > 0 ? block.end : block.start);\n }\n if (!isCollapsed(this.sel)) return null;\n const i = this.sel.focus;\n const hit =\n dir > 0\n ? this.outermostStartingAt(i)\n : this.outermostEndingAt(i);\n if (!hit) return null;\n this.selectVblock(hit.id, 'selected');\n return this.sel;\n }\n\n private outermostStartingAt(index: number): VirtualBlock | null {\n const hits = this.interactiveBlocks().filter((b) => b.start === index);\n return hits[0] ?? null;\n }\n\n private outermostEndingAt(index: number): VirtualBlock | null {\n const hits = this.interactiveBlocks().filter((b) => b.end === index);\n return hits[0] ?? null;\n }\n\n private hitVblockClick(index: number): boolean {\n const slot = this.doc.innermostSlotAt(index);\n if (slot) {\n this.selectVblock(slot.id, 'editing');\n // 空槽里的 placeholder 只是占位提示:光标永远停在槽首,不能落进文字中间。\n this.setSel(\n collapsedSel(slot.empty ? slot.start : Math.min(Math.max(index, slot.start), slot.end))\n );\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n return true;\n }\n const chain = this.doc.blocksAt(index).filter((b) => b.kind !== 'mark');\n const inner = chain[chain.length - 1];\n if (inner) {\n this.selectVblock(inner.id, 'selected');\n return true;\n }\n return false;\n }\n\n private snapIndexForDrag(anchor: number, focus: number): number {\n const editing = this.editingSlot();\n if (editing) {\n if (editing.empty) return editing.start;\n return Math.min(editing.end, Math.max(editing.start, focus));\n }\n const from = Math.min(anchor, focus);\n const to = Math.max(anchor, focus);\n if (to === from) return focus;\n const intersecting = this.interactiveBlocks().filter((b) => b.start < to && b.end > from);\n if (!intersecting.length) return focus;\n const ids = new Set(intersecting.map((b) => b.id));\n let common: VirtualBlock | null = null;\n for (const b of intersecting) {\n let p = b.parentId ? this.doc.blockById(b.parentId) : null;\n while (p && !ids.has(p.id)) p = p.parentId ? this.doc.blockById(p.parentId) : null;\n if (p && ids.has(p.id)) {\n if (!common || p.end - p.start > common.end - common.start) common = p;\n }\n }\n if (common) return focus >= anchor ? common.end : common.start;\n let snapped = focus;\n for (const b of intersecting) {\n if (!b.parentId || !ids.has(b.parentId)) {\n if (focus >= anchor) snapped = Math.max(snapped, b.end);\n else snapped = Math.min(snapped, b.start);\n }\n }\n return snapped;\n }\n\n private selectionPaintRects() {\n const top = this.stackTop();\n if (top?.mode === 'selected') {\n const outlines: { x: number; y: number; w: number; h: number; outline: true; radius: number }[] = [];\n for (const line of this.layout.lines) {\n for (const vb of line.vblocks ?? []) {\n if (vb.id !== top.id) continue;\n outlines.push({\n x: vb.x,\n y: vb.y,\n w: vb.w,\n h: vb.h,\n outline: true,\n radius: vb.chrome.radius ?? (vb.kind === 'virtualSlot' ? 4 : 6)\n });\n }\n }\n return outlines;\n }\n if (this.editingSlot()) return selectionRects(this.layout, this.sel);\n return selectionRects(this.layout, this.snapSelIfNeeded(this.sel));\n }\n\n private snapSelIfNeeded(sel: Selection): Selection {\n if (this.stackTop() || isCollapsed(sel)) return sel;\n const from = selStart(sel);\n const to = selEnd(sel);\n const intersecting = this.interactiveBlocks().filter((b) => b.start < to && b.end > from && (from > b.start || to < b.end));\n if (!intersecting.length) return sel;\n let start = from;\n let end = to;\n for (const b of intersecting) {\n start = Math.min(start, b.start);\n end = Math.max(end, b.end);\n }\n if (sel.anchor <= sel.focus) return { anchor: start, focus: end };\n return { anchor: end, focus: start };\n }\n\n /** 对照常见 Docs 行为:先选中嵌入块,再按同一方向才跳过。 */\n private moveAcrossEmbed(dir: 1 | -1): Selection | null {\n const embed = this.selectedImage();\n if (embed) {\n return collapsedSel(dir < 0 ? embed.index : embed.index + 1);\n }\n if (!isCollapsed(this.sel)) return null;\n const i = this.sel.focus;\n if (dir > 0 && this.doc.spacers[i] === MARKERS.IMAGE) {\n return { anchor: i, focus: i + 1 };\n }\n if (dir < 0 && i > 0 && this.doc.spacers[i - 1] === MARKERS.IMAGE) {\n return { anchor: i, focus: i - 1 };\n }\n return null;\n }\n\n private setSel(next: Selection) {\n const moved = next.anchor !== this.sel.anchor || next.focus !== this.sel.focus;\n this.sel = next;\n if (moved) this.typingStyle = null;\n }\n\n private afterCaretMove() {\n this.typingStyle = null;\n this.keepTypingOnNextClick = false;\n // 用户主动挪了光标,下一次输入不该并进上一批:撤销时应该分开退。\n this.undoStack.resetBatching();\n this.resetBlink();\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n this.scrollCaret();\n }\n\n private stepIndex(index: number, dir: 1 | -1): number {\n let i = index;\n for (let n = 0; n < 8; n++) {\n if (dir < 0) {\n if (i <= 0) return 0;\n i -= prevCodePointLen(this.doc.spacers, i);\n } else {\n if (i >= this.doc.length) return this.doc.length;\n i += nextCodePointLen(this.doc.spacers, i);\n }\n const ch = this.doc.spacers[dir < 0 ? i : i - 1];\n if (!ch || ch === MARKERS.PARAGRAPH || ch === MARKERS.IMAGE || !isStructural(ch)) return i;\n if (dir < 0 && i === 0) return 0;\n }\n return i;\n }\n\n /** 上下移动的出发 x:选中的是整个嵌入对象(芯片 / 图片)时取它的中心,否则取光标位置。 */\n private verticalStartX(index: number): number {\n const embed = this.selectedImage();\n if (embed && !embed.entity.float) return embed.x + embed.w / 2;\n return caretFromIndex(this.layout, index).x;\n }\n\n private verticalMove(index: number, dir: 1 | -1, x: number): number {\n const lines = this.layout.lines;\n const idx = lines.findIndex((l) => index >= l.start && index <= l.end);\n const cur = idx >= 0 ? idx : 0;\n const next = Math.max(0, Math.min(lines.length - 1, cur + dir));\n const line = lines[next];\n // 目标列落在某个行内嵌入对象(芯片、图片)的横向范围里,就把它当成命中整个对象:\n // 否则按最近停靠点吸附会随机落到它左边或右边,用户看到的是\"有时选中有时在旁边\"。\n const hitEmbed = line.images.find((img) => !img.entity.float && x >= img.x && x <= img.x + img.w);\n if (hitEmbed) return hitEmbed.index;\n return hitTestIndex(this.layout, x, line.y + 1);\n }\n}\n\n/** canvas 能解析的颜色才可比;var() 非法时不相等,避免误伤。 */\nfunction cssColorsEqual(a: string, b: string): boolean {\n if (a === b) return true;\n const ctx = typeof document === 'undefined' ? null : document.createElement('canvas').getContext('2d');\n if (!ctx) return false;\n ctx.fillStyle = '#000000';\n ctx.fillStyle = a;\n const left = ctx.fillStyle;\n ctx.fillStyle = '#000000';\n ctx.fillStyle = b;\n const right = ctx.fillStyle;\n if (left === '#000000' && a.trim() !== '#000000' && a.trim() !== '#000' && a.trim().toLowerCase() !== 'black' && a.trim() !== 'rgb(0, 0, 0)') {\n return false;\n }\n return left === right;\n}\n\nfunction isStructural(ch: string): boolean {\n return ch === MARKERS.PARAGRAPH || ch === MARKERS.TABLE_START || ch === MARKERS.TABLE_END || ch === MARKERS.TABLE_ROW || ch === MARKERS.TABLE_CELL;\n}\n\nfunction fakePlainClipboard(text: string): DataTransfer {\n const data = new DataTransfer();\n data.setData('text/plain', text);\n return data;\n}\n\nfunction sliceToHtml(slice: Slice): string {\n const esc = (s: string) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n return `<p>${esc(slice.text.replace(/[\\n\\u0010\\u0011\\u0012\\u001c\\u0007]/g, ' '))}</p>`;\n}\n\nfunction openSafeUrl(url: string): boolean {\n let href = url.trim();\n if (/^www\\./i.test(href)) href = `https://${href}`;\n try {\n const parsed = new URL(href);\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') return false;\n window.open(parsed.href, '_blank', 'noopener,noreferrer');\n return true;\n } catch {\n return false;\n }\n}\n\n"],"names":["CODE_LANGUAGES","BAR_H","LINE_H","PAD","measureCode","entity","contentWidth","lines","codePlugin","box","root","bar","sel","lang","opt","input","emitEmbedChange","el","ctx","imagePlugin","node","img","imageOf","src","MARKERS","isTableMarker","ch","prevCodePointLen","text","index","c","p","nextCodePointLen","blockCache","parseBlocks","spacers","blocks","parseBlocksUncached","i","table","parseTable","j","start","rows","rowMarker","cells","cellMarker","paragraphs","paraStart","end","findTableAt","block","isEmptyParagraph","para","isVisuallyEmptyDoc","doc","props","findParagraphAt","clamped","row","cell","paragraphsIntersecting","from","to","out","uniqueRanges","ranges","seen","r","k","cellAt","nearestSafeIndex","cellContentRange","_a","isLastTableCell","hit","lastRow","lastCol","nextCellIndex","dir","here","col","target","expandRangeOverStructures","slice","emptyTableSpacers","cols","s","LINK_COLOR","VIDEO_ASPECT","selStart","selEnd","isCollapsed","DEFAULT_TEXT","DEFAULT_PARAGRAPH","MAX_LIST_INDENT","HEADING_TEXT","hasTextProps","textPropsEqual","a","b","underlineKind","style","cloneStyle","span","cloneEntity","cloneVirtualBlock","chromeTextProps","chrome","shiftVirtualBlocksOnInsert","len","shiftVirtualBlocksOnDelete","rangesOverlap","rangesCross","rangeContains","depthOf","byId","d","id","parent","sortOuterToInner","map","la","lb","ancestorChain","chain","cur","clipVirtualBlocks","hits","ids","FONT_FAMILY","LINE_HEIGHT","PAGE_CONTENT_WIDTH","PAGE_PADDING_X","PAGE_PADDING_Y","LIST_MARKER_WIDTH","INDENT_STEP","CELL_PAD","MIN_COL_WIDTH","COL_BORDER_HIT","widthCache","localeReady","ensureLocale","setLocale","fontFamilyOf","raw","resolveFont","canvasFont","font","measureWidth","key","prepared","prepareWithSegments","w","measureNaturalWidth","glyphCache","GLYPH_CACHE_MAX","naturalWidth","measureGlyphWidths","widths","prevWidth","cp","width","lineHeightOf","REF_PAD","REF_HEAD","refInnerWidth","boxW","chromeFallback","t","inner","innermostEmptySlot","resolvedTextStyle","heading","link","href","_b","_c","_d","HOST_FALLBACK_W","HOST_FALLBACK_H","embedLayoutSize","maxWidth","host","height","embedOccupiesLine","preparedCache","preparedFor","collectRuns","runs","n","ns","fitPrefix","lo","hi","best","mid","wrapParagraph","items","lineW","lineStart","flush","lineEnd","run","isolated","rest","restIndex","restPrepared","remain","widthForLine","line","layoutNextLine","bandSlot","contentX","contentW","bandTop","bandH","obstacles","gap","left","right","f","cursorIndex","fallback","createWrapCursor","skipFloats","wrapCursorDone","wrapCursorIndex","wrapCursorPeek","wrapCursorSkip","consumeWrapLine","UL_MARKERS","listMarkerText","olIndex","layoutParagraph","x","y","paraProps","indent","markerText","markerW","align","floats","allObstacles","useFlow","paragraphHasFloat","lineY","peek","side","size","fx","slot","buildLine","wrapped","nextOl","counter","maxW","markerX","contentH","item","emptyStyle","dx","glyphs","images","caretStops","cx","local","marker","vblockFragments","lineH","fillRight","sorted","boxes","g","im","top","bottom","padX","continues","boxLeft","boxRight","layoutTable","paraIndex","stored","even","hasStored","colWidths","_","sum","cy","rowCells","maxH","innerW","paras","py","ol","pp","pl","h","fragmentFingerprint","fragmentId","fragment","hostFingerprint","hasImagesCache","hasImages","has","mediaFingerprint","parts","e","StyleIndex","spans","__publicField","running","types","INLINE_STYLES","ParagraphPropsIndex","textDefaultsKey","hashParagraph","styles","floatKey","propsKey","tdKey","vblockFingerprint","hashTable","floatBoxes","paragraphBottom","moveParagraph","dy","di","inPlace","shiftParagraphInPlace","l","v","moveTable","stats","layoutDocument","prev","insets","depth","contentY","tables","topOl","activeFloats","dirtyTop","dirtyBottom","markDirty","styleIndex","prevByHash","entry","inPlaceAllowed","shifted","canShiftInPlace","pickCached","hash","ry","cached","oldY","oldBottom","oldH","now","old","dirty","attachRefInners","model","sortedLinesCache","sortedLines","layout","caretFromIndex","near","caretFromIndexIn","allowNearest","bestLine","bestX","bestIndex","bestDist","exact","stop","dist","earlier","later","hitTestIndex","localX","localY","closestCaretOnLines","bestScore","inY","inX","score","selectionRects","cellRects","cellGridRects","rects","stops","rightCandidates","x0","x1","punchEmbeds","next","overlapY","overlapX","imageBoxAt","r0","r1","c0","c1","hitColBorder","fillOf","rainbowAt","sunsetAt","cssFill","runWidth","fill","canvasFill","glyphIndex","runT","paintCanvasUnderline","kind","color","amp","step","px","up","paintCanvasStrike","groupDecorationRuns","strike","baseline","REF_JUMP","innerUsedSize","measureRef","emptyInner","used","countLabel","paintInner","renderInnerLine","hole","pic","wrap","innerCss","deco","runW","weight","italic","refPlugin","badge","body","paintChip","decorateRefEl","count","title","editing","selected","DEFAULT_SELECT_OPTIONS","FILLED_IMAGE","ICONS","defaultSlotLabel","slotKindOf","slotOptionsOf","slotPlaceholder","slotCaption","slotFilled","measureSlot","label","textW","extra","closeMenus","except","menu","openSelectMenu","name","btn","clear","onDoc","slotEntities","filled","imageFilled","icon","thumb","slotPlugin","file","current","entityId","leaveEdit","startTextEdit","commitText","value","cancelText","activate","EMBED_EXIT_EDIT","applyVideo","videoPlugin","renderer","setHostEmbedRenderer","FALLBACK_SIZE","handles","handlesById","emitMeasure","detail","EMBED_MEASURE","observeSize","rec","ro","syncHostSelected","selectedId","syncRecSelected","contextOf","patch","commit","EMBED_COMMIT","EMBED_CHANGE","mountInto","handle","hostEmbedPlugin","activateHostEmbed","req","destroyHostEmbed","plugins","registerEmbed","plugin","embedPlugin","syncEmbedLayer","cache","canvas","placeEmbed","builtinEmbedPlugins","insertSpacers","insertBeforeIndex","NULL_MUTATION","deleteSpacers","startIndex","endIndex","applyStyle","styleType","addEntity","updateEntity","deleteEntity","addFragment","deleteFragment","addVirtualBlock","deleteVirtualBlock","blockId","updateVirtualBlock","scoped","multi","unwrap","m","commands","flat","mutation","reverse","mutations","appliers","applyMutation","applyMutations","cloneFragment","cloneSlice","previewTitle","max","normalizeFragmentSlice","sliceHasContent","STYLE_TYPES","restoreStyles","type","inverters","_doc","restoredBlocks","before","invertMutation","newRange","min","range","rangeEquals","shiftIndex","shiftPosition","offset","shiftIndexExclusive","shiftRange","leadingLength","position","leadEnd","transformCoordinateAgainstDeletedRange","deleted","transformRangeAgainstDeletedRange","newStart","endpointDeleted","newEnd","insertAgainstInsert","cmd","other","aWins","insertAgainstDelete","length","deleteAgainstInsert","copyWithRange","deleteAgainstDelete","removed","styleAgainstInsert","copyStyleWithRange","styleAgainstDelete","transformers","transform","o","transformBoth","others","transformIndex","shiftedByInserts","transformSelection","MERGEABLE_KINDS","mergeKeyFor","scope","editMeta","init","editResult","flatten","isEmptyEdit","mergeEdits","first","second","invertEdit","Collector","selection","one","scopeContext","outer","runOperation","op","result","resolveTextProps","resolveParagraphProps","rangeIsOnlyMarkers","contentRuns","base","runStart","content","textSegments","points","existing","spanCovering","expectedParagraphSpans","inherit","EMPTY_SLICE","emitInsert","emitDelete","emitStyle","emitTextStyle","seg","normalizeParagraphs","needed","needKeys","curKeys","differing","guard","grew","ensureParagraphAfter","applyTextStyle","applyLink","url","clearFrom","clearTo","removeLink","applyParagraphStyle","RULES","lastMatch","reg","matchMarkdown","paraText","rule","full","matchStart","matchEnd","shouldTryMarkdown","inserted","entitySeq","fragmentSeq","virtualBlockSeq","nextEntityId","nextFragmentId","nextVirtualBlockId","DocumentModel","initial","shiftStylesOnInsert","shiftStylesOnDelete","kept","snap","entities","fragmentIds","fragments","virtualBlocks","probe","normalized","documentFromSlice","sliceFromDocument","inside","ending","ensure","merged","last","collapsedSel","sliceWithoutParagraphGroup","groupId","keep","insertImage","updateImage","blockMap","validateInsert","inferParentId","selfId","insertVirtualBlock","spec","parentId","placeholder","empty","child","removeVirtualBlock","updateVirtualBlockChrome","restoreChain","snaps","targetId","nextStart","nextEnd","isTarget","clearSlot","slotInlineText","fillSlot","safe","coverAncestorsOf","pid","coverVirtualBlocks","remapIncomingVirtualBlocks","occupied","idMap","remapped","extendMarksAtEnd","nl","isLastParagraphWithGroupId","splitParagraphSpans","cursor","insertText","insertParagraph","oldProps","inList","paraEndContent","atStart","atEnd","exitGroup","leftProps","rightProps","deleteRange","expanded","backspace","prevProps","deleteForward","applyMarkdownShortcut","caret","restyleParagraph","consume","tableSpan","writeColWidths","tableStart","tableEnd","insertTable","insertTableRow","insertTableCol","inserts","at","deleteTableRow","deleteTableCol","setTableColWidths","looksLikeMarkdown","parseInline","re","blockProps","ul","markdownToSlice","emitPara","tokens","tok","emitEmbed","fence","buf","oneLineMath","materializeSlice","lookup","scratch","source","insertSlice","asCopy","incoming","nested","remap","insertMarkdown","paraEnd","cut","pasteText","promoteRange","insertRef","unlinkRef","runScoped","runEdit","meta","UNDO_BATCH_MS","UndoRedoStack","edit","withinWindow","sameRun","undoStep","intervening","pair","forward","remote","ImeSurface","handler","arrow","modArrow","horizontal","altArrow","navKeys","SHORTCUTS","swallow","INPUT_SHORTCUTS","inputShortcuts","submit","submitUsesShift","matches","sc","stroke","findShortcut","IME_PASSTHROUGH","strokeOf","bindKeyboard","onKeyDown","ENTRY","STAGES","stat","samples","PerfProbe","editor","getPainter","painter","orig","args","tick","rl","self","arr","fr","frames","fps","ms","fn","proto","dt","segmenter","getSegmenter","maxCaretIndex","wordSpans","wordTarget","paragraphTarget","wordRangeAt","SLICE_MIME","serializeSlice","parseSlice","data","sliceFromClipboard","CANVAS_GUTTER","VIEWPORT_MARGIN","MAX_ZOOM_SHARPNESS","CanvasPainter","dpr","zoom","band","vb","visible","trails","rect","vv","viewTop","viewH","force","vis","margin","wantH","changed","maxTop","legal","covers","scaleChanged","moved","fullW","resized","topCss","editorRoot","family","markerTop","cs","radius","rainbow","grad","alpha","solid","caretW","editorCs","glow","metrics","ascent","descent","fontH","cssText","HtmlPainter","renderTableChrome","renderLine","on","placeCaret","fade","anim","renderVBlock","border","Editor","options","indices","pos","after","ops.updateImage","edge","refBox","interactive","openSafeUrl","ratio","ops.setTableColWidths","startW","startH","level","delta","hostType","opts","extend","unit","active","mode","prevColor","nextColor","match","cssColorsEqual","computed","selColor","selRadius","cssFamily","ops.slotInlineText","ops.fillSlot","ops.insertSlice","ops.insertVirtualBlock","origin","ops.updateVirtualBlockChrome","ops.removeVirtualBlock","ops.applyParagraphStyle","pred","ops.deleteRange","patchFor","patches","clientX","clientY","embed","canPromote","event","disabled","any","avail","selectionAfter","revert","settle","ops.clearSlot","minStart","maxEnd","ops.emitDelete","ops.emitInsert","ops.normalizeParagraphs","anchor","ops.insertText","selectedNow","ops.applyMarkdownShortcut","fakePlainClipboard","payload","ops.pasteText","explicit","pending","fromHeading","ops.insertParagraph","toHeading","res","ops.backspace","ops.deleteForward","ops.applyTextStyle","ops.applyLink","ops.removeLink","sized","ops.insertImage","slotKind","ops.promoteRange","picked","ops.insertRef","ops.unlinkRef","nw","nh","w0","h0","scale","video","ops.insertTable","focus","ops.insertTableRow","ops.insertTableCol","ops.deleteTableRow","ops.deleteTableCol","composing","show","opacity","mapped","demoCaret","posKey","showCaret","imeH","anchorPos","imeY","composeW","underlineH","idx","oy","surface","parents","geom","views","isRoot","isSlot","isRef","isHost","sliceToHtml","startX","w1","vnext","vertical","goalX","remember","children","pb","intersecting","common","snapped","outlines","isStructural","hitEmbed","parsed"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/embed/code.ts","../src/embed/image.ts","../src/model/markers.ts","../src/model/blocks.ts","../src/model/types.ts","../src/model/virtualBlock.ts","../src/layout/measure.ts","../src/layout/refMetrics.ts","../src/layout/style.ts","../src/layout/wrap.ts","../src/layout/engine.ts","../src/paint/decorations.ts","../src/embed/ref.ts","../src/embed/slot.ts","../src/embed/video.ts","../src/embed/host.ts","../src/embed/registry.ts","../src/embed/index.ts","../src/mutations/types.ts","../src/mutations/apply.ts","../src/model/fragment.ts","../src/mutations/invert.ts","../src/mutations/ranges.ts","../src/mutations/transform.ts","../src/mutations/selection.ts","../src/edits/editResult.ts","../src/operations/context.ts","../src/operations/resolve.ts","../src/operations/primitives.ts","../src/operations/style.ts","../src/convert/markdown.ts","../src/model/document.ts","../src/operations/entity.ts","../src/operations/virtualBlock.ts","../src/operations/text.ts","../src/operations/table.ts","../src/convert/mdPaste.ts","../src/operations/slice.ts","../src/edits/transaction.ts","../src/edits/undoStack.ts","../src/input/ime.ts","../src/commands/shortcuts.ts","../src/input/keyboard.ts","../src/perf.ts","../src/perfPanel.ts","../src/input/caretMotion.ts","../src/convert/clipboard.ts","../src/paint/canvasPainter.ts","../src/paint/htmlPainter.ts","../src/editor.ts"],"sourcesContent":["import { EmbedEntity } from '../model/types';\nimport { EmbedBox, EmbedPlugin, emitEmbedChange } from './types';\n\nexport const CODE_LANGUAGES = ['plain', 'javascript', 'typescript', 'python', 'json', 'html', 'css'] as const;\nconst BAR_H = 28;\nconst LINE_H = 18;\nconst PAD = 12;\n\nexport function measureCode(entity: EmbedEntity, contentWidth: number): { width: number; height: number } {\n const lines = Math.max(1, (entity.code ?? '').split('\\n').length);\n const width = Math.max(160, entity.width || contentWidth);\n return { width, height: BAR_H + PAD * 2 + lines * LINE_H };\n}\n\nexport const codePlugin: EmbedPlugin = {\n kind: 'code',\n keepAspectRatio: false,\n interactive: true,\n overlayOnCanvas: true,\n measure: measureCode,\n create(box) {\n const root = document.createElement('div');\n root.className = 'mini-embed mini-code mini-embed-interactive';\n const bar = document.createElement('div');\n bar.className = 'mini-code-bar';\n const sel = document.createElement('select');\n sel.className = 'mini-code-lang';\n for (const lang of CODE_LANGUAGES) {\n const opt = document.createElement('option');\n opt.value = lang;\n opt.textContent = lang;\n sel.appendChild(opt);\n }\n bar.appendChild(sel);\n const input = document.createElement('textarea');\n input.className = 'mini-code-input';\n input.spellcheck = false;\n input.value = box.entity.code ?? '';\n sel.value = box.entity.language ?? 'plain';\n root.append(bar, input);\n\n sel.addEventListener('change', () => {\n emitEmbedChange(root, { id: box.entity.id, patch: { language: sel.value } }, true);\n });\n input.addEventListener('input', () => {\n emitEmbedChange(root, { id: box.entity.id, patch: { code: input.value } });\n });\n input.addEventListener('blur', () => {\n emitEmbedChange(root, { id: box.entity.id, patch: { code: input.value } }, true);\n });\n return root;\n },\n update(el, box) {\n const sel = el.querySelector<HTMLSelectElement>('.mini-code-lang');\n const input = el.querySelector<HTMLTextAreaElement>('.mini-code-input');\n if (sel && document.activeElement !== sel) sel.value = box.entity.language ?? 'plain';\n if (input && document.activeElement !== input) input.value = box.entity.code ?? '';\n },\n paintCanvasBackdrop(ctx, box) {\n ctx.fillStyle = '#f4f6f8';\n ctx.fillRect(box.x, box.y, box.w, box.h);\n }\n};\n","import { EmbedBox, EmbedPlugin } from './types';\n\nexport const imagePlugin: EmbedPlugin = {\n kind: 'image',\n keepAspectRatio: true,\n interactive: false,\n overlayOnCanvas: false,\n measure(entity) {\n return { width: entity.width, height: entity.height };\n },\n create(box) {\n const node = document.createElement('img');\n node.className = 'mini-embed mini-image';\n node.draggable = false;\n node.src = box.entity.src ?? '';\n return node;\n },\n update(el, box) {\n const img = el as HTMLImageElement;\n if (box.entity.src && img.src !== box.entity.src) img.src = box.entity.src;\n el.classList.toggle('is-inline', box.h <= 32);\n },\n paintCanvasBackdrop(ctx, box, imageOf) {\n const src = box.entity.src;\n if (!src) return;\n const node = imageOf(src);\n if (!node.complete || node.naturalWidth <= 0) return;\n if (box.h <= 32) {\n ctx.save();\n ctx.beginPath();\n ctx.roundRect(box.x, box.y, box.w, box.h, 6);\n ctx.clip();\n ctx.drawImage(node, box.x, box.y, box.w, box.h);\n ctx.restore();\n return;\n }\n ctx.drawImage(node, box.x, box.y, box.w, box.h);\n }\n};\n","/** 文档流里的结构标记:每个标记占一个下标,和普通字符一样参与排版与选区。 */\nexport const MARKERS = {\n PARAGRAPH: '\\n',\n IMAGE: '*',\n TABLE_START: '\\u0010',\n TABLE_END: '\\u0011',\n TABLE_ROW: '\\u0012',\n TABLE_CELL: '\\u001c'\n} as const;\n\nexport function isTableMarker(ch: string): boolean {\n return (\n ch === MARKERS.TABLE_START ||\n ch === MARKERS.TABLE_END ||\n ch === MARKERS.TABLE_ROW ||\n ch === MARKERS.TABLE_CELL\n );\n}\n\nexport function isStructuralMarker(ch: string): boolean {\n return ch === MARKERS.PARAGRAPH || isTableMarker(ch);\n}\n\nexport function prevCodePointLen(text: string, index: number): number {\n if (index <= 0) return 0;\n const c = text.charCodeAt(index - 1);\n if (c >= 0xdc00 && c <= 0xdfff && index >= 2) {\n const p = text.charCodeAt(index - 2);\n if (p >= 0xd800 && p <= 0xdbff) return 2;\n }\n return 1;\n}\n\nexport function nextCodePointLen(text: string, index: number): number {\n if (index >= text.length) return 0;\n const c = text.charCodeAt(index);\n if (c >= 0xd800 && c <= 0xdbff && index + 1 < text.length) {\n const n = text.charCodeAt(index + 1);\n if (n >= 0xdc00 && n <= 0xdfff) return 2;\n }\n return 1;\n}\n","import { isTableMarker, MARKERS } from './markers';\nimport type { ParagraphProps } from './types';\n\nexport interface ParaRange {\n start: number;\n end: number;\n}\n\nexport interface TableCellBlock {\n marker: number;\n start: number;\n end: number;\n paragraphs: ParaRange[];\n}\n\nexport interface TableRowBlock {\n marker: number;\n start: number;\n end: number;\n cells: TableCellBlock[];\n}\n\nexport interface ParagraphBlock {\n kind: 'paragraph';\n start: number;\n end: number;\n}\n\nexport interface TableBlock {\n kind: 'table';\n start: number;\n end: number;\n rows: TableRowBlock[];\n}\n\nexport type Block = ParagraphBlock | TableBlock;\n\n/**\n * parseBlocks 结果缓存。spacers 是不可变字符串,内容一样块结构就一样;一次按键里\n * 排版、工具栏、状态栏、操作层会把全文解析十几次,长文档下每次都是毫秒级。\n * 只留最近两份(当前文档 + 片段/临时文档交替时不互相挤掉)。返回值视为只读。\n */\nconst blockCache: { spacers: string; blocks: Block[] }[] = [];\n\nexport function parseBlocks(spacers: string): Block[] {\n for (const c of blockCache) {\n if (c.spacers === spacers) return c.blocks;\n }\n const blocks = parseBlocksUncached(spacers);\n blockCache.unshift({ spacers, blocks });\n if (blockCache.length > 2) blockCache.pop();\n return blocks;\n}\n\nfunction parseBlocksUncached(spacers: string): Block[] {\n const blocks: Block[] = [];\n let i = 0;\n while (i < spacers.length) {\n if (spacers[i] === MARKERS.TABLE_START) {\n const table = parseTable(spacers, i);\n blocks.push(table);\n i = table.end;\n } else {\n let j = i;\n while (j < spacers.length && spacers[j] !== MARKERS.PARAGRAPH && spacers[j] !== MARKERS.TABLE_START) {\n j++;\n }\n if (j < spacers.length && spacers[j] === MARKERS.PARAGRAPH) {\n j++;\n }\n if (j === i) {\n i++;\n continue;\n }\n blocks.push({ kind: 'paragraph', start: i, end: j });\n i = j;\n }\n }\n return blocks;\n}\n\nfunction parseTable(spacers: string, start: number): TableBlock {\n let i = start + 1;\n const rows: TableRowBlock[] = [];\n while (i < spacers.length && spacers[i] !== MARKERS.TABLE_END) {\n if (spacers[i] !== MARKERS.TABLE_ROW) {\n i++;\n continue;\n }\n const rowMarker = i;\n i += 1;\n const cells: TableCellBlock[] = [];\n while (i < spacers.length && spacers[i] === MARKERS.TABLE_CELL) {\n const cellMarker = i;\n i += 1;\n const paragraphs: ParaRange[] = [];\n let paraStart = i;\n while (i < spacers.length && !isTableMarker(spacers[i])) {\n if (spacers[i] === MARKERS.PARAGRAPH) {\n paragraphs.push({ start: paraStart, end: i + 1 });\n paraStart = i + 1;\n }\n i++;\n }\n if (paraStart < i) {\n paragraphs.push({ start: paraStart, end: i });\n }\n if (paragraphs.length === 0) {\n paragraphs.push({ start: i, end: i });\n }\n cells.push({ marker: cellMarker, start: cellMarker, end: i, paragraphs });\n }\n rows.push({ marker: rowMarker, start: rowMarker, end: i, cells });\n }\n let end = i;\n if (i < spacers.length && spacers[i] === MARKERS.TABLE_END) {\n end = i + 1;\n }\n return { kind: 'table', start, end, rows };\n}\n\nexport function findTableAt(spacers: string, index: number): TableBlock | null {\n for (const block of parseBlocks(spacers)) {\n if (block.kind === 'table' && index >= block.start && index < block.end) {\n return block;\n }\n }\n return null;\n}\n\nexport function isEmptyParagraph(spacers: string, para: ParaRange): boolean {\n const contentEnd = spacers[para.end - 1] === MARKERS.PARAGRAPH ? para.end - 1 : para.end;\n return contentEnd <= para.start;\n}\n\n/** 列表标记 / 标题画在段落样式上,不进 spacer;有它们时占位符不能当空文档。 */\nexport function isVisuallyEmptyDoc(doc: {\n spacers: string;\n entities: { size: number };\n paragraphPropsAt: (index: number) => ParagraphProps;\n}): boolean {\n if (doc.entities.size > 0) return false;\n for (const ch of doc.spacers) {\n if (ch !== MARKERS.PARAGRAPH) return false;\n }\n for (const block of parseBlocks(doc.spacers)) {\n if (block.kind !== 'paragraph') return false;\n const props = doc.paragraphPropsAt(block.start);\n if ((props.list ?? 'none') !== 'none') return false;\n if ((props.heading ?? 0) > 0) return false;\n if ((props.indent ?? 0) > 0) return false;\n }\n return true;\n}\n\nexport function findParagraphAt(spacers: string, index: number): ParaRange | null {\n const clamped = Math.max(0, Math.min(index, spacers.length));\n for (const block of parseBlocks(spacers)) {\n if (block.kind === 'paragraph' && clamped >= block.start && clamped <= block.end) {\n if (clamped === block.end && clamped < spacers.length) continue;\n return { start: block.start, end: block.end };\n }\n if (block.kind === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const para of cell.paragraphs) {\n if (clamped >= para.start && clamped <= para.end) {\n if (clamped === para.end && clamped < cell.end) continue;\n return para;\n }\n }\n }\n }\n }\n }\n if (spacers.length === 0) return { start: 0, end: 0 };\n return null;\n}\n\nexport function paragraphsIntersecting(spacers: string, start: number, end: number): ParaRange[] {\n const from = Math.min(start, end);\n const to = Math.max(start, end);\n if (from === to) {\n const para = findParagraphAt(spacers, from);\n return para ? [para] : [];\n }\n const out: ParaRange[] = [];\n for (const block of parseBlocks(spacers)) {\n if (block.kind === 'paragraph') {\n if (block.end > from && block.start < to) out.push(block);\n } else {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const para of cell.paragraphs) {\n if (para.end > from && para.start < to) out.push(para);\n }\n }\n }\n }\n }\n return uniqueRanges(out);\n}\n\nfunction uniqueRanges(ranges: ParaRange[]): ParaRange[] {\n const seen = new Set<string>();\n const out: ParaRange[] = [];\n for (const r of ranges) {\n const k = `${r.start}:${r.end}`;\n if (!seen.has(k)) {\n seen.add(k);\n out.push(r);\n }\n }\n return out;\n}\n\nexport function cellAt(spacers: string, index: number): { table: TableBlock; row: number; col: number; cell: TableCellBlock } | null {\n const table = findTableAt(spacers, index);\n if (!table) return null;\n for (let r = 0; r < table.rows.length; r++) {\n const row = table.rows[r];\n for (let c = 0; c < row.cells.length; c++) {\n const cell = row.cells[c];\n if (index >= cell.start && index < cell.end) {\n return { table, row: r, col: c, cell };\n }\n if (index === cell.end && c === row.cells.length - 1 && r === table.rows.length - 1) {\n return { table, row: r, col: c, cell };\n }\n }\n }\n return null;\n}\n\n/** 把下标吸附到最近的安全落点,避开表格结构标记 */\nexport function nearestSafeIndex(spacers: string, index: number): number {\n const i = Math.max(0, Math.min(index, spacers.length));\n const ch = spacers[i];\n if (ch === MARKERS.TABLE_CELL) return i + 1;\n if (ch === MARKERS.TABLE_ROW) return i + 2;\n if (ch === MARKERS.TABLE_START) return i + 3;\n if (ch === MARKERS.TABLE_END) return Math.max(0, i - 1);\n return i;\n}\n\nexport function cellContentRange(cell: TableCellBlock): { start: number; end: number } {\n return {\n start: cell.paragraphs[0]?.start ?? cell.start + 1,\n end: cell.end\n };\n}\n\nexport function isLastTableCell(hit: { table: TableBlock; row: number; col: number }): boolean {\n const lastRow = hit.table.rows.length - 1;\n const lastCol = hit.table.rows[lastRow].cells.length - 1;\n return hit.row === lastRow && hit.col === lastCol;\n}\n\nexport function nextCellIndex(spacers: string, index: number, dir: 1 | -1): number | null {\n const here = cellAt(spacers, index);\n if (!here) return null;\n const { table, row, col } = here;\n let r = row;\n let c = col + dir;\n if (c >= table.rows[r].cells.length) {\n r += 1;\n c = 0;\n } else if (c < 0) {\n r -= 1;\n if (r >= 0) c = table.rows[r].cells.length - 1;\n }\n if (r < 0 || r >= table.rows.length) return null;\n const target = table.rows[r].cells[c];\n return target.paragraphs[0]?.start ?? target.start + 1;\n}\n\nexport function expandRangeOverStructures(spacers: string, start: number, end: number): { start: number; end: number } {\n let from = Math.min(start, end);\n let to = Math.max(start, end);\n if (from === to) return { start: from, end: to };\n for (const block of parseBlocks(spacers)) {\n if (block.kind !== 'table') continue;\n const overlaps = from < block.end && to > block.start;\n if (!overlaps) continue;\n const slice = spacers.slice(Math.max(from, block.start), Math.min(to, block.end));\n const touchesEdge = slice.includes(MARKERS.TABLE_START) || slice.includes(MARKERS.TABLE_END) || from <= block.start || to >= block.end;\n if (touchesEdge) {\n from = Math.min(from, block.start);\n to = Math.max(to, block.end);\n }\n }\n return { start: from, end: to };\n}\n\nexport function emptyTableSpacers(rows: number, cols: number): string {\n let s = MARKERS.TABLE_START;\n for (let r = 0; r < rows; r++) {\n s += MARKERS.TABLE_ROW;\n for (let c = 0; c < cols; c++) {\n s += MARKERS.TABLE_CELL + MARKERS.PARAGRAPH;\n }\n }\n s += MARKERS.TABLE_END;\n return s;\n}\n","export type HeadingLevel = 0 | 1 | 2 | 3;\nexport type Align = 'left' | 'center' | 'right';\nexport type ListKind = 'none' | 'ul' | 'ol';\nexport type StyleType = 'text' | 'paragraph' | 'table' | 'cell' | 'image' | 'link';\n\nexport type UnderlineStyle = 'single' | 'double' | 'wavy' | 'dotted' | 'marker';\nexport type TextFill = 'solid' | 'rainbow' | 'sunset';\n\nexport interface TextProps {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n underlineStyle?: UnderlineStyle;\n strikethrough?: boolean;\n fontSize?: number;\n /**\n * CSS font-family 栈。须具名或宿主 CSS 变量(如 `var(--Body-Medium-Font, Manrope)`)。\n * 测宽会在挂载后改用 getComputedStyle 解析后的值。不要用 `system-ui`。\n */\n fontFamily?: string;\n /** 字重,默认 400。`bold: true` 时仍为 700。 */\n fontWeight?: number;\n color?: string;\n fill?: TextFill;\n}\n\nexport interface ParagraphProps {\n heading?: HeadingLevel;\n align?: Align;\n list?: ListKind;\n indent?: number;\n /** 非空时此段属于同一分组;末段末尾回车新段不再继承。空串表示无分组。 */\n groupId?: string;\n}\n\nexport interface TableProps {\n colWidths?: number[];\n}\n\nexport interface CellProps {\n background?: string;\n}\n\nexport interface ImageProps {\n entityId: string;\n}\n\nexport interface LinkProps {\n url: string;\n}\n\nexport type StyleProps = TextProps | ParagraphProps | TableProps | CellProps | ImageProps | LinkProps;\n\n/** 外链默认色 */\nexport const LINK_COLOR = '#2374d1';\n\nexport interface StyleSpan {\n start: number;\n end: number;\n type: StyleType;\n props: StyleProps;\n}\n\n/** 行内嵌入对象:挂在 `*` 占位符上的实体类型 */\n/** `internalSlot` = SDK 内置芯片;`hostSlot` = 宿主自绘芯片。 */\nexport type EmbedKind = 'image' | 'video' | 'code' | 'formula' | 'internalSlot' | 'ref' | 'hostSlot';\nexport type SlotKind = 'text' | 'image' | 'select';\nexport type MediaKind = EmbedKind;\n\nexport interface EmbedEntity {\n id: string;\n kind?: EmbedKind;\n width: number;\n height: number;\n src?: string;\n language?: string;\n code?: string;\n latex?: string;\n displayMode?: boolean;\n slotKind?: SlotKind;\n label?: string;\n slotValue?: string;\n slotOptions?: string[];\n float?: 'left' | 'right';\n fragmentId?: string;\n /**\n * 宿主渲染型嵌入对象(kind:'hostSlot')承载的业务数据。SDK 不解释其内容,只负责\n * 存取、随实体序列化、在数据变化时通知宿主渲染器重渲。宿主通常在此存业务对象\n * 的引用 id(引用式承载),完整数据由宿主自己的 store 解析。\n */\n data?: unknown;\n /** host 型嵌入对象的类型标识(如 'objectRef'),由宿主定义,SDK 原样透传给渲染器。 */\n hostType?: string;\n}\n\nexport interface Fragment {\n id: string;\n title?: string;\n slice: Slice;\n}\n\n/** @deprecated 使用 EmbedEntity;保留别名以免切片/布局大面积改名 */\nexport type ImageEntity = EmbedEntity;\n\n/** 视频默认宽高比 */\nexport const VIDEO_ASPECT = 1920 / 1080;\n\n/**\n * 虚拟块种类:\n * - `region`:一层皮,整体选中/进出,文字不可直接编辑;\n * - `virtualSlot`:最内层文本槽,像输入框(placeholder、选中、进出);\n * - `mark`:纯样式区间,只给文本流加背景/边框/文字缺省,交互与普通文本完全一致。\n * 不参与区间树(parentId 恒为 null)、不进选中/编辑状态机,可与其它块任意叠放。\n */\nexport type VirtualBlockKind = 'region' | 'virtualSlot' | 'mark';\n\n/**\n * 虚拟块的皮和文字缺省。块皮(底、边、圆角、内边距)只能放这里;\n * 文字字段与 {@link TextProps} 对齐,作排版期 fallback,不是 applyStyle 轨道。\n */\nexport interface VirtualBlockChrome {\n background?: string;\n /** 仅 mark:鼠标悬停在该区间上时用这个底色替换 background(整段、含折行各行) */\n hoverBackground?: string;\n borderColor?: string;\n borderWidth?: number;\n radius?: number;\n /** 水平内边距:只外扩底色/边框(行首行尾也外扩),不影响排版。编辑器 padding.x 小于它时,边缘处会被裁 */\n paddingX?: number;\n color?: string;\n fontSize?: number;\n fontFamily?: string;\n fontWeight?: number;\n bold?: boolean;\n italic?: boolean;\n /** 仅 slot:empty 时用这个色画 placeholder */\n placeholderColor?: string;\n}\n\n/**\n * 盖在同一条 spacers 上的可嵌套区间。不占额外字符,不是实体、不是 fragment。\n * 坐标是模型半开区间 [start, end)。\n */\nexport interface VirtualBlock {\n id: string;\n parentId: string | null;\n kind: VirtualBlockKind;\n start: number;\n end: number;\n chrome: VirtualBlockChrome;\n placeholder?: string;\n empty?: boolean;\n}\n\nexport interface Slice {\n text: string;\n styles: StyleSpan[];\n entities: ImageEntity[];\n fragments?: Fragment[];\n virtualBlocks?: VirtualBlock[];\n}\n\nexport interface Selection {\n anchor: number;\n focus: number;\n}\n\nexport function selStart(sel: Selection): number {\n return Math.min(sel.anchor, sel.focus);\n}\n\nexport function selEnd(sel: Selection): number {\n return Math.max(sel.anchor, sel.focus);\n}\n\nexport function isCollapsed(sel: Selection): boolean {\n return sel.anchor === sel.focus;\n}\n\nexport const DEFAULT_TEXT: Required<Pick<TextProps, 'fontSize' | 'color'>> & TextProps = {\n fontSize: 16,\n color: '#1f2329',\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false\n};\n\nexport const DEFAULT_PARAGRAPH: Required<ParagraphProps> = {\n heading: 0,\n align: 'left',\n list: 'none',\n indent: 0,\n groupId: ''\n};\n\n/** 列表最大嵌套层级 */\nexport const MAX_LIST_INDENT = 8;\n\nexport const HEADING_TEXT: Record<HeadingLevel, TextProps> = {\n 0: { fontSize: 16, bold: false },\n 1: { fontSize: 28, bold: true },\n 2: { fontSize: 22, bold: true },\n 3: { fontSize: 18, bold: true }\n};\n\nexport function hasTextProps(props: TextProps): boolean {\n return (\n props.bold !== undefined ||\n props.italic !== undefined ||\n props.underline !== undefined ||\n props.underlineStyle !== undefined ||\n props.strikethrough !== undefined ||\n props.fontSize !== undefined ||\n props.fontFamily !== undefined ||\n props.fontWeight !== undefined ||\n props.color !== undefined ||\n props.fill !== undefined\n );\n}\n\nexport function textPropsEqual(a: TextProps, b: TextProps): boolean {\n return (\n a.bold === b.bold &&\n a.italic === b.italic &&\n a.underline === b.underline &&\n a.underlineStyle === b.underlineStyle &&\n a.strikethrough === b.strikethrough &&\n a.fontSize === b.fontSize &&\n a.fontFamily === b.fontFamily &&\n a.fontWeight === b.fontWeight &&\n a.color === b.color &&\n a.fill === b.fill\n );\n}\n\nexport function underlineKind(style: TextProps): UnderlineStyle | 'none' {\n if (style.underline === false) return 'none';\n if (style.underlineStyle) return style.underlineStyle;\n if (style.underline) return 'single';\n return 'none';\n}\n\nexport function paraPropsEqual(a: ParagraphProps, b: ParagraphProps): boolean {\n return (\n a.heading === b.heading &&\n a.align === b.align &&\n a.list === b.list &&\n a.indent === b.indent &&\n (a.groupId ?? '') === (b.groupId ?? '')\n );\n}\n\nexport function cloneStyle(span: StyleSpan): StyleSpan {\n return { start: span.start, end: span.end, type: span.type, props: { ...span.props } };\n}\n\nexport function cloneEntity(entity: ImageEntity): ImageEntity {\n return { ...entity };\n}\n\nexport function cloneVirtualBlock(block: VirtualBlock): VirtualBlock {\n return { ...block, chrome: { ...block.chrome } };\n}\n\n/** 虚拟块 chrome 上与 TextProps 对齐的文字缺省。 */\nexport function chromeTextProps(chrome: VirtualBlockChrome): TextProps {\n const props: TextProps = {};\n if (chrome.bold !== undefined) props.bold = chrome.bold;\n if (chrome.italic !== undefined) props.italic = chrome.italic;\n if (chrome.fontSize !== undefined) props.fontSize = chrome.fontSize;\n if (chrome.fontFamily !== undefined) props.fontFamily = chrome.fontFamily;\n if (chrome.fontWeight !== undefined) props.fontWeight = chrome.fontWeight;\n if (chrome.color !== undefined) props.color = chrome.color;\n return props;\n}\n","/**\n * 虚拟块区间表的机械运算:挪坐标、裁切、包含判定。\n *\n * 合法性(不交叉、slot 是叶子)由 Operation 保证。这里只做和 style 同类的\n * 闭开区间算术,以及 Slice 裁切时的平移。\n */\nimport { cloneVirtualBlock, VirtualBlock } from './types';\n\nexport function shiftVirtualBlocksOnInsert(\n blocks: Iterable<VirtualBlock>,\n index: number,\n len: number\n): VirtualBlock[] {\n if (!len) return [...blocks].map(cloneVirtualBlock);\n return [...blocks].map((b) => {\n if (b.end <= index) return cloneVirtualBlock(b);\n if (b.start >= index) return cloneVirtualBlock({ ...b, start: b.start + len, end: b.end + len });\n return cloneVirtualBlock({ ...b, end: b.end + len });\n });\n}\n\nexport function shiftVirtualBlocksOnDelete(\n blocks: Iterable<VirtualBlock>,\n start: number,\n end: number\n): VirtualBlock[] {\n const len = end - start;\n if (len <= 0) return [...blocks].map(cloneVirtualBlock);\n const out: VirtualBlock[] = [];\n for (const b of blocks) {\n if (b.end <= start) {\n out.push(cloneVirtualBlock(b));\n } else if (b.start >= end) {\n out.push(cloneVirtualBlock({ ...b, start: b.start - len, end: b.end - len }));\n } else if (b.start < start && b.end > end) {\n out.push(cloneVirtualBlock({ ...b, end: b.end - len }));\n } else if (b.start < start) {\n if (start > b.start) out.push(cloneVirtualBlock({ ...b, end: start }));\n } else if (b.end > end) {\n out.push(cloneVirtualBlock({ ...b, start, end: b.end - len }));\n }\n }\n return out.filter((b) => b.end > b.start);\n}\n\n/** 半开区间是否相交(相邻不算)。 */\nexport function rangesOverlap(a: { start: number; end: number }, b: { start: number; end: number }): boolean {\n return a.start < b.end && b.start < a.end;\n}\n\n/** 是否交叉:相交但谁也不包含谁。 */\nexport function rangesCross(a: { start: number; end: number }, b: { start: number; end: number }): boolean {\n return rangesOverlap(a, b) && !rangeContains(a, b) && !rangeContains(b, a);\n}\n\n/** a 是否包含 b(相等也算包含)。 */\nexport function rangeContains(a: { start: number; end: number }, b: { start: number; end: number }): boolean {\n return a.start <= b.start && a.end >= b.end;\n}\n\nexport function depthOf(block: VirtualBlock, byId: Map<string, VirtualBlock>): number {\n let d = 0;\n let id = block.parentId;\n const seen = new Set<string>([block.id]);\n while (id && !seen.has(id)) {\n seen.add(id);\n const parent = byId.get(id);\n if (!parent) break;\n d += 1;\n id = parent.parentId;\n }\n return d;\n}\n\n/** 外层在前:覆盖更长的、同长则更浅的排前面。 */\nexport function sortOuterToInner(blocks: VirtualBlock[], byId?: Map<string, VirtualBlock>): VirtualBlock[] {\n const map = byId ?? new Map(blocks.map((b) => [b.id, b]));\n return [...blocks].sort((a, b) => {\n const la = a.end - a.start;\n const lb = b.end - b.start;\n if (la !== lb) return lb - la;\n return depthOf(a, map) - depthOf(b, map);\n });\n}\n\nexport function ancestorChain(block: VirtualBlock, byId: Map<string, VirtualBlock>): VirtualBlock[] {\n const chain: VirtualBlock[] = [];\n let cur: VirtualBlock | undefined = block;\n const seen = new Set<string>();\n while (cur && !seen.has(cur.id)) {\n seen.add(cur.id);\n chain.unshift(cloneVirtualBlock(cur));\n cur = cur.parentId ? byId.get(cur.parentId) : undefined;\n }\n return chain;\n}\n\n/**\n * 裁到半开区间 [from, to) 并平移到以 0 为原点。\n * 父块若没被裁进来,parentId 置 null。\n */\nexport function clipVirtualBlocks(\n blocks: Iterable<VirtualBlock>,\n from: number,\n to: number\n): VirtualBlock[] {\n const hits: VirtualBlock[] = [];\n for (const b of blocks) {\n const start = Math.max(b.start, from);\n const end = Math.min(b.end, to);\n if (end <= start) continue;\n hits.push(\n cloneVirtualBlock({\n ...b,\n start: start - from,\n end: end - from\n })\n );\n }\n const ids = new Set(hits.map((b) => b.id));\n for (const b of hits) {\n if (b.parentId && !ids.has(b.parentId)) b.parentId = null;\n }\n return hits;\n}\n\nexport function offsetVirtualBlocks(blocks: Iterable<VirtualBlock>, offset: number): VirtualBlock[] {\n if (!offset) return [...blocks].map(cloneVirtualBlock);\n return [...blocks].map((b) => cloneVirtualBlock({ ...b, start: b.start + offset, end: b.end + offset }));\n}\n","import { measureNaturalWidth, prepareWithSegments, setLocale } from '@chenglou/pretext';\nimport { DEFAULT_TEXT, TextProps } from '../model/types';\n\n/**\n * 默认测量/绘制字体。具名字体,避免 system-ui 在 canvas 与 DOM 上解析不一致。\n *\n * 宿主可通过 `textDefaults.fontFamily` / 文字 span 覆盖。\n * `.mini-editor` 的 `--mini-font-family` 必须与当前测量字体一致。\n */\nexport const FONT_FAMILY = '\"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif';\n\nexport const LINE_HEIGHT = 1.6;\nexport const PAGE_CONTENT_WIDTH = 680;\nexport const PAGE_PADDING_X = 72;\nexport const PAGE_PADDING_Y = 56;\nexport const LIST_MARKER_WIDTH = 28;\nexport const INDENT_STEP = 24;\nexport const CELL_PAD = 8;\n/** 列宽下限(约 18pt,这里用 px) */\nexport const MIN_COL_WIDTH = 36;\nexport const COL_BORDER_HIT = 4;\n\nconst widthCache = new Map<string, number>();\nconst WIDTH_CACHE_MAX = 20000;\nlet localeReady = false;\n\nexport function ensureLocale() {\n if (localeReady) return;\n setLocale('zh-CN');\n localeReady = true;\n}\n\nexport function fontFamilyOf(props?: TextProps | null): string {\n const raw = props?.fontFamily?.trim();\n // canvas / pretext 不能解析 CSS 变量;测宽应使用 getComputedStyle 解析后的栈。\n if (!raw || /\\bvar\\s*\\(/i.test(raw)) return FONT_FAMILY;\n return raw;\n}\n\nexport function resolveFont(props: TextProps): { size: number; weight: string; style: string; family: string } {\n return {\n size: props.fontSize ?? DEFAULT_TEXT.fontSize,\n weight: props.bold ? '700' : String(props.fontWeight ?? 400),\n style: props.italic ? 'italic' : 'normal',\n family: fontFamilyOf(props)\n };\n}\n\n/** canvas / pretext 用的 font 字符串,需与绘制层 CSS 一致。 */\nexport function canvasFont(props: TextProps): string {\n const font = resolveFont(props);\n return `${font.style} ${font.weight} ${font.size}px ${font.family}`;\n}\n\n/**\n * 宽度测量走 pretext:canvas measureText + 分段缓存,不读 DOM、不触发布局回流。\n * 同一 font+text 只 prepare 一次。\n */\nexport function measureWidth(text: string, props: TextProps): number {\n if (!text) return 0;\n ensureLocale();\n const font = canvasFont(props);\n const key = `${font}\\0${text}`;\n const hit = widthCache.get(key);\n if (hit !== undefined) return hit;\n const prepared = prepareWithSegments(text, font, { whiteSpace: 'pre-wrap' });\n const w = measureNaturalWidth(prepared);\n if (widthCache.size >= WIDTH_CACHE_MAX) widthCache.clear();\n widthCache.set(key, w);\n return w;\n}\n\nconst glyphCache = new Map<string, number[]>();\nconst GLYPH_CACHE_MAX = 4000;\n\nfunction naturalWidth(text: string, font: string): number {\n if (!text) return 0;\n return measureNaturalWidth(prepareWithSegments(text, font, { whiteSpace: 'pre-wrap' }));\n}\n\n/**\n * 一段文字里每个 UTF-16 单元的前进宽度,用于摆字(glyph.x / caret stop)。\n *\n * 折行用的是整串测宽(带字距调整,如 `Te` 比两个字单独相加窄)。如果摆字改用\n * 「每个字单独测宽再累加」,同一行的实际宽度会比折行时认为的宽,最后一个字就会\n * 越过版心被裁掉。所以这里取前缀宽度之差:`w[k] = width(text[0..k]) - width(text[0..k-1])`,\n * 一整段的宽度之和与 {@link measureWidth}(text) 严格相等。\n *\n * 代理对:高位单元带整个码点的宽度,低位单元为 0,保持 `text.length` 个元素。\n */\nexport function measureGlyphWidths(text: string, props: TextProps): number[] {\n if (!text) return [];\n ensureLocale();\n const font = canvasFont(props);\n const key = `${font}\\0${text}`;\n const hit = glyphCache.get(key);\n if (hit) return hit;\n\n const widths = new Array<number>(text.length).fill(0);\n let prevWidth = 0;\n let k = 0;\n while (k < text.length) {\n const cp = text.codePointAt(k) ?? 0;\n const end = k + (cp > 0xffff ? 2 : 1);\n const width = end === text.length ? measureWidth(text, props) : naturalWidth(text.slice(0, end), font);\n widths[k] = Math.max(0, width - prevWidth);\n prevWidth = width;\n k = end;\n }\n\n if (glyphCache.size >= GLYPH_CACHE_MAX) glyphCache.clear();\n glyphCache.set(key, widths);\n return widths;\n}\n\nexport function lineHeightOf(props: TextProps): number {\n return Math.round((props.fontSize ?? DEFAULT_TEXT.fontSize) * LINE_HEIGHT);\n}\n\nexport function isCjk(ch: string): boolean {\n const c = ch.charCodeAt(0);\n return (\n (c >= 0x4e00 && c <= 0x9fff) ||\n (c >= 0x3400 && c <= 0x4dbf) ||\n (c >= 0x3000 && c <= 0x303f) ||\n (c >= 0xff00 && c <= 0xffef)\n );\n}\n\nexport function canBreakAfter(ch: string): boolean {\n if (!ch) return false;\n if (/\\s/.test(ch)) return true;\n return isCjk(ch);\n}\n","/** 与正文对齐,不再为轨或标题栏留空。 */\nexport const REF_PAD = 0;\nexport const REF_HEAD = 0;\n\nexport function refInnerWidth(boxW: number): number {\n return Math.max(40, boxW - REF_PAD);\n}\n","import { DocumentModel } from '../model/document';\nimport { DEFAULT_TEXT, HEADING_TEXT, LINK_COLOR, LinkProps, ParagraphProps, TextProps, VirtualBlock } from '../model/types';\n\nfunction chromeFallback(doc: DocumentModel, index: number): TextProps {\n const chain = doc.blocksAt(index);\n const t: TextProps = {};\n for (const b of chain) {\n const c = b.chrome;\n if (c.bold !== undefined) t.bold = c.bold;\n if (c.italic !== undefined) t.italic = c.italic;\n if (c.fontSize !== undefined) t.fontSize = c.fontSize;\n if (c.fontFamily !== undefined) t.fontFamily = c.fontFamily;\n if (c.fontWeight !== undefined) t.fontWeight = c.fontWeight;\n if (c.color !== undefined) t.color = c.color;\n }\n const inner = innermostEmptySlot(chain);\n if (inner?.chrome.placeholderColor) t.color = inner.chrome.placeholderColor;\n return t;\n}\n\nfunction innermostEmptySlot(chain: VirtualBlock[]): VirtualBlock | null {\n for (let i = chain.length - 1; i >= 0; i--) {\n if (chain[i].kind === 'virtualSlot' && chain[i].empty) return chain[i];\n }\n return null;\n}\n\nexport function resolvedTextStyle(doc: DocumentModel, index: number, para: ParagraphProps): TextProps {\n const heading = HEADING_TEXT[para.heading ?? 0];\n const span = doc.styles.find((s) => s.type === 'text' && s.start <= index && index < s.end);\n const link = doc.styles.find((s) => s.type === 'link' && s.start <= index && index < s.end);\n const t = span ? (span.props as TextProps) : {};\n const chrome = chromeFallback(doc, index);\n const href = link ? (link.props as LinkProps).url : '';\n return {\n bold: t.bold ?? chrome.bold ?? heading.bold ?? false,\n italic: t.italic ?? chrome.italic ?? false,\n underline: t.underline ?? (href ? true : false),\n underlineStyle: t.underlineStyle,\n strikethrough: t.strikethrough ?? false,\n fontSize:\n t.fontSize ??\n chrome.fontSize ??\n ((para.heading ?? 0) > 0 ? heading.fontSize : undefined) ??\n doc.textDefaults?.fontSize ??\n DEFAULT_TEXT.fontSize,\n fontFamily: t.fontFamily ?? chrome.fontFamily ?? doc.textDefaults?.fontFamily,\n fontWeight: t.fontWeight ?? chrome.fontWeight ?? doc.textDefaults?.fontWeight,\n color: t.color ?? chrome.color ?? (href ? LINK_COLOR : doc.textDefaults?.color ?? DEFAULT_TEXT.color),\n fill: t.fill\n };\n}\n","import { layoutNextLine, prepareWithSegments, type PreparedTextWithSegments } from '@chenglou/pretext';\nimport { DocumentModel } from '../model/document';\nimport { isTableMarker, MARKERS } from '../model/markers';\nimport { DEFAULT_TEXT, ImageEntity, ParagraphProps, TextProps, textPropsEqual } from '../model/types';\nimport { canvasFont, ensureLocale, measureWidth } from './measure';\nimport { resolvedTextStyle } from './style';\n\nexport type WrapItem =\n | { kind: 'text'; index: number; length: number; text: string; style: TextProps }\n | { kind: 'image'; index: number; length: 1; entity: ImageEntity };\n\n/** 与 host 插件 FALLBACK 一致:未回传测宽前不要按 0 排版,否则后随文字会叠进胶囊。 */\nconst HOST_FALLBACK_W = 120;\nconst HOST_FALLBACK_H = 24;\n\nexport function embedLayoutSize(entity: ImageEntity, maxWidth?: number): { width: number; height: number } {\n const host = entity.kind === 'hostSlot';\n let width = entity.width > 0 ? entity.width : host ? HOST_FALLBACK_W : 0;\n const height = entity.height > 0 ? entity.height : host ? HOST_FALLBACK_H : entity.height;\n if (maxWidth != null && maxWidth > 0 && width > maxWidth) width = maxWidth;\n return { width, height };\n}\n\n/** 测宽达到行宽则独占一行。芯片 host 按 kind 行内折,不走高度阈值;代码块/视频仍按高度独占。 */\nexport function embedOccupiesLine(entity: ImageEntity, maxWidth: number): boolean {\n if (entity.float) return false;\n const raw = entity.width > 0 ? entity.width : entity.kind === 'hostSlot' ? HOST_FALLBACK_W : 0;\n if (raw >= maxWidth - 0.5) return true;\n if (entity.kind === 'hostSlot') return false;\n const height = entity.height > 0 ? entity.height : entity.height;\n return height > 36;\n}\n\nexport type WrappedLine = { items: WrapItem[]; start: number; end: number };\n\nconst preparedCache = new Map<string, PreparedTextWithSegments>();\nconst PREPARED_CACHE_MAX = 4000;\n\nfunction preparedFor(text: string, style: TextProps): PreparedTextWithSegments {\n ensureLocale();\n const font = canvasFont(style);\n const key = `${font}\\0${text}`;\n const hit = preparedCache.get(key);\n if (hit) return hit;\n const prepared = prepareWithSegments(text, font, { whiteSpace: 'pre-wrap' });\n if (preparedCache.size >= PREPARED_CACHE_MAX) preparedCache.clear();\n preparedCache.set(key, prepared);\n return prepared;\n}\n\n/** 窗口末尾留出的余量:断行若落在这里面,可能受被截掉的后文影响(避头尾、粘连标点),要加大窗口重排 */\nconst WINDOW_SLACK = 8;\n\n/**\n * `rest` 从头开始、宽度 `width` 内的第一行文字。\n *\n * 只把“一行够用”的前缀窗口交给 pretext,排满窗口再加倍。每行都对整段剩余文字\n * prepare 一次是 O(段长²):4000 字的单段每次输入要 300ms+。\n */\nfunction nextLineText(rest: string, style: TextProps, width: number): string {\n const size = style.fontSize ?? DEFAULT_TEXT.fontSize;\n // 最窄的字形约 0.25em(i、l、空格),按它估一行最多能放几个字\n let n = Math.max(64, Math.ceil(width / (size * 0.25)) + WINDOW_SLACK * 2);\n for (;;) {\n const whole = n >= rest.length;\n const win = whole ? rest : rest.slice(0, n);\n const line = layoutNextLine(preparedFor(win, style), { segmentIndex: 0, graphemeIndex: 0 }, width);\n const len = line?.text ? Math.min(line.text.length, win.length) : win.length;\n if (whole || len <= win.length - WINDOW_SLACK) return win.slice(0, len);\n n *= 2;\n }\n}\n\nexport type SourceRun =\n | { kind: 'text'; index: number; text: string; style: TextProps }\n | { kind: 'image'; index: number; entity: ImageEntity };\n\nfunction collectRuns(doc: DocumentModel, start: number, end: number, para: ParagraphProps): SourceRun[] {\n const runs: SourceRun[] = [];\n let i = start;\n while (i < end) {\n const ch = doc.spacers[i];\n if (ch === MARKERS.PARAGRAPH || isTableMarker(ch)) {\n i += 1;\n continue;\n }\n if (ch === MARKERS.IMAGE) {\n const entity = doc.imageAt(i);\n if (entity) {\n runs.push({ kind: 'image', index: i, entity });\n i += 1;\n continue;\n }\n }\n const style = resolvedTextStyle(doc, i, para);\n let j = i + 1;\n while (j < end) {\n const n = doc.spacers[j];\n if (n === MARKERS.PARAGRAPH || n === MARKERS.IMAGE || isTableMarker(n)) break;\n const ns = resolvedTextStyle(doc, j, para);\n if (!textPropsEqual(style, ns)) break;\n j += 1;\n }\n const text = doc.spacers.slice(i, j);\n runs.push({ kind: 'text', index: i, text, style });\n i = j;\n }\n return runs;\n}\n\nfunction fitPrefix(text: string, style: TextProps, maxWidth: number): string {\n if (!text) return '';\n if (measureWidth(text, style) <= maxWidth) return text;\n let lo = 1;\n let hi = text.length;\n let best = 1;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n if (measureWidth(text.slice(0, mid), style) <= maxWidth) {\n best = mid;\n lo = mid + 1;\n } else {\n hi = mid - 1;\n }\n }\n return text.slice(0, best);\n}\n\n/**\n * 断行走 pretext 的 prepareWithSegments + layoutNextLine(pre-wrap)。\n * 嵌入对象(图/视频/代码/公式)保持原子盒,不交给 pretext。\n */\nexport function wrapParagraph(\n doc: DocumentModel,\n start: number,\n end: number,\n para: ParagraphProps,\n maxWidth: number\n): WrappedLine[] {\n const runs = collectRuns(doc, start, end, para);\n const lines: WrappedLine[] = [];\n let items: WrapItem[] = [];\n let lineW = 0;\n let lineStart = start;\n\n const flush = (lineEnd: number) => {\n lines.push({ items, start: lineStart, end: lineEnd });\n items = [];\n lineW = 0;\n lineStart = lineEnd;\n };\n\n for (const run of runs) {\n if (run.kind === 'image') {\n const isolated = embedOccupiesLine(run.entity, maxWidth);\n const w = embedLayoutSize(run.entity, maxWidth).width;\n if (isolated) {\n if (items.length > 0) flush(run.index);\n items.push({ kind: 'image', index: run.index, length: 1, entity: run.entity });\n flush(run.index + 1);\n continue;\n }\n if (items.length > 0 && lineW + w > maxWidth) flush(run.index);\n items.push({ kind: 'image', index: run.index, length: 1, entity: run.entity });\n lineW += w;\n continue;\n }\n\n let rest = run.text;\n let restIndex = run.index;\n while (rest.length) {\n const remain = maxWidth - lineW;\n if (items.length > 0 && remain <= 0) {\n flush(restIndex);\n continue;\n }\n const widthForLine = items.length > 0 ? Math.max(1, remain) : Math.max(1, maxWidth);\n let text = fitPrefix(nextLineText(rest, run.style, widthForLine), run.style, widthForLine);\n if (!text) {\n text = rest[0] ?? '';\n }\n if (items.length > 0 && measureWidth(text, run.style) > remain + 0.5 && remain < maxWidth) {\n flush(restIndex);\n continue;\n }\n const w = measureWidth(text, run.style);\n items.push({\n kind: 'text',\n index: restIndex,\n length: text.length,\n text,\n style: run.style\n });\n lineW += w;\n rest = rest.slice(text.length);\n restIndex += text.length;\n if (rest) flush(restIndex);\n }\n }\n\n if (items.length > 0 || lines.length === 0) {\n flush(end);\n }\n return lines;\n}\n\nexport type FlowObstacle = { x: number; y: number; w: number; h: number; side: 'left' | 'right' };\n\nexport function bandSlot(\n contentX: number,\n contentW: number,\n bandTop: number,\n bandH: number,\n obstacles: FlowObstacle[],\n gap = 14\n): { x: number; w: number } {\n let left = contentX;\n let right = contentX + contentW;\n for (const f of obstacles) {\n if (f.y + f.h <= bandTop + 0.5 || f.y >= bandTop + bandH - 0.5) continue;\n if (f.side === 'left') left = Math.max(left, f.x + f.w + gap);\n else right = Math.min(right, f.x - gap);\n }\n return { x: left, w: Math.max(48, right - left) };\n}\n\nexport type RunCursor = { runs: SourceRun[]; i: number; off: number };\n\nfunction cursorIndex(cur: RunCursor, fallback: number): number {\n const run = cur.runs[cur.i];\n if (!run) return fallback;\n return run.kind === 'text' ? run.index + cur.off : run.index;\n}\n\nexport function createWrapCursor(doc: DocumentModel, start: number, end: number, para: ParagraphProps, skipFloats = true): RunCursor {\n const runs = collectRuns(doc, start, end, para).filter((r) => !(skipFloats && r.kind === 'image' && r.entity.float));\n return { runs, i: 0, off: 0 };\n}\n\nexport function wrapCursorDone(cur: RunCursor): boolean {\n return cur.i >= cur.runs.length;\n}\n\nexport function wrapCursorIndex(cur: RunCursor, fallback: number): number {\n return cursorIndex(cur, fallback);\n}\n\nexport function wrapCursorPeek(cur: RunCursor): SourceRun | undefined {\n return cur.runs[cur.i];\n}\n\nexport function wrapCursorSkip(cur: RunCursor) {\n cur.i += 1;\n cur.off = 0;\n}\n\nexport function consumeWrapLine(cur: RunCursor, maxWidth: number): WrapItem[] {\n const items: WrapItem[] = [];\n let lineW = 0;\n while (!wrapCursorDone(cur)) {\n const run = cur.runs[cur.i];\n const remain = maxWidth - lineW;\n if (run.kind === 'image') {\n if (run.entity.float) break;\n const isolated = embedOccupiesLine(run.entity, maxWidth);\n const w = embedLayoutSize(run.entity, maxWidth).width;\n if (isolated) {\n if (items.length > 0) break;\n items.push({ kind: 'image', index: run.index, length: 1, entity: run.entity });\n cur.i += 1;\n break;\n }\n if (items.length > 0 && w > remain) break;\n items.push({ kind: 'image', index: run.index, length: 1, entity: run.entity });\n lineW += w;\n cur.i += 1;\n continue;\n }\n const rest = run.text.slice(cur.off);\n if (!rest) {\n cur.i += 1;\n cur.off = 0;\n continue;\n }\n if (items.length > 0 && remain <= 0) break;\n const widthForLine = items.length > 0 ? Math.max(1, remain) : Math.max(1, maxWidth);\n let text = fitPrefix(nextLineText(rest, run.style, widthForLine), run.style, widthForLine);\n if (!text) text = rest[0] ?? '';\n if (items.length > 0 && measureWidth(text, run.style) > remain + 0.5 && remain < maxWidth) break;\n const w = measureWidth(text, run.style);\n items.push({ kind: 'text', index: run.index + cur.off, length: text.length, text, style: run.style });\n lineW += w;\n cur.off += text.length;\n if (cur.off >= run.text.length) {\n cur.i += 1;\n cur.off = 0;\n }\n if (cur.off > 0) break;\n }\n return items;\n}\n","import { parseBlocks, TableBlock } from '../model/blocks';\nimport { DocumentModel } from '../model/document';\nimport { MARKERS } from '../model/markers';\nimport {\n DEFAULT_PARAGRAPH,\n ParagraphProps,\n StyleSpan,\n Selection,\n selEnd,\n selStart\n} from '../model/types';\nimport { depthOf, sortOuterToInner } from '../model/virtualBlock';\nimport { CELL_PAD, COL_BORDER_HIT, INDENT_STEP, lineHeightOf, LIST_MARKER_WIDTH, measureGlyphWidths, measureWidth, PAGE_CONTENT_WIDTH, PAGE_PADDING_X, PAGE_PADDING_Y } from './measure';\nimport { refInnerWidth } from './refMetrics';\nimport { resolvedTextStyle } from './style';\nimport { CaretPos, CaretStop, CellLayout, DocLayout, GlyphBox, ImageBox, LineBox, ParagraphLayout, SelRect, TableLayout, VBlockFragment } from './types';\nimport { bandSlot, consumeWrapLine, createWrapCursor, embedLayoutSize, FlowObstacle, wrapCursorDone, wrapCursorIndex, wrapCursorPeek, wrapCursorSkip, wrapParagraph, WrapItem } from './wrap';\n\nexport { resolvedTextStyle } from './style';\n\nconst UL_MARKERS = ['•', '◦', '▪'];\n\nfunction listMarkerText(para: ParagraphProps, olIndex: number): string {\n if (para.list === 'ul') return UL_MARKERS[(para.indent ?? 0) % UL_MARKERS.length];\n if (para.list === 'ol') return `${olIndex}.`;\n return '';\n}\n\nfunction layoutParagraph(\n doc: DocumentModel,\n start: number,\n end: number,\n x: number,\n y: number,\n maxWidth: number,\n olIndex: number,\n obstacles: FlowObstacle[] = [],\n paraProps?: ParagraphProps\n): ParagraphLayout {\n const props: ParagraphProps = { ...DEFAULT_PARAGRAPH, ...(paraProps ?? doc.paragraphPropsAt(start)) };\n const indent = (props.indent ?? 0) * INDENT_STEP;\n const markerText = listMarkerText(props, olIndex);\n const markerW = props.list && props.list !== 'none' ? LIST_MARKER_WIDTH : 0;\n const contentX = x + indent + markerW;\n const contentW = Math.max(80, maxWidth - indent - markerW);\n const align = props.align ?? 'left';\n const floats: ImageBox[] = [];\n const allObstacles = [...obstacles];\n const useFlow = allObstacles.length > 0 || paragraphHasFloat(doc, start, end);\n const lines: LineBox[] = [];\n let lineY = y;\n\n if (!useFlow) {\n const wrapped = wrapParagraph(doc, start, end, props, contentW);\n for (let i = 0; i < wrapped.length; i++) {\n const row = wrapped[i];\n const line = buildLine(\n doc,\n props,\n row.items,\n contentX,\n lineY,\n contentW,\n align,\n start,\n row.start,\n row.end,\n markerText && i === 0 ? markerText : '',\n x + indent\n );\n lines.push(line);\n lineY += line.h;\n }\n } else {\n const cur = createWrapCursor(doc, start, end, props, false);\n let i = 0;\n do {\n const peek = wrapCursorPeek(cur);\n if (peek?.kind === 'image' && peek.entity.float) {\n const side = peek.entity.float;\n const size = embedLayoutSize(peek.entity, maxWidth);\n const fx = side === 'left' ? x : x + maxWidth - size.width;\n const box: ImageBox = { index: peek.index, x: fx, y: lineY, w: size.width, h: size.height, entity: peek.entity };\n floats.push(box);\n allObstacles.push({ x: box.x, y: box.y, w: box.w, h: box.h, side });\n wrapCursorSkip(cur);\n continue;\n }\n const slot = bandSlot(contentX, contentW, lineY, 28, allObstacles);\n const lineStart = wrapCursorIndex(cur, start);\n const items = wrapCursorDone(cur) ? [] : consumeWrapLine(cur, slot.w);\n const lineEnd = wrapCursorDone(cur) ? end : wrapCursorIndex(cur, end);\n const line = buildLine(\n doc,\n props,\n items,\n slot.x,\n lineY,\n slot.w,\n align,\n start,\n lineStart,\n items.length ? lineEnd : end,\n markerText && i === 0 ? markerText : '',\n x + indent\n );\n lines.push(line);\n lineY += line.h;\n i += 1;\n } while (!wrapCursorDone(cur));\n }\n\n return {\n start,\n end,\n x,\n y,\n w: maxWidth,\n h: Math.max(0, lineY - y),\n props,\n lines,\n floats\n };\n}\n\nfunction paragraphHasFloat(doc: DocumentModel, start: number, end: number): boolean {\n for (let i = start; i < end; i++) {\n if (doc.spacers[i] === MARKERS.IMAGE && doc.imageAt(i)?.float) return true;\n }\n return false;\n}\n\nfunction nextOl(counter: Map<number, number>, props: ParagraphProps): number {\n if (props.list !== 'ol') {\n if (props.list === 'none') counter.clear();\n return 1;\n }\n const key = props.indent ?? 0;\n const n = (counter.get(key) ?? 0) + 1;\n counter.set(key, n);\n for (const k of [...counter.keys()]) {\n if (k > key) counter.delete(k);\n }\n return n;\n}\n\nfunction buildLine(\n doc: DocumentModel,\n para: ParagraphProps,\n items: WrapItem[],\n x: number,\n y: number,\n maxW: number,\n align: ParagraphProps['align'],\n paraStart: number,\n lineStart: number,\n lineEnd: number,\n markerText: string,\n markerX: number\n): LineBox {\n let contentW = 0;\n let contentH = 20;\n for (const item of items) {\n if (item.kind === 'image') {\n const size = embedLayoutSize(item.entity, maxW);\n contentW += size.width;\n contentH = Math.max(contentH, size.height);\n } else {\n contentW += measureWidth(item.text, item.style);\n contentH = Math.max(contentH, lineHeightOf(item.style));\n }\n }\n if (items.length === 0) {\n const emptyStyle = resolvedTextStyle(doc, lineStart, para);\n contentH = lineHeightOf(emptyStyle);\n }\n\n let dx = 0;\n if (align === 'center') dx = Math.max(0, (maxW - contentW) / 2);\n if (align === 'right') dx = Math.max(0, maxW - contentW);\n\n const glyphs: GlyphBox[] = [];\n const images: ImageBox[] = [];\n const caretStops: CaretStop[] = [{ index: lineStart, x: x + dx }];\n let cx = x + dx;\n\n for (const item of items) {\n if (item.kind === 'image') {\n const size = embedLayoutSize(item.entity, maxW);\n images.push({\n index: item.index,\n x: cx,\n y: y + Math.max(0, (contentH - size.height) / 2),\n w: size.width,\n h: size.height,\n entity: item.entity\n });\n cx += size.width;\n caretStops.push({ index: item.index + 1, x: cx });\n } else {\n let local = cx;\n // 摆字宽度取前缀宽度之差,与折行时的整串测宽口径一致,否则带字距调整的字体\n // (如 Manrope 的 `Te`)逐字累加会比折行预算宽,行尾字会越过版心。\n const widths = measureGlyphWidths(item.text, item.style);\n for (let k = 0; k < item.text.length; k++) {\n const ch = item.text[k];\n const w = widths[k];\n glyphs.push({\n index: item.index + k,\n x: local,\n y,\n w,\n h: contentH,\n text: ch,\n style: item.style\n });\n local += w;\n caretStops.push({ index: item.index + k + 1, x: local });\n }\n cx = local;\n }\n }\n\n if (caretStops[caretStops.length - 1].index !== lineEnd) {\n caretStops.push({ index: lineEnd, x: cx });\n }\n\n const marker = markerText\n ? {\n x: markerX,\n y,\n w: LIST_MARKER_WIDTH,\n h: contentH,\n text: markerText,\n kind: para.list ?? 'none'\n }\n : undefined;\n\n return {\n paragraphStart: paraStart,\n start: lineStart,\n end: lineEnd,\n x,\n y,\n w: maxW,\n h: contentH,\n ascent: contentH,\n align: align ?? 'left',\n glyphs,\n images,\n marker,\n caretStops,\n vblocks: vblockFragments(doc, lineStart, lineEnd, y, contentH, glyphs, images, !align || align === 'left' ? x + maxW : null)\n };\n}\n\nfunction vblockFragments(\n doc: DocumentModel,\n lineStart: number,\n lineEnd: number,\n y: number,\n lineH: number,\n glyphs: GlyphBox[],\n images: ImageBox[],\n fillRight: number | null\n): VBlockFragment[] {\n const hits = doc.virtualBlocksOverlapping(lineStart, lineEnd);\n if (!hits.length) return [];\n const sorted = sortOuterToInner(hits, doc.virtualBlocks);\n const out: VBlockFragment[] = [];\n for (const b of sorted) {\n const boxes: { x: number; y: number; w: number; h: number }[] = [];\n for (const g of glyphs) {\n if (g.index >= b.start && g.index < b.end) boxes.push(g);\n }\n for (const im of images) {\n if (im.index >= b.start && im.index < b.end) boxes.push(im);\n }\n if (!boxes.length) continue;\n const left = Math.min(...boxes.map((box) => box.x));\n const right = Math.max(...boxes.map((box) => box.x + box.w));\n const top = Math.min(...boxes.map((box) => box.y));\n const bottom = Math.max(...boxes.map((box) => box.y + box.h));\n // 只支持水平内边距:底色左右各外扩 padX(行首行尾也外扩)。\n // 它只影响绘制,不参与排版:字形位置、折行、行高都不变。\n const padX = b.chrome.paddingX ?? 0;\n // 区间还延续到后面的行(折行或跨段)时,这一行铺满到内容区右缘,各行连成一个整体;\n // 只有最后一行按文字实际宽度。仅左对齐行这样处理,居中/右对齐保持按内容宽度。\n const continues = b.end > lineEnd && /[^\\n]/.test(doc.spacers.slice(lineEnd, b.end));\n const boxLeft = left - padX;\n const boxRight = continues && fillRight != null ? Math.max(right, fillRight) + padX : right + padX;\n out.push({\n id: b.id,\n kind: b.kind,\n depth: depthOf(b, doc.virtualBlocks),\n x: boxLeft,\n y: Math.min(top, y),\n w: Math.max(0, boxRight - boxLeft),\n h: Math.max(lineH, bottom - top),\n chrome: { ...b.chrome },\n empty: b.empty,\n first: b.start >= lineStart,\n last: !continues\n });\n }\n return out.sort((a, b) => a.depth - b.depth);\n}\n\nfunction layoutTable(doc: DocumentModel, table: TableBlock, x: number, y: number, maxWidth: number, paraIndex: ParagraphPropsIndex): TableLayout {\n const cols = Math.max(1, ...table.rows.map((r) => r.cells.length));\n const stored = doc.tablePropsAt(table.start).colWidths ?? [];\n const even = Math.floor(maxWidth / cols);\n const hasStored = stored.length >= cols && stored.slice(0, cols).every((w) => w > 0);\n const colWidths = hasStored\n ? stored.slice(0, cols)\n : Array.from({ length: cols }, (_, i) => (stored[i] && stored[i] > 0 ? stored[i] : even));\n if (!hasStored) {\n const sum = colWidths.reduce((a, b) => a + b, 0);\n if (sum !== maxWidth) colWidths[cols - 1] += maxWidth - sum;\n }\n\n const cells: CellLayout[] = [];\n let cy = y;\n for (let r = 0; r < table.rows.length; r++) {\n const row = table.rows[r];\n const rowCells: CellLayout[] = [];\n let maxH = 32;\n let cx = x;\n for (let c = 0; c < cols; c++) {\n const cell = row.cells[c];\n const w = colWidths[c];\n const innerW = Math.max(1, w - CELL_PAD * 2);\n const paras: ParagraphLayout[] = [];\n let py = cy + CELL_PAD;\n const ol = new Map<number, number>();\n if (cell) {\n for (const para of cell.paragraphs) {\n const pp = paraIndex.at(para.start, para.end);\n const pl = layoutParagraph(doc, para.start, para.end, cx + CELL_PAD, py, innerW, nextOl(ol, pp), [], pp);\n paras.push(pl);\n py += pl.h;\n }\n }\n const h = Math.max(32, py - cy + CELL_PAD);\n maxH = Math.max(maxH, h);\n rowCells.push({\n row: r,\n col: c,\n start: cell?.start ?? table.start,\n end: cell?.end ?? table.start,\n x: cx,\n y: cy,\n w,\n h,\n paragraphs: paras\n });\n cx += w;\n }\n for (const cell of rowCells) cell.h = maxH;\n cells.push(...rowCells);\n cy += maxH;\n }\n\n return {\n start: table.start,\n end: table.end,\n x,\n y,\n w: colWidths.reduce((a, b) => a + b, 0),\n h: cy - y,\n colWidths,\n cells\n };\n}\n\nfunction fragmentFingerprint(doc: DocumentModel, fragmentId?: string): string {\n if (!fragmentId) return '';\n const fragment = doc.fragments.get(fragmentId);\n if (!fragment) return fragmentId;\n return `${fragment.slice.text}:${fragment.slice.styles.length}:${fragment.slice.entities.length}`;\n}\n\nfunction hostFingerprint(entity: { kind?: string; hostType?: string; data?: unknown }): string {\n if (entity.kind !== 'hostSlot') return '';\n try {\n return `${entity.hostType ?? ''}:${JSON.stringify(entity.data ?? null)}`;\n } catch {\n return entity.hostType ?? '';\n }\n}\n\nconst hasImagesCache = new WeakMap<DocumentModel, { spacers: string; has: boolean }>();\nfunction hasImages(doc: DocumentModel): boolean {\n const c = hasImagesCache.get(doc);\n if (c && c.spacers === doc.spacers) return c.has;\n const has = doc.spacers.includes(MARKERS.IMAGE);\n hasImagesCache.set(doc, { spacers: doc.spacers, has });\n return has;\n}\n\nfunction mediaFingerprint(doc: DocumentModel, start: number, end: number): string {\n // 全文没有嵌入对象是最常见的情况,直接跳过逐字扫描(indexOf 结果按文档缓存,见 hasImages)\n if (!hasImages(doc)) return '';\n const parts: string[] = [];\n for (let i = start; i < end; i++) {\n if (doc.spacers[i] !== MARKERS.IMAGE) continue;\n const e = doc.imageAt(i);\n if (e) {\n parts.push(\n `${e.id}:${e.kind ?? 'image'}:${hostFingerprint(e)}:${e.width}x${e.height}:${e.float ?? ''}:${e.code ?? ''}:${e.latex ?? ''}:${e.slotKind ?? ''}:${e.label ?? ''}:${e.slotValue ?? ''}:${e.src ?? ''}:${e.fragmentId ?? ''}:${fragmentFingerprint(doc, e.fragmentId)}:${(e.slotOptions ?? []).join('/')}`\n );\n }\n }\n return parts.join(',');\n}\n\n/**\n * 按块查样式区间的索引。\n *\n * 每排一次版就要给每个块算一次内容哈希,而哈希要知道「盖住这个块的样式区间」。\n * 直接在全表上筛是块数 × 区间数,长文档里这是排版的主要开销。\n *\n * 区间表本身按 `start` 有序(模型每次写完都会规范化),所以再存一列「前 i 个区间\n * 里最大的 end」—— 这一列必然单调,可以二分出第一个可能盖住本块的位置。它不要求\n * 区间互不相交,同一个下标上叠着文字、链接、图片好几层也照样对。\n */\nexport class StyleIndex {\n private spans: StyleSpan[];\n /** maxEnd[i] = spans[0..i] 里最大的 end,单调不减 */\n private maxEnd: number[];\n\n constructor(spans: StyleSpan[]) {\n this.spans = spans;\n this.maxEnd = [];\n let running = -Infinity;\n for (const s of spans) {\n running = Math.max(running, s.end);\n this.maxEnd.push(running);\n }\n }\n\n /** 第一个可能与 `start` 之后相交的区间下标。 */\n private lowerBound(start: number): number {\n let lo = 0;\n let hi = this.spans.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (this.maxEnd[mid] > start) hi = mid;\n else lo = mid + 1;\n }\n return lo;\n }\n\n /**\n * 块内的样式区间,端点相对块起点、并裁到块边界内。\n *\n * 相对化是缓存能跨编辑复用的前提:在文档中间插一个字,后面每个块的绝对下标都会\n * 平移,但它们的排版结果一模一样。裁剪是同一个道理 —— 一段样式伸到块外多远,不\n * 影响这个块怎么排。\n */\n key(start: number, end: number, types?: Set<string>): string {\n const parts: string[] = [];\n for (let i = this.lowerBound(start); i < this.spans.length; i++) {\n const s = this.spans[i];\n if (s.start >= end) break;\n if (s.end <= start) continue;\n if (types && !types.has(s.type)) continue;\n parts.push(\n `${s.type}:${Math.max(s.start, start) - start}:${Math.min(s.end, end) - start}:${JSON.stringify(s.props)}`\n );\n }\n return parts.join('|');\n }\n}\n\nconst INLINE_STYLES = new Set(['text', 'link', 'image']);\n\n/**\n * 段落属性查表。`doc.paragraphPropsAt` 每次都要 parseBlocks 扫全文来找段落边界,\n * 排版循环里已经知道每个块的 [start,end),再按位置扫一遍就是 段落数×全文长度 的平方开销\n * (8 万字 / 1000 段实测 1.7s)。这里一次性把段落样式区间收进 Map,按区间精确命中,\n * 命不中再退回重叠查找,语义与 paragraphPropsAt 一致。\n */\nclass ParagraphPropsIndex {\n private exact = new Map<string, StyleSpan>();\n private spans: StyleSpan[];\n\n constructor(doc: DocumentModel) {\n this.spans = doc.styles.filter((s) => s.type === 'paragraph');\n for (const s of this.spans) this.exact.set(`${s.start}:${s.end}`, s);\n }\n\n private keys = new WeakMap<StyleSpan, string>();\n private defaultKey = JSON.stringify(DEFAULT_PARAGRAPH);\n\n private spanFor(start: number, end: number): StyleSpan | undefined {\n return this.exact.get(`${start}:${end}`) ?? this.spans.find((s) => s.start < end && s.end > start);\n }\n\n at(start: number, end: number): ParagraphProps {\n return { ...DEFAULT_PARAGRAPH, ...(this.spanFor(start, end)?.props as ParagraphProps | undefined) };\n }\n\n /** 用于哈希的属性串:同一个样式区间只 stringify 一次 */\n key(start: number, end: number): string {\n const span = this.spanFor(start, end);\n if (!span) return this.defaultKey;\n let k = this.keys.get(span);\n if (!k) this.keys.set(span, (k = JSON.stringify({ ...DEFAULT_PARAGRAPH, ...span.props })));\n return k;\n }\n}\n\nfunction textDefaultsKey(doc: DocumentModel): string {\n return JSON.stringify({ f: doc.textDefaults?.fontFamily, w: doc.textDefaults?.fontWeight, s: doc.textDefaults?.fontSize });\n}\n\nfunction hashParagraph(doc: DocumentModel, styles: StyleIndex, start: number, end: number, width: number, olIndex: number, floatKey: string, propsKey: string, tdKey: string): string {\n return `p:${width}:${olIndex}:${floatKey}:${propsKey}:${doc.spacers.slice(start, end)}:${styles.key(start, end, INLINE_STYLES)}:${mediaFingerprint(doc, start, end)}:${vblockFingerprint(doc, start, end)}:td:${tdKey}`;\n}\n\nfunction vblockFingerprint(doc: DocumentModel, start: number, end: number): string {\n return doc\n .virtualBlocksOverlapping(start, end)\n // 区间相对段首:段落整体平移时哈希不变,才能命中缓存\n .map((b) => `${b.id}:${b.kind}:${b.parentId}:${b.start - start}:${b.end - start}:${b.empty ? 1 : 0}:${b.placeholder ?? ''}:${JSON.stringify(b.chrome)}`)\n .join(';');\n}\n\nfunction hashTable(doc: DocumentModel, styles: StyleIndex, table: TableBlock, width: number): string {\n return `t:${width}:${doc.spacers.slice(table.start, table.end)}:${styles.key(table.start, table.end)}:${mediaFingerprint(doc, table.start, table.end)}`;\n}\n\n/**\n * 把一份缓存的块布局搬到新位置:`dy` 是纵向位移,`di` 是下标位移。\n *\n * 下标必须跟着搬。布局里到处存着 spacer 下标(字形、图片、行的首尾、光标落点),\n * 命中测试和选区全靠它们 —— 只平移 y 会让复用的块指向错误的字符。\n *\n * 引用块的 `inner` 不动:它是片段自己坐标空间里的布局,和外层的下标无关。\n */\nfunction floatBoxes(paras: ParagraphLayout[]): ImageBox[] {\n return paras.flatMap((p) => p.floats ?? []);\n}\n\n/** 一个段落实际占的纵向范围:浮动图片可以探到段落之外。 */\nfunction paragraphBottom(p: ParagraphLayout): number {\n let bottom = p.y + p.h;\n for (const f of p.floats ?? []) bottom = Math.max(bottom, f.y + f.h);\n return bottom;\n}\n\nfunction moveParagraph(p: ParagraphLayout, dy: number, di: number, inPlace: boolean): ParagraphLayout {\n if (!dy && !di) return p;\n if (inPlace) return shiftParagraphInPlace(p, dy, di);\n return {\n ...p,\n y: p.y + dy,\n start: p.start + di,\n end: p.end + di,\n lines: p.lines.map((l) => ({\n ...l,\n y: l.y + dy,\n paragraphStart: l.paragraphStart + di,\n start: l.start + di,\n end: l.end + di,\n glyphs: l.glyphs.map((g) => ({ ...g, y: g.y + dy, index: g.index + di })),\n images: l.images.map((im) => ({ ...im, y: im.y + dy, index: im.index + di })),\n vblocks: l.vblocks?.map((v) => ({ ...v, y: v.y + dy })),\n marker: l.marker ? { ...l.marker, y: l.marker.y + dy } : undefined,\n caretStops: l.caretStops.map((c) => ({ ...c, index: c.index + di }))\n })),\n floats: p.floats?.map((f) => ({ ...f, y: f.y + dy, index: f.index + di }))\n };\n}\n\n/**\n * 就地平移。上一份布局在增量排版后就被丢弃(Editor 只保留最新一份),复用的块没必要\n * 深拷贝:8 万字文档在中间敲一个字,后面所有段落的下标都要加 1,拷贝 8 万个字形对象\n * 外加 GC 要二三十毫秒,就地改字段只要一两毫秒。\n */\nfunction shiftParagraphInPlace(p: ParagraphLayout, dy: number, di: number): ParagraphLayout {\n p.y += dy;\n p.start += di;\n p.end += di;\n for (const l of p.lines) {\n l.y += dy;\n l.paragraphStart += di;\n l.start += di;\n l.end += di;\n if (dy) {\n for (const g of l.glyphs) g.y += dy;\n for (const im of l.images) im.y += dy;\n if (l.vblocks) for (const v of l.vblocks) v.y += dy;\n if (l.marker) l.marker.y += dy;\n }\n if (di) {\n for (const g of l.glyphs) g.index += di;\n for (const im of l.images) im.index += di;\n for (const c of l.caretStops) c.index += di;\n }\n }\n if (p.floats) {\n for (const f of p.floats) {\n f.y += dy;\n f.index += di;\n }\n }\n return p;\n}\n\nfunction moveTable(t: TableLayout, dy: number, di: number, inPlace: boolean): TableLayout {\n if (!dy && !di) return t;\n if (inPlace) {\n t.y += dy;\n t.start += di;\n t.end += di;\n for (const c of t.cells) {\n c.y += dy;\n c.start += di;\n c.end += di;\n for (const p of c.paragraphs) moveParagraph(p, dy, di, true);\n }\n return t;\n }\n return {\n ...t,\n y: t.y + dy,\n start: t.start + di,\n end: t.end + di,\n cells: t.cells.map((c) => ({\n ...c,\n y: c.y + dy,\n start: c.start + di,\n end: c.end + di,\n paragraphs: c.paragraphs.map((p) => moveParagraph(p, dy, di, false))\n }))\n };\n}\n\n/**\n * 上一次排版复用了多少块、重排了多少块。\n *\n * 只为诊断和自检存在 —— 自检要能确认「确实复用了」,否则缓存整体失效也会静静\n * 通过。嵌套排版(引用块内部)累加进同一份计数,顶层调用时清零。\n */\nexport interface LayoutStats {\n reused: number;\n laidOut: number;\n}\n\nlet stats: LayoutStats = { reused: 0, laidOut: 0 };\n\nexport function lastLayoutStats(): LayoutStats {\n return { ...stats };\n}\n\nexport function layoutDocument(\n doc: DocumentModel,\n contentWidth = PAGE_CONTENT_WIDTH,\n prev?: DocLayout,\n insets: { x: number; y: number } = { x: PAGE_PADDING_X, y: PAGE_PADDING_Y },\n depth = 0\n): DocLayout {\n if (depth === 0) stats = { reused: 0, laidOut: 0 };\n const contentX = insets.x;\n const contentY = insets.y;\n const paragraphs: ParagraphLayout[] = [];\n const tables: TableLayout[] = [];\n let y = contentY;\n const topOl = new Map<number, number>();\n let activeFloats: FlowObstacle[] = [];\n\n // 脏区带:只有这个纵向区间里的像素变了,绘制层据此决定重画哪一段。\n // 判定规则很简单,也正因为简单才守得住:\n // 复用且没挪位置 → 像素一模一样,干净;\n // 复用但挪了位置 → 老位置和新位置都脏;\n // 重排的块 → 它自己那一段脏。\n // 一个块高度变了,它下面的块就会挪位置、跟着进脏区,所以「只标自己这一段」\n // 不会漏 —— 下面全都没挪,恰好说明这个块的高度没变。\n //\n // 挪位置的块连老位置一起标。理论上老位置会被下面的块顺带覆盖(块是竖直连续\n // 堆叠的),但那是个全局论证,一处不成立就花屏 —— 一个 Math.min 换掉这份心智\n // 负担,值得。\n //\n // 浮动图片是这套推理真正的例外:它能探出所在段落之外。所以段落占的像素高度按\n // max(段高, 浮动图底边) 算,而且循环之后还要拿上一份布局里的浮动图单独对一遍。\n let dirtyTop = Infinity;\n let dirtyBottom = -Infinity;\n const markDirty = (top: number, bottom: number) => {\n dirtyTop = Math.min(dirtyTop, top);\n dirtyBottom = Math.max(dirtyBottom, bottom);\n };\n // 没有上一份布局、或者宽度变了,一切都要重来\n if (!prev || prev.contentWidth !== contentWidth) markDirty(0, Infinity);\n\n const styleIndex = new StyleIndex(doc.styles);\n const paraIndex = new ParagraphPropsIndex(doc);\n const tdKey = textDefaultsKey(doc);\n // 同一哈希可能对应多个块(空行、重复段落很常见)。按哈希只留一个会让所有同款块都\n // 「命中」最后那一个,再被当成挪了位置:每次敲字都要深拷贝并标脏整篇。\n // 这里保留全部候选,优先取纵向位置相同的,其次取下标相同的。\n type Cached = ParagraphLayout | TableLayout;\n const prevByHash = new Map<string, { byY: Map<number, Cached>; byStart: Map<number, Cached>; first: Cached }>();\n if (prev) {\n for (const b of [...prev.paragraphs, ...prev.tables]) {\n if (!b.hash) continue;\n let entry = prevByHash.get(b.hash);\n if (!entry) prevByHash.set(b.hash, (entry = { byY: new Map(), byStart: new Map(), first: b }));\n entry.byY.set(Math.round(b.y), b);\n entry.byStart.set(b.start, b);\n }\n }\n // 就地平移的前提:prev 没被消费过(同一份布局只能喂一次),且同一个缓存块在本轮\n // 只被一个新块复用(同哈希多块时 first 兜底可能重复命中,重复的那次退回拷贝)。\n const inPlaceAllowed = !!prev && !prev.consumed;\n if (prev) prev.consumed = true;\n const shifted = new Set<Cached>();\n const canShiftInPlace = (c: Cached): boolean => {\n if (!inPlaceAllowed || shifted.has(c)) return false;\n shifted.add(c);\n return true;\n };\n const pickCached = (hash: string, y: number, start: number): Cached | undefined => {\n const entry = prevByHash.get(hash);\n if (!entry) return undefined;\n const ry = Math.round(y);\n return entry.byY.get(ry) ?? entry.byY.get(ry - 1) ?? entry.byY.get(ry + 1) ?? entry.byStart.get(start) ?? entry.first;\n };\n\n for (const block of parseBlocks(doc.spacers)) {\n if (block.kind === 'paragraph') {\n const props = paraIndex.at(block.start, block.end);\n const olIndex = nextOl(topOl, props);\n activeFloats = activeFloats.filter((f) => f.y + f.h > y + 0.5);\n const floatKey = activeFloats.map((f) => `${f.side}:${Math.round(f.w)}x${Math.round(Math.max(0, f.y + f.h - y))}`).join(',');\n const hash = hashParagraph(doc, styleIndex, block.start, block.end, contentWidth, olIndex, floatKey, paraIndex.key(block.start, block.end), tdKey);\n const cached = pickCached(hash, y, block.start);\n let p: ParagraphLayout;\n if (cached && 'lines' in cached && cached.hash === hash) {\n const oldY = cached.y;\n const oldBottom = paragraphBottom(cached);\n p = moveParagraph(cached, y - oldY, block.start - cached.start, canShiftInPlace(cached));\n p.hash = hash;\n stats.reused++;\n if (Math.abs(oldY - y) > 0.5) {\n markDirty(Math.min(oldY, y), Math.max(oldBottom, paragraphBottom(p)));\n }\n } else {\n p = layoutParagraph(doc, block.start, block.end, contentX, y, contentWidth, olIndex, activeFloats, props);\n p.hash = hash;\n stats.laidOut++;\n markDirty(y, paragraphBottom(p));\n }\n for (const f of p.floats ?? []) {\n if (f.entity.float) activeFloats.push({ x: f.x, y: f.y, w: f.w, h: f.h, side: f.entity.float });\n }\n paragraphs.push(p);\n y += p.h;\n } else {\n topOl.clear();\n const hash = hashTable(doc, styleIndex, block, contentWidth);\n const cached = pickCached(hash, y, block.start);\n let t: TableLayout;\n if (cached && 'cells' in cached && cached.hash === hash) {\n const oldY = cached.y;\n const oldH = cached.h;\n t = moveTable(cached, y - oldY, block.start - cached.start, canShiftInPlace(cached));\n t.hash = hash;\n stats.reused++;\n if (Math.abs(oldY - y) > 0.5) {\n markDirty(Math.min(oldY, y), Math.max(oldY + oldH, y + t.h));\n }\n } else {\n t = layoutTable(doc, block, contentX, y, contentWidth, paraIndex);\n t.hash = hash;\n stats.laidOut++;\n markDirty(y, y + t.h);\n }\n tables.push(t);\n y += t.h + 12;\n }\n }\n\n // 浮动图片探出段落之外,老位置推不出来 —— 直接比:位置或尺寸变了的,老位置也脏\n if (prev) {\n const now = new Map(floatBoxes(paragraphs).map((f) => [f.entity.id, f]));\n for (const old of floatBoxes(prev.paragraphs)) {\n const cur = now.get(old.entity.id);\n if (!cur || cur.x !== old.x || cur.y !== old.y || cur.w !== old.w || cur.h !== old.h) {\n markDirty(old.y, old.y + old.h);\n }\n }\n }\n\n const height = y + insets.y;\n // 文档高度变了说明尾部有内容进出,那一段也要重画(文档变短时得擦掉旧像素)\n if (prev && Math.abs(prev.height - height) > 0.5) {\n markDirty(Math.min(prev.height, height), Math.max(prev.height, height));\n }\n // 「全部重画」用 Infinity 表示,但不该漏进公开结构里,落地成实际画过的最大底边。\n // 注意不能拿文档高度去裁真实的脏区底边 —— 浮动图片可以探出文档底边之外。\n const dirty =\n dirtyTop < dirtyBottom\n ? {\n top: Math.max(0, dirtyTop),\n bottom: Number.isFinite(dirtyBottom) ? dirtyBottom : Math.max(height, prev?.height ?? 0)\n }\n : { top: 0, bottom: 0 };\n\n const lines: LineBox[] = [];\n const images: ImageBox[] = [];\n for (const p of paragraphs) {\n lines.push(...p.lines);\n for (const l of p.lines) {\n l.images = attachRefInners(doc, l.images, depth);\n images.push(...l.images);\n }\n if (p.floats) {\n p.floats = attachRefInners(doc, p.floats, depth);\n images.push(...p.floats);\n }\n }\n for (const t of tables) {\n for (const c of t.cells) {\n for (const p of c.paragraphs) {\n lines.push(...p.lines);\n for (const l of p.lines) {\n l.images = attachRefInners(doc, l.images, depth);\n images.push(...l.images);\n }\n }\n }\n }\n\n return {\n width: contentWidth + insets.x * 2,\n height,\n contentX,\n contentY,\n contentWidth,\n paragraphs,\n tables,\n lines,\n images,\n dirty\n };\n}\n\nfunction attachRefInners(doc: DocumentModel, boxes: ImageBox[], depth: number): ImageBox[] {\n if (depth > 0) return boxes;\n return boxes.map((box) => {\n if (box.entity.kind !== 'ref' || !box.entity.fragmentId) return box;\n const innerW = refInnerWidth(box.w);\n const model = doc.ensureFragmentModel(box.entity.fragmentId);\n return { ...box, inner: layoutDocument(model, innerW, undefined, { x: 0, y: 0 }, depth + 1) };\n });\n}\n\n/**\n * 按起始下标排好序的行,挂在 layout 上惰性建一次。`layout.lines` 是段落行在前、表格行\n * 在后,不保证全局有序,所以不能直接二分。\n */\nconst sortedLinesCache = new WeakMap<DocLayout, LineBox[]>();\nfunction sortedLines(layout: DocLayout): LineBox[] {\n let sorted = sortedLinesCache.get(layout);\n if (!sorted) {\n sorted = [...layout.lines].sort((a, b) => a.start - b.start || a.end - b.end);\n sortedLinesCache.set(layout, sorted);\n }\n return sorted;\n}\n\nexport function caretFromIndex(layout: DocLayout, index: number): CaretPos {\n // 先二分出包含该下标的几行(含前后各一行兜底),命中精确停靠点就不必扫全文:\n // 长文档里光标闪烁每帧都要调这里,全扫一遍 8 万个停靠点太贵。\n const sorted = sortedLines(layout);\n let lo = 0;\n let hi = sorted.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (sorted[mid].end < index) lo = mid + 1;\n else hi = mid;\n }\n let to = lo;\n while (to < sorted.length && sorted[to].start <= index) to++;\n const near = sorted.slice(Math.max(0, lo - 1), Math.min(sorted.length, to + 1));\n return caretFromIndexIn(layout, near, index) ?? caretFromIndexIn(layout, layout.lines, index, true)!;\n}\n\nfunction caretFromIndexIn(layout: DocLayout, lines: LineBox[], index: number, allowNearest = false): CaretPos | null {\n let bestLine: LineBox | null = null;\n let bestX = layout.contentX;\n let bestIndex = index;\n let bestDist = Infinity;\n const exact: { line: LineBox; x: number }[] = [];\n for (const line of lines) {\n for (const stop of line.caretStops) {\n if (stop.index === index) exact.push({ line, x: stop.x });\n const dist = Math.abs(stop.index - index);\n if (dist < bestDist || (dist === bestDist && stop.index <= index)) {\n bestDist = dist;\n bestLine = line;\n bestX = stop.x;\n bestIndex = stop.index;\n }\n }\n }\n if (bestDist !== 0 && !allowNearest) return null;\n // 默认同一下标取后一行(回车换行、普通折行)。仅当后一行是以该下标开头的嵌入对象\n // (文本槽折到下一行、光标在槽前)时,改用上一行行尾,避免光标画在槽行行首。\n if (exact.length >= 2) {\n const earlier = exact[0];\n const later = exact[exact.length - 1];\n const laterIsEmbedHead =\n later.line.caretStops[0]?.index === index &&\n later.line.images.some((img) => img.index === index);\n if (laterIsEmbedHead) {\n bestLine = earlier.line;\n bestX = earlier.x;\n bestIndex = index;\n }\n }\n if (!bestLine) return { x: layout.contentX, y: layout.contentY, h: 24, index };\n return { x: bestX, y: bestLine.y, h: bestLine.h, index: bestIndex };\n}\n\nexport function hitTestIndex(layout: DocLayout, localX: number, localY: number): number {\n for (const table of layout.tables) {\n if (localX < table.x || localX > table.x + table.w || localY < table.y || localY > table.y + table.h) {\n continue;\n }\n for (const cell of table.cells) {\n if (localX >= cell.x && localX < cell.x + cell.w && localY >= cell.y && localY < cell.y + cell.h) {\n const lines = cell.paragraphs.flatMap((p) => p.lines);\n if (lines.length) return closestCaretOnLines(lines, localX, localY);\n return cell.paragraphs[0]?.start ?? cell.start + 1;\n }\n }\n }\n return closestCaretOnLines(layout.lines, localX, localY);\n}\n\nfunction closestCaretOnLines(lines: LineBox[], localX: number, localY: number): number {\n if (lines.length === 0) return 0;\n let best = lines[0];\n let bestScore = Infinity;\n for (const line of lines) {\n const inY = localY >= line.y && localY < line.y + line.h;\n const inX = localX >= line.x && localX <= line.x + line.w;\n if (inY && inX) {\n best = line;\n break;\n }\n const dy = localY < line.y ? line.y - localY : localY >= line.y + line.h ? localY - (line.y + line.h) : 0;\n const dx = localX < line.x ? line.x - localX : localX > line.x + line.w ? localX - (line.x + line.w) : 0;\n const score = dy * 10000 + dx;\n if (score < bestScore) {\n bestScore = score;\n best = line;\n }\n }\n let stop = best.caretStops[0];\n let bestDist = Infinity;\n for (const s of best.caretStops) {\n const d = Math.abs(s.x - localX);\n if (d < bestDist) {\n bestDist = d;\n stop = s;\n }\n }\n return stop.index;\n}\n\nexport function selectionRects(layout: DocLayout, sel: Selection): SelRect[] {\n const from = selStart(sel);\n const to = selEnd(sel);\n if (from === to) return [];\n const cellRects = cellGridRects(layout, from, to);\n if (cellRects) return cellRects;\n const rects: SelRect[] = [];\n for (const line of layout.lines) {\n if (line.end <= from || line.start >= to) {\n const covers =\n line.caretStops.some((s) => s.index >= from && s.index < to) ||\n (from < line.end && to > line.start);\n if (!covers) continue;\n }\n const stops = line.caretStops;\n const left = stops.find((s) => s.index >= from) ?? stops[0];\n const rightCandidates = stops.filter((s) => s.index <= to);\n const right = rightCandidates[rightCandidates.length - 1] ?? stops[stops.length - 1];\n const x0 = Math.min(left.x, right.x);\n const x1 = Math.max(left.x, right.x);\n if (x1 > x0) {\n rects.push({ x: x0, y: line.y, w: x1 - x0, h: line.h });\n }\n }\n return punchEmbeds(rects, layout.images);\n}\n\nfunction punchEmbeds(rects: SelRect[], boxes: ImageBox[]): SelRect[] {\n let out = rects;\n for (const b of boxes) {\n const next: SelRect[] = [];\n for (const r of out) {\n const overlapY = r.y < b.y + b.h && r.y + r.h > b.y;\n const overlapX = r.x < b.x + b.w && r.x + r.w > b.x;\n if (!overlapY || !overlapX) {\n next.push(r);\n continue;\n }\n if (r.x < b.x - 1) next.push({ x: r.x, y: r.y, w: b.x - r.x - 2, h: r.h });\n if (r.x + r.w > b.x + b.w + 1) next.push({ x: b.x + b.w + 2, y: r.y, w: r.x + r.w - (b.x + b.w) - 2, h: r.h });\n }\n out = next.filter((r) => r.w > 2);\n }\n return out;\n}\n\nexport function imageBoxAt(layout: DocLayout, index: number): ImageBox | null {\n return layout.images.find((b) => b.index === index) ?? null;\n}\n\nfunction cellGridRects(layout: DocLayout, from: number, to: number): SelRect[] | null {\n let a: CellLayout | null = null;\n let b: CellLayout | null = null;\n for (const table of layout.tables) {\n for (const cell of table.cells) {\n if (from >= cell.start && from < cell.end) a = cell;\n if (to > cell.start && to <= cell.end) b = cell;\n if (from === cell.start) a = cell;\n if (to === cell.end) b = cell;\n }\n if (a && b && a !== b && table.cells.includes(a) && table.cells.includes(b)) {\n const r0 = Math.min(a.row, b.row);\n const r1 = Math.max(a.row, b.row);\n const c0 = Math.min(a.col, b.col);\n const c1 = Math.max(a.col, b.col);\n return table.cells\n .filter((c) => c.row >= r0 && c.row <= r1 && c.col >= c0 && c.col <= c1)\n .map((c) => ({ x: c.x, y: c.y, w: c.w, h: c.h }));\n }\n if (a && b && a === b && from <= a.start + 1 && to >= a.end) {\n return [{ x: a.x, y: a.y, w: a.w, h: a.h }];\n }\n a = null;\n b = null;\n }\n return null;\n}\n\nexport function hitColBorder(\n layout: DocLayout,\n x: number,\n y: number\n): { tableStart: number; col: number; widths: number[] } | null {\n for (const table of layout.tables) {\n if (y < table.y || y > table.y + table.h || x < table.x - COL_BORDER_HIT || x > table.x + table.w + COL_BORDER_HIT) {\n continue;\n }\n let cx = table.x;\n for (let i = 0; i < table.colWidths.length - 1; i++) {\n cx += table.colWidths[i];\n if (Math.abs(x - cx) <= COL_BORDER_HIT) {\n return { tableStart: table.start, col: i, widths: [...table.colWidths] };\n }\n }\n }\n return null;\n}\n","import { TextFill, TextProps, underlineKind } from '../model/types';\nimport { GlyphBox } from '../layout/types';\n\nexport function fillOf(style: TextProps): TextFill {\n return style.fill ?? 'solid';\n}\n\nexport function rainbowAt(index: number): string {\n const hue = (index * 37) % 360;\n return `hsl(${hue} 80% 46%)`;\n}\n\nexport function sunsetAt(t: number): string {\n const stops = ['#ff4d6d', '#ff8a4c', '#ffd166', '#06d6a0'];\n const x = Math.max(0, Math.min(0.999, t)) * (stops.length - 1);\n return stops[Math.floor(x)];\n}\n\nexport function cssFill(style: TextProps, runWidth: number): string {\n const fill = fillOf(style);\n if (fill === 'rainbow') {\n return `-webkit-background-clip:text;background-clip:text;color:transparent;background-image:linear-gradient(90deg,#ff4d6d,#ffd166,#06d6a0,#4cc9f0,#ff4d6d);background-size:${Math.max(120, runWidth)}px 100%;`;\n }\n if (fill === 'sunset') {\n return `-webkit-background-clip:text;background-clip:text;color:transparent;background-image:linear-gradient(90deg,#ff4d6d,#ff8a4c,#ffd166);`;\n }\n return '';\n}\n\nexport function canvasFill(style: TextProps, glyphIndex: number, runT = 0): string {\n const fill = fillOf(style);\n if (fill === 'rainbow') return rainbowAt(glyphIndex);\n if (fill === 'sunset') return sunsetAt(runT);\n return style.color ?? '#1f2329';\n}\n\nexport function paintCanvasUnderline(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n size: number,\n kind: ReturnType<typeof underlineKind>,\n color: string\n) {\n if (kind === 'none' || w <= 0) return;\n ctx.save();\n ctx.strokeStyle = color;\n ctx.fillStyle = color;\n const t = Math.max(1, size / 16);\n if (kind === 'marker') {\n ctx.globalAlpha = 0.35;\n ctx.strokeStyle = '#ffd166';\n ctx.lineWidth = Math.max(6, size * 0.28);\n ctx.lineCap = 'round';\n ctx.beginPath();\n ctx.moveTo(x, y - 1);\n ctx.quadraticCurveTo(x + w / 2, y + 3, x + w, y - 2);\n ctx.stroke();\n ctx.restore();\n return;\n }\n ctx.lineWidth = t;\n ctx.lineCap = 'round';\n if (kind === 'double') {\n ctx.fillRect(x, y, w, t);\n ctx.fillRect(x, y + t + 2, w, t);\n } else if (kind === 'dotted') {\n ctx.setLineDash([t * 1.6, t * 1.8]);\n ctx.beginPath();\n ctx.moveTo(x, y + t / 2);\n ctx.lineTo(x + w, y + t / 2);\n ctx.stroke();\n } else if (kind === 'wavy') {\n ctx.beginPath();\n const amp = Math.max(1.4, size * 0.08);\n const step = Math.max(4, size * 0.28);\n ctx.moveTo(x, y);\n for (let px = x; px <= x + w; px += step) {\n const up = ((px - x) / step) % 2 < 1;\n ctx.quadraticCurveTo(px + step / 2, y + (up ? -amp : amp), Math.min(x + w, px + step), y);\n }\n ctx.stroke();\n } else {\n ctx.fillRect(x, y, w, t);\n }\n ctx.restore();\n}\n\nexport function paintCanvasStrike(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, size: number, color: string) {\n ctx.fillStyle = color;\n ctx.fillRect(x, y, w, Math.max(1, size / 16));\n}\n\nexport function groupDecorationRuns(glyphs: GlyphBox[]): { x: number; y: number; w: number; size: number; kind: ReturnType<typeof underlineKind>; strike: boolean; color: string }[] {\n const out: { x: number; y: number; w: number; size: number; kind: ReturnType<typeof underlineKind>; strike: boolean; color: string }[] = [];\n let cur: (typeof out)[number] | null = null;\n for (const g of glyphs) {\n const kind = underlineKind(g.style);\n const strike = !!g.style.strikethrough;\n const size = g.style.fontSize ?? 16;\n const color = fillOf(g.style) === 'solid' ? g.style.color ?? '#1f2329' : rainbowAt(g.index);\n const baseline = g.y + g.h * 0.78;\n if (\n cur &&\n cur.kind === kind &&\n cur.strike === strike &&\n Math.abs(cur.y - baseline) < 1 &&\n Math.abs(cur.x + cur.w - g.x) < 0.6\n ) {\n cur.w += g.w;\n } else {\n if (cur) out.push(cur);\n cur = { x: g.x, y: baseline, w: g.w, size, kind, strike, color };\n }\n }\n if (cur) out.push(cur);\n return out;\n}\n","import { layoutDocument } from '../layout/engine';\nimport { canvasFont } from '../layout/measure';\nimport { REF_HEAD, REF_PAD, refInnerWidth } from '../layout/refMetrics';\nimport { DocLayout } from '../layout/types';\nimport { DocumentModel } from '../model/document';\nimport { underlineKind } from '../model/types';\nimport { cssFill, fillOf } from '../paint/decorations';\nimport { EmbedBox, EmbedPlugin } from './types';\n\nexport { REF_HEAD, REF_PAD, refInnerWidth } from '../layout/refMetrics';\nexport const REF_JUMP = 'mini-ref-jump';\nexport const REF_HIT = 'mini-ref-hit';\n\nexport interface RefJumpDetail {\n id: string;\n fragmentId: string;\n}\n\nexport interface RefHitDetail {\n id: string;\n fragmentId: string;\n localX: number;\n localY: number;\n}\n\nfunction innerUsedSize(layout: DocLayout): { width: number; height: number } {\n let right = layout.contentX;\n for (const line of layout.lines) {\n for (const g of line.glyphs) right = Math.max(right, g.x + g.w);\n for (const img of line.images) right = Math.max(right, img.x + img.w);\n for (const stop of line.caretStops) right = Math.max(right, stop.x);\n }\n for (const table of layout.tables) right = Math.max(right, table.x + table.w);\n return {\n width: Math.max(8, Math.ceil(right - layout.contentX)),\n height: Math.max(layout.height, 8)\n };\n}\n\nexport function measureRef(\n entity: { fragmentId?: string; width?: number },\n contentWidth: number,\n host?: DocumentModel\n): { width: number; height: number } {\n const maxW = Math.max(40, contentWidth);\n const innerW = refInnerWidth(maxW);\n const inner =\n entity.fragmentId && host\n ? layoutDocument(host.ensureFragmentModel(entity.fragmentId), innerW, undefined, { x: 0, y: 0 }, 1)\n : emptyInner(innerW);\n const used = innerUsedSize(inner);\n return { width: Math.min(maxW, used.width), height: used.height };\n}\n\nfunction emptyInner(width: number): DocLayout {\n return {\n width,\n height: 24,\n contentX: 0,\n contentY: 0,\n contentWidth: width,\n paragraphs: [],\n tables: [],\n lines: [],\n images: [],\n dirty: { top: 0, bottom: 0 }\n };\n}\n\nfunction countLabel(el: HTMLElement): string {\n const n = Number(el.dataset.refCount ?? 1);\n return n > 1 ? `引用 · ${n}` : '引用';\n}\n\nfunction paintInner(host: HTMLElement, layout: DocLayout | undefined) {\n host.replaceChildren();\n if (!layout) return;\n for (const line of layout.lines) {\n if (line.glyphs.length) host.appendChild(renderInnerLine(line));\n for (const img of line.images) {\n const hole = document.createElement('div');\n hole.className = 'mini-ref-hole';\n hole.style.cssText = `left:${img.x}px;top:${img.y}px;width:${img.w}px;height:${img.h}px;`;\n hole.textContent = img.entity.kind === 'image' ? '' : img.entity.kind ?? 'embed';\n if (img.entity.kind === 'image' && img.entity.src) {\n const pic = document.createElement('img');\n pic.src = img.entity.src;\n pic.alt = '';\n pic.style.cssText = 'width:100%;height:100%;object-fit:cover;border-radius:4px;';\n hole.replaceChildren(pic);\n }\n host.appendChild(hole);\n }\n }\n}\n\nfunction renderInnerLine(line: DocLayout['lines'][number]): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'mini-ref-line';\n let run: { text: string; style: (typeof line.glyphs)[0]['style']; x: number; y: number; h: number; w: number; start: number } | null = null;\n const flush = () => {\n if (!run) return;\n const span = document.createElement('span');\n span.className = `mini-run${fillOf(run.style) !== 'solid' ? ' is-fill' : ''}`;\n span.textContent = run.text;\n span.style.cssText = `left:${run.x}px;top:${run.y}px;height:${run.h}px;${innerCss(run.style, run.w)}`;\n wrap.appendChild(span);\n const deco = underlineKind(run.style);\n if (deco !== 'none' || run.style.strikethrough) {\n const bar = document.createElement('span');\n bar.className = `mini-deco mini-deco-${deco}${run.style.strikethrough ? ' is-strike' : ''}`;\n bar.style.cssText = `left:${run.x}px;top:${run.y}px;width:${run.w}px;height:${run.h}px;color:${run.style.color ?? '#1f2329'};`;\n wrap.appendChild(bar);\n }\n run = null;\n };\n for (const g of line.glyphs) {\n if (\n run &&\n run.style.bold === g.style.bold &&\n run.style.italic === g.style.italic &&\n run.style.underline === g.style.underline &&\n run.style.underlineStyle === g.style.underlineStyle &&\n run.style.strikethrough === g.style.strikethrough &&\n run.style.fontSize === g.style.fontSize &&\n run.style.color === g.style.color &&\n run.style.fill === g.style.fill &&\n run.start + run.text.length === g.index\n ) {\n run.text += g.text;\n run.w += g.w;\n } else {\n flush();\n run = { start: g.index, text: g.text, style: g.style, x: g.x, y: g.y, h: g.h, w: g.w };\n }\n }\n flush();\n return wrap;\n}\n\nfunction innerCss(style: DocLayout['lines'][number]['glyphs'][0]['style'], runW: number): string {\n const size = style.fontSize ?? 16;\n const weight = style.bold ? '700' : String(style.fontWeight ?? 400);\n const italic = style.italic ? 'italic' : 'normal';\n const color = style.color ?? '#1f2329';\n return `font-style:${italic};font-weight:${weight};font-size:${size}px;line-height:${size * 1.6}px;font-family:var(--mini-font-family);color:${color};text-decoration:none;${cssFill(style, runW)}`;\n}\n\nexport const refPlugin: EmbedPlugin = {\n kind: 'ref',\n keepAspectRatio: false,\n interactive: true,\n overlayOnCanvas: true,\n measure(entity, contentWidth, host) {\n return measureRef(entity, contentWidth, host);\n },\n create(box) {\n const root = document.createElement('div');\n root.className = 'mini-embed mini-ref mini-embed-interactive';\n const badge = document.createElement('span');\n badge.className = 'mini-ref-badge';\n badge.textContent = '引用';\n const body = document.createElement('div');\n body.className = 'mini-ref-body';\n root.append(badge, body);\n\n badge.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const fragmentId = root.dataset.fragmentId;\n if (!fragmentId) return;\n root.dispatchEvent(\n new CustomEvent<RefJumpDetail>(REF_JUMP, {\n bubbles: true,\n detail: { id: root.dataset.entity || box.entity.id, fragmentId }\n })\n );\n });\n paintChip(root, box);\n return root;\n },\n update(el, box) {\n paintChip(el, box);\n },\n paintCanvasBackdrop(ctx, box) {\n ctx.save();\n ctx.fillStyle = '#fff8dc';\n ctx.beginPath();\n ctx.roundRect(box.x, box.y, box.w, box.h, 3);\n ctx.fill();\n const inner = box.inner;\n if (inner) {\n ctx.translate(box.x + REF_PAD, box.y + REF_HEAD);\n for (const line of inner.lines) {\n for (const g of line.glyphs) {\n ctx.save();\n ctx.font = canvasFont(g.style);\n ctx.fillStyle = g.style.color ?? '#1f2329';\n ctx.textBaseline = 'top';\n ctx.fillText(g.text, g.x, g.y);\n ctx.restore();\n }\n }\n }\n ctx.restore();\n }\n};\n\nfunction paintChip(el: HTMLElement, box: EmbedBox) {\n const fragmentId = box.entity.fragmentId ?? '';\n el.dataset.fragmentId = fragmentId;\n el.dataset.refCount = el.dataset.refCount ?? '1';\n const badge = el.querySelector('.mini-ref-badge');\n if (badge) badge.textContent = countLabel(el);\n const body = el.querySelector<HTMLElement>('.mini-ref-body');\n if (body) {\n body.style.height = `${Math.max(24, box.h)}px`;\n paintInner(body, box.inner);\n }\n}\n\nexport function decorateRefEl(el: HTMLElement, count: number, title: string, editing: boolean, selected = false) {\n el.dataset.refCount = String(count);\n el.dataset.refTitle = title;\n el.classList.toggle('is-editing', editing);\n el.classList.toggle('is-selected', selected);\n const badge = el.querySelector('.mini-ref-badge');\n if (badge) badge.textContent = count > 1 ? `引用 · ${count}` : '引用';\n}\n","import { measureWidth } from '../layout/measure';\nimport { EmbedEntity, SlotKind } from '../model/types';\nimport { EMBED_EXIT_EDIT, EmbedPlugin, emitEmbedChange } from './types';\n\nexport const DEFAULT_SELECT_OPTIONS = ['小美', '阿力'] as const;\nconst FILLED_IMAGE = { width: 72, height: 40 };\n\nconst ICONS: Record<SlotKind, string> = {\n text:\n '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"M3 3.6h10M8 3.6v8.8M5.6 12.4h4.8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\"/></svg>',\n image:\n '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" aria-hidden=\"true\"><rect x=\"2.2\" y=\"3.2\" width=\"11.6\" height=\"9.6\" rx=\"1.6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\"/><path d=\"M3.4 11.2 6.1 8.2l2 1.7 2.4-3 2.1 4.3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/><circle cx=\"6\" cy=\"6.1\" r=\".9\" fill=\"currentColor\"/><path d=\"M11.2 4.6v2.4M10 5.8h2.4\" stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linecap=\"round\"/></svg>',\n select:\n '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"M4 6.2 8 10l4-3.8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>'\n};\n\nexport function defaultSlotLabel(kind: SlotKind): string {\n if (kind === 'image') return '上传图片';\n if (kind === 'select') return '请选择';\n return '输入文本';\n}\n\nexport function slotKindOf(entity: EmbedEntity): SlotKind {\n if (entity.slotKind === 'image' || entity.slotKind === 'select' || entity.slotKind === 'text') return entity.slotKind;\n return 'text';\n}\n\nexport function slotOptionsOf(entity: EmbedEntity): string[] {\n return entity.slotOptions?.length ? entity.slotOptions : [...DEFAULT_SELECT_OPTIONS];\n}\n\nexport function slotPlaceholder(entity: EmbedEntity): string {\n return entity.label || defaultSlotLabel(slotKindOf(entity));\n}\n\nexport function slotCaption(entity: EmbedEntity): string {\n return entity.slotValue?.trim() || slotPlaceholder(entity);\n}\n\nexport function slotFilled(entity: EmbedEntity): boolean {\n if (slotKindOf(entity) === 'image') return !!entity.src;\n return !!entity.slotValue?.trim();\n}\n\nexport function measureSlot(entity: EmbedEntity): { width: number; height: number } {\n if (slotKindOf(entity) === 'image' && entity.src) return { ...FILLED_IMAGE };\n const label = slotCaption(entity);\n const textW = typeof document === 'undefined' ? label.length * 13 : measureWidth(label, { fontSize: 13 });\n const extra = slotKindOf(entity) === 'select' ? 8 : 0;\n return { width: Math.ceil(28 + 16 + textW + 18 + extra), height: 28 };\n}\n\nfunction closeMenus(except?: HTMLElement) {\n for (const menu of document.querySelectorAll('.mini-slot-menu')) {\n if (menu === except) continue;\n menu.remove();\n }\n}\n\nfunction openSelectMenu(root: HTMLElement, entity: EmbedEntity) {\n closeMenus();\n const menu = document.createElement('div');\n menu.className = 'mini-slot-menu';\n const id = root.dataset.entity || entity.id;\n for (const name of slotOptionsOf(entity)) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = name;\n if (name === entity.slotValue) btn.classList.add('is-on');\n btn.addEventListener('mousedown', (e) => e.stopPropagation());\n btn.addEventListener('click', (e) => {\n e.stopPropagation();\n emitEmbedChange(root, { id, patch: { slotValue: name } }, true);\n menu.remove();\n });\n menu.appendChild(btn);\n }\n const clear = document.createElement('button');\n clear.type = 'button';\n clear.textContent = '清除';\n clear.addEventListener('mousedown', (e) => e.stopPropagation());\n clear.addEventListener('click', (e) => {\n e.stopPropagation();\n emitEmbedChange(root, { id, patch: { slotValue: '' } }, true);\n menu.remove();\n });\n menu.appendChild(clear);\n root.appendChild(menu);\n const onDoc = (e: MouseEvent) => {\n if (root.contains(e.target as Node)) return;\n menu.remove();\n document.removeEventListener('mousedown', onDoc);\n };\n document.addEventListener('mousedown', onDoc);\n}\n\nconst slotEntities = new WeakMap<HTMLElement, EmbedEntity>();\n\nfunction paintChip(el: HTMLElement, entity: EmbedEntity) {\n if (el.classList.contains('is-editing')) return;\n const kind = slotKindOf(entity);\n const filled = slotFilled(entity);\n const imageFilled = kind === 'image' && filled;\n el.className = `mini-embed mini-slot mini-embed-interactive${filled ? ' is-filled' : ''}${imageFilled ? ' is-image-filled' : ''}`;\n el.dataset.slotKind = kind;\n const icon = el.querySelector<HTMLElement>('.mini-slot-icon');\n const text = el.querySelector<HTMLElement>('.mini-slot-text');\n const thumb = el.querySelector<HTMLImageElement>('.mini-slot-thumb');\n const input = el.querySelector<HTMLInputElement>('.mini-slot-input');\n if (icon) {\n icon.hidden = imageFilled;\n icon.innerHTML = ICONS[kind];\n }\n if (text) {\n text.hidden = imageFilled;\n text.textContent = slotCaption(entity);\n }\n if (thumb) {\n thumb.hidden = !imageFilled;\n if (imageFilled && entity.src) thumb.src = entity.src;\n else thumb.removeAttribute('src');\n }\n if (input) input.hidden = true;\n}\n\nexport const slotPlugin: EmbedPlugin = {\n kind: 'internalSlot',\n keepAspectRatio: false,\n interactive: true,\n overlayOnCanvas: true,\n measure: measureSlot,\n create(box) {\n const root = document.createElement('span');\n const icon = document.createElement('span');\n icon.className = 'mini-slot-icon';\n const text = document.createElement('span');\n text.className = 'mini-slot-text';\n const thumb = document.createElement('img');\n thumb.className = 'mini-slot-thumb';\n thumb.alt = '';\n thumb.draggable = false;\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'mini-slot-input';\n input.hidden = true;\n const file = document.createElement('input');\n file.type = 'file';\n file.accept = 'image/*';\n file.className = 'mini-slot-file';\n root.append(icon, text, thumb, input, file);\n slotEntities.set(root, box.entity);\n\n let baseline = box.entity.slotValue ?? '';\n const current = () => slotEntities.get(root) ?? box.entity;\n const entityId = () => root.dataset.entity || current().id;\n\n const leaveEdit = () => {\n root.classList.remove('is-editing');\n input.hidden = true;\n icon.hidden = false;\n text.hidden = false;\n };\n\n const startTextEdit = () => {\n const entity = current();\n baseline = entity.slotValue ?? '';\n root.classList.add('is-editing');\n closeMenus();\n icon.hidden = true;\n text.hidden = true;\n thumb.hidden = true;\n input.hidden = false;\n input.value = baseline;\n input.placeholder = slotPlaceholder(entity);\n input.focus();\n input.select();\n };\n\n const commitText = () => {\n if (!root.classList.contains('is-editing')) return;\n const value = input.value;\n leaveEdit();\n emitEmbedChange(root, { id: entityId(), patch: { slotValue: value } }, true);\n };\n\n const cancelText = () => {\n if (!root.classList.contains('is-editing')) return;\n leaveEdit();\n emitEmbedChange(root, { id: entityId(), patch: { slotValue: baseline } }, true);\n };\n\n const activate = () => {\n const entity = current();\n const kind = slotKindOf(entity);\n if (kind === 'image') {\n file.click();\n return;\n }\n if (kind === 'select') {\n openSelectMenu(root, entity);\n return;\n }\n startTextEdit();\n };\n\n root.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).closest('.mini-slot-menu, .mini-slot-file, .mini-slot-input')) return;\n activate();\n });\n root.addEventListener('mini-slot-activate', activate);\n input.addEventListener('mousedown', (e) => e.stopPropagation());\n input.addEventListener('click', (e) => e.stopPropagation());\n input.addEventListener('input', () => {\n emitEmbedChange(root, { id: entityId(), patch: { slotValue: input.value } });\n });\n input.addEventListener('blur', () => {\n window.setTimeout(() => {\n if (root.contains(document.activeElement)) return;\n commitText();\n }, 0);\n });\n input.addEventListener('keydown', (e) => {\n e.stopPropagation();\n if (e.key === 'Enter') {\n e.preventDefault();\n commitText();\n return;\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n cancelText();\n return;\n }\n if (e.key === 'ArrowLeft' && input.selectionStart === 0 && input.selectionEnd === 0) {\n e.preventDefault();\n commitText();\n root.dispatchEvent(new CustomEvent(EMBED_EXIT_EDIT, { bubbles: true, detail: { id: entityId(), side: 'before' } }));\n return;\n }\n if (\n e.key === 'ArrowRight' &&\n input.selectionStart === input.value.length &&\n input.selectionEnd === input.value.length\n ) {\n e.preventDefault();\n commitText();\n root.dispatchEvent(new CustomEvent(EMBED_EXIT_EDIT, { bubbles: true, detail: { id: entityId(), side: 'after' } }));\n }\n });\n file.addEventListener('mousedown', (e) => e.stopPropagation());\n file.addEventListener('change', () => {\n const f = file.files?.[0];\n file.value = '';\n if (!f) return;\n emitEmbedChange(\n root,\n {\n id: entityId(),\n patch: { slotValue: '', src: URL.createObjectURL(f) }\n },\n true\n );\n });\n\n paintChip(root, box.entity);\n return root;\n },\n update(el, box) {\n slotEntities.set(el, box.entity);\n paintChip(el, box.entity);\n },\n paintCanvasBackdrop(ctx, box, imageOf) {\n const r = Math.min(12, box.h / 2);\n ctx.beginPath();\n ctx.roundRect(box.x, box.y, box.w, box.h, r);\n if (slotKindOf(box.entity) === 'image' && box.entity.src) {\n ctx.save();\n ctx.clip();\n try {\n ctx.drawImage(imageOf(box.entity.src), box.x, box.y, box.w, box.h);\n } catch {\n ctx.fillStyle = '#e9edf5';\n ctx.fill();\n }\n ctx.restore();\n return;\n }\n ctx.fillStyle = slotFilled(box.entity) ? '#e9edf5' : '#f2f4f7';\n ctx.fill();\n ctx.fillStyle = slotFilled(box.entity) ? '#1f2329' : '#98a2b3';\n ctx.font = '13px \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif';\n ctx.textBaseline = 'middle';\n ctx.fillText(slotCaption(box.entity), box.x + 34, box.y + box.h / 2);\n }\n};\n","import { EmbedBox, EmbedPlugin } from './types';\n\nfunction applyVideo(el: HTMLVideoElement, box: EmbedBox) {\n if (box.entity.src && el.src !== box.entity.src) el.src = box.entity.src;\n}\n\nexport const videoPlugin: EmbedPlugin = {\n kind: 'video',\n keepAspectRatio: true,\n interactive: true,\n overlayOnCanvas: true,\n measure(entity) {\n return { width: entity.width, height: entity.height };\n },\n create(box) {\n const node = document.createElement('video');\n node.className = 'mini-embed mini-image mini-video mini-embed-interactive';\n node.controls = true;\n node.preload = 'metadata';\n node.playsInline = true;\n node.draggable = false;\n applyVideo(node, box);\n return node;\n },\n update(el, box) {\n applyVideo(el as HTMLVideoElement, box);\n },\n paintCanvasBackdrop(ctx, box) {\n ctx.fillStyle = '#111827';\n ctx.fillRect(box.x, box.y, box.w, box.h);\n }\n};\n","import { EmbedEntity } from '../model/types';\nimport { EmbedBox, EmbedChangeDetail, EMBED_CHANGE, EMBED_COMMIT, EMBED_MEASURE, EmbedMeasureDetail, EmbedPlugin } from './types';\n\n/**\n * 宿主渲染型嵌入对象。\n *\n * 与内置的自绘型嵌入对象(image/slot/ref 等由 SDK 自己建 DOM、自己画)不同,\n * host 型把节点内部 DOM 的渲染权交给宿主:SDK 只负责在文本流里占一个字符位、\n * 用 measure 得到的尺寸给它绝对定位、并管理它的挂载/更新/卸载生命周期;节点里\n * 具体画什么由宿主提供的 {@link HostEmbedRenderer} 决定。宿主据此把自己框架\n * (axii / React 等)的业务组件 render 进 SDK 交出的容器里。\n *\n * 数据是引用式的:实体 {@link EmbedEntity.data} 里通常只存业务对象的引用 id,\n * 完整数据与状态由宿主自己的 store 维护、自行 resolve。数据变化经宿主回调写回\n * 实体(复用 EMBED_CHANGE / EMBED_COMMIT 事件回路),尺寸变化经 requestResize\n * 通知 SDK 重排。\n */\n\n/** SDK 交给宿主渲染器的上下文,随实体/选中态变化。 */\nexport interface HostEmbedContext {\n /** 当前实体(含 hostType / data 等业务字段)。 */\n entity: EmbedEntity;\n /** 该嵌入对象当前是否被选中(外层光标选区覆盖它)。 */\n selected: boolean;\n /**\n * 写回实体数据。commit=false 为预览(不进撤销栈),commit=true 落定(进撤销栈)。\n * patch 可含 data / width / height 等实体字段。\n */\n emitChange(patch: Partial<EmbedEntity>, commit?: boolean): void;\n /** 宿主渲染后尺寸确定/变化时调用,通知 SDK 用新尺寸重排。 */\n requestResize(width: number, height: number): void;\n}\n\n/**\n * 选中 host 后按键激活。引擎不解释业务 UI(下拉等),只问宿主要不要吞掉这次按键。\n * 返回 true:已处理,不再插段;false / 未实现:按默认换行。\n */\nexport interface HostActivateRequest {\n key: 'Enter';\n shift: boolean;\n}\n\n/** 一次 mount 返回的句柄,供 SDK 在实体/选中态变化和卸载时调用。 */\nexport interface HostEmbedHandle {\n /** 实体或选中态变化时,SDK 调它同步宿主渲染。 */\n update(ctx: HostEmbedContext): void;\n /** 节点从文档移除时,SDK 调它清理宿主侧资源(卸载组件、解绑等)。 */\n destroy(): void;\n /**\n * 整颗选中时的激活(对齐公式 Enter 进编辑)。省略则选中回车仍插段。\n */\n activate?(req: HostActivateRequest): boolean;\n}\n\n/** 宿主渲染器:把业务组件挂进 SDK 交出的容器。由构造 Editor 时通过 options 注入。 */\nexport interface HostEmbedRenderer {\n /**\n * 把业务组件渲染进 container。container 是 SDK 建好的空节点,已做好占位与定位。\n * 返回句柄供后续 update / destroy。\n */\n mount(container: HTMLElement, ctx: HostEmbedContext): HostEmbedHandle;\n}\n\n/** 当前 Editor 注入的渲染器。单例:一个运行时只有一个宿主渲染器。 */\nlet renderer: HostEmbedRenderer | null = null;\n\nexport function setHostEmbedRenderer(r: HostEmbedRenderer | null) {\n renderer = r;\n}\n\n/** host 型实体的默认兜底尺寸(宿主尚未回传测量前)。 */\nconst FALLBACK_SIZE = { width: 120, height: 24 };\n\n/** 每个容器 el 对应的宿主句柄、最近一次 box 与自动测尺观察器,供 update/卸载使用。 */\ntype HostRec = { el: HTMLElement; handle: HostEmbedHandle; box: EmbedBox; ro?: ResizeObserver; lastSize?: string };\n\nconst handles = new WeakMap<HTMLElement, HostRec>();\n/** 按实体 id 索引,光标移动时不经过 querySelector / data-entity,避免对不上。 */\nconst handlesById = new Map<string, HostRec>();\n\n/**\n * 把尺寸回报为 EMBED_MEASURE:只触发重排,不进撤销栈。\n *\n * 无论来自 SDK 的自动观察还是宿主手动调 requestResize,都走这里。延到微任务里\n * 派发有两个原因:宿主常在 mount 首帧就报,而此刻容器可能还没挂进文档树(create\n * 返回后 registry 才 appendChild),同步事件冒泡不到编辑器;且重排里再改 DOM 会\n * 触发 ResizeObserver 递归,延迟能断开这个同步链。\n */\nfunction emitMeasure(el: HTMLElement, id: string, width: number, height: number) {\n const detail: EmbedMeasureDetail = { id, width, height };\n queueMicrotask(() =>\n el.dispatchEvent(new CustomEvent(EMBED_MEASURE, { bubbles: true, detail }))\n );\n}\n\n/**\n * SDK 自动观察 host 块尺寸。宿主只管把组件画进容器,尺寸变化 SDK 自动感知并重排,\n * 宿主零负担、无需自己装 ResizeObserver 或调 requestResize。\n *\n * 观察的是内层 measure 节点 `inner`,不是外层 `el`:外层 el 会被 placeEmbed 按\n * 回填尺寸强制设宽高(用于占位定位),量它只会量到回填值、无法反映内容真实需求,\n * 形成自我印证;内层 inner 不设宽高、由宿主内容自然撑开,量到的才是内容真实占位。\n */\nfunction observeSize(inner: HTMLElement, id: string, rec: { ro?: ResizeObserver; lastSize?: string }) {\n if (typeof ResizeObserver === 'undefined') return;\n const ro = new ResizeObserver(() => {\n const width = Math.round(inner.offsetWidth);\n const height = Math.round(inner.offsetHeight);\n if (!width || !height) return;\n // 交接帧可能量到「一列字」的窄高盒子;写回会锁死排版,直到下次输入再撑开。\n if (width < 48 && height > width * 3) return;\n const key = `${width}x${height}`;\n // 去重:避免尺寸未变时反复触发重排。\n if (key === rec.lastSize) return;\n rec.lastSize = key;\n emitMeasure(inner, id, width, height);\n });\n ro.observe(inner);\n rec.ro = ro;\n}\n\n/**\n * 光标选中变化时打标并通知宿主。排版层不会每次重排,所以不能只靠 plugin.update。\n * 按实体 id 找句柄,并把 selected 直接写进 ctx,不依赖 data-entity 对得上。\n */\nexport function decorateHostEl(el: HTMLElement, selected: boolean) {\n const rec = handles.get(el) ?? handlesById.get(el.dataset.entity ?? '');\n if (!rec) {\n el.classList.toggle('is-selected', selected);\n return;\n }\n syncRecSelected(rec, selected);\n}\n\nexport function syncHostSelected(selectedId: string | null) {\n for (const rec of handlesById.values()) {\n syncRecSelected(rec, rec.box.entity.id === selectedId);\n }\n}\n\nfunction syncRecSelected(rec: HostRec, selected: boolean) {\n const prev = rec.el.classList.contains('is-selected');\n rec.el.classList.toggle('is-selected', selected);\n if (prev === selected) return;\n rec.handle.update({ ...contextOf(rec.el, rec.box), selected });\n}\n\nfunction contextOf(el: HTMLElement, box: EmbedBox): HostEmbedContext {\n const id = box.entity.id;\n return {\n entity: box.entity,\n // 选中态由编辑器通过 DOM class 标记(与自绘型一致),这里读回给宿主。\n selected: el.classList.contains('is-selected'),\n emitChange(patch, commit = false) {\n const detail: EmbedChangeDetail = { id, patch };\n el.dispatchEvent(new CustomEvent(commit ? EMBED_COMMIT : EMBED_CHANGE, { bubbles: true, detail }));\n },\n // 手动挡:SDK 默认已自动观察容器尺寸,宿主一般不用调这个;只有想自己精确\n // 控制回报时机的场景才用。走的是和自动观察同一条通道。\n requestResize(width, height) {\n emitMeasure(el, id, width, height);\n }\n };\n}\n\n/** 把宿主组件挂进内层节点,记录句柄并开启自动测尺。create/补挂共用。 */\nfunction mountInto(el: HTMLElement, inner: HTMLElement, box: EmbedBox) {\n const handle = renderer!.mount(inner, contextOf(el, box));\n const rec: HostRec = {\n el,\n handle,\n box\n };\n handles.set(el, rec);\n handlesById.set(box.entity.id, rec);\n observeSize(inner, box.entity.id, rec);\n}\n\nexport const hostEmbedPlugin: EmbedPlugin = {\n kind: 'hostSlot',\n keepAspectRatio: false,\n interactive: true,\n overlayOnCanvas: true,\n measure(entity) {\n // 宿主渲染型尺寸由宿主 render 后经 requestResize 回写到实体;此处用实体上已\n // 记录的尺寸,尚无则回退兜底值(首帧后宿主回传即触发重排修正)。\n const width = entity.width > 0 ? entity.width : FALLBACK_SIZE.width;\n const height = entity.height > 0 ? entity.height : FALLBACK_SIZE.height;\n return { width, height };\n },\n create(box) {\n const el = document.createElement('span');\n el.className = 'mini-embed mini-host mini-embed-interactive';\n // 标记 kind,供 syncEmbedLayer 移除时找到本插件调用 destroy 清理副作用。\n el.dataset.kind = 'hostSlot';\n // 内层 measure 节点:不设宽高、由宿主内容自然撑开,既是宿主的挂载点,\n // 也是 SDK 自动测尺的观察对象(见 observeSize)。\n const inner = document.createElement('span');\n inner.className = 'mini-host-inner';\n el.appendChild(inner);\n if (!renderer) {\n // 未注入渲染器:留一个占位容器,避免报错;宿主接入后应始终提供 renderer。\n return el;\n }\n mountInto(el, inner, box);\n return el;\n },\n update(el, box) {\n const rec = handles.get(el);\n if (rec) {\n rec.box = box;\n rec.el = el;\n handlesById.set(box.entity.id, rec);\n rec.handle.update({\n ...contextOf(el, box),\n selected: el.classList.contains('is-selected')\n });\n } else if (renderer) {\n // 容器已存在但尚未 mount(例如 create 时 renderer 未就绪):补挂。\n const inner = el.querySelector<HTMLElement>('.mini-host-inner') ?? el;\n mountInto(el, inner, box);\n }\n },\n paintCanvasBackdrop() {\n // 宿主渲染型只走 DOM 图层(overlayOnCanvas=true),canvas 后端不额外画底。\n }\n};\n\n/** 选中 host 按 Enter:转给该实体的 {@link HostEmbedHandle.activate}。 */\nexport function activateHostEmbed(id: string, req: HostActivateRequest): boolean {\n return handlesById.get(id)?.handle.activate?.(req) === true;\n}\n\n/** host 块从文档移除时清理:停掉自动测尺、卸载宿主组件、释放记录。 */\nexport function destroyHostEmbed(el: HTMLElement) {\n const rec = handles.get(el);\n if (rec) {\n rec.ro?.disconnect();\n rec.handle.destroy();\n handles.delete(el);\n handlesById.delete(rec.box.entity.id);\n }\n}\n","import { EmbedKind } from '../model/types';\nimport { EmbedBox, EmbedPlugin, placeEmbed } from './types';\n\nconst plugins = new Map<EmbedKind, EmbedPlugin>();\n\nexport function registerEmbed(plugin: EmbedPlugin) {\n plugins.set(plugin.kind, plugin);\n}\n\nexport function embedPlugin(kind: EmbedKind | undefined): EmbedPlugin {\n const hit = plugins.get(kind ?? 'image') ?? plugins.get('image');\n if (!hit) {\n throw new Error(\n `嵌入插件未注册:${kind ?? 'image'}。` +\n '请先 registerEmbed(...) 或构造 Editor 时传 plugins —— ' +\n '注意在构造 Editor 之前调用 embedPlugin 的代码(如预先构建文档)需要自己先注册。'\n );\n }\n return hit;\n}\n\nexport function syncEmbedLayer(\n host: HTMLElement,\n cache: Map<string, HTMLElement>,\n boxes: EmbedBox[],\n canvas: boolean\n) {\n const seen = new Set<string>();\n for (const box of boxes) {\n const plugin = embedPlugin(box.entity.kind);\n if (canvas && !plugin.overlayOnCanvas) continue;\n seen.add(box.entity.id);\n let el = cache.get(box.entity.id);\n if (!el) {\n el = plugin.create(box);\n host.appendChild(el);\n cache.set(box.entity.id, el);\n }\n plugin.update(el, box);\n placeEmbed(el, box);\n }\n for (const [id, el] of cache) {\n if (!seen.has(id)) {\n // 移除前给插件一次清理副作用的机会(观察器、外部组件等)。\n plugins.get((el.dataset.kind ?? '') as EmbedKind)?.destroy?.(el);\n el.remove();\n cache.delete(id);\n }\n }\n}\n","import { codePlugin } from './code';\nimport { imagePlugin } from './image';\nimport { refPlugin } from './ref';\nimport { slotPlugin } from './slot';\nimport { EmbedPlugin } from './types';\nimport { videoPlugin } from './video';\nimport { hostEmbedPlugin } from './host';\n\n/**\n * 默认内置插件。不含公式 —— 公式依赖 KaTeX / MathLive,体积很大,\n * 需要时从 `medeo-rte/formula` 单独引入再传给 Editor。\n */\nexport const builtinEmbedPlugins: EmbedPlugin[] = [\n imagePlugin,\n videoPlugin,\n codePlugin,\n slotPlugin,\n refPlugin\n];\n\nexport { codePlugin, imagePlugin, refPlugin, slotPlugin, videoPlugin };\nexport { hostEmbedPlugin, setHostEmbedRenderer, destroyHostEmbed, activateHostEmbed, decorateHostEl, syncHostSelected } from './host';\nexport type { HostEmbedRenderer, HostEmbedContext, HostEmbedHandle, HostActivateRequest } from './host';\nexport { embedPlugin, registerEmbed, syncEmbedLayer } from './registry';\nexport { measureCode } from './code';\nexport { decorateRefEl, measureRef, REF_HEAD, REF_HIT, REF_JUMP, REF_PAD, refInnerWidth } from './ref';\nexport { defaultSlotLabel, measureSlot } from './slot';\nexport { EMBED_CHANGE, EMBED_COMMIT, EMBED_EXIT_EDIT, EMBED_MEASURE, type EmbedBox, type EmbedChangeDetail, type EmbedExitDetail, type EmbedMeasureDetail, type EmbedPlugin } from './types';\n","/**\n * Mutation —— 文档变更的原子单元,也是 OT 变换的对象。\n *\n * 设计要点:\n * - Mutation 是**纯数据**,可直接 JSON 序列化后走网络。行为(应用、变换、求逆、\n * 合并)不挂在它身上,而是按 `type` 到注册表里查,见 registry.ts。\n * - 索引一律是**闭区间**语义,`deleteSpacers` 的 `[startIndex, endIndex]` 含两端。\n * 与文档模型半开区间的转换在 apply/invert 边界上做。\n * - 上层的一次用户操作(比如「按退格」)通常展开成多条 mutation,\n * 用 `multi` 打包成一步。\n */\nimport { EmbedEntity, Fragment, StyleProps, StyleType, VirtualBlock } from '../model/types';\n\n/** 在 insertBeforeIndex 之前插入这串 spacer。 */\nexport interface InsertSpacersMutation {\n type: 'insertSpacers';\n insertBeforeIndex: number;\n spacers: string;\n}\n\n/** 删除闭区间 [startIndex, endIndex]。 */\nexport interface DeleteSpacersMutation {\n type: 'deleteSpacers';\n startIndex: number;\n endIndex: number;\n}\n\n/** 给闭区间 [startIndex, endIndex] 覆盖一段样式。props 为 null 表示清除该类型。 */\nexport interface ApplyStyleMutation {\n type: 'applyStyle';\n styleType: StyleType;\n startIndex: number;\n endIndex: number;\n props: StyleProps | null;\n}\n\nexport interface AddEntityMutation {\n type: 'addEntity';\n entity: EmbedEntity;\n}\n\nexport interface UpdateEntityMutation {\n type: 'updateEntity';\n entityId: string;\n props: Partial<EmbedEntity>;\n}\n\nexport interface DeleteEntityMutation {\n type: 'deleteEntity';\n entityId: string;\n}\n\n/**\n * 新建一个同步块(fragment)。\n *\n * fragment 和 entity 一样按 id 寻址,不占主文档坐标空间,因此不参与下标变换。\n * 提取同步块(promoteRange)时发这条,撤销即删除它。\n */\nexport interface AddFragmentMutation {\n type: 'addFragment';\n fragment: Fragment;\n}\n\n/** 删除一个同步块。逆操作把整份 Fragment 原样加回来。 */\nexport interface DeleteFragmentMutation {\n type: 'deleteFragment';\n fragmentId: string;\n}\n\n/** 写入一个虚拟块。同 id 存在则整体替换。区间随字符插删由 applier 机械挪动。 */\nexport interface AddVirtualBlockMutation {\n type: 'addVirtualBlock';\n block: VirtualBlock;\n}\n\n/** 删除一个虚拟块。 */\nexport interface DeleteVirtualBlockMutation {\n type: 'deleteVirtualBlock';\n blockId: string;\n}\n\n/** 用完整值覆盖一个虚拟块(含区间与 chrome)。 */\nexport interface UpdateVirtualBlockMutation {\n type: 'updateVirtualBlock';\n blockId: string;\n block: VirtualBlock;\n}\n\n/** 变换后被完全抵消的操作。应用时什么都不做。 */\nexport interface NullMutation {\n type: 'null';\n}\n\n/** 一组按序执行的 mutation,构成一个不可分割的步骤。 */\nexport interface MultiMutation {\n type: 'multi';\n commands: Mutation[];\n}\n\n/**\n * 把一条 mutation 定向到某个片段(同步块)的坐标空间里去执行。\n *\n * 片段的内容是独立的一条字符流,下标和主文档不共享。用这层包装之后,\n * 片段内部的编辑和主文档编辑就是同一种东西了:进同一个撤销栈、走同一套变换。\n * 不同片段的操作天然不冲突,变换时直接原样放行。\n */\nexport interface ScopedMutation {\n type: 'scoped';\n fragmentId: string;\n inner: Mutation;\n}\n\nexport type Mutation =\n | InsertSpacersMutation\n | DeleteSpacersMutation\n | ApplyStyleMutation\n | AddEntityMutation\n | UpdateEntityMutation\n | DeleteEntityMutation\n | AddFragmentMutation\n | DeleteFragmentMutation\n | AddVirtualBlockMutation\n | DeleteVirtualBlockMutation\n | UpdateVirtualBlockMutation\n | NullMutation\n | MultiMutation\n | ScopedMutation;\n\nexport type MutationType = Mutation['type'];\n\n// ---- 构造 ----------------------------------------------------------------\n\nexport function insertSpacers(insertBeforeIndex: number, spacers: string): Mutation {\n return spacers ? { type: 'insertSpacers', insertBeforeIndex, spacers } : NULL_MUTATION;\n}\n\n/** 入参是闭区间。 */\nexport function deleteSpacers(startIndex: number, endIndex: number): Mutation {\n return endIndex >= startIndex ? { type: 'deleteSpacers', startIndex, endIndex } : NULL_MUTATION;\n}\n\n/** 从半开区间 [start, end) 构造,便于和文档模型对接。 */\nexport function deleteSpacersHalfOpen(start: number, end: number): Mutation {\n return deleteSpacers(start, end - 1);\n}\n\nexport function applyStyle(\n styleType: StyleType,\n startIndex: number,\n endIndex: number,\n props: StyleProps | null\n): Mutation {\n return endIndex >= startIndex\n ? { type: 'applyStyle', styleType, startIndex, endIndex, props }\n : NULL_MUTATION;\n}\n\nexport function addEntity(entity: EmbedEntity): Mutation {\n return { type: 'addEntity', entity };\n}\n\nexport function updateEntity(entityId: string, props: Partial<EmbedEntity>): Mutation {\n return { type: 'updateEntity', entityId, props };\n}\n\nexport function deleteEntity(entityId: string): Mutation {\n return { type: 'deleteEntity', entityId };\n}\n\nexport function addFragment(fragment: Fragment): Mutation {\n return { type: 'addFragment', fragment };\n}\n\nexport function deleteFragment(fragmentId: string): Mutation {\n return { type: 'deleteFragment', fragmentId };\n}\n\nexport function addVirtualBlock(block: VirtualBlock): Mutation {\n return { type: 'addVirtualBlock', block };\n}\n\nexport function deleteVirtualBlock(blockId: string): Mutation {\n return { type: 'deleteVirtualBlock', blockId };\n}\n\nexport function updateVirtualBlock(blockId: string, block: VirtualBlock): Mutation {\n return { type: 'updateVirtualBlock', blockId, block: { ...block, id: blockId } };\n}\n\nexport const NULL_MUTATION: NullMutation = { type: 'null' };\n\n/**\n * 把 inner 定向到某个片段。\n *\n * inner 是组合时会摊成「一串各自定向的单条」,这样 scoped 始终只包一条实操,\n * 逐条求逆和逐条变换才对得上。\n */\nexport function scoped(fragmentId: string, inner: Mutation): Mutation {\n if (inner.type === 'null') return NULL_MUTATION;\n if (inner.type === 'multi') return multi(unwrap(inner).map((m) => scoped(fragmentId, m)));\n return { type: 'scoped', fragmentId, inner };\n}\n\n/** 打包成一步。会摊平嵌套的 multi、滤掉 null;空则返回 null mutation。 */\nexport function multi(commands: Mutation[]): Mutation {\n const flat: Mutation[] = [];\n for (const c of commands) {\n if (c.type === 'null') continue;\n if (c.type === 'multi') flat.push(...unwrap(c));\n else flat.push(c);\n }\n if (flat.length === 0) return NULL_MUTATION;\n if (flat.length === 1) return flat[0];\n return { type: 'multi', commands: flat };\n}\n\n/** 摊平成一维列表,null 被滤掉。 */\nexport function unwrap(mutation: Mutation): Mutation[] {\n if (mutation.type === 'null') return [];\n if (mutation.type !== 'multi') return [mutation];\n const out: Mutation[] = [];\n for (const c of mutation.commands) out.push(...unwrap(c));\n return out;\n}\n\n/** multi 的逆序摊平。求逆时用:撤销一组操作要从最后一条倒着来。 */\nexport function reverse(mutations: Mutation[]): Mutation[] {\n return [...mutations].reverse();\n}\n","/**\n * 把 mutation 作用到文档模型上。\n *\n * 这一层是**机械写入**:不校验、不合并、不推导。所有语义判断都该在上层做完,\n * mutation 到这里时携带的已经是解析好的完整值。\n *\n * 区间语义在这里换挡:mutation 用闭区间 [start, end],\n * 文档模型用半开区间 [start, end),所以下面凡是调模型的地方都 +1。\n */\nimport { cloneEntity, StyleSpan } from '../model/types';\nimport { DocumentModel } from '../model/document';\nimport { Mutation, MutationType, unwrap } from './types';\n\nexport type ApplierFor<T extends MutationType> = (\n doc: DocumentModel,\n mutation: Extract<Mutation, { type: T }>\n) => void;\n\n/** 每种 mutation 一个 applier。少一种编译不过。 */\nexport type Appliers = { [T in MutationType]: ApplierFor<T> };\n\nexport const appliers: Appliers = {\n null: () => {},\n\n multi: (doc, mutation) => {\n for (const c of unwrap(mutation)) applyMutation(doc, c);\n },\n\n insertSpacers: (doc, mutation) => {\n doc.applyInsertSpacers(mutation.insertBeforeIndex, mutation.spacers);\n },\n\n deleteSpacers: (doc, mutation) => {\n doc.applyDeleteSpacers(mutation.startIndex, mutation.endIndex + 1);\n },\n\n applyStyle: (doc, mutation) => {\n const start = mutation.startIndex;\n const end = mutation.endIndex + 1;\n const next: StyleSpan[] = mutation.props\n ? [{ start, end, type: mutation.styleType, props: mutation.props }]\n : [];\n doc.applyStyleSpans(mutation.styleType, start, end, next);\n },\n\n addEntity: (doc, mutation) => {\n doc.entities.set(mutation.entity.id, cloneEntity(mutation.entity));\n },\n\n updateEntity: (doc, mutation) => {\n const cur = doc.entities.get(mutation.entityId);\n if (cur) doc.entities.set(mutation.entityId, cloneEntity({ ...cur, ...mutation.props }));\n },\n\n deleteEntity: (doc, mutation) => {\n doc.entities.delete(mutation.entityId);\n },\n\n addFragment: (doc, mutation) => {\n doc.applyAddFragment(mutation.fragment);\n },\n\n deleteFragment: (doc, mutation) => {\n doc.applyDeleteFragment(mutation.fragmentId);\n },\n\n addVirtualBlock: (doc, mutation) => {\n doc.applyAddVirtualBlock(mutation.block);\n },\n\n deleteVirtualBlock: (doc, mutation) => {\n doc.applyDeleteVirtualBlock(mutation.blockId);\n },\n\n updateVirtualBlock: (doc, mutation) => {\n doc.applyUpdateVirtualBlock(mutation.blockId, mutation.block);\n },\n\n // 路由到片段自己的模型上执行,然后把派生出来的 Slice 刷新一遍供引用处渲染。\n scoped: (doc, mutation) => {\n applyMutation(doc.ensureFragmentModel(mutation.fragmentId), mutation.inner);\n doc.syncFragment(mutation.fragmentId);\n }\n};\n\nexport function applyMutation(doc: DocumentModel, mutation: Mutation): void {\n // 单次转型:TS 无法把 appliers[m.type] 和 m 的类型关联起来,但查表本身是安全的。\n (appliers[mutation.type] as ApplierFor<MutationType>)(doc, mutation);\n}\n\n/** 依次应用一串 mutation。 */\nexport function applyMutations(doc: DocumentModel, mutations: Mutation[]): void {\n for (const m of mutations) applyMutation(doc, m);\n}\n","import { cloneEntity, cloneStyle, cloneVirtualBlock, Fragment, Slice } from './types';\nimport { MARKERS } from './markers';\n\nexport function cloneFragment(fragment: Fragment): Fragment {\n return {\n id: fragment.id,\n title: fragment.title,\n slice: cloneSlice(fragment.slice)\n };\n}\n\nexport function cloneSlice(slice: Slice): Slice {\n return {\n text: slice.text,\n styles: slice.styles.map(cloneStyle),\n entities: slice.entities.map(cloneEntity),\n fragments: slice.fragments?.map(cloneFragment),\n virtualBlocks: slice.virtualBlocks?.map(cloneVirtualBlock)\n };\n}\n\nexport function previewTitle(slice: Slice, max = 18): string {\n const text = slice.text.replace(/\\n+/g, ' ').replace(/\\*/g, '').trim();\n if (!text) return '未命名同步块';\n return text.length > max ? `${text.slice(0, max)}…` : text;\n}\n\nexport function normalizeFragmentSlice(slice: Slice): Slice {\n let text = slice.text;\n const styles = slice.styles.map(cloneStyle);\n if (!text.endsWith(MARKERS.PARAGRAPH)) text += MARKERS.PARAGRAPH;\n return {\n text,\n styles,\n entities: slice.entities.map(cloneEntity),\n virtualBlocks: slice.virtualBlocks?.map(cloneVirtualBlock)\n };\n}\n\nexport function sliceHasContent(slice: Slice): boolean {\n return slice.text.replace(/\\n/g, '').replace(/\\s/g, '').length > 0 || slice.entities.length > 0;\n}\n","/**\n * 求逆:给一条 mutation 算出能把它撤销掉的 mutation。\n *\n * 有的逆是纯算术(插入的逆就是删掉同样长度),有的必须先读文档\n * (删除的逆要把被删的内容原样记下来),所以求逆一律要在**应用之前**做。\n * 组合操作更要逐条交错:算第 n 条的逆 → 应用第 n 条 → 再算第 n+1 条的逆,\n * 否则后面几条的逆会建立在错误的状态上。用 applyAndInvert 就不会踩到。\n */\nimport { cloneEntity, cloneVirtualBlock, StyleSpan, StyleType } from '../model/types';\nimport { cloneFragment } from '../model/fragment';\nimport { DocumentModel } from '../model/document';\nimport { applyMutation } from './apply';\nimport {\n addEntity,\n addFragment,\n addVirtualBlock,\n applyStyle,\n deleteEntity,\n deleteFragment,\n deleteSpacers,\n deleteVirtualBlock,\n insertSpacers,\n Mutation,\n MutationType,\n multi,\n NULL_MUTATION,\n scoped,\n unwrap,\n updateEntity,\n updateVirtualBlock\n} from './types';\n\nconst STYLE_TYPES: StyleType[] = ['text', 'paragraph', 'table', 'cell', 'image', 'link'];\n\n/** 记录半开区间 [start, end) 上的全部样式,生成能原样恢复它们的 mutation。 */\nfunction restoreStyles(doc: DocumentModel, start: number, end: number): Mutation[] {\n const out: Mutation[] = [];\n for (const type of STYLE_TYPES) {\n const spans = doc.styleSpansOver(type, start, end);\n // 先清空整段,再逐段填回去 —— 否则残留的旧区间会和恢复的混在一起\n out.push(applyStyle(type, start, end - 1, null));\n for (const s of spans) out.push(applyStyle(type, s.start, s.end - 1, s.props));\n }\n return out;\n}\n\nexport type InverterFor<T extends MutationType> = (\n doc: DocumentModel,\n mutation: Extract<Mutation, { type: T }>\n) => Mutation;\n\n/** 每种 mutation 一个 inverter。少一种编译不过。 */\nexport type Inverters = { [T in MutationType]: InverterFor<T> };\n\nexport const inverters: Inverters = {\n null: () => NULL_MUTATION,\n\n multi: () => {\n throw new Error('组合操作要用 applyAndInvert 逐条交错求逆,不能整体求逆');\n },\n\n insertSpacers: (_doc, mutation) =>\n deleteSpacers(\n mutation.insertBeforeIndex,\n mutation.insertBeforeIndex + mutation.spacers.length - 1\n ),\n\n // 只管字符与样式。落在这段里的实体由 Operation 层显式发 deleteEntity,\n // 它们的逆(addEntity)自然排在这条前面,不需要在这里兜底。\n deleteSpacers: (doc, mutation) => {\n const start = mutation.startIndex;\n const end = mutation.endIndex + 1;\n const restoredBlocks = doc.virtualBlocksOverlapping(start, end).map((b) => addVirtualBlock(cloneVirtualBlock(b)));\n return multi([\n insertSpacers(start, doc.spacers.slice(start, end)),\n ...restoreStyles(doc, start, end),\n ...restoredBlocks\n ]);\n },\n\n applyStyle: (doc, mutation) =>\n multi(\n restoreStyles(doc, mutation.startIndex, mutation.endIndex + 1).filter(\n (m) => m.type === 'applyStyle' && m.styleType === mutation.styleType\n )\n ),\n\n addEntity: (doc, mutation) =>\n doc.entities.has(mutation.entity.id)\n ? updateEntity(mutation.entity.id, cloneEntity(doc.entities.get(mutation.entity.id)!))\n : deleteEntity(mutation.entity.id),\n\n updateEntity: (doc, mutation) => {\n const cur = doc.entities.get(mutation.entityId);\n if (!cur) return NULL_MUTATION;\n const before: Record<string, unknown> = {};\n for (const key of Object.keys(mutation.props)) {\n before[key] = (cur as unknown as Record<string, unknown>)[key];\n }\n return updateEntity(mutation.entityId, before as Partial<typeof cur>);\n },\n\n deleteEntity: (doc, mutation) => {\n const cur = doc.entities.get(mutation.entityId);\n return cur ? addEntity(cloneEntity(cur)) : NULL_MUTATION;\n },\n\n // 覆盖已有 id 时,逆是把旧 fragment 加回来;否则逆是删掉它。\n addFragment: (doc, mutation) => {\n const cur = doc.fragments.get(mutation.fragment.id);\n return cur ? addFragment(cloneFragment(cur)) : deleteFragment(mutation.fragment.id);\n },\n\n deleteFragment: (doc, mutation) => {\n const cur = doc.fragments.get(mutation.fragmentId);\n return cur ? addFragment(cloneFragment(cur)) : NULL_MUTATION;\n },\n\n addVirtualBlock: (doc, mutation) => {\n const cur = doc.blockById(mutation.block.id);\n return cur ? addVirtualBlock(cur) : deleteVirtualBlock(mutation.block.id);\n },\n\n updateVirtualBlock: (doc, mutation) => {\n const cur = doc.blockById(mutation.blockId);\n return cur ? updateVirtualBlock(mutation.blockId, cur) : NULL_MUTATION;\n },\n\n deleteVirtualBlock: (doc, mutation) => {\n const cur = doc.blockById(mutation.blockId);\n return cur ? addVirtualBlock(cur) : NULL_MUTATION;\n },\n\n // 在片段自己的模型上求逆,再包回同一个片段\n scoped: (doc, mutation) =>\n scoped(\n mutation.fragmentId,\n invertMutation(doc.ensureFragmentModel(mutation.fragmentId), mutation.inner)\n )\n};\n\n/**\n * 算出 mutation 的逆。必须在 mutation 被应用**之前**调用。\n * 组合操作请改用 {@link applyAndInvert}。\n */\nexport function invertMutation(doc: DocumentModel, mutation: Mutation): Mutation {\n return (inverters[mutation.type] as InverterFor<MutationType>)(doc, mutation);\n}\n\n/**\n * 应用 mutation,同时返回它的逆。\n * 组合操作会逐条交错处理,逆按相反顺序排列。\n */\nexport function applyAndInvert(doc: DocumentModel, mutation: Mutation): Mutation {\n const forward = unwrap(mutation);\n const inverses: Mutation[] = [];\n for (const m of forward) {\n inverses.unshift(invertMutation(doc, m));\n applyMutation(doc, m);\n }\n return multi(inverses);\n}\n","/**\n * 闭区间与索引变换。\n *\n * 注意区间语义:这一层全部用**闭区间** `[min, max]`,`min > max` 即为空。\n * 文档模型对外的 `deleteRange(start, end)` 用的是半开区间 `[start, end)`,\n * 两者在 mutation 的边界上转换(见 mutations.ts 的 deleteSpacers)。\n * 不要把两种语义混着用,差一位的 bug 都出在这里。\n */\n\nexport interface Range {\n min: number;\n max: number;\n}\n\n/** 空区间用 null 表示。 */\nexport type MaybeRange = Range | null;\n\nexport function newRange(min: number, max: number): MaybeRange {\n return min <= max ? { min, max } : null;\n}\n\nexport function rangeContains(range: Range, value: number): boolean {\n return value >= range.min && value <= range.max;\n}\n\nexport function rangeEquals(a: MaybeRange, b: MaybeRange): boolean {\n if (!a || !b) return a === b;\n return a.min === b.min && a.max === b.max;\n}\n\n/** 区间长度(闭区间,含两端)。 */\nexport function rangeLength(range: Range): number {\n return range.max - range.min + 1;\n}\n\n/** 把「位于 shiftPosition 及其之后」的坐标平移 offset。 */\nexport function shiftIndex(index: number, shiftPosition: number, offset: number): number {\n return index >= shiftPosition ? index + offset : index;\n}\n\n/**\n * 同上,但落在 shiftPosition 上的坐标**不动**。\n * 选区的起点要用这个:在光标处插入字符,光标不该被推走。\n */\nexport function shiftIndexExclusive(index: number, shiftPosition: number, offset: number): number {\n return index === shiftPosition ? index : shiftIndex(index, shiftPosition, offset);\n}\n\nexport function shiftRange(range: MaybeRange, shiftPosition: number, offset: number): MaybeRange {\n if (!range) return null;\n return newRange(\n shiftIndex(range.min, shiftPosition, offset),\n shiftIndex(range.max, shiftPosition, offset)\n );\n}\n\nexport function shiftRangeExclusive(range: MaybeRange, shiftPosition: number, offset: number): MaybeRange {\n if (!range) return null;\n return newRange(\n shiftIndexExclusive(range.min, shiftPosition, offset),\n shiftIndex(range.max, shiftPosition, offset)\n );\n}\n\n/** position 之前被删掉的长度。 */\nexport function leadingLength(position: number, range: Range): number {\n const leadEnd = Math.min(position - 1, range.max);\n return Math.max(0, leadEnd - range.min + 1);\n}\n\nexport function transformCoordinateAgainstDeletedRange(position: number, deleted: Range): number {\n return position - leadingLength(position, deleted);\n}\n\n/**\n * 把一个区间放到「deleted 已被删除」的坐标系里。整段被删则返回空。\n *\n * 一般情况只需把坐标减去它前面被删掉的长度;但如果端点本身落在被删范围内,\n * 这种平移不足以把它收回来,还要再多缩一位。\n */\nexport function transformRangeAgainstDeletedRange(range: MaybeRange, deleted: Range): MaybeRange {\n if (!range) return null;\n const newStart = transformCoordinateAgainstDeletedRange(range.min, deleted);\n const endpointDeleted = rangeContains(deleted, range.max);\n const newEnd = transformCoordinateAgainstDeletedRange(range.max, deleted) - (endpointDeleted ? 1 : 0);\n return newRange(newStart, newEnd);\n}\n","/**\n * OT 变换。\n *\n * `transform(a, b, aWins)` 的含义:b 已经被应用了,把 a 改写成能在「b 之后」\n * 正确执行的形式。`aWins` 是并列时的优先级 —— 两个插入落在同一个下标时,\n * 赢的一方留在原地,输的一方被推到后面。两端必须对同一对操作给出相反的\n * `aWins`,否则会各自算出不同的结果,文档就分叉了。\n */\nimport {\n ApplyStyleMutation,\n DeleteSpacersMutation,\n InsertSpacersMutation,\n Mutation,\n MutationType,\n NULL_MUTATION,\n multi,\n scoped,\n unwrap\n} from './types';\nimport {\n MaybeRange,\n newRange,\n rangeEquals,\n shiftIndex,\n shiftRange,\n transformRangeAgainstDeletedRange\n} from './ranges';\nimport { shiftVirtualBlocksOnDelete, shiftVirtualBlocksOnInsert } from '../model/virtualBlock';\n\n// ---- insert 对各类操作 ----------------------------------------------------\n\nfunction insertAgainstInsert(\n cmd: InsertSpacersMutation,\n other: InsertSpacersMutation,\n aWins: boolean\n): Mutation {\n // 并列插入:赢家不动\n if (other.insertBeforeIndex === cmd.insertBeforeIndex && aWins) return cmd;\n return {\n ...cmd,\n insertBeforeIndex: shiftIndex(cmd.insertBeforeIndex, other.insertBeforeIndex, other.spacers.length)\n };\n}\n\nfunction insertAgainstDelete(cmd: InsertSpacersMutation, other: DeleteSpacersMutation): Mutation {\n // 插入点落在被删掉的那段里 —— 锚点没了,这次插入作废\n if (other.startIndex < cmd.insertBeforeIndex && other.endIndex >= cmd.insertBeforeIndex) {\n return NULL_MUTATION;\n }\n const length = other.endIndex - other.startIndex + 1;\n return {\n ...cmd,\n insertBeforeIndex: shiftIndex(cmd.insertBeforeIndex, other.startIndex + 1, -length)\n };\n}\n\n// ---- delete 对各类操作 ----------------------------------------------------\n\nfunction deleteAgainstInsert(cmd: DeleteSpacersMutation, other: InsertSpacersMutation): Mutation {\n const shifted = shiftRange(\n newRange(cmd.startIndex, cmd.endIndex),\n other.insertBeforeIndex,\n other.spacers.length\n );\n return copyWithRange(cmd, shifted);\n}\n\nfunction deleteAgainstDelete(cmd: DeleteSpacersMutation, other: DeleteSpacersMutation): Mutation {\n const removed = transformRangeAgainstDeletedRange(newRange(cmd.startIndex, cmd.endIndex), {\n min: other.startIndex,\n max: other.endIndex\n });\n return copyWithRange(cmd, removed);\n}\n\nfunction copyWithRange(cmd: DeleteSpacersMutation, range: MaybeRange): Mutation {\n if (!range) return NULL_MUTATION;\n if (rangeEquals(range, newRange(cmd.startIndex, cmd.endIndex))) return cmd;\n return { ...cmd, startIndex: range.min, endIndex: range.max };\n}\n\n// ---- applyStyle 对各类操作 ------------------------------------------------\n// 样式区间跟着内容走,规则与 delete 的区间变换一致。\n\nfunction styleAgainstInsert(cmd: ApplyStyleMutation, other: InsertSpacersMutation): Mutation {\n const shifted = shiftRange(\n newRange(cmd.startIndex, cmd.endIndex),\n other.insertBeforeIndex,\n other.spacers.length\n );\n return copyStyleWithRange(cmd, shifted);\n}\n\nfunction styleAgainstDelete(cmd: ApplyStyleMutation, other: DeleteSpacersMutation): Mutation {\n const removed = transformRangeAgainstDeletedRange(newRange(cmd.startIndex, cmd.endIndex), {\n min: other.startIndex,\n max: other.endIndex\n });\n return copyStyleWithRange(cmd, removed);\n}\n\nfunction copyStyleWithRange(cmd: ApplyStyleMutation, range: MaybeRange): Mutation {\n if (!range) return NULL_MUTATION;\n if (rangeEquals(range, newRange(cmd.startIndex, cmd.endIndex))) return cmd;\n return { ...cmd, startIndex: range.min, endIndex: range.max };\n}\n\n// ---- 分发 ----------------------------------------------------------------\n\nexport type TransformerFor<T extends MutationType> = (\n cmd: Extract<Mutation, { type: T }>,\n other: Mutation,\n aWins: boolean\n) => Mutation;\n\n/** 每种 mutation 一个 transformer。少一种编译不过。 */\nexport type Transformers = { [T in MutationType]: TransformerFor<T> };\n\nexport const transformers: Transformers = {\n null: (cmd) => cmd,\n\n multi: (cmd, other, aWins) => multi(unwrap(cmd).map((c) => transform(c, other, aWins))),\n\n insertSpacers: (cmd, other, aWins) => {\n if (other.type === 'insertSpacers') return insertAgainstInsert(cmd, other, aWins);\n if (other.type === 'deleteSpacers') return insertAgainstDelete(cmd, other);\n return cmd;\n },\n\n deleteSpacers: (cmd, other) => {\n if (other.type === 'insertSpacers') return deleteAgainstInsert(cmd, other);\n if (other.type === 'deleteSpacers') return deleteAgainstDelete(cmd, other);\n return cmd;\n },\n\n applyStyle: (cmd, other) => {\n if (other.type === 'insertSpacers') return styleAgainstInsert(cmd, other);\n if (other.type === 'deleteSpacers') return styleAgainstDelete(cmd, other);\n return cmd;\n },\n\n // 实体操作按 id 寻址,不受下标变化影响\n addEntity: (cmd) => cmd,\n updateEntity: (cmd) => cmd,\n deleteEntity: (cmd) => cmd,\n\n // fragment 同样按 id 寻址,不占主文档坐标空间,原样放行\n addFragment: (cmd) => cmd,\n deleteFragment: (cmd) => cmd,\n\n addVirtualBlock: (cmd, other, aWins) => {\n if (other.type === 'insertSpacers') {\n const [shifted] = shiftVirtualBlocksOnInsert(\n [cmd.block],\n other.insertBeforeIndex,\n other.spacers.length\n );\n return shifted ? { ...cmd, block: shifted } : NULL_MUTATION;\n }\n if (other.type === 'deleteSpacers') {\n const shifted = shiftVirtualBlocksOnDelete([cmd.block], other.startIndex, other.endIndex + 1);\n return shifted[0] ? { ...cmd, block: shifted[0] } : NULL_MUTATION;\n }\n if (other.type === 'addVirtualBlock' && other.block.id === cmd.block.id) {\n return aWins ? cmd : other;\n }\n if (other.type === 'deleteVirtualBlock' && other.blockId === cmd.block.id) {\n return cmd;\n }\n if (other.type === 'updateVirtualBlock' && other.blockId === cmd.block.id) {\n return aWins ? cmd : { type: 'addVirtualBlock', block: other.block };\n }\n return cmd;\n },\n\n updateVirtualBlock: (cmd, other, aWins) => {\n if (other.type === 'insertSpacers') {\n const [shifted] = shiftVirtualBlocksOnInsert(\n [cmd.block],\n other.insertBeforeIndex,\n other.spacers.length\n );\n return shifted ? { ...cmd, block: shifted } : NULL_MUTATION;\n }\n if (other.type === 'deleteSpacers') {\n const shifted = shiftVirtualBlocksOnDelete([cmd.block], other.startIndex, other.endIndex + 1);\n return shifted[0] ? { ...cmd, blockId: cmd.blockId, block: shifted[0] } : NULL_MUTATION;\n }\n if (other.type === 'deleteVirtualBlock' && other.blockId === cmd.blockId) {\n return NULL_MUTATION;\n }\n if (other.type === 'updateVirtualBlock' && other.blockId === cmd.blockId) {\n return aWins ? cmd : other;\n }\n if (other.type === 'addVirtualBlock' && other.block.id === cmd.blockId) {\n return aWins ? cmd : { ...cmd, block: other.block };\n }\n return cmd;\n },\n\n deleteVirtualBlock: (cmd, other) => {\n if (other.type === 'deleteVirtualBlock' && other.blockId === cmd.blockId) return NULL_MUTATION;\n return cmd;\n },\n\n // 每个片段是独立的坐标空间。同一片段就往里递归,不同片段(或主文档的操作)\n // 天然不冲突,原样放行 —— 这是 scoped 这个设计最省事的地方。\n scoped: (cmd, other, aWins) => {\n if (other.type !== 'scoped' || other.fragmentId !== cmd.fragmentId) return cmd;\n return scoped(cmd.fragmentId, transform(cmd.inner, other.inner, aWins));\n }\n};\n\n/** 把 cmd 变换到「other 已应用」之后的坐标系里。 */\nexport function transform(cmd: Mutation, other: Mutation, aWins: boolean): Mutation {\n if (cmd.type === 'null' || other.type === 'null') return cmd;\n\n // other 是组合:把 cmd 逐条穿过去。这一步取决于 other 的类型,\n // 所以留在入口,不能塞进按 cmd.type 分派的表里。\n if (other.type === 'multi') {\n let out: Mutation = cmd;\n for (const o of unwrap(other)) out = transform(out, o, aWins);\n return out;\n }\n\n return (transformers[cmd.type] as TransformerFor<MutationType>)(cmd, other, aWins);\n}\n\n/**\n * 把一串操作变换到另一串之后。\n *\n * 关键在内层那次反向变换:a 列表里的第 i 条被 b[j] 变换的同时,b[j] 自己也要\n * 被变换后的 a[i] 推一把,否则 a 的第 i+1 条再对上 b[j] 时,b[j] 还停在旧坐标系里,\n * 结果就错了。\n */\nexport function transformCommands(a: Mutation[], b: Mutation[], aWins: boolean): Mutation[] {\n const others = [...b];\n const out: Mutation[] = [];\n for (let i = 0; i < a.length; i++) {\n let cur = a[i];\n for (let j = 0; j < others.length; j++) {\n const before = cur;\n cur = transform(before, others[j], aWins);\n others[j] = transform(others[j], before, !aWins);\n }\n out.push(cur);\n }\n return out;\n}\n\n/** 双向变换:同时得到 a'(在 b 之后执行)和 b'(在 a 之后执行)。 */\nexport function transformBoth(\n a: Mutation[],\n b: Mutation[],\n aWins = true\n): { a: Mutation[]; b: Mutation[] } {\n const others = [...b];\n const out: Mutation[] = [];\n for (let i = 0; i < a.length; i++) {\n let cur = a[i];\n for (let j = 0; j < others.length; j++) {\n const before = cur;\n cur = transform(before, others[j], aWins);\n others[j] = transform(others[j], before, !aWins);\n }\n out.push(cur);\n }\n return { a: out, b: others };\n}\n","/**\n * 选区 rebase:别人的操作落地后,把本地光标/选区挪到正确的新位置。\n *\n * 插入点正好等于光标位置时,光标推不推走由 `shiftedByInserts` 决定:\n * 本地刚敲下的字要跟着走(光标落在新字之后),而协作者在你光标处插入时\n * 你的光标应该原地不动。默认按后者。\n */\nimport { Selection } from '../model/types';\nimport { Mutation, unwrap } from './types';\nimport { shiftIndex, shiftIndexExclusive, transformCoordinateAgainstDeletedRange } from './ranges';\n\nexport function transformIndex(\n index: number,\n mutations: Mutation[],\n shiftedByInserts = false\n): number {\n let cur = index;\n for (const m of mutations) {\n if (m.type === 'insertSpacers') {\n cur = shiftedByInserts\n ? shiftIndex(cur, m.insertBeforeIndex, m.spacers.length)\n : shiftIndexExclusive(cur, m.insertBeforeIndex, m.spacers.length);\n } else if (m.type === 'deleteSpacers') {\n cur = transformCoordinateAgainstDeletedRange(cur, { min: m.startIndex, max: m.endIndex });\n } else if (m.type === 'multi') {\n cur = transformIndex(cur, unwrap(m), shiftedByInserts);\n }\n }\n return cur;\n}\n\nexport function transformSelection(\n sel: Selection,\n mutations: Mutation[],\n shiftedByInserts = false\n): Selection {\n const flat = mutations.flatMap((m) => unwrap(m));\n return {\n anchor: transformIndex(sel.anchor, flat, shiftedByInserts),\n focus: transformIndex(sel.focus, flat, shiftedByInserts)\n };\n}\n","/**\n * EditResult —— 一次用户操作的完整记录。\n *\n * 同时存**正向**和**逆向**两串 mutation:逆向是在应用正向的当时算出来的,\n * 因为很多逆操作(比如删除的逆)必须读到删之前的文档才能算。等到要撤销时\n * 再算就晚了。\n */\nimport { Selection } from '../model/types';\nimport { Mutation, reverse, unwrap } from '../mutations';\n\n/**\n * 编辑种类。新增一种编辑必须先在这里登记 —— 因为撤销的合并规则是按 kind 查的,\n * 漏登记会让新编辑落到默认的「不合并」上,症状很隐蔽。\n */\nexport type EditKind =\n | 'insert.text'\n | 'insert.paragraph'\n | 'insert.paste'\n | 'delete.backward'\n | 'delete.forward'\n | 'delete.selection'\n | 'style.text'\n | 'style.paragraph'\n | 'style.link'\n | 'embed.insert'\n | 'embed.update'\n | 'embed.resize'\n | 'embed.delete'\n | 'table.insert'\n | 'table.structure'\n | 'table.colWidth'\n | 'table.clearCells'\n | 'ref.promote'\n | 'ref.insert'\n | 'ref.unlink'\n | 'vblock.insert'\n | 'vblock.update'\n | 'vblock.remove';\n\n/**\n * 允许与相邻同类编辑合并成一步撤销的种类。\n *\n * 只有「连着做同一件事」才该合并:连续打字撤销时应该整段消失,而不是一个字\n * 一个字地退。别的都不合并 —— 尤其不能只看时间窗口,那会把「打几个字」和紧随\n * 其后的「点加粗」并成一步,撤销时文字和加粗一起没了。\n */\nconst MERGEABLE_KINDS = new Set<EditKind>([\n 'insert.text',\n 'delete.backward',\n 'delete.forward'\n]);\n\n/** 某个种类的默认合并键。同键才合并,null 表示永不合并。 */\nexport function mergeKeyFor(kind: EditKind, scope: string | null): string | null {\n if (!MERGEABLE_KINDS.has(kind)) return null;\n // 带上 scope:主文档里打字和片段里打字不是同一串输入\n return scope ? `${kind}@${scope}` : kind;\n}\n\nexport interface EditMeta {\n kind: EditKind;\n /** 相同且非 null 才允许与相邻一步合并成同一步撤销;null 表示永不合并。 */\n mergeKey: string | null;\n /** 本地产生的还是远端同步过来的。只有本地的才能被撤销。 */\n local: boolean;\n /** 是否占一步撤销。某些操作(如纯元数据变更)不占。 */\n undoable: boolean;\n /**\n * 这次编辑发生在哪个片段的坐标空间里,null 表示主文档。\n * 选区字段属于这个空间,撤销时要照它决定把选区还给谁。\n */\n scope: string | null;\n}\n\nexport interface EditResult {\n /** 正向操作 */\n mutations: Mutation[];\n /** 逆向操作,已按相反顺序排好,可直接依次执行 */\n inverse: Mutation[];\n selectionBefore: Selection;\n selectionAfter: Selection;\n meta: EditMeta;\n}\n\nexport function editMeta(init: Partial<EditMeta> & { kind: EditKind }): EditMeta {\n const scope = init.scope ?? null;\n return {\n kind: init.kind,\n mergeKey: init.mergeKey !== undefined ? init.mergeKey : mergeKeyFor(init.kind, scope),\n local: init.local ?? true,\n undoable: init.undoable ?? true,\n scope\n };\n}\n\nexport function editResult(init: {\n mutations: Mutation | Mutation[];\n inverse: Mutation | Mutation[];\n selectionBefore: Selection;\n selectionAfter: Selection;\n meta: Partial<EditMeta> & { kind: EditKind };\n}): EditResult {\n const flatten = (m: Mutation | Mutation[]) =>\n Array.isArray(m) ? m.flatMap(unwrap) : unwrap(m);\n return {\n mutations: flatten(init.mutations),\n inverse: flatten(init.inverse),\n selectionBefore: { ...init.selectionBefore },\n selectionAfter: { ...init.selectionAfter },\n meta: editMeta(init.meta)\n };\n}\n\nexport function isEmptyEdit(e: EditResult): boolean {\n return e.mutations.length === 0;\n}\n\n/**\n * 合并相邻两步(连续输入合成一步撤销)。\n *\n * 正向按时间顺序拼接;逆向要**倒过来**拼 —— 撤销一组操作得从最后一条开始退。\n * 选区取首尾:撤销后回到第一步之前的位置。\n */\nexport function mergeEdits(first: EditResult, second: EditResult): EditResult {\n return {\n mutations: [...first.mutations, ...second.mutations],\n inverse: [...second.inverse, ...first.inverse],\n selectionBefore: { ...first.selectionBefore },\n selectionAfter: { ...second.selectionAfter },\n meta: {\n ...first.meta,\n local: first.meta.local && second.meta.local,\n undoable: first.meta.undoable || second.meta.undoable\n }\n };\n}\n\n/** 交换正逆两串,得到「撤销这一步」本身作为一步操作。 */\nexport function invertEdit(e: EditResult): EditResult {\n return {\n mutations: e.inverse,\n inverse: reverse(e.mutations),\n selectionBefore: { ...e.selectionAfter },\n selectionAfter: { ...e.selectionBefore },\n meta: { ...e.meta }\n };\n}\n","/**\n * Operation 的执行上下文。\n *\n * Operation 通过 `emit` 改文档,通过 `doc` 读文档。`emit` 是**立即生效**的 ——\n * 发一条就写一条,所以同一个 Operation 里后续的读能看到前面的效果。复杂操作\n * 因此可以「读—写—再读」,比如先插入换行、再读出新的段落边界、再给新段落发样式。\n *\n * 逆操作在写入**之前**算出来(很多逆必须读到变更前的文档),正逆两串一起收集。\n */\nimport { DocumentModel } from '../model/document';\nimport { Selection } from '../model/types';\nimport { Mutation, applyMutation, invertMutation, scoped, unwrap } from '../mutations';\n\nexport interface OperationContext {\n /** 读文档。写只能走 emit */\n readonly doc: DocumentModel;\n /** 当前选区 */\n selection(): Selection;\n /** 移动选区。不产生 mutation */\n select(next: Selection): void;\n /** 发一条 mutation:先求逆、立即写入、正逆两串都收集 */\n emit(mutation: Mutation): void;\n}\n\n/** Operation 就是一个拿 context 的函数。组合就是传同一个 ctx 下去。 */\nexport type Operation<R = void> = (ctx: OperationContext) => R;\n\nexport interface OperationRun {\n /** 正向操作,按执行顺序 */\n forward: Mutation[];\n /** 逆向操作,已按相反顺序排好 */\n inverse: Mutation[];\n selectionBefore: Selection;\n selectionAfter: Selection;\n}\n\nclass Collector implements OperationContext {\n readonly forward: Mutation[] = [];\n readonly inverse: Mutation[] = [];\n private sel: Selection;\n\n constructor(readonly doc: DocumentModel, selection: Selection) {\n this.sel = { ...selection };\n }\n\n selection(): Selection {\n return { ...this.sel };\n }\n\n select(next: Selection) {\n this.sel = { ...next };\n }\n\n emit(mutation: Mutation) {\n // unwrap 把 multi 摊平、把 null 滤掉,所以下面只面对单条实操\n for (const one of unwrap(mutation)) {\n this.inverse.unshift(invertMutation(this.doc, one));\n applyMutation(this.doc, one);\n this.forward.push(one);\n }\n }\n}\n\n/**\n * 把上下文切到某个片段(同步块)的坐标空间。\n *\n * 片段有自己的一条字符流,下标从 0 起,和主文档不共享。切过去之后,所有\n * Operation 都能原样复用 —— 它们读到的是片段模型,发出的 mutation 自动包上\n * `scoped`,落进的还是外层那一份操作串。选区共用外层的格子,因为调用方一开始\n * 就是拿片段选区起的事务。\n */\nexport function scopeContext(outer: OperationContext, fragmentId: string): OperationContext {\n return {\n doc: outer.doc.ensureFragmentModel(fragmentId),\n selection: () => outer.selection(),\n select: (next) => outer.select(next),\n emit: (mutation) => outer.emit(scoped(fragmentId, mutation))\n };\n}\n\n/** 跑一个 Operation,拿到它产生的操作串与选区变化。 */\nexport function runOperation<R>(\n doc: DocumentModel,\n selection: Selection,\n op: Operation<R>\n): { run: OperationRun; result: R } {\n const ctx = new Collector(doc, selection);\n const result = op(ctx);\n return {\n run: {\n forward: ctx.forward,\n inverse: ctx.inverse,\n selectionBefore: { ...selection },\n selectionAfter: ctx.selection()\n },\n result\n };\n}\n","/**\n * 解析助手:Operation 层「读模型 → 判断」的那一半。\n *\n * mutation 携带的必须是完整解析过的值,不能是补丁。谁负责把「用户想加粗」\n * 变成「这段的完整文字属性是 {bold:true, size:16, color:'#111'}」?就是这里。\n * 这些函数只读文档,不写文档。\n */\nimport { parseBlocks } from '../model/blocks';\nimport { DocumentModel } from '../model/document';\nimport { isTableMarker, MARKERS } from '../model/markers';\nimport { DEFAULT_PARAGRAPH, ParagraphProps, StyleSpan, StyleType, TextProps } from '../model/types';\n\n/** 落在 index 处的完整文字属性。没有区间时是空对象,代表「未着色」。 */\nexport function resolveTextProps(doc: DocumentModel, index: number): TextProps {\n return doc.textPropsAt(index);\n}\n\n/** 落在 index 所属段落上的完整段落属性,缺省项补齐。 */\nexport function resolveParagraphProps(doc: DocumentModel, index: number): ParagraphProps {\n return doc.paragraphPropsAt(index);\n}\n\n/** 半开区间 [start, end) 内是否只有结构标记(段分隔、表格骨架、图片占位)。 */\nexport function rangeIsOnlyMarkers(doc: DocumentModel, start: number, end: number): boolean {\n for (let i = start; i < end; i++) {\n const ch = doc.spacers[i];\n if (ch === MARKERS.IMAGE) continue;\n if (ch !== MARKERS.PARAGRAPH && !isTableMarker(ch)) return false;\n }\n return true;\n}\n\n/** 一段文本里「真正是内容」的片段,用来给新插入的字上色时跳过结构标记。 */\nexport function contentRuns(text: string, base: number): [number, number][] {\n const runs: [number, number][] = [];\n let runStart = -1;\n for (let i = 0; i < text.length; i++) {\n const ch = text[i];\n const content = ch !== MARKERS.PARAGRAPH && !isTableMarker(ch);\n if (content && runStart < 0) runStart = base + i;\n if (!content && runStart >= 0) {\n runs.push([runStart, base + i]);\n runStart = -1;\n }\n }\n if (runStart >= 0) runs.push([runStart, base + text.length]);\n return runs;\n}\n\n/**\n * 把半开区间 [from, to) 按「已有 text 区间的边界」切成若干小段。\n * 每段要么整段落在某个已有区间里(带上它,属性要在它基础上合并),\n * 要么是空档(属性从零起)。这是文字上色能算出完整值的前提。\n */\nexport function textSegments(\n doc: DocumentModel,\n from: number,\n to: number\n): { start: number; end: number; existing: StyleSpan | null }[] {\n const points = new Set<number>([from, to]);\n for (const s of doc.styles) {\n if (s.type !== 'text' || s.end <= from || s.start >= to) continue;\n if (s.start > from && s.start < to) points.add(s.start);\n if (s.end > from && s.end < to) points.add(s.end);\n }\n const sorted = [...points].sort((a, b) => a - b);\n const out: { start: number; end: number; existing: StyleSpan | null }[] = [];\n for (let k = 0; k < sorted.length - 1; k++) {\n const start = sorted[k];\n const end = sorted[k + 1];\n if (start >= end) continue;\n const existing =\n doc.styles.find((s) => s.type === 'text' && s.start <= start && s.end >= end) ?? null;\n out.push({ start, end, existing });\n }\n return out;\n}\n\n/** 某一类样式里,完整覆盖 [start, end) 的那条区间。 */\nexport function spanCovering(\n doc: DocumentModel,\n type: StyleType,\n start: number,\n end: number\n): StyleSpan | null {\n return doc.styles.find((s) => s.type === type && s.start <= start && s.end >= end) ?? null;\n}\n\n/**\n * 按当前字符流算出「段落区间应该长什么样」。\n *\n * 段分隔符一插一删,段落的边界就变了。这里从块结构重新推导出该有的一组\n * paragraph 区间,属性尽量沿用原来落在同一位置的那条 —— 这就是回车后新段\n * 能继承缩进和列表状态的原因。\n */\nexport function expectedParagraphSpans(doc: DocumentModel): StyleSpan[] {\n const out: StyleSpan[] = [];\n // 每段都对全部样式线性 find 是 O(段数²),几千段时每次输入十几毫秒。\n // 这里建一次索引,取“数组里最靠前的那条”,与线性 find 的结果一致。\n const exact = new Map<string, number>();\n const byStart: number[] = [];\n doc.styles.forEach((s, i) => {\n if (s.type !== 'paragraph') return;\n const k = `${s.start}:${s.end}`;\n if (!exact.has(k)) exact.set(k, i);\n byStart.push(i);\n });\n byStart.sort((a, b) => doc.styles[a].start - doc.styles[b].start || a - b);\n const firstStartAtLeast = (x: number) => {\n let lo = 0;\n let hi = byStart.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (doc.styles[byStart[mid]].start < x) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n };\n const inherit = (start: number, end: number): StyleSpan => {\n let at = exact.get(`${start}:${end}`);\n if (at === undefined) {\n // 起点落在 [start, end) 内的区间(必然与本段相交),取数组下标最小的\n for (let k = firstStartAtLeast(start); k < byStart.length; k++) {\n const i = byStart[k];\n if (doc.styles[i].start >= end) break;\n if (doc.styles[i].end > start && (at === undefined || i < at)) at = i;\n }\n }\n const existing = at === undefined ? undefined : doc.styles[at];\n return {\n start,\n end,\n type: 'paragraph',\n props: { ...DEFAULT_PARAGRAPH, ...(existing?.props as ParagraphProps | undefined) }\n };\n };\n for (const block of parseBlocks(doc.spacers)) {\n if (block.kind === 'paragraph') {\n out.push(inherit(block.start, block.end));\n } else {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const para of cell.paragraphs) {\n if (para.end > para.start) out.push(inherit(para.start, para.end));\n }\n }\n }\n }\n }\n return out.sort((a, b) => a.start - b.start || a.end - b.end);\n}\n","/**\n * Operation 层的低级发射助手。\n *\n * 这些不是 mutation,也不是完整的 Operation,而是介于两者之间的常用动作:\n * 「删一段字符流并顺手清掉附着的实体」「把段落区间重新对齐到块结构」之类。\n * 它们只通过 ctx.emit 改文档,所以每一步都进日志、都能被撤销和变换。\n */\nimport { Slice, StyleSpan, StyleType, TextProps } from '../model/types';\nimport {\n applyStyle,\n deleteEntity,\n deleteSpacers,\n insertSpacers,\n multi,\n Mutation\n} from '../mutations';\nimport { MARKERS } from '../model/markers';\nimport { OperationContext } from './context';\nimport { expectedParagraphSpans, rangeIsOnlyMarkers, textSegments } from './resolve';\n\nconst EMPTY_SLICE: Slice = { text: '', styles: [], entities: [] };\n\n/** 在 index 处插入原始 spacer 串。不做任何段落推导。 */\nexport function emitInsert(ctx: OperationContext, index: number, text: string): number {\n const i = ctx.doc.clamp(index);\n if (!text) return i;\n ctx.emit(insertSpacers(i, text));\n return i + text.length;\n}\n\n/**\n * 删掉半开区间 [start, end),返回被删内容。\n *\n * 落在区间里的实体会显式发一条 deleteEntity —— 让实体的消失也是一条 mutation,\n * 而不是删字符的隐式副作用,否则撤销和协同都对不上账。\n */\nexport function emitDelete(ctx: OperationContext, start: number, end: number): Slice {\n const from = ctx.doc.clamp(Math.min(start, end));\n const to = ctx.doc.clamp(Math.max(start, end));\n if (to <= from) return EMPTY_SLICE;\n const slice = ctx.doc.takeSlice(from, to);\n for (const e of slice.entities) ctx.emit(deleteEntity(e.id));\n ctx.emit(deleteSpacers(from, to - 1));\n return slice;\n}\n\n/** 给半开区间 [start, end) 覆盖一条样式区间。props 必须已解析完整。 */\nexport function emitStyle(\n ctx: OperationContext,\n type: StyleType,\n start: number,\n end: number,\n props: StyleSpan['props'] | null\n) {\n if (end <= start) return;\n ctx.emit(applyStyle(type, start, end - 1, props));\n}\n\n/**\n * 文字上色。把区间按已有区间边界切段,每段各自算出**合并后的完整属性**再发。\n * 纯结构标记的空档不上色,免得给段分隔符染上颜色。\n */\nexport function emitTextStyle(ctx: OperationContext, start: number, end: number, patch: TextProps) {\n const from = ctx.doc.clamp(Math.min(start, end));\n const to = ctx.doc.clamp(Math.max(start, end));\n if (from >= to) return;\n const out: Mutation[] = [];\n for (const seg of textSegments(ctx.doc, from, to)) {\n if (seg.existing) {\n out.push(applyStyle('text', seg.start, seg.end - 1, { ...(seg.existing.props as TextProps), ...patch }));\n } else if (!rangeIsOnlyMarkers(ctx.doc, seg.start, seg.end)) {\n out.push(applyStyle('text', seg.start, seg.end - 1, { ...patch }));\n }\n }\n ctx.emit(multi(out));\n}\n\n/**\n * 把 paragraph 区间重新对齐到当前块结构,只发实际有出入的那一段。\n *\n * 从前这是模型在删字符时偷偷做的,逆操作里没有记录,所以撤销要靠整篇比对样式。\n * 现在它是显式的 applyStyle,逆自然就跟着有了。\n */\nexport function normalizeParagraphs(ctx: OperationContext) {\n const doc = ctx.doc;\n // 全选删除会把最后一个段分隔符一并清掉,文档变成空串。之后再打字第一次回车\n // 只会补上这个收口符,视觉上仍是一行;必须在这里把空文档收成一段 `\\n`。\n if (!doc.spacers.endsWith(MARKERS.PARAGRAPH)) {\n emitInsert(ctx, doc.spacers.length, MARKERS.PARAGRAPH);\n }\n const needed = expectedParagraphSpans(doc);\n const current = doc.styles\n .filter((s) => s.type === 'paragraph')\n .sort((a, b) => a.start - b.start || a.end - b.end);\n\n if (sameSpans(needed, current)) return;\n\n const key = (s: StyleSpan) => `${s.start}:${s.end}:${JSON.stringify(s.props)}`;\n const needKeys = new Set(needed.map(key));\n const curKeys = new Set(current.map(key));\n const differing = [\n ...current.filter((s) => !needKeys.has(key(s))),\n ...needed.filter((s) => !curKeys.has(key(s)))\n ];\n if (differing.length === 0) return;\n\n // 清除范围要囊括每一条与之相交的目标区间,否则会把某段从中间切断。\n let from = Math.min(...differing.map((s) => s.start));\n let to = Math.max(...differing.map((s) => s.end));\n for (let guard = 0; guard < 8; guard++) {\n let grew = false;\n for (const s of needed) {\n if (s.start < to && s.end > from) {\n if (s.start < from) {\n from = s.start;\n grew = true;\n }\n if (s.end > to) {\n to = s.end;\n grew = true;\n }\n }\n }\n if (!grew) break;\n }\n\n const out: Mutation[] = [applyStyle('paragraph', from, to - 1, null)];\n for (const s of needed) {\n if (s.end <= from || s.start >= to) continue;\n out.push(applyStyle('paragraph', s.start, s.end - 1, s.props));\n }\n ctx.emit(multi(out));\n}\n\n/** 两组已排序的区间逐条相同(属性按键值比较,不看键序)。 */\nfunction sameSpans(a: StyleSpan[], b: StyleSpan[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i].start !== b[i].start || a[i].end !== b[i].end) return false;\n const pa = (a[i].props ?? {}) as Record<string, unknown>;\n const pb = (b[i].props ?? {}) as Record<string, unknown>;\n const ka = Object.keys(pa);\n if (ka.length !== Object.keys(pb).length) return false;\n for (const k of ka) if (pa[k] !== pb[k]) return false;\n }\n return true;\n}\n\n/** 文档尾部必须有一个段分隔符收口,插表格之后要补。 */\nexport function ensureParagraphAfter(ctx: OperationContext, index: number) {\n if (index < ctx.doc.spacers.length) return;\n emitInsert(ctx, index, MARKERS.PARAGRAPH);\n}\n","/**\n * 样式类 Operation。\n *\n * 这一组最能说明 Operation 层存在的意义:用户表达的是补丁(「加粗」),\n * mutation 要求的是完整值(「这段的文字属性是 …」)。中间那步解析在这里做。\n */\nimport { paragraphsIntersecting } from '../model/blocks';\nimport { DEFAULT_TEXT, LINK_COLOR, ParagraphProps, TextProps } from '../model/types';\nimport { Operation } from './context';\nimport { emitStyle, emitTextStyle, normalizeParagraphs } from './primitives';\nimport { resolveParagraphProps } from './resolve';\n\n/** 给半开区间 [start, end) 打文字样式补丁。 */\nexport function applyTextStyle(start: number, end: number, patch: TextProps): Operation {\n return (ctx) => {\n emitTextStyle(ctx, start, end, patch);\n };\n}\n\n/**\n * 给区间套链接。\n *\n * 与之相交的旧链接要整条清掉(而不是只清重叠部分),否则会留下半截尾巴 ——\n * 所以清除范围先向外扩到覆盖所有相交的链接区间。\n */\nexport function applyLink(start: number, end: number, url: string): Operation {\n return (ctx) => {\n const from = ctx.doc.clamp(Math.min(start, end));\n const to = ctx.doc.clamp(Math.max(start, end));\n if (from >= to || !url) return;\n\n let clearFrom = from;\n let clearTo = to;\n for (const s of ctx.doc.styles) {\n if (s.type !== 'link' || s.start >= to || s.end <= from) continue;\n clearFrom = Math.min(clearFrom, s.start);\n clearTo = Math.max(clearTo, s.end);\n }\n emitStyle(ctx, 'link', clearFrom, clearTo, null);\n emitStyle(ctx, 'link', from, to, { url });\n emitTextStyle(ctx, from, to, { color: LINK_COLOR, underline: true });\n };\n}\n\n/** 摘掉落在 index 处的链接,顺带把链接色和下划线还原成默认。 */\nexport function removeLink(index: number): Operation {\n return (ctx) => {\n const span = ctx.doc.linkSpanAt(index);\n if (!span) return;\n const { start, end } = span;\n emitStyle(ctx, 'link', start, end, null);\n emitTextStyle(ctx, start, end, { color: DEFAULT_TEXT.color, underline: false });\n };\n}\n\n/**\n * 给区间覆盖到的每个段落打段落样式补丁。\n *\n * 段落属性是整段一个值,所以逐段读出现值、合并补丁、整段覆盖回去。\n */\nexport function applyParagraphStyle(start: number, end: number, patch: ParagraphProps): Operation {\n return (ctx) => {\n for (const para of paragraphsIntersecting(ctx.doc.spacers, start, end)) {\n const next = { ...resolveParagraphProps(ctx.doc, para.start), ...patch };\n emitStyle(ctx, 'paragraph', para.start, para.end, next);\n }\n normalizeParagraphs(ctx);\n };\n}\n","import { HeadingLevel, ListKind, TextProps } from '../model/types';\n\n/** 常用 Markdown 输入的即时识别规则。 */\nexport type MarkdownHit =\n | { kind: 'heading'; level: HeadingLevel; consume: number }\n | { kind: 'list'; list: ListKind; consume: number }\n | { kind: 'code-block'; consume: number; language: string }\n | { kind: 'formula'; matchStart: number; matchEnd: number; latex: string; displayMode: boolean }\n | {\n kind: 'text';\n style: TextProps;\n matchStart: number;\n matchEnd: number;\n inner: string;\n };\n\nconst RULES: Array<{ type: string; reg: RegExp }> = [\n { type: 'CODE_BLOCK', reg: /^```(\\w*)\\s$/ },\n { type: 'FORMULA_BLOCK', reg: /\\$\\$([^$]+)\\$\\$\\s$/ },\n { type: 'FORMULA', reg: /\\$([^$\\n]+)\\$\\s$/ },\n { type: 'BOLD', reg: /\\*{2}.+\\*{2}\\s$/ },\n { type: 'STRIKETHROUGH', reg: /[~~]{2}.+[~~]{2}\\s$/ },\n { type: 'UNDER_LINE', reg: /[~~].+[~~]\\s$/ },\n { type: 'HEADING3', reg: /^#{3}\\s$/ },\n { type: 'HEADING2', reg: /^#{2}\\s$/ },\n { type: 'HEADING1', reg: /^#\\s$/ },\n { type: 'NUMBERED_LIST', reg: /^\\d+\\.\\s$/ },\n { type: 'BULLETED_LIST', reg: /^(-|\\*|\\+)\\s$/ },\n { type: 'ITALIC', reg: /\\*.+\\*\\s$/ }\n];\n\nfunction lastMatch(text: string, reg: RegExp): RegExpMatchArray | null {\n const m = text.match(reg);\n return m && m[0] ? m : null;\n}\n\nexport function matchMarkdown(paraText: string): MarkdownHit | null {\n for (const rule of RULES) {\n const m = lastMatch(paraText, rule.reg);\n if (!m) continue;\n const full = m[0];\n const matchStart = paraText.lastIndexOf(full);\n const matchEnd = matchStart + full.length;\n\n if (rule.type === 'CODE_BLOCK') {\n return { kind: 'code-block', consume: full.length, language: (m[1] || 'plain').toLowerCase() };\n }\n if (rule.type === 'FORMULA_BLOCK') {\n return { kind: 'formula', matchStart, matchEnd, latex: m[1] ?? '', displayMode: true };\n }\n if (rule.type === 'FORMULA') {\n return { kind: 'formula', matchStart, matchEnd, latex: m[1] ?? '', displayMode: false };\n }\n if (rule.type === 'HEADING1') return { kind: 'heading', level: 1, consume: full.length };\n if (rule.type === 'HEADING2') return { kind: 'heading', level: 2, consume: full.length };\n if (rule.type === 'HEADING3') return { kind: 'heading', level: 3, consume: full.length };\n if (rule.type === 'NUMBERED_LIST') return { kind: 'list', list: 'ol', consume: full.length };\n if (rule.type === 'BULLETED_LIST') return { kind: 'list', list: 'ul', consume: full.length };\n\n if (rule.type === 'BOLD') {\n return { kind: 'text', style: { bold: true }, matchStart, matchEnd, inner: full.slice(2, full.length - 3) };\n }\n if (rule.type === 'ITALIC') {\n return { kind: 'text', style: { italic: true }, matchStart, matchEnd, inner: full.slice(1, full.length - 2) };\n }\n if (rule.type === 'UNDER_LINE') {\n return { kind: 'text', style: { underline: true }, matchStart, matchEnd, inner: full.slice(1, full.length - 2) };\n }\n if (rule.type === 'STRIKETHROUGH') {\n return {\n kind: 'text',\n style: { strikethrough: true },\n matchStart,\n matchEnd,\n inner: full.slice(2, full.length - 3)\n };\n }\n }\n return null;\n}\n\nexport function shouldTryMarkdown(inserted: string): boolean {\n if (!inserted) return false;\n const ch = inserted[inserted.length - 1];\n return ch === ' ' || ch === '-' || ch === '*' || ch === '`' || ch === '$';\n}\n","/**\n * 文档模型 —— 状态本身,不含任何编辑语义。\n *\n * 这一层只做两件事:\n * 1. **读**。给上层提供「index 处的文字属性是什么」「这段字符流长什么样」之类的查询。\n * 2. **落地 mutation**。四个 `apply*` 方法是 mutation applier 唯一的着陆点,\n * 它们是机械动作:挪坐标、写字段,不做判断、不推导、不补救。\n *\n * 「打字要继承左边的样式」「删掉段分隔符后段落边界要重算」这类判断一律不在这里,\n * 而在 Operation 层(src/operations/)。模型不偷偷改自己,是撤销和协同能对上账的前提。\n *\n * fragment(同步块)的增删也走 mutation:addFragment / deleteFragment 落到\n * applyAddFragment / applyDeleteFragment 上,和 entity 一样按 id 寻址、不占坐标空间。\n */\nimport { findParagraphAt, findTableAt, parseBlocks } from './blocks';\nimport { isTableMarker, MARKERS } from './markers';\nimport { cloneFragment, normalizeFragmentSlice, previewTitle } from './fragment';\nimport {\n cloneEntity,\n cloneStyle,\n cloneVirtualBlock,\n DEFAULT_PARAGRAPH,\n Fragment,\n ImageEntity,\n ImageProps,\n ParagraphProps,\n Selection,\n Slice,\n StyleSpan,\n StyleType,\n TableProps,\n TextProps,\n textPropsEqual,\n VirtualBlock\n} from './types';\nimport {\n clipVirtualBlocks,\n shiftVirtualBlocksOnDelete,\n shiftVirtualBlocksOnInsert,\n sortOuterToInner\n} from './virtualBlock';\n\nlet entitySeq = 1;\nlet fragmentSeq = 1;\nlet virtualBlockSeq = 1;\n\nexport function nextEntityId(): string {\n return `emb_${entitySeq++}`;\n}\n\nexport function nextFragmentId(): string {\n return `frag_${fragmentSeq++}`;\n}\n\nexport function nextVirtualBlockId(): string {\n return `vb_${virtualBlockSeq++}`;\n}\n\nexport type DocSnapshot = {\n spacers: string;\n styles: StyleSpan[];\n entities: ImageEntity[];\n fragments: Fragment[];\n virtualBlocks: VirtualBlock[];\n};\n\nexport class DocumentModel {\n spacers = '\\n';\n styles: StyleSpan[] = [{ start: 0, end: 1, type: 'paragraph', props: { ...DEFAULT_PARAGRAPH } }];\n entities = new Map<string, ImageEntity>();\n fragments = new Map<string, Fragment>();\n virtualBlocks = new Map<string, VirtualBlock>();\n private fragmentModels = new Map<string, DocumentModel>();\n\n constructor(initial?: {\n spacers: string;\n styles: StyleSpan[];\n entities?: ImageEntity[];\n fragments?: Fragment[];\n virtualBlocks?: VirtualBlock[];\n }) {\n if (initial) {\n this.spacers = initial.spacers;\n this.styles = initial.styles.map(cloneStyle);\n this.entities = new Map((initial.entities ?? []).map((e) => [e.id, cloneEntity(e)]));\n this.fragments = new Map((initial.fragments ?? []).map((f) => [f.id, cloneFragment(f)]));\n this.virtualBlocks = new Map((initial.virtualBlocks ?? []).map((b) => [b.id, cloneVirtualBlock(b)]));\n }\n }\n\n /** 未写 text span 时的默认字号/颜色。嵌入式输入框可覆盖文档编辑器的 16px 默认。 */\n textDefaults: TextProps | null = null;\n\n get length(): number {\n return this.spacers.length;\n }\n\n clamp(index: number): number {\n return Math.max(0, Math.min(index, this.spacers.length));\n }\n\n // ---- mutation 落地点 ----------------------------------------------------\n // 只给 mutation applier 用。别的地方要改文档,请发 mutation。\n\n /** insertSpacers 的落地:插入字符,已有样式区间跟着挪。 */\n applyInsertSpacers(index: number, text: string) {\n if (!text) return;\n const i = this.clamp(index);\n this.spacers = this.spacers.slice(0, i) + text + this.spacers.slice(i);\n this.styles = shiftStylesOnInsert(this.styles, i, text.length);\n this.replaceVirtualBlocks(shiftVirtualBlocksOnInsert(this.virtualBlocks.values(), i, text.length));\n }\n\n /** deleteSpacers 的落地(半开区间):删字符,样式区间跟着裁剪与前挪。 */\n applyDeleteSpacers(start: number, end: number) {\n const from = this.clamp(Math.min(start, end));\n const to = this.clamp(Math.max(start, end));\n if (to <= from) return;\n this.spacers = this.spacers.slice(0, from) + this.spacers.slice(to);\n this.styles = shiftStylesOnDelete(this.styles, from, to);\n this.replaceVirtualBlocks(shiftVirtualBlocksOnDelete(this.virtualBlocks.values(), from, to));\n }\n\n /** addVirtualBlock 的落地:同 id 则整体替换。 */\n applyAddVirtualBlock(block: VirtualBlock) {\n this.virtualBlocks.set(block.id, cloneVirtualBlock(block));\n }\n\n applyDeleteVirtualBlock(blockId: string) {\n this.virtualBlocks.delete(blockId);\n }\n\n applyUpdateVirtualBlock(blockId: string, block: VirtualBlock) {\n if (!this.virtualBlocks.has(blockId)) return;\n this.virtualBlocks.set(blockId, cloneVirtualBlock({ ...block, id: blockId }));\n }\n\n /**\n * applyStyle 的落地(半开区间):把某类样式在这段里整体换成给定的一组区间。\n * 语义是**覆盖**不是合并补丁,所以传进来的 props 必须已经解析完整。\n */\n /** addFragment 的落地:把整份 fragment 写入。已打开过的派生模型作废重建。 */\n applyAddFragment(fragment: Fragment) {\n this.fragments.set(fragment.id, cloneFragment(fragment));\n this.fragmentModels.delete(fragment.id);\n }\n\n /** deleteFragment 的落地:移除 fragment 及其派生模型。 */\n applyDeleteFragment(fragmentId: string) {\n this.fragments.delete(fragmentId);\n this.fragmentModels.delete(fragmentId);\n }\n\n applyStyleSpans(type: StyleType, start: number, end: number, next: StyleSpan[]) {\n // 横跨区间边界的区间要在边界处裁开保留两头,不能整条抹掉。\n const kept: StyleSpan[] = [];\n for (const s of this.styles) {\n if (s.type !== type || s.end <= start || s.start >= end) {\n kept.push(s);\n continue;\n }\n if (s.start < start) kept.push(cloneStyle({ ...s, start: s.start, end: start }));\n if (s.end > end) kept.push(cloneStyle({ ...s, start: end, end: s.end }));\n }\n this.styles = kept.concat(next.map(cloneStyle));\n this.mergeStyles();\n }\n\n // ---- 快照 --------------------------------------------------------------\n\n snapshot(): DocSnapshot {\n for (const id of this.fragmentModels.keys()) this.syncFragment(id);\n return {\n spacers: this.spacers,\n styles: this.styles.map(cloneStyle),\n entities: [...this.entities.values()].map(cloneEntity),\n fragments: [...this.fragments.values()].map(cloneFragment),\n virtualBlocks: this.listVirtualBlocks()\n };\n }\n\n restore(snap: DocSnapshot) {\n this.spacers = snap.spacers;\n this.styles = snap.styles.map(cloneStyle);\n this.entities = new Map(snap.entities.map((e) => [e.id, cloneEntity(e)]));\n this.fragments = new Map((snap.fragments ?? []).map((f) => [f.id, cloneFragment(f)]));\n this.virtualBlocks = new Map((snap.virtualBlocks ?? []).map((b) => [b.id, cloneVirtualBlock(b)]));\n this.fragmentModels.clear();\n }\n\n // ---- 读 ----------------------------------------------------------------\n\n /** 取半开区间 [start, end) 的内容副本,含落在里面的实体与它们引用的同步块。 */\n takeSlice(start: number, end: number): Slice {\n const from = this.clamp(Math.min(start, end));\n const to = this.clamp(Math.max(start, end));\n const text = this.spacers.slice(from, to);\n const styles = this.styles\n .filter((s) => s.end > from && s.start < to)\n .map((s) => ({\n ...cloneStyle(s),\n start: Math.max(0, s.start - from),\n end: Math.min(s.end, to) - from\n }))\n .filter((s) => s.end > s.start);\n const entities: ImageEntity[] = [];\n const fragmentIds = new Set<string>();\n for (const s of this.styles) {\n if (s.type === 'image' && s.start >= from && s.end <= to) {\n const id = (s.props as { entityId: string }).entityId;\n const e = this.entities.get(id);\n if (e) {\n entities.push(cloneEntity(e));\n if (e.kind === 'ref' && e.fragmentId) fragmentIds.add(e.fragmentId);\n }\n }\n }\n const fragments = [...fragmentIds]\n .map((id) => this.fragments.get(id))\n .filter((f): f is Fragment => !!f)\n .map(cloneFragment);\n const virtualBlocks = clipVirtualBlocks(this.virtualBlocks.values(), from, to);\n return { text, styles, entities, fragments, virtualBlocks };\n }\n\n /**\n * 读出某类样式在半开区间 [start, end) 内的分布,边缘按区间裁剪。\n * 求 applyStyle 的逆操作时用来记录「原来长什么样」。\n */\n styleSpansOver(type: StyleType, start: number, end: number): StyleSpan[] {\n return this.styles\n .filter((s) => s.type === type && s.start < end && s.end > start)\n .map((s) => cloneStyle({ ...s, start: Math.max(s.start, start), end: Math.min(s.end, end) }))\n .filter((s) => s.end > s.start)\n .sort((a, b) => a.start - b.start);\n }\n\n imageAt(index: number): ImageEntity | null {\n const span = this.imageSpanAt(index);\n if (!span) return null;\n return this.entities.get((span.props as { entityId: string }).entityId) ?? null;\n }\n\n imageSpanAt(index: number): StyleSpan | null {\n return this.styles.find((s) => s.type === 'image' && s.start <= index && index < s.end) ?? null;\n }\n\n textPropsAt(index: number): TextProps {\n const i = this.clamp(index);\n const probe = i > 0 ? i - 1 : i;\n const span = this.styles.find((s) => s.type === 'text' && s.start <= probe && probe < s.end);\n return span ? { ...(span.props as TextProps) } : {};\n }\n\n paragraphPropsAt(index: number): ParagraphProps {\n const para = findParagraphAt(this.spacers, index);\n if (!para) return { ...DEFAULT_PARAGRAPH };\n const span =\n this.styles.find((s) => s.type === 'paragraph' && s.start === para.start && s.end === para.end) ??\n this.styles.find((s) => s.type === 'paragraph' && s.start < para.end && s.end > para.start);\n return { ...DEFAULT_PARAGRAPH, ...(span?.props as ParagraphProps | undefined) };\n }\n\n linkSpanAt(index: number): StyleSpan | null {\n const i = this.clamp(index);\n const probe = i > 0 ? i - 1 : i;\n return this.styles.find((s) => s.type === 'link' && s.start <= probe && probe < s.end) ?? null;\n }\n\n linkUrlAt(index: number): string | null {\n const span = this.linkSpanAt(index);\n return span ? (span.props as { url: string }).url : null;\n }\n\n tablePropsAt(index: number): TableProps {\n const table = findTableAt(this.spacers, index);\n if (!table) return {};\n const span = this.styles.find((s) => s.type === 'table' && s.start <= table.start && s.end >= table.end);\n return { ...(span?.props as TableProps | undefined) };\n }\n\n /** 半开区间 [start, end) 的可读文本,结构标记被剔除,图片算一个空格。 */\n plainText(start: number, end: number): string {\n const from = this.clamp(Math.min(start, end));\n const to = this.clamp(Math.max(start, end));\n let out = '';\n for (let i = from; i < to; i++) {\n const ch = this.spacers[i];\n if (ch === MARKERS.IMAGE) out += ' ';\n else if (!isTableMarker(ch)) out += ch;\n }\n return out;\n }\n\n // ---- 同步块 ------------------------------------------------------------\n\n /**\n * 构造一份新的 fragment(分配 id、规范化 slice),但**不写模型**。\n * 落地由 addFragment mutation 完成,这样提取同步块能进撤销栈、走协同。\n */\n buildFragment(slice: Slice, title?: string): Fragment {\n const normalized = normalizeFragmentSlice(slice);\n return { id: nextFragmentId(), title: title || previewTitle(normalized), slice: normalized };\n }\n\n ensureFragmentModel(id: string): DocumentModel {\n let model = this.fragmentModels.get(id);\n if (model) return model;\n const fragment = this.fragments.get(id);\n model = documentFromSlice(fragment?.slice ?? { text: MARKERS.PARAGRAPH, styles: [], entities: [] });\n this.fragmentModels.set(id, model);\n return model;\n }\n\n syncFragment(id: string) {\n const model = this.fragmentModels.get(id);\n const fragment = this.fragments.get(id);\n if (!model || !fragment) return;\n fragment.slice = sliceFromDocument(model);\n fragment.title = previewTitle(fragment.slice);\n }\n\n listFragments(): Fragment[] {\n for (const id of this.fragmentModels.keys()) this.syncFragment(id);\n return [...this.fragments.values()].map(cloneFragment);\n }\n\n refIndices(fragmentId: string): number[] {\n const hits: number[] = [];\n for (let i = 0; i < this.spacers.length; i++) {\n if (this.spacers[i] !== MARKERS.IMAGE) continue;\n if (this.imageAt(i)?.fragmentId === fragmentId) hits.push(i);\n }\n return hits;\n }\n\n refCount(fragmentId: string): number {\n return this.refIndices(fragmentId).length;\n }\n\n rangeHasRef(start: number, end: number): boolean {\n const from = this.clamp(Math.min(start, end));\n const to = this.clamp(Math.max(start, end));\n for (let i = from; i < to; i++) {\n if (this.spacers[i] === MARKERS.IMAGE && this.imageAt(i)?.kind === 'ref') return true;\n }\n return false;\n }\n\n // ---- 虚拟块 ------------------------------------------------------------\n\n listVirtualBlocks(): VirtualBlock[] {\n return sortOuterToInner([...this.virtualBlocks.values()], this.virtualBlocks);\n }\n\n blockById(id: string): VirtualBlock | null {\n const block = this.virtualBlocks.get(id);\n return block ? cloneVirtualBlock(block) : null;\n }\n\n /** 覆盖下标 i 的虚拟块,外层在前。 */\n blocksAt(index: number): VirtualBlock[] {\n const i = this.clamp(index);\n const hits = [...this.virtualBlocks.values()].filter((b) => b.start <= i && i < b.end);\n return sortOuterToInner(hits, this.virtualBlocks).map(cloneVirtualBlock);\n }\n\n virtualBlocksOverlapping(start: number, end: number): VirtualBlock[] {\n const from = this.clamp(Math.min(start, end));\n const to = this.clamp(Math.max(start, end));\n return [...this.virtualBlocks.values()]\n .filter((b) => b.start < to && b.end > from)\n .map(cloneVirtualBlock);\n }\n\n innermostSlotAt(index: number): VirtualBlock | null {\n const hits = this.blocksAt(index);\n for (let i = hits.length - 1; i >= 0; i--) {\n if (hits[i].kind === 'virtualSlot') return hits[i];\n }\n return null;\n }\n\n /** 含槽尾光标:`start <= i <= end` 的最内层 slot。 */\n slotAtCaret(index: number): VirtualBlock | null {\n const i = this.clamp(index);\n const inside = this.innermostSlotAt(i);\n if (inside) return inside;\n const ending = [...this.virtualBlocks.values()].filter((b) => b.kind === 'virtualSlot' && b.end === i);\n if (!ending.length) return null;\n const sorted = sortOuterToInner(ending, this.virtualBlocks);\n return cloneVirtualBlock(sorted[sorted.length - 1]);\n }\n\n private replaceVirtualBlocks(next: VirtualBlock[]) {\n this.virtualBlocks = new Map(next.map((b) => [b.id, cloneVirtualBlock(b)]));\n }\n\n // ---- 构造期整理 ---------------------------------------------------------\n\n /**\n * 把 paragraph 区间对齐到块结构。\n *\n * 只在**构造**文档时用(从切片建模型、从磁盘读文档)。编辑过程中的对齐是\n * Operation 层的 normalizeParagraphs,走 mutation,因为它必须能被撤销。\n */\n normalize() {\n const needed: StyleSpan[] = [];\n const ensure = (start: number, end: number): StyleSpan => {\n const existing =\n this.styles.find((s) => s.type === 'paragraph' && s.start === start && s.end === end) ??\n this.styles.find((s) => s.type === 'paragraph' && s.start < end && s.end > start && s.start >= start);\n return {\n start,\n end,\n type: 'paragraph',\n props: { ...DEFAULT_PARAGRAPH, ...(existing?.props as ParagraphProps | undefined) }\n };\n };\n for (const block of parseBlocks(this.spacers)) {\n if (block.kind === 'paragraph') {\n needed.push(ensure(block.start, block.end));\n } else {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const para of cell.paragraphs) {\n if (para.end > para.start) needed.push(ensure(para.start, para.end));\n }\n }\n }\n }\n }\n this.styles = this.styles.filter((s) => s.type !== 'paragraph').concat(needed);\n this.mergeStyles();\n }\n\n /** 排序 + 合并相邻且属性相同的文字区间。纯粹的规范化,不改变可见结果。 */\n private mergeStyles() {\n this.styles.sort((a, b) => a.start - b.start || a.end - b.end || a.type.localeCompare(b.type));\n const merged: StyleSpan[] = [];\n for (const s of this.styles) {\n if (s.end <= s.start) continue;\n const last = merged[merged.length - 1];\n // 段落/表格/图片区间不能跨块合并,否则回车后精确匹配失败会掉回正文。\n if (\n last &&\n last.type === 'text' &&\n s.type === 'text' &&\n last.end === s.start &&\n textPropsEqual(last.props as TextProps, s.props as TextProps)\n ) {\n last.end = s.end;\n } else {\n merged.push(s);\n }\n }\n this.styles = merged;\n }\n}\n\nexport function shiftStylesOnInsert(styles: StyleSpan[], index: number, len: number): StyleSpan[] {\n return styles.map((s) => {\n if (s.end <= index) return s;\n if (s.start >= index) return { ...s, start: s.start + len, end: s.end + len };\n return { ...s, end: s.end + len };\n });\n}\n\nexport function shiftStylesOnDelete(styles: StyleSpan[], start: number, end: number): StyleSpan[] {\n const len = end - start;\n const out: StyleSpan[] = [];\n for (const s of styles) {\n if (s.end <= start) {\n out.push(s);\n } else if (s.start >= end) {\n out.push({ ...s, start: s.start - len, end: s.end - len });\n } else if (s.start < start && s.end > end) {\n out.push({ ...s, start: s.start, end: s.end - len });\n } else if (s.start < start) {\n if (start > s.start) out.push({ ...s, start: s.start, end: start });\n } else if (s.end > end) {\n out.push({ ...s, start, end: s.end - len });\n }\n }\n return out.filter((s) => s.end > s.start);\n}\n\nexport function collapsedSel(index: number): Selection {\n return { anchor: index, focus: index };\n}\n\nexport function documentFromSlice(slice: Slice): DocumentModel {\n const normalized = normalizeFragmentSlice(slice);\n const doc = new DocumentModel();\n doc.spacers = normalized.text || MARKERS.PARAGRAPH;\n doc.styles = normalized.styles.map(cloneStyle);\n doc.entities = new Map(normalized.entities.map((e) => [e.id, cloneEntity(e)]));\n doc.virtualBlocks = new Map((normalized.virtualBlocks ?? []).map((b) => [b.id, cloneVirtualBlock(b)]));\n if (!doc.styles.some((s) => s.type === 'paragraph')) {\n doc.styles.push({ start: 0, end: doc.spacers.length, type: 'paragraph', props: { ...DEFAULT_PARAGRAPH } });\n }\n doc.normalize();\n return doc;\n}\n\nexport function sliceFromDocument(doc: DocumentModel): Slice {\n return {\n text: doc.spacers,\n styles: doc.styles.map(cloneStyle),\n entities: [...doc.entities.values()].map(cloneEntity),\n virtualBlocks: doc.listVirtualBlocks()\n };\n}\n\n/** 去掉指定 groupId 的段落,留下其余内容。 */\nexport function sliceWithoutParagraphGroup(doc: DocumentModel, groupId: string): Slice {\n const id = groupId.trim();\n const keep: { start: number; end: number }[] = [];\n for (const block of parseBlocks(doc.spacers)) {\n if (block.kind === 'table') {\n keep.push({ start: block.start, end: block.end });\n continue;\n }\n if ((doc.paragraphPropsAt(block.start).groupId ?? '') !== id) {\n keep.push({ start: block.start, end: block.end });\n }\n }\n if (!keep.length) {\n return { text: MARKERS.PARAGRAPH, styles: [], entities: [] };\n }\n let text = '';\n const styles: StyleSpan[] = [];\n const entities: ImageEntity[] = [];\n for (const range of keep) {\n const offset = text.length;\n text += doc.spacers.slice(range.start, range.end);\n for (const span of doc.styles) {\n if (span.end <= range.start || span.start >= range.end) continue;\n const start = Math.max(span.start, range.start) - range.start + offset;\n const end = Math.min(span.end, range.end) - range.start + offset;\n if (end <= start) continue;\n if (span.type === 'image') {\n const entityId = (span.props as ImageProps).entityId;\n const entity = entityId ? doc.entities.get(entityId) : undefined;\n if (!entity) continue;\n const next = cloneEntity({ ...entity, id: nextEntityId() });\n entities.push(next);\n styles.push({ start, end, type: 'image', props: { entityId: next.id } });\n continue;\n }\n styles.push({ start, end, type: span.type, props: { ...span.props } });\n }\n }\n if (!text.endsWith(MARKERS.PARAGRAPH)) text += MARKERS.PARAGRAPH;\n return { text, styles, entities };\n}\n","/**\n * 实体类 Operation:图片、公式、代码块、槽位、同步块引用。\n *\n * 实体本身存在 id → 实体的表里,字符流上只留一个 IMAGE 占位符,\n * 由一条 image 样式区间把占位符和实体 id 绑起来。插一个实体因此是三条 mutation。\n */\nimport { cloneEntity, ImageEntity } from '../model/types';\nimport { MARKERS } from '../model/markers';\nimport { addEntity, updateEntity } from '../mutations';\nimport { nextEntityId } from '../model/document';\nimport { Operation } from './context';\nimport { emitInsert, emitStyle } from './primitives';\n\nexport type NewEntity = Omit<ImageEntity, 'id' | 'kind'> & { id?: string; kind?: ImageEntity['kind'] };\n\n/** 在 index 处插入一个实体,返回占位符之后的位置。 */\nexport function insertImage(index: number, entity: NewEntity): Operation<number> {\n return (ctx) => {\n const i = ctx.doc.clamp(index);\n const full = cloneEntity({\n ...entity,\n id: entity.id ?? nextEntityId(),\n kind: entity.kind ?? 'image'\n } as ImageEntity);\n ctx.emit(addEntity(full));\n emitInsert(ctx, i, MARKERS.IMAGE);\n emitStyle(ctx, 'image', i, i + 1, { entityId: full.id });\n return i + 1;\n };\n}\n\nexport type ImagePatch = Partial<\n Pick<\n ImageEntity,\n | 'width'\n | 'height'\n | 'code'\n | 'language'\n | 'latex'\n | 'src'\n | 'displayMode'\n | 'slotKind'\n | 'label'\n | 'slotValue'\n | 'slotOptions'\n | 'data'\n | 'hostType'\n >\n>;\n\n/** 改实体属性。undefined 的字段代表「不动」,在这里就剔掉,别让它盖掉原值。 */\nexport function updateImage(id: string, patch: ImagePatch): Operation {\n return (ctx) => {\n if (!ctx.doc.entities.has(id)) return;\n const props: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(patch)) {\n if (v !== undefined) props[k] = v;\n }\n if (!Object.keys(props).length) return;\n ctx.emit(updateEntity(id, props as ImagePatch));\n };\n}\n","/**\n * 虚拟块 Operation:套皮、拆皮、清槽、填槽、插入后盖住新字。\n *\n * 嵌套合法性在这里判断,通过才发 mutation。插删字符对区间的机械挪动在\n * applier 里,但清槽会把覆盖整段删掉(块被表里摘掉),所以这里要按快照补回。\n */\nimport { chromeTextProps, hasTextProps, TextProps, VirtualBlock, VirtualBlockChrome, VirtualBlockKind } from '../model/types';\nimport { ancestorChain, rangeContains, rangesCross, sortOuterToInner } from '../model/virtualBlock';\nimport { nextVirtualBlockId } from '../model/document';\nimport { addVirtualBlock, deleteVirtualBlock, updateVirtualBlock } from '../mutations';\nimport { Operation } from './context';\nimport { emitDelete, emitInsert, emitTextStyle } from './primitives';\nimport { resolveTextProps } from './resolve';\n\nexport interface VirtualBlockSpec {\n id?: string;\n parentId?: string | null;\n kind: VirtualBlockKind;\n start: number;\n end: number;\n chrome?: VirtualBlockChrome;\n placeholder?: string;\n empty?: boolean;\n}\n\nfunction blockMap(doc: { virtualBlocks: Map<string, VirtualBlock> }) {\n return doc.virtualBlocks;\n}\n\nexport function validateInsert(doc: { virtualBlocks: Map<string, VirtualBlock> }, block: VirtualBlock): string | null {\n if (block.end <= block.start) return 'empty-range';\n // mark 是纯样式叠层:不进区间树,也不受嵌套/交叉约束。\n if (block.kind === 'mark') return null;\n if (block.parentId) {\n const parent = doc.virtualBlocks.get(block.parentId);\n if (!parent) return 'missing-parent';\n if (!rangeContains(parent, block)) return 'outside-parent';\n if (parent.kind === 'virtualSlot') return 'virtualSlot-parent';\n }\n for (const other of doc.virtualBlocks.values()) {\n if (other.id === block.id || other.kind === 'mark') continue;\n if (rangesCross(block, other)) return 'cross';\n }\n if (block.kind === 'virtualSlot') {\n for (const other of doc.virtualBlocks.values()) {\n if (other.id === block.id || other.kind === 'mark') continue;\n if (other.parentId === block.id) return 'slot-child';\n if (rangeContains(block, other) && other.id !== block.parentId) return 'slot-child';\n }\n }\n return null;\n}\n\nfunction inferParentId(\n doc: { virtualBlocks: Map<string, VirtualBlock> },\n start: number,\n end: number,\n selfId?: string\n): string | null {\n const range = { start, end };\n let best: VirtualBlock | null = null;\n for (const b of doc.virtualBlocks.values()) {\n if (selfId && b.id === selfId) continue;\n if (b.kind === 'mark') continue;\n if (!rangeContains(b, range)) continue;\n if (!best || b.end - b.start < best.end - best.start) best = b;\n }\n return best?.id ?? null;\n}\n\n/**\n * 把 [start, end) 包成一层皮。不改字。\n * 完全落在新区间里的已有块会改挂到这一层下面。\n */\nexport function insertVirtualBlock(spec: VirtualBlockSpec): Operation<string | null> {\n return (ctx) => {\n const doc = ctx.doc;\n const start = doc.clamp(Math.min(spec.start, spec.end));\n const end = doc.clamp(Math.max(spec.start, spec.end));\n if (end <= start) return null;\n\n const id = spec.id && !doc.virtualBlocks.has(spec.id) ? spec.id : nextVirtualBlockId();\n const parentId =\n spec.kind === 'mark' ? null : spec.parentId !== undefined ? spec.parentId : inferParentId(doc, start, end, id);\n const placeholder =\n spec.kind === 'virtualSlot' ? spec.placeholder ?? doc.spacers.slice(start, end) : spec.placeholder;\n const empty =\n spec.kind === 'virtualSlot' ? spec.empty ?? (placeholder != null && doc.spacers.slice(start, end) === placeholder) : spec.empty;\n const block: VirtualBlock = {\n id,\n parentId,\n kind: spec.kind,\n start,\n end,\n chrome: { ...(spec.chrome ?? {}) },\n placeholder,\n empty\n };\n const err = validateInsert(doc, block);\n if (err) return null;\n\n ctx.emit(addVirtualBlock(block));\n for (const child of [...doc.virtualBlocks.values()]) {\n if (child.id === id || child.kind === 'mark' || block.kind === 'mark') continue;\n if (child.parentId === parentId && rangeContains(block, child) && child.id !== id) {\n ctx.emit(updateVirtualBlock(child.id, { ...child, parentId: id }));\n }\n }\n return id;\n };\n}\n\n/** 拆掉皮,字和胶囊留下。子块改挂到被拆掉那一层的父上。 */\nexport function removeVirtualBlock(id: string): Operation<boolean> {\n return (ctx) => {\n const block = ctx.doc.blockById(id);\n if (!block) return false;\n for (const child of ctx.doc.listVirtualBlocks()) {\n if (child.parentId === id) {\n ctx.emit(updateVirtualBlock(child.id, { ...child, parentId: block.parentId }));\n }\n }\n ctx.emit(deleteVirtualBlock(id));\n return true;\n };\n}\n\nexport function updateVirtualBlockChrome(id: string, chrome: VirtualBlockChrome): Operation<boolean> {\n return (ctx) => {\n const block = ctx.doc.blockById(id);\n if (!block) return false;\n ctx.emit(updateVirtualBlock(id, { ...block, chrome: { ...block.chrome, ...chrome } }));\n return true;\n };\n}\n\nfunction restoreChain(\n ctx: { doc: { blockById(id: string): VirtualBlock | null }; emit(m: import('../mutations').Mutation): void },\n snaps: VirtualBlock[],\n targetId: string,\n nextStart: number,\n nextEnd: number,\n empty: boolean\n) {\n for (const snap of snaps) {\n const isTarget = snap.id === targetId;\n const cur = ctx.doc.blockById(snap.id);\n let next: VirtualBlock;\n if (isTarget) {\n next = { ...snap, start: nextStart, end: nextEnd, empty };\n } else if (cur) {\n next = {\n ...cur,\n start: Math.min(cur.start, nextStart),\n end: Math.max(cur.end, nextEnd)\n };\n } else {\n next = { ...snap, start: nextStart, end: nextEnd };\n }\n if (cur) ctx.emit(updateVirtualBlock(snap.id, next));\n else ctx.emit(addVirtualBlock(next));\n }\n}\n\n/** 把槽内容换成 placeholder,empty=true。槽和父块都留下。 */\nexport function clearSlot(id: string): Operation<boolean> {\n return (ctx) => {\n const block = ctx.doc.blockById(id);\n if (!block || block.kind !== 'virtualSlot') return false;\n const placeholder = block.placeholder ?? '';\n if (!placeholder) return false;\n const from = block.start;\n const to = block.end;\n const snaps = ancestorChain(block, blockMap(ctx.doc));\n emitDelete(ctx, from, to);\n emitInsert(ctx, from, placeholder);\n restoreChain(ctx, snaps, id, from, from + placeholder.length, true);\n return true;\n };\n}\n\n/** 槽是行内区间:去掉尾部换行,中间的段分隔折成空格。 */\nexport function slotInlineText(text: string): string {\n return text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n').replace(/\\n+$/, '').replace(/\\n+/g, ' ');\n}\n\n/**\n * empty 时覆盖 placeholder;已填则整段替换。一次事务。\n * 返回新光标(槽尾)。槽内不进段分隔符。\n */\nexport function fillSlot(id: string, text: string, inherit?: TextProps): Operation<number | null> {\n return (ctx) => {\n const block = ctx.doc.blockById(id);\n if (!block || block.kind !== 'virtualSlot') return null;\n const safe = slotInlineText(text);\n const from = block.start;\n const to = block.end;\n const snaps = ancestorChain(block, blockMap(ctx.doc));\n const left = inherit ?? {\n ...resolveTextProps(ctx.doc, from),\n ...chromeTextProps(block.chrome)\n };\n emitDelete(ctx, from, to);\n if (safe) emitInsert(ctx, from, safe);\n const end = from + safe.length;\n const empty = safe.length === 0 || safe === (block.placeholder ?? '');\n restoreChain(ctx, snaps, id, from, end, empty && !!block.placeholder);\n if (safe && left && hasTextProps(left)) emitTextStyle(ctx, from, end, left);\n return end;\n };\n}\n\n/** 按 id 找到槽/块,连祖先一起撑开盖住 [start, end)。 */\nexport function coverAncestorsOf(id: string, start: number, end: number): Operation<void> {\n return (ctx) => {\n const block = ctx.doc.blockById(id);\n if (!block) return;\n const ids = [id];\n let pid = block.parentId;\n const seen = new Set(ids);\n while (pid && !seen.has(pid)) {\n seen.add(pid);\n ids.push(pid);\n pid = ctx.doc.blockById(pid)?.parentId ?? null;\n }\n coverVirtualBlocks(ids, start, end)(ctx);\n };\n}\n\n/** 插入后把指定块(及仍在的祖先)撑开盖住 [start, end)。 */\nexport function coverVirtualBlocks(ids: string[], start: number, end: number): Operation<void> {\n return (ctx) => {\n const unique = [...new Set(ids)];\n const blocks = unique\n .map((id) => ctx.doc.blockById(id))\n .filter((b): b is VirtualBlock => !!b);\n for (const b of sortOuterToInner(blocks, blockMap(ctx.doc))) {\n const next: VirtualBlock = {\n ...b,\n start: Math.min(b.start, start),\n end: Math.max(b.end, end),\n empty: b.kind === 'virtualSlot' ? false : b.empty\n };\n if (next.start !== b.start || next.end !== b.end || next.empty !== b.empty) {\n ctx.emit(updateVirtualBlock(b.id, next));\n }\n }\n };\n}\n\nexport function remapIncomingVirtualBlocks(\n blocks: VirtualBlock[],\n offset: number,\n occupied: Set<string>\n): VirtualBlock[] {\n if (!blocks.length) return [];\n const idMap = new Map<string, string>();\n for (const b of blocks) {\n let id = b.id;\n if (!id || occupied.has(id) || idMap.has(id)) {\n id = nextVirtualBlockId();\n }\n idMap.set(b.id, id);\n occupied.add(id);\n }\n const remapped = blocks.map((b) => ({\n ...b,\n id: idMap.get(b.id)!,\n parentId: b.parentId ? (idMap.get(b.parentId) ?? null) : null,\n start: b.start + offset,\n end: b.end + offset,\n chrome: { ...b.chrome }\n }));\n return sortOuterToInner(remapped, new Map(remapped.map((b) => [b.id, b])));\n}\n\n/**\n * 在 index 处插入了 text 之后,把「恰好在 index 结束」的 mark 向右撑开,\n * 让右边缘继续输入算区间内;遇到换行就断(只撑到第一个 \\n 之前)。\n * 插入本身已由调用方 emit,这里只补区间。\n */\nexport function extendMarksAtEnd(index: number, text: string): Operation<void> {\n return (ctx) => {\n if (!text || text.startsWith('\\n')) return;\n const nl = text.indexOf('\\n');\n const len = nl === -1 ? text.length : nl;\n for (const b of ctx.doc.listVirtualBlocks()) {\n if (b.kind !== 'mark' || b.end !== index) continue;\n ctx.emit(updateVirtualBlock(b.id, { ...b, end: b.end + len }));\n }\n };\n}\n","/**\n * 字符流类 Operation:打字、回车、退格、删除、Markdown 快捷输入。\n *\n * 这一组的共性是「插删字符会改变段落边界」,所以每个操作在动完字符流之后\n * 都要把段落区间重新对齐 —— 而且对齐动作本身也是 mutation,不是模型的暗箱。\n */\nimport { expandRangeOverStructures, findParagraphAt, findTableAt, isEmptyParagraph, parseBlocks } from '../model/blocks';\nimport { isTableMarker, MARKERS, nextCodePointLen, prevCodePointLen } from '../model/markers';\nimport { DEFAULT_PARAGRAPH, hasTextProps, ParagraphProps, Slice, TextProps } from '../model/types';\nimport { applyStyle, multi } from '../mutations';\nimport { matchMarkdown } from '../convert/markdown';\nimport { Operation, OperationContext } from './context';\nimport { emitDelete, emitInsert, emitTextStyle, normalizeParagraphs } from './primitives';\nimport { contentRuns, resolveParagraphProps, resolveTextProps } from './resolve';\nimport { applyParagraphStyle, applyTextStyle } from './style';\nimport { insertImage } from './entity';\nimport { coverAncestorsOf, extendMarksAtEnd, fillSlot } from './virtualBlock';\n\nconst EMPTY_SLICE: Slice = { text: '', styles: [], entities: [] };\n\nfunction isLastParagraphWithGroupId(\n doc: { spacers: string; paragraphPropsAt: (i: number) => ParagraphProps },\n paraStart: number,\n groupId: string\n): boolean {\n if (!groupId) return false;\n let last = -1;\n for (const block of parseBlocks(doc.spacers)) {\n if (block.kind !== 'paragraph') continue;\n if ((doc.paragraphPropsAt(block.start).groupId ?? '') === groupId) last = block.start;\n }\n return last === paraStart;\n}\n\n/**\n * 插入的文本里带换行时,被劈开的那个段落要变成两段,且两段都继承原属性。\n * 光靠 normalizeParagraphs 推不出来 —— 它只能让后半段回落到默认属性。\n */\nfunction splitParagraphSpans(ctx: OperationContext, index: number, text: string) {\n if (!text.includes('\\n')) return;\n let cursor = index;\n for (const ch of text) {\n if (ch === '\\n') {\n const para = findParagraphAt(ctx.doc.spacers, cursor);\n if (para && para.start < cursor + 1 && para.end > cursor + 1) {\n const props = resolveParagraphProps(ctx.doc, para.start);\n ctx.emit(\n multi([\n applyStyle('paragraph', para.start, para.end - 1, null),\n applyStyle('paragraph', para.start, cursor, { ...props }),\n applyStyle('paragraph', cursor + 1, para.end - 1, { ...props })\n ])\n );\n }\n }\n cursor += ch.length;\n }\n}\n\n/** 在 index 处插入文本,继承左侧文字样式(或调用方指定的样式)。返回新光标位置。 */\nexport function insertText(index: number, text: string, inherit?: TextProps): Operation<number> {\n return (ctx) => {\n if (!text) return ctx.doc.clamp(index);\n const safe = text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n const i = ctx.doc.clamp(index);\n const slot = ctx.doc.slotAtCaret(i);\n if (slot?.empty) {\n const end = fillSlot(slot.id, safe, inherit)(ctx);\n return end ?? i;\n }\n const left = inherit ?? resolveTextProps(ctx.doc, i);\n\n emitInsert(ctx, i, safe);\n extendMarksAtEnd(i, safe)(ctx);\n splitParagraphSpans(ctx, i, safe);\n if (left && hasTextProps(left)) {\n for (const [a, b] of contentRuns(safe, i)) emitTextStyle(ctx, a, b, left);\n }\n if (slot) coverAncestorsOf(slot.id, i, i + safe.length)(ctx);\n normalizeParagraphs(ctx);\n return i + safe.length;\n };\n}\n\n/** 回车。空列表项上先降缩进再退出列表;否则切段,两段各自继承合适的属性。 */\nexport function insertParagraph(index: number): Operation<number> {\n return (ctx) => {\n let i = ctx.doc.clamp(index);\n const slot = ctx.doc.slotAtCaret(i);\n // 槽不是多段容器:落在槽内时把回车挪到槽后,避免一个 slot 跨两段。\n if (slot && i > slot.start && i < slot.end) i = slot.end;\n const para = findParagraphAt(ctx.doc.spacers, i);\n const oldProps: ParagraphProps = para\n ? resolveParagraphProps(ctx.doc, para.start)\n : { ...DEFAULT_PARAGRAPH };\n const inList = (oldProps.list ?? 'none') !== 'none';\n\n if (para && inList && isEmptyParagraph(ctx.doc.spacers, para)) {\n const indent = oldProps.indent ?? 0;\n const patch: ParagraphProps = indent > 0 ? { indent: indent - 1 } : { list: 'none', indent: 0 };\n applyParagraphStyle(para.start, para.end, patch)(ctx);\n return i;\n }\n\n const paraEndContent =\n para && ctx.doc.spacers[para.end - 1] === MARKERS.PARAGRAPH ? para.end - 1 : para?.end ?? i;\n const atStart = !!para && i <= para.start;\n const atEnd = !!para && i >= paraEndContent;\n const groupId = String(oldProps.groupId ?? '');\n const exitGroup =\n !!para && !!groupId && atEnd && isLastParagraphWithGroupId(ctx.doc, para.start, groupId);\n\n emitInsert(ctx, i, MARKERS.PARAGRAPH);\n if (para) {\n const leftProps = { ...oldProps };\n const rightProps = { ...oldProps };\n const heading = oldProps.heading ?? 0;\n // 标题段在段尾回车时,新起的一段回落成正文;在段首回车则让上面那段是正文。\n if (heading && !inList && atEnd) rightProps.heading = 0;\n if (heading && !inList && atStart) leftProps.heading = 0;\n // 分组最后一段末尾回车:新段不再带 groupId。\n if (exitGroup) rightProps.groupId = '';\n ctx.emit(\n multi([\n applyStyle('paragraph', para.start, para.end, null),\n applyStyle('paragraph', para.start, i, leftProps),\n applyStyle('paragraph', i + 1, para.end, rightProps)\n ])\n );\n }\n normalizeParagraphs(ctx);\n return i + 1;\n };\n}\n\n/** 删掉一段区间,边界会向外扩到不切断表格等结构。 */\nexport function deleteRange(start: number, end: number): Operation<Slice> {\n return (ctx) => {\n const expanded = expandRangeOverStructures(\n ctx.doc.spacers,\n ctx.doc.clamp(start),\n ctx.doc.clamp(end)\n );\n if (expanded.start === expanded.end) return EMPTY_SLICE;\n const slice = emitDelete(ctx, expanded.start, expanded.end);\n normalizeParagraphs(ctx);\n return slice;\n };\n}\n\nexport type DeleteHit = { start: number; end: number; slice: Slice } | null;\n\n/** 退格。列表段首先去 bullet;删段分隔符时存活段继承上一段属性;表格骨架不动。 */\nexport function backspace(index: number): Operation<DeleteHit> {\n return (ctx) => {\n const doc = ctx.doc;\n const i = doc.clamp(index);\n const para = findParagraphAt(doc.spacers, i);\n const atStart = !!para && i === para.start;\n const props = para ? resolveParagraphProps(doc, para.start) : { ...DEFAULT_PARAGRAPH };\n\n if (atStart && (props.list ?? 'none') !== 'none') {\n applyParagraphStyle(para.start, para.end, { list: 'none', indent: 0 })(ctx);\n return { start: i, end: i, slice: EMPTY_SLICE };\n }\n if (i <= 0) return null;\n\n const prev = doc.spacers[i - 1];\n // 表格结构标记一律不删:TABLE_END 由编辑器侧改成选中整表。\n if (isTableMarker(prev)) return null;\n\n if (prev === MARKERS.PARAGRAPH) {\n const prevProps = resolveParagraphProps(doc, i - 1);\n const slice = emitDelete(ctx, i - 1, i);\n normalizeParagraphs(ctx);\n const merged = findParagraphAt(doc.spacers, i - 1);\n if (merged) applyParagraphStyle(merged.start, merged.end, prevProps)(ctx);\n return { start: i - 1, end: i, slice };\n }\n\n const len = prevCodePointLen(doc.spacers, i);\n const from = i - len;\n const span = doc.spacers[from] === MARKERS.IMAGE && doc.imageAt(from) ? 1 : len;\n const slice = emitDelete(ctx, from, from + span);\n normalizeParagraphs(ctx);\n return { start: from, end: from + span, slice };\n };\n}\n\n/** Delete 键。整表要整体删掉,其余按一个码点删。 */\nexport function deleteForward(index: number): Operation<DeleteHit> {\n return (ctx) => {\n const doc = ctx.doc;\n const i = doc.clamp(index);\n if (i >= doc.spacers.length) return null;\n const ch = doc.spacers[i];\n if (ch === MARKERS.TABLE_START) {\n const table = findTableAt(doc.spacers, i);\n if (table) {\n const slice = emitDelete(ctx, table.start, table.end);\n normalizeParagraphs(ctx);\n return { start: table.start, end: table.end, slice };\n }\n }\n if (isTableMarker(ch)) return null;\n const len = nextCodePointLen(doc.spacers, i);\n const slice = emitDelete(ctx, i, i + len);\n normalizeParagraphs(ctx);\n return { start: i, end: i + len, slice };\n };\n}\n\n/** 打完字后试着把 `# `、`- `、`**x**` 之类就地转成真正的样式或嵌入块。 */\nexport function applyMarkdownShortcut(caret: number): Operation<number> {\n return (ctx) => {\n const doc = ctx.doc;\n const i = doc.clamp(caret);\n const para = findParagraphAt(doc.spacers, i);\n if (!para) return i;\n const hit = matchMarkdown(doc.spacers.slice(para.start, i));\n if (!hit) return i;\n\n const restyleParagraph = (consume: number, patch: ParagraphProps) => {\n emitDelete(ctx, para.start, para.start + consume);\n normalizeParagraphs(ctx);\n const next = findParagraphAt(doc.spacers, para.start) ?? { start: para.start, end: para.start + 1 };\n applyParagraphStyle(next.start, next.end, patch)(ctx);\n return next.start;\n };\n\n if (hit.kind === 'heading') {\n return restyleParagraph(hit.consume, { heading: hit.level, list: 'none' });\n }\n if (hit.kind === 'list') {\n if (resolveParagraphProps(doc, para.start).list === hit.list) return i;\n return restyleParagraph(hit.consume, { list: hit.list, heading: 0 });\n }\n if (hit.kind === 'code-block') {\n emitDelete(ctx, para.start, para.start + hit.consume);\n normalizeParagraphs(ctx);\n return insertImage(para.start, {\n kind: 'code',\n width: 680,\n height: 80,\n language: hit.language || 'plain',\n code: ''\n })(ctx);\n }\n if (hit.kind === 'formula') {\n const from = para.start + hit.matchStart;\n emitDelete(ctx, from, para.start + hit.matchEnd);\n normalizeParagraphs(ctx);\n return insertImage(from, {\n kind: 'formula',\n width: 200,\n height: 48,\n latex: hit.latex,\n displayMode: hit.displayMode\n })(ctx);\n }\n\n const from = para.start + hit.matchStart;\n emitDelete(ctx, from, para.start + hit.matchEnd);\n normalizeParagraphs(ctx);\n emitInsert(ctx, from, `${hit.inner} `);\n if (hit.inner) applyTextStyle(from, from + hit.inner.length, hit.style)(ctx);\n normalizeParagraphs(ctx);\n return from + hit.inner.length + 1;\n };\n}","/**\n * 表格类 Operation。\n *\n * 表格在字符流里是一串结构标记,在样式里是一条覆盖整表的 table 区间(存列宽)。\n * 增删行列既要动字符流,也要同步列宽数组,两件事都得是显式 mutation。\n */\nimport { cellAt, emptyTableSpacers, findParagraphAt, findTableAt } from '../model/blocks';\nimport { MARKERS } from '../model/markers';\nimport { TableProps } from '../model/types';\nimport { Operation, OperationContext } from './context';\nimport { emitDelete, emitInsert, emitStyle, ensureParagraphAfter, normalizeParagraphs } from './primitives';\nimport { insertParagraph } from './text';\n\n/** 覆盖整表的那条 table 区间,找不到就返回 null。 */\nfunction tableSpan(ctx: OperationContext, start: number, end: number) {\n return ctx.doc.styles.find((s) => s.type === 'table' && s.start <= start && s.end >= end) ?? null;\n}\n\nfunction writeColWidths(ctx: OperationContext, tableStart: number, tableEnd: number, widths: number[]) {\n const span = tableSpan(ctx, tableStart, tableEnd);\n const props = { ...((span?.props as TableProps | undefined) ?? {}), colWidths: [...widths] };\n const from = span?.start ?? tableStart;\n const to = span?.end ?? tableEnd;\n emitStyle(ctx, 'table', from, to, props);\n}\n\n/** 插入空表。表格不能嵌在段落中间,所以必要时先把当前段切开。返回首格光标位置。 */\nexport function insertTable(index: number, rows = 2, cols = 2): Operation<number> {\n return (ctx) => {\n let i = ctx.doc.clamp(index);\n const para = findParagraphAt(ctx.doc.spacers, i);\n if (para && ctx.doc.spacers[para.end - 1] === '\\n' && i >= para.end - 1) {\n i = para.end;\n } else if (para && i > para.start && i < para.end) {\n i = insertParagraph(i)(ctx);\n }\n\n const table = emptyTableSpacers(rows, cols);\n emitInsert(ctx, i, table);\n emitStyle(ctx, 'table', i, i + table.length, {\n colWidths: Array.from({ length: cols }, () => 0)\n } satisfies TableProps);\n ensureParagraphAfter(ctx, i + table.length);\n normalizeParagraphs(ctx);\n return i + table.indexOf(MARKERS.TABLE_CELL) + 1;\n };\n}\n\n/** 在当前行下面插一行。 */\nexport function insertTableRow(index: number): Operation<boolean> {\n return (ctx) => {\n const hit = cellAt(ctx.doc.spacers, index);\n if (!hit) return false;\n const cols = Math.max(...hit.table.rows.map((r) => r.cells.length));\n let spacers = MARKERS.TABLE_ROW;\n for (let c = 0; c < cols; c++) spacers += MARKERS.TABLE_CELL + MARKERS.PARAGRAPH;\n emitInsert(ctx, hit.table.rows[hit.row].end, spacers);\n normalizeParagraphs(ctx);\n return true;\n };\n}\n\n/** 在当前列右边插一列。从下往上插,免得前面的插入把后面的坐标顶跑。 */\nexport function insertTableCol(index: number): Operation<boolean> {\n return (ctx) => {\n const hit = cellAt(ctx.doc.spacers, index);\n if (!hit) return false;\n const inserts: number[] = [];\n for (const row of [...hit.table.rows].reverse()) {\n inserts.push(row.cells[Math.min(hit.col, row.cells.length - 1)].end);\n }\n for (const at of inserts) emitInsert(ctx, at, MARKERS.TABLE_CELL + MARKERS.PARAGRAPH);\n\n const table = findTableAt(ctx.doc.spacers, index);\n if (table) {\n const span = tableSpan(ctx, table.start, table.end);\n const widths = [...(((span?.props as TableProps | undefined)?.colWidths) ?? [])];\n widths.splice(hit.col + 1, 0, 0);\n writeColWidths(ctx, table.start, table.end, widths);\n }\n normalizeParagraphs(ctx);\n return true;\n };\n}\n\n/** 删当前行。最后一行不给删。 */\nexport function deleteTableRow(index: number): Operation<boolean> {\n return (ctx) => {\n const hit = cellAt(ctx.doc.spacers, index);\n if (!hit || hit.table.rows.length <= 1) return false;\n const row = hit.table.rows[hit.row];\n emitDelete(ctx, row.start, row.end);\n normalizeParagraphs(ctx);\n return true;\n };\n}\n\n/** 删当前列。最后一列不给删。 */\nexport function deleteTableCol(index: number): Operation<boolean> {\n return (ctx) => {\n const hit = cellAt(ctx.doc.spacers, index);\n if (!hit) return false;\n if (Math.max(...hit.table.rows.map((r) => r.cells.length)) <= 1) return false;\n for (const row of [...hit.table.rows].reverse()) {\n const cell = row.cells[hit.col];\n if (cell) emitDelete(ctx, cell.start, cell.end);\n }\n const table = findTableAt(ctx.doc.spacers, hit.table.start);\n if (table) {\n const span = tableSpan(ctx, table.start, table.end);\n const widths = (span?.props as TableProps | undefined)?.colWidths;\n if (widths && widths.length > hit.col) {\n const next = [...widths];\n next.splice(hit.col, 1);\n writeColWidths(ctx, table.start, table.end, next);\n }\n }\n normalizeParagraphs(ctx);\n return true;\n };\n}\n\n/** 拖动列边界后落定列宽。 */\nexport function setTableColWidths(index: number, widths: number[]): Operation {\n return (ctx) => {\n const table = findTableAt(ctx.doc.spacers, index);\n if (!table) return;\n writeColWidths(ctx, table.start, table.end, widths);\n };\n}\n","import { MARKERS } from '../model/markers';\nimport { DEFAULT_PARAGRAPH, EmbedEntity, HeadingLevel, LINK_COLOR, ParagraphProps, Slice, StyleSpan, TextProps } from '../model/types';\n\n/**\n * 粘贴前的 Markdown 探测:先看标题/列表/链接,再看行内粗斜删除线。\n */\nexport function looksLikeMarkdown(text: string): boolean {\n const normalized = `\\n\\n${text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n')}\\n\\n`;\n return (\n /^(#{1,6})[ \\t]+.+/m.test(normalized) ||\n /(?:^|\\n) {0,3}([*+-]|\\d+\\.)[ \\t]+/.test(normalized) ||\n /\\[((?:\\[[^\\]]*]|[^\\[\\]])*)][ \\t]*\\([ \\t]?<?\\S+/.test(normalized) ||\n /\\*\\*[^*]+\\*\\*/.test(text) ||\n /(?<!\\*)\\*[^*\\n]+\\*(?!\\*)/.test(text) ||\n /~~.+~~/.test(text) ||\n /__[^_]+__/.test(text) ||\n /```/.test(text) ||\n /\\$\\$[\\s\\S]+\\$\\$/.test(text) ||\n /\\$[^$\\n]+\\$/.test(text)\n );\n}\n\ntype InlineTok = { text: string; style: TextProps; url?: string };\n\nfunction parseInline(input: string): InlineTok[] {\n const out: InlineTok[] = [];\n const re =\n /(\\*\\*\\*(.+?)\\*\\*\\*|\\*\\*(.+?)\\*\\*|\\*(.+?)\\*|~~(.+?)~~|__(.+?)__|\\[([^\\]]+)\\]\\(([^)]+)\\))/g;\n let last = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(input))) {\n if (m.index > last) out.push({ text: input.slice(last, m.index), style: {} });\n if (m[2] !== undefined) out.push({ text: m[2], style: { bold: true, italic: true } });\n else if (m[3] !== undefined) out.push({ text: m[3], style: { bold: true } });\n else if (m[4] !== undefined) out.push({ text: m[4], style: { italic: true } });\n else if (m[5] !== undefined) out.push({ text: m[5], style: { strikethrough: true } });\n else if (m[6] !== undefined) out.push({ text: m[6], style: { underline: true } });\n else if (m[7] !== undefined) {\n out.push({ text: m[7], style: { color: LINK_COLOR, underline: true }, url: m[8] });\n }\n last = m.index + m[0].length;\n }\n if (last < input.length) out.push({ text: input.slice(last), style: {} });\n return out.filter((t) => t.text.length > 0);\n}\n\nfunction blockProps(line: string): { rest: string; para: ParagraphProps } {\n const heading = line.match(/^(#{1,3})\\s+(.*)$/);\n if (heading) {\n return { rest: heading[2], para: { ...DEFAULT_PARAGRAPH, heading: heading[1].length as HeadingLevel } };\n }\n const ul = line.match(/^(\\s*)[-*+]\\s+(.*)$/);\n if (ul) {\n const indent = Math.min(8, Math.floor(ul[1].replace(/\\t/g, ' ').length / 2));\n return { rest: ul[2], para: { ...DEFAULT_PARAGRAPH, list: 'ul', indent } };\n }\n const ol = line.match(/^(\\s*)\\d+\\.\\s+(.*)$/);\n if (ol) {\n const indent = Math.min(8, Math.floor(ol[1].replace(/\\t/g, ' ').length / 2));\n return { rest: ol[2], para: { ...DEFAULT_PARAGRAPH, list: 'ol', indent } };\n }\n return { rest: line, para: { ...DEFAULT_PARAGRAPH } };\n}\n\n/** 支持的 Markdown 子集:标题/列表/粗斜下划删除线/链接/代码块/公式。 */\nexport function markdownToSlice(raw: string): Slice {\n const text = raw.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n const lines = text.split('\\n');\n let spacers = '';\n const styles: StyleSpan[] = [];\n const entities: EmbedEntity[] = [];\n\n const emitPara = (line: string) => {\n const { rest, para } = blockProps(line);\n const start = spacers.length;\n const tokens = parseInline(rest);\n for (const tok of tokens) {\n const a = spacers.length;\n spacers += tok.text;\n const b = spacers.length;\n if (Object.keys(tok.style).length) {\n styles.push({ start: a, end: b, type: 'text', props: { ...tok.style } });\n }\n if (tok.url) styles.push({ start: a, end: b, type: 'link', props: { url: tok.url } });\n }\n spacers += MARKERS.PARAGRAPH;\n styles.push({ start, end: spacers.length, type: 'paragraph', props: { ...para } });\n };\n\n const emitEmbed = (entity: EmbedEntity) => {\n const start = spacers.length;\n spacers += MARKERS.IMAGE;\n styles.push({ start, end: start + 1, type: 'image', props: { entityId: entity.id } });\n entities.push(entity);\n spacers += MARKERS.PARAGRAPH;\n styles.push({ start, end: spacers.length, type: 'paragraph', props: { ...DEFAULT_PARAGRAPH } });\n };\n\n let i = 0;\n if (lines.length === 0) emitPara('');\n while (i < lines.length) {\n const line = lines[i];\n const fence = line.match(/^```(\\w*)\\s*$/);\n if (fence) {\n const buf: string[] = [];\n i += 1;\n while (i < lines.length && !/^```\\s*$/.test(lines[i])) {\n buf.push(lines[i]);\n i += 1;\n }\n if (i < lines.length) i += 1;\n emitEmbed({\n id: `md_${entities.length}`,\n kind: 'code',\n width: 680,\n height: 80,\n language: fence[1] || 'plain',\n code: buf.join('\\n')\n });\n continue;\n }\n const oneLineMath = line.match(/^\\$\\$(.+)\\$\\$\\s*$/);\n if (oneLineMath) {\n emitEmbed({\n id: `md_${entities.length}`,\n kind: 'formula',\n width: 200,\n height: 48,\n latex: oneLineMath[1],\n displayMode: true\n });\n i += 1;\n continue;\n }\n if (line.trim() === '$$') {\n const buf: string[] = [];\n i += 1;\n while (i < lines.length && lines[i].trim() !== '$$') {\n buf.push(lines[i]);\n i += 1;\n }\n if (i < lines.length) i += 1;\n emitEmbed({\n id: `md_${entities.length}`,\n kind: 'formula',\n width: 200,\n height: 48,\n latex: buf.join('\\n'),\n displayMode: true\n });\n continue;\n }\n emitPara(line);\n i += 1;\n }\n\n return { text: spacers, styles, entities };\n}\n","/**\n * 切片类 Operation:粘贴、Markdown 整段导入、同步块的提取与展开。\n *\n * 切片自带实体,插入时 id 可能和文档里已有的撞车,所以先做一轮改名再落地。\n */\nimport { findParagraphAt } from '../model/blocks';\nimport { cloneFragment, cloneSlice, sliceHasContent } from '../model/fragment';\nimport { cloneEntity, Fragment, ImageEntity, Slice, StyleType, TextProps } from '../model/types';\nimport { MARKERS } from '../model/markers';\nimport {\n collapsedSel,\n DocumentModel,\n documentFromSlice,\n nextEntityId,\n sliceFromDocument\n} from '../model/document';\nimport { addEntity, addFragment } from '../mutations';\nimport { looksLikeMarkdown, markdownToSlice } from '../convert/mdPaste';\nimport { Operation, runOperation } from './context';\nimport { emitDelete, emitInsert, emitStyle, normalizeParagraphs } from './primitives';\nimport { insertImage } from './entity';\nimport { insertParagraph, insertText } from './text';\nimport { coverAncestorsOf, extendMarksAtEnd, fillSlot, insertVirtualBlock, remapIncomingVirtualBlocks, slotInlineText } from './virtualBlock';\nimport type { VirtualBlockSpec } from './virtualBlock';\n\n/**\n * 把切片里的同步块引用换成引用目标的实际内容。\n *\n * 跨文档粘贴不该带走一个指向源文档的悬空引用,所以复制粘贴前要先摊平。\n * 展开在一个临时文档上做,不碰真文档,因此不产生 mutation。\n */\nfunction materializeSlice(doc: DocumentModel, slice: Slice): Slice {\n if (!slice.entities.some((e) => e.kind === 'ref')) return cloneSlice(slice);\n const lookup = new Map(doc.fragments);\n for (const f of (slice.fragments ?? []) as Fragment[]) lookup.set(f.id, cloneFragment(f));\n\n const scratch = documentFromSlice(slice);\n // 从后往前换,免得前面的替换把后面引用的坐标顶跑。\n for (let i = scratch.spacers.length - 1; i >= 0; i--) {\n if (scratch.spacers[i] !== MARKERS.IMAGE) continue;\n const entity = scratch.imageAt(i);\n if (entity?.kind !== 'ref' || !entity.fragmentId) continue;\n const source = lookup.get(entity.fragmentId);\n runOperation(scratch, collapsedSel(i), (c) => {\n emitDelete(c, i, i + 1);\n normalizeParagraphs(c);\n if (source) insertSlice(i, cloneSlice(source.slice), false)(c);\n });\n }\n return sliceFromDocument(scratch);\n}\n\n/**\n * 把一个切片插到 index 处。\n *\n * asCopy 为真时先把切片里的同步块引用摊平成实际内容 —— 跨文档粘贴不该带走\n * 一个指向源文档的悬空引用。\n */\nexport function insertSlice(index: number, slice: Slice, asCopy = true): Operation<number> {\n return (ctx) => {\n const doc = ctx.doc;\n const incoming = asCopy ? materializeSlice(doc, slice) : cloneSlice(slice);\n const i = doc.clamp(index);\n const slot = doc.slotAtCaret(i);\n const nested =\n (incoming.virtualBlocks?.length ?? 0) > 0 || incoming.entities.length > 0;\n if (slot?.empty && !nested) {\n const text = slotInlineText(incoming.text);\n if (text) {\n const end = fillSlot(slot.id, text)(ctx);\n return end ?? i;\n }\n }\n\n const remap = new Map<string, string>();\n const entities = incoming.entities.map((e) => {\n if (!doc.entities.has(e.id)) return cloneEntity(e);\n const next = { ...cloneEntity(e), id: nextEntityId() };\n remap.set(e.id, next.id);\n return next;\n });\n\n emitInsert(ctx, i, incoming.text);\n extendMarksAtEnd(i, incoming.text)(ctx);\n for (const e of entities) ctx.emit(addEntity(e));\n for (const s of incoming.styles) {\n const props =\n s.type === 'image' && remap.size\n ? {\n ...(s.props as { entityId: string }),\n entityId:\n remap.get((s.props as { entityId: string }).entityId) ??\n (s.props as { entityId: string }).entityId\n }\n : { ...s.props };\n emitStyle(ctx, s.type as StyleType, s.start + i, s.end + i, props);\n }\n // 空槽插入模板:整段落在槽前(槽被机械推走),不要 cover 把树吞进槽里。\n if (slot && !slot.empty) {\n coverAncestorsOf(slot.id, i, i + incoming.text.length)(ctx);\n } else {\n const occupied = new Set(ctx.doc.virtualBlocks.keys());\n for (const block of remapIncomingVirtualBlocks(incoming.virtualBlocks ?? [], i, occupied)) {\n const spec: VirtualBlockSpec = {\n id: block.id,\n kind: block.kind,\n start: block.start,\n end: block.end,\n chrome: block.chrome,\n placeholder: block.placeholder,\n empty: block.empty\n };\n if (block.parentId) spec.parentId = block.parentId;\n insertVirtualBlock(spec)(ctx);\n }\n }\n normalizeParagraphs(ctx);\n return i + incoming.text.length;\n };\n}\n\n/** 把一段 Markdown 原文导入到 index 处。段落中间导入时先把段切开。 */\nexport function insertMarkdown(index: number, raw: string): Operation<number> {\n return (ctx) => {\n const doc = ctx.doc;\n const i = doc.clamp(index);\n const para = findParagraphAt(doc.spacers, i);\n const paraEnd =\n para && doc.spacers[para.end - 1] === MARKERS.PARAGRAPH ? para.end - 1 : para?.end ?? i;\n const at = para && i > para.start && i < paraEnd ? insertParagraph(i)(ctx) : i;\n\n const slice = markdownToSlice(raw);\n let text = slice.text;\n let styles = slice.styles;\n // 导入内容自带结尾段分隔符,而落点后面已经有一个了,去掉一个免得多出空行。\n if (text.endsWith(MARKERS.PARAGRAPH) && doc.spacers[at] === MARKERS.PARAGRAPH) {\n const cut = text.length - 1;\n text = text.slice(0, cut);\n styles = styles\n .map((s) => ({ ...s, start: Math.min(s.start, cut), end: Math.min(s.end, cut) }))\n .filter((s) => s.end > s.start);\n }\n insertSlice(at, { text, styles, entities: slice.entities })(ctx);\n return at + text.length;\n };\n}\n\n/** 粘贴纯文本。看起来像 Markdown 就走导入,否则当普通文字插入。 */\nexport function pasteText(index: number, raw: string, inherit?: TextProps): Operation<number> {\n return (ctx) =>\n looksLikeMarkdown(raw) ? insertMarkdown(index, raw)(ctx) : insertText(index, raw, inherit)(ctx);\n}\n\n/**\n * 把一段内容提取成同步块,原地换成一个引用。\n *\n * fragment 的新建走 addFragment mutation,和后续的删除、插入引用一起进操作串,\n * 因此整步可撤销、可协同。\n */\nexport function promoteRange(start: number, end: number): Operation<{ fragmentId: string; index: number } | null> {\n return (ctx) => {\n const doc = ctx.doc;\n const from = doc.clamp(Math.min(start, end));\n const to = doc.clamp(Math.max(start, end));\n if (from >= to || doc.rangeHasRef(from, to)) return null;\n const slice = doc.takeSlice(from, to);\n if (!sliceHasContent(slice)) return null;\n\n const fragment = doc.buildFragment(slice);\n ctx.emit(addFragment(fragment));\n emitDelete(ctx, from, to);\n normalizeParagraphs(ctx);\n const index = insertRef(from, fragment.id)(ctx);\n return { fragmentId: fragment.id, index };\n };\n}\n\n/** 在 index 处插一个指向同步块的引用,返回引用占位符自身的位置。 */\nexport function insertRef(index: number, fragmentId: string): Operation<number> {\n return (ctx) => {\n if (!ctx.doc.fragments.has(fragmentId)) return ctx.doc.clamp(index);\n const entity: Omit<ImageEntity, 'id'> = {\n kind: 'ref',\n fragmentId,\n width: 680,\n height: 80\n };\n return insertImage(index, entity)(ctx) - 1;\n };\n}\n\n/** 把引用就地展开成实际内容,引用本身消失。返回展开后的末尾位置。 */\nexport function unlinkRef(index: number): Operation<number | null> {\n return (ctx) => {\n const doc = ctx.doc;\n const i = doc.clamp(index);\n const entity = doc.imageAt(i);\n if (entity?.kind !== 'ref' || !entity.fragmentId) return null;\n const fragment = doc.fragments.get(entity.fragmentId);\n if (!fragment) return null;\n emitDelete(ctx, i, i + 1);\n normalizeParagraphs(ctx);\n return insertSlice(i, cloneSlice(fragment.slice), true)(ctx);\n };\n}\n","/**\n * 编辑事务 —— 一次用户操作的边界。\n *\n * 事务干的事:起一个 Operation 上下文、把里面产生的操作串收起来、包成一条\n * `EditResult` 交给撤销栈。它不碰 UI,也不决定要做什么编辑,所以宿主和自检\n * 能走同一条路径。\n *\n * 选区在事务期间归上下文管:Operation 用 `ctx.select` 落点,事务结束时一并交回。\n * 这样撤销栈拿到的「操作前/操作后选区」和操作串是同一份数据里配套的。\n */\nimport { DocumentModel } from '../model/document';\nimport { Selection } from '../model/types';\nimport { Operation, OperationContext, OperationRun, runOperation, scopeContext } from '../operations';\nimport { EditKind, EditMeta, EditResult, editResult } from './editResult';\n\nexport interface EditOutcome {\n /** 这次编辑的记录。没有产生任何变更时是 null,不该进撤销栈。 */\n edit: EditResult | null;\n /** 事务结束时的选区,属于 `meta.scope` 指定的坐标空间。 */\n selectionAfter: Selection;\n}\n\n/**\n * 在指定坐标空间里跑一段 Operation,不包装成编辑记录。\n *\n * `scope` 非空时上下文先切到该片段的坐标空间 —— Operation 原样复用,发出的\n * mutation 自动包上 `scoped`。拖拽预览这类不进撤销栈的改动直接用它。\n */\nexport function runScoped<R>(\n doc: DocumentModel,\n selection: Selection,\n scope: string | null,\n op: Operation<R>\n): { run: OperationRun; result: R } {\n return runOperation(doc, selection, (outer) => op(scope ? scopeContext(outer, scope) : outer));\n}\n\n/** 跑一次编辑事务,产出一条能进撤销栈的记录。 */\nexport function runEdit(\n doc: DocumentModel,\n selection: Selection,\n meta: Partial<EditMeta> & { kind: EditKind },\n run: (ctx: OperationContext) => void\n): EditOutcome {\n const { run: result } = runScoped(doc, selection, meta.scope ?? null, run);\n\n if (!result.forward.length) {\n return { edit: null, selectionAfter: result.selectionAfter };\n }\n return {\n edit: editResult({\n mutations: result.forward,\n inverse: result.inverse,\n selectionBefore: result.selectionBefore,\n selectionAfter: result.selectionAfter,\n meta\n }),\n selectionAfter: result.selectionAfter\n };\n}\n","/**\n * 撤销栈。\n *\n * 与「存整篇快照」的做法相比,这里存的是操作对,所以两件事成为可能:\n * 一是连续输入能在时间窗口内合并成一步;二是撤销时能把逆操作变换到\n * 「协作者的改动已经落地」之后的坐标系里,撤销自己的编辑不会误伤别人的。\n *\n * 栈顶是下标 0(最近一步),与遍历「比它更新的操作」的写法配合更自然。\n */\nimport { Selection } from '../model/types';\nimport { EditResult, invertEdit, isEmptyEdit, mergeEdits } from './editResult';\nimport { transformBoth, transformSelection } from '../mutations';\n\n/** 连续输入的合并窗口。超过这个间隔就另起一步。 */\nexport const UNDO_BATCH_MS = 2000;\n\nexport class UndoRedoStack {\n private undos: EditResult[] = [];\n private redos: EditResult[] = [];\n private lastPushAt = 0;\n private batchOpen = false;\n private now: () => number;\n\n constructor(now: () => number = () => Date.now()) {\n this.now = now;\n }\n\n get canUndo(): boolean {\n return this.undos.some((e) => e.meta.local && e.meta.undoable);\n }\n\n get canRedo(): boolean {\n return this.redos.length > 0;\n }\n\n clear() {\n this.undos = [];\n this.redos = [];\n this.batchOpen = false;\n }\n\n /** 选区被用户主动移动时调用,打断合并窗口。 */\n resetBatching() {\n this.batchOpen = false;\n }\n\n push(edit: EditResult) {\n if (isEmptyEdit(edit)) return;\n\n if (!edit.meta.local) {\n // 远端操作也要进栈:撤销本地操作时需要跨过它们做变换\n this.undos.unshift(edit);\n this.batchOpen = false;\n return;\n }\n\n // 合并要三个条件同时成立:在时间窗口内、批次没被打断、两步是同一串\n // 连续动作(mergeKey 相同且非 null)。少了最后一条,「打几个字」和紧随其后的\n // 「点加粗」会被并成一步,撤销时文字和加粗一起消失。\n const top = this.undos[0];\n const withinWindow = this.batchOpen && this.now() - this.lastPushAt < UNDO_BATCH_MS;\n const sameRun = !!edit.meta.mergeKey && top?.meta.mergeKey === edit.meta.mergeKey;\n if (withinWindow && sameRun && top?.meta.local && top.meta.undoable && edit.meta.undoable) {\n this.undos[0] = mergeEdits(top, edit);\n } else {\n this.undos.unshift(edit);\n this.batchOpen = true;\n }\n this.lastPushAt = this.now();\n this.redos = [];\n }\n\n /**\n * 取出下一步要撤销的操作,已变换到当前坐标系。\n *\n * 栈里可能夹着协作者的操作,所以不能直接弹栈顶:要找到最近一条本地可撤销的,\n * 把它的逆操作依次穿过它上面那些更新的操作,同时把那些操作也反向变换一遍\n * (它们的坐标系因为这次撤销也变了,留在栈里下次还要用)。\n */\n popForUndo(): EditResult | null {\n const index = this.undos.findIndex((e) => e.meta.local && e.meta.undoable);\n if (index < 0) return null;\n\n let target = this.undos[index];\n for (let i = index - 1; i >= 0; i--) {\n target = this.rebase(target, i);\n }\n this.undos.splice(index, 1);\n\n const undoStep = invertEdit(target);\n this.redos.unshift(target);\n this.batchOpen = false;\n return undoStep;\n }\n\n popForRedo(): EditResult | null {\n const target = this.redos.shift();\n if (!target) return null;\n this.undos.unshift(target);\n this.batchOpen = false;\n return target;\n }\n\n /**\n * 把 target 变换到「栈中第 i 条(更新的那条)已应用」之后,\n * 同时把第 i 条变换到「target 被撤销」之后。\n */\n private rebase(target: EditResult, i: number): EditResult {\n const intervening = this.undos[i];\n // 撤销时真正要跑的是逆操作,所以拿它去和中间操作对撞\n const pair = transformBoth(target.inverse, intervening.mutations, true);\n const forward = transformBoth(target.mutations, intervening.mutations, true);\n\n this.undos[i] = {\n ...intervening,\n mutations: pair.b,\n inverse: transformBoth(intervening.inverse, target.inverse, false).a\n };\n\n return {\n ...target,\n mutations: forward.a,\n inverse: pair.a,\n selectionBefore: transformSelection(target.selectionBefore, intervening.mutations),\n selectionAfter: transformSelection(target.selectionAfter, intervening.mutations)\n };\n }\n\n /** 远端操作落地后,把栈里所有本地操作变换到新坐标系。 */\n rebaseAgainstRemote(remote: EditResult) {\n for (let i = 0; i < this.undos.length; i++) {\n const e = this.undos[i];\n this.undos[i] = {\n ...e,\n mutations: transformBoth(e.mutations, remote.mutations, false).a,\n inverse: transformBoth(e.inverse, remote.mutations, false).a,\n selectionBefore: transformSelection(e.selectionBefore, remote.mutations),\n selectionAfter: transformSelection(e.selectionAfter, remote.mutations)\n };\n }\n for (let i = 0; i < this.redos.length; i++) {\n const e = this.redos[i];\n this.redos[i] = {\n ...e,\n mutations: transformBoth(e.mutations, remote.mutations, false).a,\n inverse: transformBoth(e.inverse, remote.mutations, false).a\n };\n }\n }\n\n /** 调试用:当前撤销栈里各步的操作条数。 */\n describe(): { undos: number[]; redos: number[] } {\n return {\n undos: this.undos.map((e) => e.mutations.length),\n redos: this.redos.map((e) => e.mutations.length)\n };\n }\n}\n\nexport type { EditResult, Selection };\n","export interface ImeHandler {\n onInsertText(text: string): void;\n onInsertParagraph(): void;\n onBackspace(): void;\n onDeleteForward(): void;\n onPaste(data: DataTransfer | null): void;\n onCompositionChange(active: boolean, text: string): void;\n}\n\nexport class ImeSurface {\n readonly el: HTMLDivElement;\n composing = false;\n private handler: ImeHandler;\n private keyConsumed = false;\n private ctxMenu = false;\n\n constructor(handler: ImeHandler) {\n this.handler = handler;\n this.el = document.createElement('div');\n this.el.className = 'mini-ime';\n this.el.contentEditable = 'true';\n this.el.spellcheck = false;\n this.el.setAttribute('role', 'textbox');\n this.el.setAttribute('aria-multiline', 'true');\n this.el.addEventListener('beforeinput', this.onBeforeInput);\n this.el.addEventListener('compositionstart', this.onCompStart);\n this.el.addEventListener('compositionupdate', this.onCompUpdate);\n this.el.addEventListener('compositionend', this.onCompEnd);\n this.el.addEventListener('paste', this.onPaste);\n this.el.addEventListener('keydown', this.onKeydownGuard);\n }\n\n focus() {\n if (document.activeElement !== this.el) this.el.focus({ preventScroll: true });\n }\n\n markKeyConsumed() {\n this.keyConsumed = true;\n }\n\n /**\n * 右键菜单:把隐藏的 contenteditable 临时挪到鼠标下并放入选中文字、全选。\n * 浏览器按 contextmenu 事件时鼠标下的元素决定菜单种类,落在 canvas 上会弹出\n * “存储图片”之类;落在可编辑文本上才是 剪切/拷贝/粘贴。复制/剪切/粘贴事件\n * 仍由编辑器接管,所以这里的文字只用来启用菜单项,不会被当作输入。\n */\n beginContextMenu(x: number, y: number, text: string) {\n if (this.composing) return;\n this.ctxMenu = true;\n this.el.classList.add('is-ctxmenu');\n this.el.style.left = `${x - 12}px`;\n this.el.style.top = `${y - 12}px`;\n this.el.style.width = '24px';\n this.el.style.height = '24px';\n this.el.textContent = text;\n this.focus();\n if (text) {\n const range = document.createRange();\n range.selectNodeContents(this.el);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n }\n }\n\n endContextMenu() {\n if (!this.ctxMenu) return;\n this.ctxMenu = false;\n this.el.classList.remove('is-ctxmenu');\n this.el.style.width = '';\n this.clear();\n }\n\n moveTo(x: number, y: number, h: number) {\n if (this.ctxMenu) return;\n this.el.style.left = `${x}px`;\n this.el.style.top = `${y}px`;\n this.el.style.height = `${Math.max(18, h)}px`;\n }\n\n clear() {\n this.el.textContent = '';\n }\n\n destroy() {\n this.el.removeEventListener('beforeinput', this.onBeforeInput);\n this.el.removeEventListener('compositionstart', this.onCompStart);\n this.el.removeEventListener('compositionupdate', this.onCompUpdate);\n this.el.removeEventListener('compositionend', this.onCompEnd);\n this.el.removeEventListener('paste', this.onPaste);\n this.el.removeEventListener('keydown', this.onKeydownGuard);\n this.el.remove();\n }\n\n private onCompStart = () => {\n this.composing = true;\n this.el.classList.add('is-composing');\n this.handler.onCompositionChange(true, '');\n };\n\n private onCompUpdate = (e: CompositionEvent) => {\n this.handler.onCompositionChange(true, e.data ?? this.el.textContent ?? '');\n };\n\n private onCompEnd = (e: CompositionEvent) => {\n this.composing = false;\n this.el.classList.remove('is-composing');\n const text = e.data || this.el.textContent || '';\n this.clear();\n this.handler.onCompositionChange(false, '');\n if (text) this.handler.onInsertText(text);\n };\n\n private onBeforeInput = (e: InputEvent) => {\n if (this.keyConsumed) {\n this.keyConsumed = false;\n // 快捷键在 keydown 里已经改过模型,这里只吞「同一次按键」带出来的默认输入\n // (退格/删除/换段)。keydown 若已 preventDefault,有的浏览器根本不会再派\n // 这次 beforeinput,标志会一直挂到下一键;绝不能把随后的 insertText 也挡掉,\n // 否则删除后再打的第一个字符会消失,第二次才进得去。\n const echo =\n e.inputType.startsWith('delete') ||\n e.inputType === 'insertParagraph' ||\n e.inputType === 'insertLineBreak';\n if (echo) {\n e.preventDefault();\n return;\n }\n }\n if (e.inputType === 'insertCompositionText') return;\n // 组合态里的一切输入(含删除候选串的 delete*)都交给浏览器在这个\n // contentEditable 内部消化。组合串的增删经 compositionupdate 镜像到模型,\n // 删除永远只作用在候选串上,绝不落到文档正文。\n if (this.composing) return;\n e.preventDefault();\n switch (e.inputType) {\n case 'insertText':\n case 'insertReplacementText':\n if (e.data) this.handler.onInsertText(e.data);\n break;\n case 'insertParagraph':\n case 'insertLineBreak':\n this.handler.onInsertParagraph();\n break;\n case 'deleteContentBackward':\n this.handler.onBackspace();\n break;\n case 'deleteContentForward':\n this.handler.onDeleteForward();\n break;\n case 'insertFromPaste':\n break;\n default:\n break;\n }\n };\n\n private onPaste = (e: ClipboardEvent) => {\n e.preventDefault();\n this.handler.onPaste(e.clipboardData);\n };\n\n private onKeydownGuard = (e: KeyboardEvent) => {\n if (e.key === 'Tab') e.preventDefault();\n };\n}\n","/**\n * 快捷键表。\n *\n * 一张纯数据表:按键组合 → 命令。它不认识 DOM 事件,也不认识编辑器 —— 匹配用的\n * 是 {@link KeyStroke} 这个最小结构,由输入源从事件里摘出来。这样这张表可以被\n * 直接断言,也可以将来换成宿主配置的。\n */\nimport { ArrowKey, CommandTable } from './types';\n\n/** 一次按键,从平台事件里摘出来的最小信息。 */\nexport interface KeyStroke {\n /** `KeyboardEvent.key`,大小写原样 */\n key: string;\n /** Cmd(mac)或 Ctrl */\n mod: boolean;\n shift: boolean;\n /** Option(mac)/ Alt */\n alt: boolean;\n /** 单独的 Cmd(mac)。省略时视为没按;`mod` 仍是 Cmd||Ctrl 的并集 */\n meta?: boolean;\n /** 单独的 Ctrl。省略时视为没按 */\n ctrl?: boolean;\n}\n\nexport interface Shortcut {\n /** 匹配的键名,单字母键写小写 */\n key: string;\n /** 是否要求按下 Cmd/Ctrl。省略等同 false —— 必须**没**按 */\n mod?: boolean;\n /** true 要求按 Shift,false 要求没按,省略则不管 */\n shift?: boolean;\n /**\n * true 要求按 Alt/Option,false 要求没按,省略则不管。\n *\n * 省略=不管(而不是像 `mod` 那样默认没按),是为了不改变既有行为:Option+方向键、\n * Option+Backspace 现在都落在无修饰键的条目上。需要区分时,把 `alt: true` 的条目\n * 排在无修饰键条目之前即可,与「带修饰键的排在前面」的顺序约定一致。\n */\n alt?: boolean;\n /**\n * 这个键本身会引发一次文本输入(beforeInput)。吞掉按键之后还得把那次输入一并\n * 压掉,否则内容会被写两遍。只有真正产生输入的键要标。\n *\n * 注意:keydown 里会 preventDefault,部分浏览器因此不再派 beforeinput。\n * IME 层只能按 inputType 吞删除/换段回声,不能无差别丢掉下一次 insertText。\n */\n suppressesInput?: boolean;\n /** 返回 false 表示这次没处理,事件不该被吞 */\n run(c: CommandTable, stroke: KeyStroke): void | boolean;\n}\n\nconst arrow = (key: ArrowKey): Shortcut => ({\n key,\n run: (c, s) => c.moveCaret(key, s.shift)\n});\n\n/**\n * 带修饰键的方向键 / Home / End。mac 和 Windows 的习惯不同,这里一起登记:\n * - Cmd+←→ 行首/行尾,Cmd+↑↓ 文首/文尾(mac)\n * - Option+←→ 按词,Option+↑↓ 按段(mac)\n * - Ctrl+←→ 按词,Ctrl+↑↓ 按段(Windows/Linux)\n * - Home/End 行首/行尾,Ctrl/Cmd+Home/End 文首/文尾\n * Shift 一律表示扩选。\n */\nconst modArrow = (key: ArrowKey): Shortcut => ({\n key,\n mod: true,\n run: (c, s) => {\n const dir = key === 'ArrowLeft' || key === 'ArrowUp' ? -1 : 1;\n const horizontal = key === 'ArrowLeft' || key === 'ArrowRight';\n // 没按 Cmd(只有 Ctrl)→ Windows 口径;按了 Cmd → mac 口径。\n if (!s.meta) return c.moveCaretBy(horizontal ? 'word' : 'paragraph', dir, s.shift);\n return c.moveCaretBy(horizontal ? 'line' : 'doc', dir, s.shift);\n }\n});\n\nconst altArrow = (key: ArrowKey): Shortcut => ({\n key,\n alt: true,\n run: (c, s) => {\n const dir = key === 'ArrowLeft' || key === 'ArrowUp' ? -1 : 1;\n const horizontal = key === 'ArrowLeft' || key === 'ArrowRight';\n return c.moveCaretBy(horizontal ? 'word' : 'paragraph', dir, s.shift);\n }\n});\n\nconst navKeys = (): Shortcut[] => [\n { key: 'Home', mod: true, run: (c, s) => c.moveCaretBy('doc', -1, s.shift) },\n { key: 'End', mod: true, run: (c, s) => c.moveCaretBy('doc', 1, s.shift) },\n { key: 'Home', run: (c, s) => c.moveCaretBy('line', -1, s.shift) },\n { key: 'End', run: (c, s) => c.moveCaretBy('line', 1, s.shift) },\n modArrow('ArrowLeft'),\n modArrow('ArrowRight'),\n modArrow('ArrowUp'),\n modArrow('ArrowDown'),\n altArrow('ArrowLeft'),\n altArrow('ArrowRight'),\n altArrow('ArrowUp'),\n altArrow('ArrowDown')\n];\n\n/**\n * 顺序有意义:从上往下取第一条匹配的。带修饰键的排在前面,免得被无修饰键的\n * 条目截住。\n */\nexport const SHORTCUTS: Shortcut[] = [\n { key: 'z', mod: true, shift: false, run: (c) => c.undo() },\n { key: 'z', mod: true, shift: true, run: (c) => c.redo() },\n { key: 'y', mod: true, run: (c) => c.redo() },\n { key: 'b', mod: true, run: (c) => c.toggleBold() },\n { key: 'i', mod: true, run: (c) => c.toggleItalic() },\n { key: 'u', mod: true, run: (c) => c.toggleUnderline() },\n { key: 'k', mod: true, run: (c) => c.toggleLink() },\n { key: 'a', mod: true, run: (c) => c.selectAll() },\n\n { key: 'Escape', run: (c) => c.exitFragment() },\n { key: 'Enter', suppressesInput: true, run: (c, s) => c.insertParagraph({ shift: s.shift }) },\n { key: 'Backspace', suppressesInput: true, run: (c) => c.backspace() },\n { key: 'Delete', suppressesInput: true, run: (c) => c.deleteForward() },\n { key: 'Tab', run: (c, s) => c.indentOrNextCell(s.shift ? -1 : 1) },\n\n ...navKeys(),\n arrow('ArrowLeft'),\n arrow('ArrowRight'),\n arrow('ArrowUp'),\n arrow('ArrowDown')\n];\n\n/**\n * 嵌入式输入框用的快捷键表:保留撤销/选区/删除/方向键,关掉加粗链接。\n * Enter 不在这张底表里,请用 {@link inputShortcuts} 补上换行,否则\n * keydown 不 preventDefault,contenteditable 的 beforeinput 仍会插段。\n */\nconst swallow: Shortcut['run'] = () => undefined;\n\nexport const INPUT_SHORTCUTS: Shortcut[] = [\n { key: 'z', mod: true, shift: false, run: (c) => c.undo() },\n { key: 'z', mod: true, shift: true, run: (c) => c.redo() },\n { key: 'y', mod: true, run: (c) => c.redo() },\n { key: 'b', mod: true, run: swallow },\n { key: 'i', mod: true, run: swallow },\n { key: 'u', mod: true, run: swallow },\n { key: 'k', mod: true, run: swallow },\n { key: 'a', mod: true, run: (c) => c.selectAll() },\n { key: 'Backspace', suppressesInput: true, run: (c) => c.backspace() },\n { key: 'Delete', suppressesInput: true, run: (c) => c.deleteForward() },\n ...navKeys(),\n arrow('ArrowLeft'),\n arrow('ArrowRight'),\n arrow('ArrowUp'),\n arrow('ArrowDown')\n];\n\n/**\n * 输入框快捷键。\n * - `newline`:Enter / Shift+Enter 都换行;Cmd/Ctrl+Enter 不登记,留给宿主提交。\n * - `enter` / `shift-enter`:旧口径(引擎仍提供,嵌入式输入框不要用)。\n */\nexport function inputShortcuts(\n submit: 'newline' | 'enter' | 'shift-enter' = 'newline'\n): Shortcut[] {\n if (submit === 'newline') {\n return [\n ...INPUT_SHORTCUTS,\n { key: 'Enter', suppressesInput: true, run: (c, s) => c.insertParagraph({ shift: s.shift }) }\n ];\n }\n const submitUsesShift = submit === 'shift-enter';\n return [\n ...INPUT_SHORTCUTS,\n { key: 'Enter', shift: submitUsesShift, suppressesInput: true, run: swallow },\n {\n key: 'Enter',\n shift: !submitUsesShift,\n suppressesInput: true,\n run: (c, s) => c.insertParagraph({ shift: s.shift })\n }\n ];\n}\n\nfunction matches(sc: Shortcut, stroke: KeyStroke): boolean {\n // 单字母键统一按小写比,这样 Cmd+Shift+Z 和 Cmd+Z 走同一套判断\n const key = sc.key.length === 1 ? stroke.key.toLowerCase() : stroke.key;\n if (key !== sc.key) return false;\n if (stroke.mod !== (sc.mod ?? false)) return false;\n if (sc.shift !== undefined && stroke.shift !== sc.shift) return false;\n if (sc.alt !== undefined && stroke.alt !== sc.alt) return false;\n return true;\n}\n\nexport function findShortcut(stroke: KeyStroke, table: Shortcut[] = SHORTCUTS): Shortcut | null {\n return table.find((sc) => matches(sc, stroke)) ?? null;\n}\n","/**\n * 键盘输入源:DOM 事件 → 命令。\n *\n * 这里只做三件事:判断该不该管这个事件、查表、跑命令。它不碰模型也不碰选区 ——\n * 所以「哪个键干什么」改起来只动 `commands/shortcuts.ts`,不用进这个文件。\n */\nimport { CommandTable, findShortcut, KeyStroke, Shortcut, SHORTCUTS } from '../commands';\n\n/**\n * 组合输入期间仍然放行的键。Enter 不在其列:组合态的回车是“确认候选”,由 IME 消化,\n * 绝不触发换行(否则中文输入选词按回车会错误插入段落)。\n */\nconst IME_PASSTHROUGH = new Set(['Backspace', 'Delete', 'Escape']);\n\nexport interface KeyboardHost {\n commands: CommandTable;\n /** 这个事件归不归本编辑器管(焦点、输入框内、嵌入对象里等) */\n accepts(e: KeyboardEvent): boolean;\n /** 组合输入是否进行中 */\n composing(): boolean;\n /** 吞掉了一个会引发文本输入的键,通知宿主连带压掉那次输入 */\n suppressInput(e: KeyboardEvent): void;\n shortcuts?: Shortcut[];\n /** 包住一次快捷键处理(性能面板计时用) */\n track?<T>(fn: () => T): T;\n}\n\nexport function strokeOf(e: KeyboardEvent): KeyStroke {\n return {\n key: e.key,\n mod: e.metaKey || e.ctrlKey,\n shift: e.shiftKey,\n alt: e.altKey,\n meta: e.metaKey,\n ctrl: e.ctrlKey\n };\n}\n\n/** 挂上 keydown 监听,返回解绑函数。 */\nexport function bindKeyboard(host: KeyboardHost): () => void {\n const table = host.shortcuts ?? SHORTCUTS;\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (!host.accepts(e)) return;\n // 组合输入进行中(中文候选框开着)时,回车/空格等键属于 IME 的“确认候选”动作,\n // 应交给 IME 消化,编辑器不得据此换行或插入。原生 isComposing 由浏览器在整个\n // 组合过程(含确认候选的那次按键)置真,比自维护状态更可靠,能覆盖 compositionend\n // 与 keydown 的时序竞态。keyCode 229 是同一语义在旧实现下的回退标志。\n if (e.isComposing || e.keyCode === 229) return;\n if (host.composing() && !IME_PASSTHROUGH.has(e.key)) return;\n\n const stroke = strokeOf(e);\n const sc = findShortcut(stroke, table);\n if (!sc) return;\n const run = () => sc.run(host.commands, stroke);\n if ((host.track ? host.track(run) : run()) === false) return;\n\n e.preventDefault();\n if (sc.suppressesInput) host.suppressInput(e);\n };\n\n document.addEventListener('keydown', onKeyDown);\n return () => document.removeEventListener('keydown', onKeyDown);\n}\n","/**\n * 开发用性能探针。默认不开,开了之后才给 Editor 实例打补丁,不开时零开销。\n *\n * editor.perf.start() // 开始采样,同时开始监测帧间隔\n * ...连续打字 / 按住方向键 / 中文输入法连续上屏...\n * editor.perf.report() // console.table 输出并返回数据;editor.perf.stop() 停止并还原\n *\n * 口径:\n * - 各阶段耗时是 JS 同步耗时(ms),不含浏览器合成、光栅化。\n * - `→下一帧` 是从处理函数开始到下一次 requestAnimationFrame 回调开始的时间,\n * 近似“输入到上屏”的延迟;真正画完还要再加一帧里的合成时间。\n * - 表格里的 fps 列 = 1000 / 该项耗时,表示“如果每一帧都只做这件事,最高能跑多少帧”,上限显示 999;\n * 只有 `→下一帧` 行和底部的“帧”行接近真实体感帧率。\n * - 帧间隔取 requestAnimationFrame 相邻回调的间隔。注意光标闪烁本身每帧都在跑 rAF,\n * 所以空闲时也会有帧;有意义的是“操作期间”掉不掉帧。\n */\n\nexport interface PerfStat {\n count: number;\n avg: number;\n p95: number;\n max: number;\n}\n\ntype Patchable = Record<string, (...args: unknown[]) => unknown>;\n\n/** 要测的入口:用户一次操作的同步总耗时 */\nconst ENTRY = ['insertText', 'handleComposition', 'moveCaret', 'moveCaretBy', 'backspace', 'deleteForward', 'insertParagraph'];\n/** 要测的内部阶段 */\nconst STAGES = ['relayout', 'paintChrome', 'paintCaretLayer', 'scrollCaret', 'syncToolbar', 'syncStatus', 'afterCaretMove'];\n\nfunction stat(samples: number[]): PerfStat {\n if (!samples.length) return { count: 0, avg: 0, p95: 0, max: 0 };\n const sorted = [...samples].sort((a, b) => a - b);\n const sum = sorted.reduce((a, b) => a + b, 0);\n return {\n count: sorted.length,\n avg: sum / sorted.length,\n p95: sorted[Math.min(sorted.length - 1, Math.floor(sorted.length * 0.95))],\n max: sorted[sorted.length - 1]\n };\n}\n\nexport class PerfProbe {\n private target: Patchable;\n private getPainter: () => object;\n private painter: Patchable | null = null;\n private originals = new Map<string, () => unknown>();\n private painterOriginal: ((...args: unknown[]) => unknown) | null = null;\n private samples = new Map<string, number[]>();\n private frames: number[] = [];\n private raf = 0;\n private lastFrame = 0;\n private running = false;\n\n constructor(editor: object, getPainter: () => object) {\n this.target = editor as Patchable;\n this.getPainter = getPainter;\n }\n\n get active() {\n return this.running;\n }\n\n start() {\n if (this.running) return;\n this.running = true;\n this.reset();\n for (const name of [...ENTRY, ...STAGES]) this.patch(name, ENTRY.includes(name));\n // 画家可能被 setPaintMode 换掉:只给 start 时那一个打补丁,换了之后 paintDoc 不再计时\n const painter = this.getPainter() as Patchable;\n if (typeof painter.paintDoc === 'function') {\n const orig = painter.paintDoc.bind(painter);\n this.painter = painter;\n this.painterOriginal = painter.paintDoc;\n painter.paintDoc = (...args: unknown[]) => this.time('paintDoc', () => orig(...args));\n }\n this.lastFrame = 0;\n const tick = (now: number) => {\n if (this.lastFrame) this.frames.push(now - this.lastFrame);\n this.lastFrame = now;\n this.raf = requestAnimationFrame(tick);\n };\n this.raf = requestAnimationFrame(tick);\n }\n\n stop() {\n if (!this.running) return;\n this.running = false;\n cancelAnimationFrame(this.raf);\n for (const [name, orig] of this.originals) {\n // 实例上的补丁删掉即可回到原型方法\n delete (this.target as Record<string, unknown>)[name];\n void orig;\n }\n this.originals.clear();\n if (this.painter && this.painterOriginal) {\n // paintDoc 原先是原型方法,删掉实例补丁\n delete (this.painter as Record<string, unknown>).paintDoc;\n }\n this.painter = null;\n this.painterOriginal = null;\n }\n\n reset() {\n this.samples.clear();\n this.frames = [];\n }\n\n /** 汇总并输出到控制台,返回原始统计。 */\n report() {\n const rows: Record<string, PerfStat> = {};\n for (const [label, s] of this.samples) rows[label] = stat(s);\n // relayout 里去掉已单独统计的阶段,剩下的主要是排版本身\n const rl = this.samples.get('relayout');\n if (rl) {\n const inner = ['paintDoc', 'paintChrome', 'scrollCaret', 'syncToolbar', 'syncStatus'].map(\n (k) => this.samples.get(k) ?? []\n );\n const self = rl.map((v, i) => Math.max(0, v - inner.reduce((a, arr) => a + (arr[i] ?? 0), 0)));\n rows['relayout(排版自身,估算)'] = stat(self);\n }\n const fr = stat(this.frames);\n const frames = {\n 样本帧数: fr.count,\n 平均帧率: fr.avg ? +(1000 / fr.avg).toFixed(1) : 0,\n 帧间隔p95_ms: +fr.p95.toFixed(2),\n 最长帧_ms: +fr.max.toFixed(2),\n '超过16.7ms的帧': this.frames.filter((d) => d > 16.7).length,\n '超过33ms的帧': this.frames.filter((d) => d > 33).length\n };\n const table: Record<string, Record<string, number>> = {};\n for (const [label, s] of Object.entries(rows)) {\n const fps = (ms: number) => (ms > 0 ? Math.min(999, Math.round(1000 / ms)) : 999);\n table[label] = {\n 次数: s.count,\n 平均ms: +s.avg.toFixed(3),\n p95ms: +s.p95.toFixed(3),\n 最大ms: +s.max.toFixed(3),\n 平均fps: fps(s.avg),\n p95fps: fps(s.p95),\n 最差fps: fps(s.max)\n };\n }\n console.table(table);\n console.table({ 帧: frames });\n return { rows, frames };\n }\n\n private record(label: string, ms: number) {\n let arr = this.samples.get(label);\n if (!arr) this.samples.set(label, (arr = []));\n arr.push(ms);\n if (arr.length > 5000) arr.shift();\n }\n\n private time<T>(label: string, fn: () => T): T {\n const t = performance.now();\n try {\n return fn();\n } finally {\n this.record(label, performance.now() - t);\n }\n }\n\n private patch(name: string, entry: boolean) {\n const proto = this.target[name];\n if (typeof proto !== 'function') return;\n this.originals.set(name, proto as () => unknown);\n const self = this;\n (this.target as Record<string, unknown>)[name] = function patched(this: unknown, ...args: unknown[]) {\n const t = performance.now();\n try {\n return proto.apply(this, args);\n } finally {\n const dt = performance.now() - t;\n self.record(name, dt);\n if (entry) {\n requestAnimationFrame(() => self.record(`${name}→下一帧`, performance.now() - t));\n }\n }\n };\n }\n}\n","/**\n * 常驻性能面板:每次输入上屏后显示这一次的实时值,不存历史。\n *\n * new Editor(el, { perfPanel: true }) 或 editor.setPerfPanel(true)\n *\n * 口径(同一次输入):\n * - 上屏延迟 = 浏览器收到输入事件(event.timeStamp)→ 下一帧画完。\n * “画完”用 rAF 之后再排一个任务来近似:rAF 回调之后浏览器才做样式、布局、绘制,\n * 紧随其后的任务开始时这一帧已经提交。\n * - 编辑器 = 编辑器处理这次输入的同步 JS 耗时,含紧随其后的微任务收尾(如光标层重绘)。\n * 同一帧内的多个事件(keydown + beforeinput、输入法 compositionend + insertText)累加。\n * - 排队 = 事件产生到编辑器开始处理之间的等待,主线程被别的任务占着时会变大。\n *\n * 关闭时 track() 只多一次布尔判断,不挂任何监听、不跑 rAF。\n */\n\nexport interface PerfPanelStats {\n chars: number;\n paragraphs: number;\n}\n\nconst IDLE_MS = 3000;\n/** 帧率统计窗口 */\nconst FPS_WINDOW_MS = 500;\n\ntype Metric = 'latency' | 'editor' | 'queue';\n\n/** [绿, 黄] 上限(ms),超过黄为红 */\nconst LIMITS: [number, number] = [50, 100];\n\nconst METRICS: { key: Metric; label: string }[] = [\n { key: 'latency', label: '上屏延迟' },\n { key: 'editor', label: '编辑器' },\n { key: 'queue', label: '排队' }\n];\nconst LISTEN = ['keydown', 'beforeinput', 'compositionstart', 'compositionupdate', 'compositionend', 'paste'] as const;\n\ninterface Pending {\n eventTs: number;\n queue: number;\n editor: number;\n}\n\nexport class PerfPanel {\n private on = false;\n private depth = 0;\n private eventTs = 0;\n private pending: Pending | null = null;\n private flushScheduled = false;\n private idleTimer = 0;\n private fpsRaf = 0;\n private fpsFrames = 0;\n private fpsFrom = 0;\n private fps = 0;\n private channel: MessageChannel | null = null;\n private afterPaint: Pending | null = null;\n private el: HTMLDivElement | null = null;\n private bodyEl: HTMLElement | null = null;\n private miniEl: HTMLElement | null = null;\n private f: { rows: Record<Metric, { value: HTMLElement; dot: HTMLElement }>; env: HTMLElement } | null = null;\n private getStats: () => PerfPanelStats;\n private collapsed = false;\n private left = 12;\n private top = 0;\n private placed = false;\n private drag: { mx: number; my: number; left: number; top: number; moved: boolean } | null = null;\n\n constructor(getStats: () => PerfPanelStats) {\n this.getStats = getStats;\n }\n\n get enabled() {\n return this.on;\n }\n\n enable() {\n if (this.on) return;\n this.on = true;\n for (const t of LISTEN) document.addEventListener(t, this.onEvent, { capture: true, passive: true });\n this.channel = new MessageChannel();\n this.channel.port1.onmessage = this.onPainted;\n this.mount();\n this.showIdle();\n this.fpsFrom = performance.now();\n this.fpsFrames = 0;\n this.fpsRaf = requestAnimationFrame(this.fpsTick);\n }\n\n disable() {\n if (!this.on) return;\n this.on = false;\n for (const t of LISTEN) document.removeEventListener(t, this.onEvent, { capture: true });\n cancelAnimationFrame(this.fpsRaf);\n window.clearTimeout(this.idleTimer);\n this.channel?.port1.close();\n this.channel = null;\n this.pending = null;\n this.afterPaint = null;\n this.flushScheduled = false;\n window.removeEventListener('mousemove', this.onMove);\n window.removeEventListener('mouseup', this.onUp);\n window.removeEventListener('resize', this.onResize);\n this.el?.remove();\n this.el = null;\n this.bodyEl = null;\n this.miniEl = null;\n this.f = null;\n this.drag = null;\n }\n\n /** 包住一次输入的处理。嵌套调用只计最外层。 */\n track<T>(fn: () => T): T {\n if (!this.on || this.depth) return fn();\n this.depth++;\n const t0 = performance.now();\n const ts = this.eventTs > 0 && this.eventTs <= t0 ? this.eventTs : t0;\n try {\n return fn();\n } finally {\n this.depth--;\n // 处理过程中排进来的微任务(光标层重绘等)先于这个执行,一并计入\n queueMicrotask(() => this.addSample(ts, t0, performance.now() - t0));\n }\n }\n\n private onEvent = (e: Event) => {\n this.eventTs = e.timeStamp;\n };\n\n private addSample(eventTs: number, start: number, editor: number) {\n if (!this.on) return;\n const p = this.pending;\n if (p) {\n p.editor += editor;\n if (eventTs < p.eventTs) {\n p.eventTs = eventTs;\n p.queue = Math.max(0, start - eventTs);\n }\n } else {\n this.pending = { eventTs, queue: Math.max(0, start - eventTs), editor };\n }\n if (this.flushScheduled) return;\n this.flushScheduled = true;\n requestAnimationFrame(() => {\n this.flushScheduled = false;\n this.afterPaint = this.pending;\n this.pending = null;\n this.channel?.port2.postMessage(0);\n });\n }\n\n private onPainted = () => {\n const s = this.afterPaint;\n this.afterPaint = null;\n if (!s || !this.on) return;\n this.show(performance.now() - s.eventTs, s.editor, s.queue);\n };\n\n private fpsTick = (now: number) => {\n this.fpsFrames++;\n const span = now - this.fpsFrom;\n if (span >= FPS_WINDOW_MS) {\n this.fps = Math.round((this.fpsFrames * 1000) / span);\n this.fpsFrames = 0;\n this.fpsFrom = now;\n this.showEnv();\n }\n this.fpsRaf = requestAnimationFrame(this.fpsTick);\n };\n\n private mount() {\n const el = document.createElement('div');\n el.className = 'mini-perf-panel';\n el.tabIndex = -1;\n el.style.cssText =\n 'position:fixed;left:12px;bottom:12px;z-index:2147483000;width:250px;padding:8px 10px;box-sizing:border-box;' +\n 'border-radius:8px;background:rgba(20,22,28,.86);color:#e8eaf0;user-select:none;cursor:grab;' +\n 'font:12px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;contain:layout paint style;';\n el.innerHTML =\n `<div data-f=\"mini\" style=\"display:none;align-items:center;gap:8px;cursor:grab\">` +\n `<span data-f=\"mini-fps\" style=\"opacity:.85\"></span>` +\n METRICS.map((m) => `<span data-md=\"${m.key}\">●</span>`).join('') +\n `</div>` +\n `<div data-f=\"body\">` +\n METRICS.map(\n (m) =>\n `<div style=\"display:flex;justify-content:space-between\"><span style=\"opacity:.65\">${m.label}</span>` +\n `<span><span data-v=\"${m.key}\"></span> <span data-d=\"${m.key}\">●</span></span></div>`\n ).join('') +\n `<div data-f=\"env\" style=\"margin-top:2px;opacity:.55;white-space:nowrap;overflow:hidden;text-overflow:ellipsis\"></div>` +\n `</div>`;\n const pick = (sel: string) => el.querySelector(sel) as HTMLElement;\n const rows = {} as Record<Metric, { value: HTMLElement; dot: HTMLElement }>;\n for (const m of METRICS) rows[m.key] = { value: pick(`[data-v=\"${m.key}\"]`), dot: pick(`[data-d=\"${m.key}\"]`) };\n this.f = { rows, env: pick('[data-f=\"env\"]') };\n this.bodyEl = pick('[data-f=\"body\"]');\n this.miniEl = pick('[data-f=\"mini\"]');\n el.addEventListener('mousedown', this.onDown);\n window.addEventListener('mousemove', this.onMove);\n window.addEventListener('mouseup', this.onUp);\n window.addEventListener('resize', this.onResize);\n document.body.appendChild(el);\n this.el = el;\n this.applyCollapsed();\n this.clamp();\n }\n\n private onDown = (e: MouseEvent) => {\n if (e.button !== 0 || !this.el) return;\n e.preventDefault();\n e.stopPropagation();\n const r = this.el.getBoundingClientRect();\n this.left = r.left;\n this.top = r.top;\n this.placed = true;\n this.el.style.left = `${this.left}px`;\n this.el.style.top = `${this.top}px`;\n this.el.style.bottom = 'auto';\n this.el.style.cursor = 'grabbing';\n this.drag = { mx: e.clientX, my: e.clientY, left: this.left, top: this.top, moved: false };\n };\n\n private onMove = (e: MouseEvent) => {\n const d = this.drag;\n if (!d || !this.el) return;\n const dx = e.clientX - d.mx;\n const dy = e.clientY - d.my;\n if (!d.moved && dx * dx + dy * dy < 25) return;\n d.moved = true;\n this.left = d.left + dx;\n this.top = d.top + dy;\n this.clamp();\n };\n\n private onUp = () => {\n const d = this.drag;\n this.drag = null;\n if (this.el) this.el.style.cursor = 'grab';\n if (d && !d.moved) this.toggle();\n };\n\n private onResize = () => this.clamp();\n\n private toggle() {\n this.collapsed = !this.collapsed;\n this.applyCollapsed();\n this.clamp();\n }\n\n private applyCollapsed() {\n const el = this.el;\n if (!el || !this.bodyEl || !this.miniEl) return;\n this.bodyEl.style.display = this.collapsed ? 'none' : 'block';\n this.miniEl.style.display = this.collapsed ? 'flex' : 'none';\n el.style.width = this.collapsed ? 'auto' : '250px';\n el.style.padding = this.collapsed ? '6px 10px' : '8px 10px';\n this.showEnv();\n }\n\n private clamp() {\n const el = this.el;\n if (!el) return;\n const pad = 8;\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n const maxL = Math.max(pad, window.innerWidth - w - pad);\n const maxT = Math.max(pad, window.innerHeight - h - pad);\n if (this.placed) {\n this.left = Math.min(maxL, Math.max(pad, this.left));\n this.top = Math.min(maxT, Math.max(pad, this.top));\n el.style.left = `${this.left}px`;\n el.style.top = `${this.top}px`;\n el.style.bottom = 'auto';\n }\n }\n\n private show(latency: number, editor: number, queue: number) {\n const f = this.f;\n if (!f) return;\n const values: Record<Metric, number> = { latency, editor, queue };\n for (const m of METRICS) {\n const v = values[m.key];\n const row = f.rows[m.key];\n row.value.textContent = `${v.toFixed(1)}ms`;\n const color = v <= LIMITS[0] ? '#3ddc84' : v <= LIMITS[1] ? '#f5c542' : '#ff5a5a';\n row.dot.style.color = color;\n const mini = this.el?.querySelector(`[data-md=\"${m.key}\"]`) as HTMLElement | null;\n if (mini) mini.style.color = color;\n }\n window.clearTimeout(this.idleTimer);\n this.idleTimer = window.setTimeout(() => this.showIdle(), IDLE_MS);\n }\n\n private showIdle() {\n const f = this.f;\n if (!f) return;\n for (const m of METRICS) {\n f.rows[m.key].value.textContent = '—';\n f.rows[m.key].dot.style.color = '#666';\n const mini = this.el?.querySelector(`[data-md=\"${m.key}\"]`) as HTMLElement | null;\n if (mini) mini.style.color = '#666';\n }\n this.showEnv();\n }\n\n private showEnv() {\n if (!this.f) return;\n const s = this.getStats();\n const chars = s.chars >= 10000 ? `${(s.chars / 10000).toFixed(1)}万字` : `${s.chars}字`;\n this.f.env.textContent = `帧率 ${this.fps || '—'}fps · ${chars} · ${s.paragraphs}段`;\n const miniFps = this.el?.querySelector('[data-f=\"mini-fps\"]');\n if (miniFps) miniFps.textContent = `${this.fps || '—'}fps`;\n }\n}\n\nexport function countParagraphs(spacers: string) {\n let n = 0;\n for (let i = spacers.indexOf('\\n'); i !== -1; i = spacers.indexOf('\\n', i + 1)) n++;\n return n;\n}\n","/**\n * 光标跳转目标的纯计算:按词 / 段落跳。\n *\n * 只吃字符流和下标,不碰选区与布局,便于直接断言。行首行尾、文首文尾依赖布局,\n * 由编辑器自己算。\n */\nimport { MARKERS } from '../model/markers';\n\n/** 方向键跳转的粒度 */\nexport type MoveUnit = 'word' | 'line' | 'paragraph' | 'doc';\n\nlet segmenter: Intl.Segmenter | null | undefined;\n\nfunction getSegmenter(): Intl.Segmenter | null {\n if (segmenter === undefined) {\n segmenter = typeof Intl !== 'undefined' && 'Segmenter' in Intl ? new Intl.Segmenter(undefined, { granularity: 'word' }) : null;\n }\n return segmenter;\n}\n\n/** 文档里允许放光标的最大下标:末尾那个段落符之后不是真实位置。 */\nexport function maxCaretIndex(spacers: string): number {\n return spacers.endsWith(MARKERS.PARAGRAPH) ? spacers.length - 1 : spacers.length;\n}\n\ninterface WordSpan {\n start: number;\n end: number;\n}\n\n/** 以“词”为单位切开字符流:词字符(含中文分词结果)和嵌入对象各算一个词。 */\nfunction wordSpans(spacers: string): WordSpan[] {\n const out: WordSpan[] = [];\n const seg = getSegmenter();\n if (seg) {\n for (const s of seg.segment(spacers)) {\n if (s.isWordLike || s.segment.includes(MARKERS.IMAGE)) {\n out.push({ start: s.index, end: s.index + s.segment.length });\n }\n }\n return out;\n }\n // 没有 Intl.Segmenter 的环境:按 \\w / 单个 CJK 字退化。\n const re = /[\\p{L}\\p{N}_]+|\\*/gu;\n let m: RegExpExecArray | null;\n while ((m = re.exec(spacers))) out.push({ start: m.index, end: m.index + m[0].length });\n return out;\n}\n\n/**\n * Option/Ctrl+←→ 的目标:向右到“下一个词的末尾”,向左到“上一个词的开头”。\n * 标点、空白、段落符都当作词间隔跳过。\n */\nexport function wordTarget(spacers: string, index: number, dir: 1 | -1): number {\n const spans = wordSpans(spacers);\n if (dir > 0) {\n for (const w of spans) if (w.end > index) return Math.min(w.end, maxCaretIndex(spacers));\n return maxCaretIndex(spacers);\n }\n for (let i = spans.length - 1; i >= 0; i--) if (spans[i].start < index) return spans[i].start;\n return 0;\n}\n\n/**\n * Option/Ctrl+↑↓ 的目标:向上到本段开头(已在开头则到上一段开头),\n * 向下到本段末尾(已在末尾则到下一段末尾)。\n */\nexport function paragraphTarget(spacers: string, index: number, dir: 1 | -1): number {\n const max = maxCaretIndex(spacers);\n if (dir < 0) {\n const start = index > 0 ? spacers.lastIndexOf(MARKERS.PARAGRAPH, index - 1) + 1 : 0;\n if (start < index) return start;\n if (index <= 0) return 0;\n return spacers.lastIndexOf(MARKERS.PARAGRAPH, index - 2) + 1;\n }\n const end = spacers.indexOf(MARKERS.PARAGRAPH, index);\n if (end === -1) return max;\n if (end > index) return Math.min(end, max);\n const next = spacers.indexOf(MARKERS.PARAGRAPH, index + 1);\n return next === -1 ? max : Math.min(next, max);\n}\n\n/**\n * 双击选词:返回 `index` 所在(或紧邻左侧)的词的范围;落在空白/标点上返回 null。\n * 光标恰在两词交界时取右边那个词,和原生一致。\n */\nexport function wordRangeAt(spacers: string, index: number): { start: number; end: number } | null {\n const spans = wordSpans(spacers);\n const hit = spans.find((w) => index >= w.start && index < w.end) ?? spans.find((w) => index === w.end);\n return hit ? { start: hit.start, end: hit.end } : null;\n}\n","import { ImageEntity, Slice, StyleSpan } from '../model/types';\n\n/** 自定义剪贴板 MIME:跨编辑器粘贴时保全样式与嵌入实体。 */\nexport const SLICE_MIME = 'text/x-mini-editor-slice';\n\nexport function serializeSlice(slice: Slice): string {\n return JSON.stringify(slice);\n}\n\nexport function parseSlice(raw: string): Slice | null {\n if (!raw) return null;\n try {\n const data = JSON.parse(raw) as Slice;\n if (!data || typeof data.text !== 'string' || !Array.isArray(data.styles)) return null;\n return {\n text: data.text,\n styles: (data.styles as StyleSpan[]).filter((s) => typeof s.start === 'number' && typeof s.end === 'number'),\n entities: Array.isArray(data.entities) ? (data.entities as ImageEntity[]) : [],\n virtualBlocks: Array.isArray(data.virtualBlocks) ? data.virtualBlocks : undefined\n };\n } catch {\n return null;\n }\n}\n\nexport function sliceFromClipboard(data: DataTransfer | null): Slice | null {\n if (!data) return null;\n return parseSlice(data.getData(SLICE_MIME));\n}\n","import { embedPlugin, syncEmbedLayer } from '../embed';\nimport { canvasFont, FONT_FAMILY } from '../layout/measure';\nimport { CaretPos, DocLayout, GlyphBox, SelRect } from '../layout/types';\nimport { canvasFill, groupDecorationRuns, paintCanvasStrike, paintCanvasUnderline } from './decorations';\nimport { PaintBackend } from './types';\n\n/**\n * 画布左右各比文档宽出这么多:mark 等块的 paddingX 外扩在行首行尾会画到内容区外,\n * 画布若恰好等宽就会被裁掉。画布整体左移 GUTTER 并平移绘制坐标,文字位置不变;\n * 配套的 style.css 给 .mini-page-wrap 左右各留同样宽度的可视区(负 margin 抵消)。\n */\nexport const CANVAS_GUTTER = 5;\n\n/**\n * 画布只覆盖可视区上下各这么多像素,而不是整篇文档。长文档(几万字)的整页画布\n * 会超过浏览器单张画布上限,而且每次光标闪烁都要清整张画布、每次换行都要重画全文。\n * 窗口外的内容滚进来时再按需重画。\n */\nconst VIEWPORT_MARGIN = 600;\n/**\n * 双指缩放(visualViewport.scale)不改 devicePixelRatio,位图被整体拉大就糊。这里把画布的\n * 像素密度乘上缩放倍数重画。倍数封顶,避免背包像素爆炸:放大 3 倍像素就是 9 倍。\n */\nconst MAX_ZOOM_SHARPNESS = 3;\n\nexport class CanvasPainter implements PaintBackend {\n private host: HTMLElement | null = null;\n private surface: HTMLElement | null = null;\n private canvas: HTMLCanvasElement | null = null;\n private chrome: HTMLCanvasElement | null = null;\n private ctx: CanvasRenderingContext2D | null = null;\n private chromeCtx: CanvasRenderingContext2D | null = null;\n private layout: DocLayout | null = null;\n private selRects: SelRect[] = [];\n private caret: CaretPos | null = null;\n private caretVisible = false;\n private caretTrails: CaretPos[] = [];\n private imageCache = new Map<string, HTMLImageElement>();\n private embeds: HTMLElement | null = null;\n private embedCache = new Map<string, HTMLElement>();\n private hasContent = false;\n private hoverId: string | null = null;\n /** 画布窗口在文档坐标里的顶部与高度(CSS px) */\n private winTop = 0;\n private winH = 0;\n private onScroll = () => this.followViewport();\n /** 上次重画用的像素密度(dpr × 缩放),变了就得整窗重画 */\n private lastScale = 0;\n private zoomRaf = 0;\n private zoomTimer = 0;\n private lastZoomPaint = 0;\n /** 缩放手势事件很密:节流到约 100ms 一次,手势停下后再精确补一次 */\n private onVisualViewport = () => {\n if (this.zoomRaf) return;\n this.zoomRaf = requestAnimationFrame(() => {\n this.zoomRaf = 0;\n const now = performance.now();\n if (now - this.lastZoomPaint >= 100) {\n this.lastZoomPaint = now;\n this.followViewport();\n }\n window.clearTimeout(this.zoomTimer);\n this.zoomTimer = window.setTimeout(() => this.followViewport(), 150);\n });\n };\n\n mount(host: HTMLElement) {\n this.destroy();\n this.host = host;\n this.surface = document.createElement('div');\n this.surface.className = 'mini-surface mini-surface-canvas';\n this.canvas = document.createElement('canvas');\n this.canvas.className = 'mini-canvas';\n this.chrome = document.createElement('canvas');\n this.chrome.className = 'mini-canvas mini-canvas-chrome';\n this.embeds = document.createElement('div');\n this.embeds.className = 'mini-layer mini-embeds';\n this.ctx = this.canvas.getContext('2d');\n this.chromeCtx = this.chrome.getContext('2d');\n this.surface.append(this.chrome, this.canvas, this.embeds);\n host.appendChild(this.surface);\n // 捕获阶段监听所有滚动(容器滚或窗口滚都算),只有可视区跑出画布窗口才重画\n document.addEventListener('scroll', this.onScroll, { capture: true, passive: true });\n window.addEventListener('resize', this.onScroll);\n // 双指缩放 / 缩放后平移只会动 visualViewport,不触发 document scroll\n window.visualViewport?.addEventListener('resize', this.onVisualViewport);\n window.visualViewport?.addEventListener('scroll', this.onVisualViewport);\n }\n\n /** 画布像素密度:dpr × 双指缩放倍数(封顶) */\n private pixelScale(): number {\n const dpr = window.devicePixelRatio || 1;\n const zoom = Math.min(MAX_ZOOM_SHARPNESS, Math.max(1, window.visualViewport?.scale ?? 1));\n return dpr * zoom;\n }\n\n getSurface(): HTMLElement {\n if (!this.surface) throw new Error('painter not mounted');\n return this.surface;\n }\n\n paintDoc(layout: DocLayout) {\n const prev = this.layout;\n this.layout = layout;\n const resized = this.resize(layout);\n // 画布尺寸或窗口位置一变,内容整块作废,只能全画(窗口范围内)\n const band =\n resized || !this.hasContent\n ? { top: 0, bottom: Math.max(layout.height, prev?.height ?? 0) }\n : layout.dirty;\n this.redrawContent(band);\n if (this.embeds) syncEmbedLayer(this.embeds, this.embedCache, layout.images, true);\n this.redrawChrome();\n }\n\n setHoverBlock(id: string | null) {\n if (id === this.hoverId) return;\n const prev = this.hoverId;\n this.hoverId = id;\n const layout = this.layout;\n if (!layout) return;\n for (const target of [prev, id]) {\n if (!target) continue;\n let top = Infinity;\n let bottom = -Infinity;\n for (const line of layout.lines) {\n for (const vb of line.vblocks ?? []) {\n if (vb.id !== target) continue;\n top = Math.min(top, vb.y, line.y);\n bottom = Math.max(bottom, vb.y + vb.h, line.y + line.h);\n }\n }\n if (top < bottom) this.redrawContent({ top: top - 1, bottom: bottom + 1 });\n }\n }\n\n paintSelection(rects: SelRect[]) {\n this.selRects = rects;\n this.redrawChrome();\n }\n\n paintCaret(caret: CaretPos | null, visible: boolean, trails: CaretPos[] = []) {\n this.caret = caret;\n this.caretVisible = visible;\n this.caretTrails = trails;\n this.redrawChrome();\n }\n\n destroy() {\n document.removeEventListener('scroll', this.onScroll, { capture: true });\n window.removeEventListener('resize', this.onScroll);\n window.visualViewport?.removeEventListener('resize', this.onVisualViewport);\n window.visualViewport?.removeEventListener('scroll', this.onVisualViewport);\n cancelAnimationFrame(this.zoomRaf);\n window.clearTimeout(this.zoomTimer);\n this.zoomRaf = 0;\n this.surface?.remove();\n this.host = null;\n this.surface = null;\n this.canvas = null;\n this.chrome = null;\n this.embeds = null;\n this.ctx = null;\n this.chromeCtx = null;\n this.layout = null;\n this.hasContent = false;\n this.imageCache.clear();\n for (const node of this.embedCache.values()) node.remove();\n this.embedCache.clear();\n }\n\n /** 可视区在文档坐标里的 [top, bottom]。找不到容器时就当整篇可见。 */\n private visibleRange(layout: DocLayout): { top: number; bottom: number } {\n if (!this.surface) return { top: 0, bottom: layout.height };\n const rect = this.surface.getBoundingClientRect();\n // 双指缩放后真正可见的只是布局视口的一部分:visualViewport 的 offsetTop / height\n // 都是布局视口 CSS 像素,与 getBoundingClientRect 同坐标系\n const vv = window.visualViewport;\n const viewTop = vv?.offsetTop ?? 0;\n // 个别环境(无头)visualViewport.height 给的是无意义的小数,退回 innerHeight / scale\n const vvH = vv && vv.height > 50 ? vv.height : (window.innerHeight || layout.height) / Math.max(1, vv?.scale ?? 1);\n const viewH = vvH || layout.height;\n // 浏览器窗口即最外层裁剪;容器滚动时 surface 的 rect 也会跟着变,因此一次 rect 读数就够\n return { top: Math.max(0, viewTop - rect.top), bottom: Math.min(layout.height, viewTop + viewH - rect.top) };\n }\n\n /** 按当前可视区决定画布窗口位置。返回是否挪了窗口。 */\n private placeWindow(layout: DocLayout, force: boolean): boolean {\n const vis = this.visibleRange(layout);\n const viewH = Math.max(1, vis.bottom - vis.top);\n const margin = VIEWPORT_MARGIN / Math.max(1, Math.min(MAX_ZOOM_SHARPNESS, window.visualViewport?.scale ?? 1));\n const wantH = Math.ceil(viewH + margin * 2);\n // 整篇都装得下:窗口就是整篇,位置固定为 0。短文档(业务里常见的几行输入框)必须走这条,\n // 否则残留的 winTop / winH 会让画布盖不住首行、或超出 surface 底部把容器撑出滚动条。\n if (wantH >= layout.height) {\n const changed = this.winTop !== 0 || this.winH !== layout.height;\n this.winTop = 0;\n this.winH = layout.height;\n return changed;\n }\n const maxTop = Math.max(0, layout.height - wantH);\n // 现有窗口仍然合法(没超出文档底部)且盖住了可视区,就不动\n const legal = this.winTop >= 0 && this.winTop <= maxTop && this.winTop + this.winH <= layout.height;\n const covers = vis.top >= this.winTop && vis.bottom <= this.winTop + this.winH;\n if (!force && legal && covers && this.winH >= wantH) return false;\n this.winTop = Math.min(maxTop, Math.max(0, Math.floor(vis.top - margin)));\n this.winH = wantH;\n return true;\n }\n\n /** 滚动/窗口尺寸变化:可视区离开画布窗口时挪窗口并整体重画 */\n private followViewport() {\n const layout = this.layout;\n if (!layout || !this.canvas) return;\n const scaleChanged = this.pixelScale() !== this.lastScale;\n if (!this.placeWindow(layout, scaleChanged) && !scaleChanged) return;\n this.resize(layout);\n this.redrawContent({ top: this.winTop, bottom: this.winTop + this.winH });\n this.redrawChrome();\n }\n\n private resize(layout: DocLayout): boolean {\n if (!this.surface || !this.canvas || !this.chrome || !this.ctx || !this.chromeCtx) return false;\n this.surface.style.width = `${layout.width}px`;\n this.surface.style.height = `${layout.height}px`;\n const moved = this.placeWindow(layout, false);\n const dpr = this.pixelScale();\n this.lastScale = dpr;\n const fullW = layout.width + CANVAS_GUTTER * 2;\n const w = Math.max(1, Math.round(fullW * dpr));\n const h = Math.max(1, Math.round(this.winH * dpr));\n const resized = this.canvas.width !== w || this.canvas.height !== h;\n if (resized) {\n for (const node of [this.canvas, this.chrome]) {\n node.width = w;\n node.height = h;\n node.style.width = `${fullW}px`;\n node.style.height = `${this.winH}px`;\n node.style.position = 'absolute';\n node.style.left = `${-CANVAS_GUTTER}px`;\n }\n }\n const topCss = `${this.winTop}px`;\n if (this.canvas.style.top !== topCss) {\n this.canvas.style.top = topCss;\n this.chrome.style.top = topCss;\n }\n // 绘制坐标仍是文档坐标:平移抵消窗口顶部\n this.ctx.setTransform(dpr, 0, 0, dpr, CANVAS_GUTTER * dpr, -this.winTop * dpr);\n this.chromeCtx.setTransform(dpr, 0, 0, dpr, CANVAS_GUTTER * dpr, -this.winTop * dpr);\n return resized || moved;\n }\n\n private redrawContent(band: { top: number; bottom: number }) {\n const ctx = this.ctx;\n const layout = this.layout;\n if (!ctx || !layout || !this.canvas) return;\n\n // 只画落在画布窗口里的那一段;窗口外的滚进来时由 followViewport 补画\n const top = Math.max(0, band.top, this.winTop);\n const bottom = Math.min(band.bottom, this.winTop + this.winH);\n if (top >= bottom) {\n this.hasContent = true;\n return;\n }\n const hits = (y: number, h: number) => y < bottom && y + h > top;\n ctx.save();\n ctx.beginPath();\n ctx.rect(-CANVAS_GUTTER, top, layout.width + CANVAS_GUTTER * 2, bottom - top);\n ctx.clip();\n const editorRoot = this.host?.closest('.mini-editor') as HTMLElement | null;\n // 文字画布始终透明:选区画在它下面,白底由 .mini-surface 的背景提供。\n ctx.clearRect(-CANVAS_GUTTER, top, layout.width + CANVAS_GUTTER * 2, bottom - top);\n\n ctx.strokeStyle = '#c9cdd4';\n ctx.lineWidth = 1;\n for (const table of layout.tables) {\n if (!hits(table.y, table.h)) continue;\n for (const cell of table.cells) {\n ctx.strokeRect(cell.x + 0.5, cell.y + 0.5, cell.w - 1, cell.h - 1);\n }\n }\n\n for (const line of layout.lines) {\n if (!hits(line.y, line.h)) continue;\n if (line.marker) {\n ctx.save();\n const family =\n (editorRoot ? getComputedStyle(editorRoot).fontFamily : '') || FONT_FAMILY;\n ctx.font = `400 16px ${family}`;\n ctx.fillStyle = '#667085';\n ctx.textAlign = 'right';\n ctx.textBaseline = 'top';\n const markerTop = line.marker.y + (line.marker.h - 16) / 2;\n ctx.fillText(line.marker.text, line.marker.x + line.marker.w - 8, markerTop);\n ctx.restore();\n }\n for (const vb of line.vblocks ?? []) this.paintVBlock(ctx, vb);\n for (const g of line.glyphs) this.paintGlyph(ctx, g);\n this.paintLineDeco(ctx, line.glyphs);\n for (const img of line.images) {\n embedPlugin(img.entity.kind).paintCanvasBackdrop(ctx, img, (src) => this.imageOf(src));\n }\n }\n for (const img of layout.images) {\n if (!img.entity.float || !hits(img.y, img.h)) continue;\n embedPlugin(img.entity.kind).paintCanvasBackdrop(ctx, img, (src) => this.imageOf(src));\n }\n ctx.restore();\n this.hasContent = true;\n }\n\n private redrawChrome() {\n const ctx = this.chromeCtx;\n const layout = this.layout;\n if (!ctx || !layout || !this.chrome) return;\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, this.chrome.width, this.chrome.height);\n ctx.restore();\n\n for (const r of this.selRects) {\n if (r.outline) this.strokeVBlockOutline(ctx, r);\n else this.fillSelectionRect(ctx, r);\n }\n\n for (const [i, t] of this.caretTrails.entries()) {\n this.drawCaret(ctx, t, 0.22 - i * 0.06);\n }\n if (this.caret && this.caretVisible) this.drawCaret(ctx, this.caret, this.caret.opacity ?? 1);\n }\n\n private fillSelectionRect(\n ctx: CanvasRenderingContext2D,\n r: { x: number; y: number; w: number; h: number }\n ) {\n const editorRoot = this.host?.closest('.mini-editor') as HTMLElement | null;\n const cs = editorRoot ? getComputedStyle(editorRoot) : null;\n const color = cs?.getPropertyValue('--mini-sel-color').trim() ?? '';\n const radius = cs ? parseFloat(cs.getPropertyValue('--mini-sel-radius')) || 0 : 0;\n const rainbow = editorRoot?.getAttribute('data-caret') === 'rainbow' && !color;\n ctx.beginPath();\n ctx.roundRect(r.x, r.y, r.w, r.h, radius);\n if (rainbow) {\n const grad = ctx.createLinearGradient(r.x, r.y, r.x + r.w, r.y);\n grad.addColorStop(0, 'rgba(255, 77, 109, 0.16)');\n grad.addColorStop(1, 'rgba(43, 108, 255, 0.22)');\n ctx.fillStyle = grad;\n } else {\n ctx.fillStyle = color || 'rgba(43, 108, 255, 0.22)';\n }\n ctx.fill();\n }\n\n private paintVBlock(\n ctx: CanvasRenderingContext2D,\n vb: { id: string; first: boolean; last: boolean; x: number; y: number; w: number; h: number; chrome: { background?: string; hoverBackground?: string; borderColor?: string; borderWidth?: number; radius?: number }; kind: string }\n ) {\n const c = vb.chrome;\n const fill = vb.id === this.hoverId && c.hoverBackground ? c.hoverBackground : c.background;\n const base = c.radius ?? (vb.kind === 'virtualSlot' ? 4 : vb.kind === 'mark' ? 3 : 6);\n // 首行上两角圆、末行下两角圆,其余角方;单行自然四角全圆。\n const top = vb.first ? base : 0;\n const bottom = vb.last ? base : 0;\n const radius: number[] = [top, top, bottom, bottom];\n if (fill) {\n ctx.beginPath();\n ctx.roundRect(vb.x, vb.y, vb.w, vb.h, radius);\n ctx.fillStyle = fill;\n ctx.fill();\n }\n if (c.borderWidth && c.borderColor) {\n ctx.beginPath();\n ctx.roundRect(vb.x + 0.5, vb.y + 0.5, Math.max(0, vb.w - 1), Math.max(0, vb.h - 1), radius);\n ctx.strokeStyle = c.borderColor;\n ctx.lineWidth = c.borderWidth;\n ctx.stroke();\n }\n }\n\n private strokeVBlockOutline(\n ctx: CanvasRenderingContext2D,\n r: { x: number; y: number; w: number; h: number; radius?: number }\n ) {\n const radius = r.radius ?? 6;\n ctx.beginPath();\n ctx.roundRect(r.x + 0.5, r.y + 0.5, Math.max(0, r.w - 1), Math.max(0, r.h - 1), radius);\n ctx.strokeStyle = '#2b6cff';\n ctx.lineWidth = 2;\n ctx.stroke();\n }\n\n private drawCaret(ctx: CanvasRenderingContext2D, caret: CaretPos, alpha: number) {\n const { x, y, h } = caret;\n const editorRoot = this.host?.closest('.mini-editor') as HTMLElement | null;\n const solid = editorRoot?.getAttribute('data-caret') !== 'rainbow';\n const caretW = editorRoot\n ? parseFloat(getComputedStyle(editorRoot).getPropertyValue('--mini-caret-width')) || 2\n : 2;\n const w = solid ? caretW : caret.bold ? 4.5 : 3;\n ctx.save();\n ctx.globalAlpha = Math.max(0, alpha);\n if (!solid && caret.italic) {\n ctx.translate(x, y + h);\n ctx.transform(1, 0, -0.25, 1, 0, 0);\n ctx.translate(-x, -(y + h));\n }\n const editorCs = editorRoot ? getComputedStyle(editorRoot) : null;\n if (solid) {\n ctx.fillStyle = editorCs?.getPropertyValue('--mini-caret-color').trim() || '#09090b';\n const glow = editorCs?.getPropertyValue('--mini-caret-glow').trim() ?? '';\n if (glow && glow !== 'none') {\n ctx.shadowColor = glow;\n ctx.shadowBlur = 6;\n }\n } else {\n const grad = ctx.createLinearGradient(x, y, x, y + h);\n grad.addColorStop(0, '#ff4d6d');\n grad.addColorStop(0.35, '#ffd166');\n grad.addColorStop(0.65, '#06d6a0');\n grad.addColorStop(1, '#4cc9f0');\n ctx.fillStyle = grad;\n }\n ctx.fillRect(x, y, w, h);\n ctx.restore();\n }\n\n private paintGlyph(ctx: CanvasRenderingContext2D, g: GlyphBox) {\n const size = g.style.fontSize ?? 16;\n ctx.font = canvasFont(g.style);\n ctx.fillStyle = canvasFill(g.style, g.index);\n ctx.textAlign = 'left';\n ctx.textBaseline = 'alphabetic';\n const metrics = ctx.measureText(g.text || '汉');\n const ascent = metrics.fontBoundingBoxAscent || size * 0.8;\n const descent = metrics.fontBoundingBoxDescent || size * 0.2;\n const fontH = ascent + descent;\n const boxTop = g.y + (g.h - fontH) / 2;\n const baseline = boxTop + ascent;\n ctx.fillText(g.text, g.x, baseline);\n }\n\n private paintLineDeco(ctx: CanvasRenderingContext2D, glyphs: GlyphBox[]) {\n for (const run of groupDecorationRuns(glyphs)) {\n const size = run.size;\n if (run.kind !== 'none') paintCanvasUnderline(ctx, run.x, run.y + Math.max(1, size * 0.06), run.w, size, run.kind, run.color);\n if (run.strike) paintCanvasStrike(ctx, run.x, run.y - size * 0.35, run.w, size, run.color);\n }\n }\n\n private imageOf(src: string): HTMLImageElement {\n let img = this.imageCache.get(src);\n if (img) return img;\n img = new Image();\n img.onload = () => {\n // 图片是异步到的,不知道它落在哪一段,整份重画\n if (this.layout) this.redrawContent({ top: 0, bottom: this.layout.height });\n };\n img.src = src;\n this.imageCache.set(src, img);\n return img;\n }\n}\n","import { underlineKind } from '../model/types';\nimport { syncEmbedLayer } from '../embed';\nimport { CaretPos, DocLayout, LineBox, SelRect, TableLayout, VBlockFragment } from '../layout/types';\nimport { cssFill, fillOf } from './decorations';\nimport { PaintBackend } from './types';\n\nfunction cssText(style: LineBox['glyphs'][0]['style'], runW: number): string {\n const size = style.fontSize ?? 16;\n const weight = style.bold ? '700' : String(style.fontWeight ?? 400);\n const italic = style.italic ? 'italic' : 'normal';\n const color = style.color ?? '#1f2329';\n const fill = cssFill(style, runW);\n return `font-style:${italic};font-weight:${weight};font-size:${size}px;font-family:var(--mini-font-family);color:${color};text-decoration:none;${fill}`;\n}\n\nexport class HtmlPainter implements PaintBackend {\n private host: HTMLElement | null = null;\n private surface: HTMLElement | null = null;\n private content: HTMLElement | null = null;\n private selection: HTMLElement | null = null;\n private caret: HTMLElement | null = null;\n private trails: HTMLElement[] = [];\n private embeds: HTMLElement | null = null;\n private embedCache = new Map<string, HTMLElement>();\n private hoverId: string | null = null;\n\n mount(host: HTMLElement) {\n this.destroy();\n this.host = host;\n this.surface = document.createElement('div');\n this.surface.className = 'mini-surface';\n this.selection = document.createElement('div');\n this.selection.className = 'mini-layer mini-selection';\n this.content = document.createElement('div');\n this.content.className = 'mini-layer mini-content';\n this.caret = document.createElement('div');\n this.caret.className = 'mini-caret';\n this.embeds = document.createElement('div');\n this.embeds.className = 'mini-layer mini-embeds';\n this.trails = [0, 1, 2].map(() => {\n const el = document.createElement('div');\n el.className = 'mini-caret mini-caret-trail';\n el.style.display = 'none';\n return el;\n });\n this.surface.append(this.selection, this.content, this.embeds, ...this.trails, this.caret);\n host.appendChild(this.surface);\n }\n\n getSurface(): HTMLElement {\n if (!this.surface) throw new Error('painter not mounted');\n return this.surface;\n }\n\n paintDoc(layout: DocLayout) {\n if (!this.surface || !this.content) return;\n this.surface.style.width = `${layout.width}px`;\n this.surface.style.height = `${layout.height}px`;\n // 只重建和脏区带相交的元素。元素都是绝对定位的,没动过的留在原地即可 ——\n // 连 DOM 顺序都不用管。\n const { top, bottom } = layout.dirty;\n // 空的、或者脏区带盖住了整页,就整块换掉:比逐个摘掉再补回来省事。\n // 脏区 {top:0,bottom:0} 表示「几何相对上一帧没变」,此处跳过子节点更新。\n // 调用方若整篇换了文档却仍传入空脏区,正文 DOM 会陈旧(见 Editor.setContent)。\n const full = !this.content.childElementCount || (top <= 0 && bottom >= layout.height);\n const hits = (y: number, h: number) => full || (y < bottom && y + h > top);\n\n if (full) {\n this.content.replaceChildren();\n } else {\n // 脏区带为空时 hits() 处处为假,下面几个循环自然什么都不做\n for (const child of [...this.content.children]) {\n const el = child as HTMLElement;\n if (hits(Number(el.dataset.y ?? 0), Number(el.dataset.h ?? 0))) el.remove();\n }\n }\n\n for (const table of layout.tables) {\n if (hits(table.y, table.h)) this.content.appendChild(renderTableChrome(table));\n }\n for (const line of layout.lines) {\n if (hits(line.y, line.h)) this.content.appendChild(renderLine(line));\n }\n // 嵌入对象是独立图层,自己按 id 做增删改,不受脏区带影响\n if (this.embeds) syncEmbedLayer(this.embeds, this.embedCache, layout.images, false);\n if (this.hoverId) this.applyHover();\n }\n\n setHoverBlock(id: string | null) {\n if (id === this.hoverId) return;\n this.hoverId = id;\n this.applyHover();\n }\n\n private applyHover() {\n if (!this.content) return;\n for (const node of this.content.querySelectorAll<HTMLElement>('.mini-vblock[data-hover-bg]')) {\n const on = node.dataset.id === this.hoverId;\n node.style.background = on ? node.dataset.hoverBg! : node.dataset.bg ?? 'transparent';\n }\n }\n\n paintSelection(rects: SelRect[]) {\n if (!this.selection) return;\n this.selection.replaceChildren();\n for (const r of rects) {\n const el = document.createElement('div');\n el.className = r.outline ? 'mini-vblock-outline' : 'mini-sel-rect';\n const radius = r.radius ?? 0;\n el.style.cssText = `left:${r.x}px;top:${r.y}px;width:${r.w}px;height:${r.h}px;${radius ? `border-radius:${radius}px;` : ''}`;\n this.selection.appendChild(el);\n }\n }\n\n paintCaret(caret: CaretPos | null, visible: boolean, trails: CaretPos[] = []) {\n if (!this.caret) return;\n placeCaret(this.caret, visible ? caret : null, 1);\n this.trails.forEach((el, i) => placeCaret(el, trails[i] ?? null, 0.28 - i * 0.08));\n }\n\n destroy() {\n this.surface?.remove();\n this.host = null;\n this.surface = null;\n this.content = null;\n this.selection = null;\n this.caret = null;\n this.trails = [];\n this.embeds = null;\n this.embedCache.clear();\n }\n}\n\nfunction placeCaret(el: HTMLElement, caret: CaretPos | null, fade: number) {\n if (!caret) {\n if (el.style.display !== 'none') el.style.display = 'none';\n return;\n }\n const width = caret.bold ? 4.5 : '';\n if (el.style.display !== 'block') el.style.display = 'block';\n // 光标移动时重启 CSS 闪烁动画,让它每次移动后都先亮(原生光标的表现)。\n // 不用 `void el.offsetWidth` 强制回流:长文档里一次回流要几十毫秒,而这里每帧都会跑。\n if (el.style.left !== `${caret.x}px` || el.style.top !== `${caret.y}px`) {\n for (const anim of el.getAnimations()) anim.currentTime = 0;\n }\n el.style.left = `${caret.x}px`;\n el.style.top = `${caret.y}px`;\n el.style.height = `${caret.h}px`;\n el.style.width = width === '' ? '' : `${width}px`;\n if (caret.opacity != null) el.style.opacity = String(caret.opacity * fade);\n else if (el.style.opacity) el.style.opacity = '';\n el.style.transform = caret.italic ? 'skewX(-14deg)' : 'none';\n el.classList.toggle('is-italic', !!caret.italic);\n}\n\nfunction renderLine(line: LineBox): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'mini-line';\n wrap.dataset.start = String(line.start);\n wrap.dataset.end = String(line.end);\n wrap.dataset.y = String(line.y);\n wrap.dataset.h = String(line.h);\n\n for (const vb of line.vblocks ?? []) {\n wrap.appendChild(renderVBlock(vb));\n }\n\n if (line.marker) {\n const m = document.createElement('span');\n m.className = 'mini-list-marker';\n m.textContent = line.marker.text;\n m.style.cssText = `left:${line.marker.x}px;top:${line.marker.y}px;width:${line.marker.w}px;height:${line.marker.h}px;`;\n wrap.appendChild(m);\n }\n\n if (line.glyphs.length > 0) {\n let run: { start: number; text: string; style: LineBox['glyphs'][0]['style']; x: number; y: number; h: number; w: number } | null = null;\n const flush = () => {\n if (!run) return;\n const span = document.createElement('span');\n span.className = `mini-run${fillOf(run.style) !== 'solid' ? ' is-fill' : ''}`;\n span.textContent = run.text;\n span.style.cssText = `left:${run.x}px;top:${run.y}px;width:${run.w}px;height:${run.h}px;line-height:${run.h}px;${cssText(run.style, run.w)}`;\n wrap.appendChild(span);\n const deco = underlineKind(run.style);\n if (deco !== 'none' || run.style.strikethrough) {\n const bar = document.createElement('span');\n bar.className = `mini-deco mini-deco-${deco}${run.style.strikethrough ? ' is-strike' : ''}`;\n bar.style.cssText = `left:${run.x}px;top:${run.y}px;width:${run.w}px;height:${run.h}px;color:${run.style.color ?? '#1f2329'};`;\n wrap.appendChild(bar);\n }\n run = null;\n };\n for (const g of line.glyphs) {\n if (\n run &&\n run.style.bold === g.style.bold &&\n run.style.italic === g.style.italic &&\n run.style.underline === g.style.underline &&\n run.style.underlineStyle === g.style.underlineStyle &&\n run.style.strikethrough === g.style.strikethrough &&\n run.style.fontSize === g.style.fontSize &&\n run.style.color === g.style.color &&\n run.style.fill === g.style.fill &&\n run.start + run.text.length === g.index\n ) {\n run.text += g.text;\n run.w += g.w;\n } else {\n flush();\n run = { start: g.index, text: g.text, style: g.style, x: g.x, y: g.y, h: g.h, w: g.w };\n }\n }\n flush();\n }\n\n return wrap;\n}\n\nfunction renderVBlock(vb: VBlockFragment): HTMLElement {\n const el = document.createElement('span');\n el.className = 'mini-vblock';\n el.dataset.id = vb.id;\n const c = vb.chrome;\n if (c.hoverBackground) {\n el.dataset.hoverBg = c.hoverBackground;\n el.dataset.bg = c.background ?? 'transparent';\n }\n const base = c.radius ?? (vb.kind === 'virtualSlot' ? 4 : vb.kind === 'mark' ? 3 : 6);\n // 首行上两角圆、末行下两角圆,其余角方;单行自然四角全圆。\n const top = vb.first ? base : 0;\n const bottom = vb.last ? base : 0;\n const radius = `${top}px ${top}px ${bottom}px ${bottom}px`;\n const border = c.borderWidth\n ? `${c.borderWidth}px solid ${c.borderColor ?? 'transparent'}`\n : 'none';\n el.style.cssText = [\n `left:${vb.x}px`,\n `top:${vb.y}px`,\n `width:${vb.w}px`,\n `height:${vb.h}px`,\n `background:${c.background ?? 'transparent'}`,\n `border:${border}`,\n `border-radius:${radius}`\n ].join(';');\n return el;\n}\n\nfunction renderTableChrome(table: TableLayout): HTMLElement {\n const box = document.createElement('div');\n box.className = 'mini-table';\n box.dataset.y = String(table.y);\n box.dataset.h = String(table.h);\n box.style.cssText = `left:${table.x}px;top:${table.y}px;width:${table.w}px;height:${table.h}px;`;\n for (const cell of table.cells) {\n const c = document.createElement('div');\n c.className = 'mini-cell';\n c.style.cssText = `left:${cell.x - table.x}px;top:${cell.y - table.y}px;width:${cell.w}px;height:${cell.h}px;`;\n box.appendChild(c);\n }\n return box;\n}\n","import { activateHostEmbed, builtinEmbedPlugins, decorateRefEl, defaultSlotLabel, EMBED_CHANGE, EMBED_COMMIT, EMBED_EXIT_EDIT, EMBED_MEASURE, EmbedChangeDetail, EmbedExitDetail, EmbedMeasureDetail, embedPlugin, hostEmbedPlugin, HostEmbedRenderer, measureRef, REF_HEAD, REF_JUMP, REF_PAD, refInnerWidth, registerEmbed, setHostEmbedRenderer, syncHostSelected } from './embed';\nimport { EmbedPlugin } from './embed/types';\nimport { RefJumpDetail } from './embed/ref';\nimport type { Shortcut } from './commands';\nimport { ArrowKey, CommandTable } from './commands';\nimport { EditKind, EditResult, runEdit, runScoped, UndoRedoStack } from './edits';\nimport { ImeSurface } from './input/ime';\nimport { bindKeyboard } from './input/keyboard';\nimport { caretFromIndex, hitColBorder, hitTestIndex, imageBoxAt, layoutDocument, resolvedTextStyle, selectionRects } from './layout/engine';\nimport { lineHeightOf, measureWidth, MIN_COL_WIDTH, PAGE_CONTENT_WIDTH, PAGE_PADDING_X, PAGE_PADDING_Y } from './layout/measure';\nimport { CaretPos, DocLayout, ImageBox, LineBox } from './layout/types';\nimport { PerfProbe } from './perf';\nimport { countParagraphs, PerfPanel } from './perfPanel';\nimport { maxCaretIndex, MoveUnit, paragraphTarget, wordRangeAt, wordTarget } from './input/caretMotion';\nimport { SLICE_MIME, serializeSlice, sliceFromClipboard } from './convert/clipboard';\nimport { collapsedSel, DocumentModel, documentFromSlice, nextEntityId, sliceWithoutParagraphGroup } from './model/document';\nimport { cellAt, cellContentRange, findTableAt, isLastTableCell, isVisuallyEmptyDoc, nearestSafeIndex, nextCellIndex, parseBlocks } from './model/blocks';\nimport { applyMutations } from './mutations';\nimport * as ops from './operations';\nimport type { ImagePatch, Operation, OperationContext, VirtualBlockSpec } from './operations';\nimport { shouldTryMarkdown } from './convert/markdown';\nimport { MARKERS, nextCodePointLen, prevCodePointLen } from './model/markers';\nimport { cloneEntity, EmbedEntity, isCollapsed, MAX_LIST_INDENT, ParagraphProps, selEnd, selStart, Selection, Slice, SlotKind, TextProps, underlineKind, VIDEO_ASPECT, VirtualBlock, VirtualBlockChrome } from './model/types';\nimport { CanvasPainter } from './paint/canvasPainter';\nimport { HtmlPainter } from './paint/htmlPainter';\nimport { PaintBackend } from './paint/types';\n\nexport interface EditorOptions {\n /** 初始文档。不传则新建一个空文档。 */\n doc?: DocumentModel;\n /** 初始绘制后端,默认 `html`。 */\n paint?: 'html' | 'canvas';\n /**\n * 嵌入对象插件集,默认 {@link builtinEmbedPlugins}(图片/视频/代码块/插槽/同步块)。\n * 公式需从 `medeo-rte/formula` 单独引入后追加。\n */\n plugins?: EmbedPlugin[];\n /**\n * 内容宽度策略,默认 `'fill'`。\n * - `'fill'`:撑满宿主容器,并随容器尺寸变化自动重排(编辑器适应容器)。\n * - `number`:固定像素内容宽,行为与容器尺寸无关(适合需要确定版心的场景)。\n */\n width?: 'fill' | number;\n /**\n * 内容版心内边距(像素),默认 `{ x: 72, y: 56 }`(纸张/文档形态的版心留白)。\n * 决定内容行相对绘制表面的起始偏移与四周留白。嵌入式输入框等紧凑形态可传\n * `{ x: 0, y: 0 }`,把留白完全交给宿主 CSS 控制。\n */\n padding?: { x: number; y: number };\n /**\n * 宿主渲染器。提供后即启用 host 型嵌入对象:节点内部 DOM 由宿主用自己的框架\n * 组件渲染,SDK 只管占位、定位与生命周期。用于把业务卡片(如引用对象、插槽)\n * 挂进编辑器而不由 SDK 自绘。见 {@link HostEmbedRenderer}。\n */\n hostEmbed?: HostEmbedRenderer;\n /**\n * 空文档占位文案。由 SDK 画在首行位置,组合输入一开始就关掉(中间态已镜像进模型,\n * 宿主若只看 `change` 会误判仍为空)。之后可用 {@link Editor.setPlaceholder} 改。\n */\n placeholder?: string;\n /**\n * 未写 text span 时的默认文字属性。嵌入式输入框可传 14px 对齐业务输入。\n * `fontFamily` 须具名栈(不要 `system-ui`),会同时用于 pretext 测宽与绘制。\n * 不传则仍是文档编辑器默认 16px / `#1f2329` / 中文无衬线栈。\n */\n textDefaults?: TextProps;\n /**\n * 快捷键表。默认 {@link SHORTCUTS}(文档编辑:Enter 插段、Cmd+B 加粗等)。\n * 嵌入式输入框请传 {@link inputShortcuts}(默认 newline:Enter 换行)。\n */\n shortcuts?: Shortcut[];\n /**\n * 创建完成后是否把焦点放到 IME。默认 `true`(独立编辑器 / demo)。\n * 嵌入式输入框(如页面上的 Command Box)应传 `false`,避免抢走页面焦点。\n */\n autofocus?: boolean;\n /**\n * 光标 / 选区 / 空态占位的外观。不传则与常规编辑器一致:实心光标、扁平选区、无残影。\n * 彩虹光标 / 残影需显式 `caret: 'rainbow'`。\n */\n chrome?: EditorChrome;\n /** 左下角常驻性能面板:每次输入上屏后显示上屏延迟、编辑器耗时、排队时间。默认关;也可 `setPerfPanel()` 开关。 */\n perfPanel?: boolean;\n}\n\n/** 编辑器装饰外观(光标、选区、空态占位)。与正文字号/字体测量分开,避免宿主 CSS 盖绘制层。 */\nexport interface EditorChrome {\n /** 默认 `solid`。演示能力用 `rainbow`。 */\n caret?: 'rainbow' | 'solid';\n /** `solid` 时光标颜色,默认 `#09090b`。 */\n caretColor?: string;\n /** `solid` 时光标宽度,默认 2。 */\n caretWidth?: number;\n /** 是否画光标残影。默认关闭;`rainbow` 时可打开。 */\n caretTrail?: boolean;\n /**\n * 选区高亮色。默认接近浏览器原生选区:`rgba(43, 108, 255, 0.22)`。\n * 扁平填充,不再用彩虹渐变。`caret: 'rainbow'` 且未指定本项时,demo 仍用渐变选区。\n */\n selectionColor?: string;\n /** 选区圆角,像素。默认 0(和 `::selection` 一样是矩形)。 */\n selectionRadius?: number;\n /** 中文输入中间态下划线颜色。默认 `#1f2329`。 */\n composeUnderlineColor?: string;\n /** 中文输入中间态下划线粗细,默认 2。 */\n composeUnderlineWidth?: number;\n /** 空态占位颜色。 */\n placeholderColor?: string;\n /** 空态占位透明度 0–1。现网 Chat 为 0.2。 */\n placeholderOpacity?: number;\n /**\n * 绘制表面底色。默认纸张白(`var(--page)`)。\n * 嵌入式输入框应传 `transparent`,露出宿主输入框底,不要再铺一层白/灰。\n */\n surfaceBackground?: 'paper' | 'transparent';\n}\n\n/** 插入嵌入对象的落点:文档下标,或起/止/当前光标。 */\nexport type EmbedInsertAt = number | 'start' | 'end' | 'cursor';\n\n/** 编辑器当前状态,供宿主同步工具栏、状态栏等 UI。 */\nexport interface EditorState {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n fontSize: number;\n color: string;\n heading: 0 | 1 | 2 | 3;\n align: 'left' | 'center' | 'right';\n list: 'none' | 'ul' | 'ol';\n inTable: boolean;\n canUndo: boolean;\n canRedo: boolean;\n paintMode: 'html' | 'canvas';\n hasLink: boolean;\n canPromote: boolean;\n canInsertRef: boolean;\n canUnlink: boolean;\n /** 主文档选区 */\n selection: Selection;\n /** 主文档长度(spacer 数) */\n docLength: number;\n /** 是否正在同步块内部编辑 */\n inRefEdit: boolean;\n /** 同步块内部选区,仅 inRefEdit 为真时有意义 */\n refSelection: Selection;\n /** 虚拟块作用域栈,栈顶是当前选中/编辑的那一层 */\n vblockStack: { id: string; mode: 'selected' | 'editing' }[];\n}\n\n/**\n * - `change`:文档内容变化\n * - `selectionchange`:选区或光标移动\n * - `statechange`:{@link EditorState} 任一字段可能已变,用于同步工具栏\n * - `layoutchange`:重新排版完成,可从 {@link Editor.getLayout} 取新几何\n */\nexport type EditorEvent = 'change' | 'selectionchange' | 'statechange' | 'layoutchange';\n\nexport class Editor {\n /** 编辑器根节点,已挂载到构造时传入的容器下。 */\n readonly root: HTMLElement;\n /** 编辑命令集合,宿主自建工具栏时用。 */\n readonly commands: CommandTable;\n /** 开发用性能探针:`editor.perf.start()` … `editor.perf.report()`。默认关闭,零开销 */\n readonly perf: PerfProbe;\n private perfPanel: PerfPanel;\n /** 构造时传入的宿主容器。'fill' 模式下从它测量可用宽度。 */\n private parent: HTMLElement;\n /** 内容宽度策略,见 {@link EditorOptions.width}。 */\n private widthMode: 'fill' | number = 'fill';\n /** 内容版心内边距,见 {@link EditorOptions.padding}。所有主文档排版据此定位。 */\n private padding: { x: number; y: number } = { x: PAGE_PADDING_X, y: PAGE_PADDING_Y };\n /** 当前内容宽度(单一真相来源),所有主文档排版都读它。 */\n private contentWidth: number = PAGE_CONTENT_WIDTH;\n /** 'fill' 模式下监听宿主尺寸变化以重排;其它模式为 null。 */\n private resizeObserver: ResizeObserver | null = null;\n private page: HTMLElement;\n private pageInner: HTMLElement;\n private handle: HTMLElement;\n private embedFrame: HTMLElement;\n private imeBar: HTMLElement;\n private placeholderEl: HTMLElement;\n private placeholderText = '';\n private shortcutTable: Shortcut[] | undefined;\n private textDefaults: TextProps | null = null;\n /** 挂载后由 getComputedStyle 解析出的字体栈,专供测宽(canvas 读不懂 var())。 */\n private resolvedMeasureFamily: string | null = null;\n private chrome: EditorChrome = {};\n private disabled = false;\n private paintMode: 'html' | 'canvas' = 'html';\n private listeners: { [K in EditorEvent]: Set<() => void> } = {\n change: new Set(),\n selectionchange: new Set(),\n statechange: new Set(),\n layoutchange: new Set()\n };\n private doc: DocumentModel;\n private sel: Selection = collapsedSel(0);\n private undoStack = new UndoRedoStack();\n private layout: DocLayout;\n private painter: PaintBackend;\n private ime: ImeSurface;\n private typingStyle: TextProps | null = null;\n private keepTypingOnNextClick = false;\n private caretRaf = 0;\n private caretTrails: CaretPos[] = [];\n private lastCaretKey = '';\n /** 光标闪烁相位起点:每次光标移动/重置都从“亮”重新开始,和原生光标一致。 */\n private blinkEpoch = 0;\n private blinkPosKey = '';\n private composeText = '';\n /** 组合串镜像插入模型的起点;null 表示当前没有进行中的组合。 */\n private composeAnchor: number | null = null;\n /** 当前已镜像插入模型的组合串长度,用于下次幂等替换时删旧。 */\n private composeLen = 0;\n private refEdit: { entityId: string; fragmentId: string } | null = null;\n private fragSel: Selection = collapsedSel(0);\n private refDragging = false;\n private refDragAnchor = 0;\n private unbindKeyboard: (() => void) | null = null;\n private keysArmed = true;\n private dragging = false;\n private resizing: { id: string; startX: number; startW: number; startH: number } | null = null;\n private colResizing: { tableStart: number; col: number; startX: number; widths: number[] } | null = null;\n private embedEdit: { id: string; before: EmbedEntity } | null = null;\n private dragAnchor: number = 0;\n private vblockStack: { id: string; mode: 'selected' | 'editing' }[] = [];\n\n constructor(parent: HTMLElement, options: EditorOptions = {}) {\n for (const plugin of options.plugins ?? builtinEmbedPlugins) registerEmbed(plugin);\n // 提供了宿主渲染器才启用 host 型嵌入对象:注册插件并注入渲染器。\n if (options.hostEmbed) {\n registerEmbed(hostEmbedPlugin);\n setHostEmbedRenderer(options.hostEmbed);\n }\n\n this.parent = parent;\n this.widthMode = options.width ?? 'fill';\n this.padding = options.padding ?? { x: PAGE_PADDING_X, y: PAGE_PADDING_Y };\n this.shortcutTable = options.shortcuts;\n this.textDefaults = options.textDefaults ?? null;\n this.chrome = options.chrome ?? {};\n this.doc = options.doc ?? new DocumentModel();\n this.applyTextDefaults(this.doc);\n this.sel = collapsedSel(this.doc.length - 1);\n this.paintMode = options.paint ?? 'html';\n this.painter = this.createPainter();\n this.perf = new PerfProbe(this, () => this.painter);\n this.perfPanel = new PerfPanel(() => ({\n chars: this.doc.length,\n paragraphs: countParagraphs(this.doc.spacers)\n }));\n // 此刻尚未挂载到容器,'fill' 模式测不到宽度会回退默认值;挂载后 relayout() 修正。\n this.contentWidth = this.resolveContentWidth();\n this.layout = layoutDocument(this.doc, this.contentWidth, undefined, this.padding);\n\n this.root = document.createElement('div');\n this.root.className = 'mini-editor';\n this.root.dataset.paint = this.paintMode;\n this.applyChrome();\n this.commands = {\n toggleBold: () => this.toggleText('bold'),\n toggleItalic: () => this.toggleText('italic'),\n toggleUnderline: () => this.toggleText('underline'),\n toggleStrike: () => this.toggleText('strikethrough'),\n setFontSize: (size) => this.applyText({ fontSize: size }),\n setColor: (color) => this.applyText({ color }),\n setHeading: (level) => this.applyPara(level ? { heading: level, list: 'none' } : { heading: 0 }),\n setAlign: (align) => this.applyPara({ align }),\n toggleList: (kind) => this.toggleList(kind),\n indent: (delta) => this.changeIndent(delta),\n insertImage: (file) => this.insertMediaFile(file, 'image'),\n insertVideo: (file) => this.insertMediaFile(file, 'video'),\n insertCode: () => this.insertCodeBlock(),\n insertFormula: () => this.insertFormula(),\n insertSlot: (kind) => this.insertSlot(kind),\n insertHostEmbed: (hostType, data, size) => this.insertHostEmbed(hostType, data, size),\n insertTable: () => this.insertTable(),\n addRow: () => this.tableOp('row'),\n addCol: () => this.tableOp('col'),\n removeRow: () => this.tableOp('del-row'),\n removeCol: () => this.tableOp('del-col'),\n toggleLink: () => this.toggleLink(),\n promoteRef: () => this.promoteRef(),\n insertRef: () => this.insertExistingRef(),\n unlinkRef: () => this.unlinkSelectedRef(),\n undo: () => this.undo(),\n redo: () => this.redo(),\n insertParagraph: (opts) => this.insertParagraph(opts),\n backspace: () => this.backspace(),\n deleteForward: () => this.deleteForward(),\n selectAll: () => this.selectAll(),\n indentOrNextCell: (dir) => this.indentOrNextCell(dir),\n moveCaret: (key, extend) => this.moveCaret(key, extend),\n moveCaretBy: (unit, dir, extend) => this.moveCaretBy(unit, dir, extend),\n exitFragment: () => this.exitFragmentEdit()\n };\n\n this.page = document.createElement('div');\n this.page.className = 'mini-page-wrap';\n this.pageInner = document.createElement('div');\n this.pageInner.className = 'mini-page';\n this.painter.mount(this.pageInner);\n const track = <T>(fn: () => T) => this.perfPanel.track(fn);\n this.ime = new ImeSurface({\n onInsertText: (t) => track(() => this.insertText(t)),\n onInsertParagraph: () => track(() => this.insertParagraph()),\n onBackspace: () => track(() => this.backspace()),\n onDeleteForward: () => track(() => this.deleteForward()),\n onPaste: (data) => track(() => this.pasteClipboard(data)),\n onCompositionChange: (active, text) => track(() => this.handleComposition(active, text))\n });\n this.pageInner.appendChild(this.ime.el);\n\n this.handle = document.createElement('div');\n this.handle.className = 'mini-resize';\n this.embedFrame = document.createElement('div');\n this.embedFrame.className = 'mini-embed-frame';\n this.imeBar = document.createElement('div');\n this.imeBar.className = 'mini-ime-bar';\n this.placeholderText = options.placeholder ?? '';\n this.placeholderEl = document.createElement('div');\n this.placeholderEl.className = 'mini-placeholder';\n this.placeholderEl.hidden = true;\n this.placeholderEl.setAttribute('aria-hidden', 'true');\n this.pageInner.append(this.embedFrame, this.handle, this.imeBar, this.placeholderEl);\n\n this.page.appendChild(this.pageInner);\n this.root.append(this.page);\n parent.appendChild(this.root);\n\n this.bind();\n this.syncComputedFontForMeasure();\n this.relayout({ reuse: false });\n void document.fonts.ready.then(() => {\n if (!this.root.isConnected) return;\n this.syncComputedFontForMeasure();\n this.relayout({ reuse: false });\n });\n if (options.autofocus !== false) this.ime.focus();\n this.resetBlink();\n if (options.perfPanel) this.perfPanel.enable();\n }\n\n /** 开关左下角常驻性能面板(见 `EditorOptions.perfPanel`)。 */\n setPerfPanel(on: boolean) {\n if (on) this.perfPanel.enable();\n else this.perfPanel.disable();\n }\n\n setPaintMode(mode: 'html' | 'canvas') {\n if (mode === this.paintMode) return;\n this.unbindSurface();\n this.painter.destroy();\n this.paintMode = mode;\n this.painter = this.createPainter();\n this.painter.mount(this.pageInner);\n this.pageInner.append(this.ime.el, this.embedFrame, this.handle, this.imeBar);\n this.bindSurface();\n this.root.dataset.paint = mode;\n this.pageInner.classList.remove('is-flipping');\n void this.pageInner.offsetWidth;\n this.pageInner.classList.add('is-flipping');\n this.relayout();\n this.ime.focus();\n }\n\n // ---- 公共 API ----------------------------------------------------------\n\n /** 滚动容器。宿主要做小地图、滚动联动时用。 */\n get scroller(): HTMLElement {\n return this.page;\n }\n\n /**\n * 页面元素(内容画布所在的定位上下文)。\n * 宿主要往内容上叠东西(标尺、网格、水印、角标)时挂到这里。\n */\n get pageElement(): HTMLElement {\n return this.pageInner;\n }\n\n /** 当前绘制后端。 */\n get paint(): 'html' | 'canvas' {\n return this.paintMode;\n }\n\n /** 更新空态占位文案。传空字符串则不再显示。 */\n setPlaceholder(text: string) {\n this.placeholderText = text ?? '';\n this.syncPlaceholder();\n }\n\n /** 更新光标 / 选区等装饰外观,立即重绘 chrome。 */\n setChrome(patch: Partial<EditorChrome>) {\n this.chrome = { ...this.chrome, ...patch };\n this.applyChrome();\n this.paintChrome();\n }\n\n /**\n * 更新默认正文字号/颜色/字体。已写进 span 的同色文字会跟着改(给主题切换用),不进撤销。\n */\n setTextDefaults(patch: TextProps) {\n const prevColor = this.textDefaults?.color;\n this.textDefaults = { ...this.textDefaults, ...patch };\n this.applyTextDefaults(this.doc);\n const nextColor = this.textDefaults?.color;\n if (prevColor && nextColor && prevColor !== nextColor) {\n this.recolorMatchingText(prevColor, nextColor);\n }\n this.relayout({ reuse: false });\n }\n\n /** 把文档里等于 from 的文字色改成 to,不发 change、不进历史。 */\n private recolorMatchingText(from: string, to: string) {\n const match = (value?: string) => !!value && cssColorsEqual(value, from);\n for (const span of this.doc.styles) {\n if (span.type !== 'text') continue;\n const props = span.props as TextProps;\n if (match(props.color)) props.color = to;\n }\n if (this.typingStyle && match(this.typingStyle.color)) {\n this.typingStyle = { ...this.typingStyle, color: to };\n }\n }\n\n private applyTextDefaults(doc: DocumentModel) {\n if (!this.textDefaults && !this.resolvedMeasureFamily) {\n doc.textDefaults = null;\n return;\n }\n doc.textDefaults = {\n ...this.textDefaults,\n ...(this.resolvedMeasureFamily ? { fontFamily: this.resolvedMeasureFamily } : {}),\n };\n }\n\n private syncComputedFontForMeasure() {\n const computed = getComputedStyle(this.root).fontFamily?.trim();\n if (!computed) return;\n this.resolvedMeasureFamily = computed;\n this.applyTextDefaults(this.doc);\n }\n\n private createPainter(): PaintBackend {\n return this.paintMode === 'canvas' ? new CanvasPainter() : new HtmlPainter();\n }\n\n private caretIsSolid() {\n return this.chrome.caret !== 'rainbow';\n }\n\n private caretTrailEnabled() {\n return this.chrome.caretTrail === true;\n }\n\n private applyChrome() {\n this.root.dataset.caret = this.caretIsSolid() ? 'solid' : 'rainbow';\n this.root.dataset.surface =\n this.chrome.surfaceBackground === 'transparent' ? 'transparent' : 'paper';\n this.root.style.setProperty('--mini-caret-color', this.chrome.caretColor ?? '#09090b');\n this.root.style.setProperty(\n '--mini-caret-width',\n `${this.chrome.caretWidth ?? 2}px`\n );\n this.root.style.setProperty(\n '--mini-ime-underline-color',\n this.chrome.composeUnderlineColor ?? '#1f2329'\n );\n this.root.style.setProperty(\n '--mini-ime-underline-width',\n `${this.chrome.composeUnderlineWidth ?? 2}px`\n );\n const solid = this.caretIsSolid();\n const selColor = this.chrome.selectionColor;\n if (selColor) {\n this.root.style.setProperty('--mini-sel-color', selColor);\n } else if (solid) {\n this.root.style.setProperty('--mini-sel-color', 'rgba(43, 108, 255, 0.22)');\n } else {\n this.root.style.removeProperty('--mini-sel-color');\n }\n const selRadius =\n this.chrome.selectionRadius ?? (solid ? 0 : 6);\n this.root.style.setProperty('--mini-sel-radius', `${selRadius}px`);\n const cssFamily = this.textDefaults?.fontFamily?.trim();\n if (cssFamily) {\n this.root.style.setProperty('--mini-font-family', cssFamily);\n }\n const weight = this.textDefaults?.fontWeight;\n if (weight != null) {\n this.root.style.setProperty('--mini-font-weight', String(weight));\n }\n const contentW = this.layout?.contentWidth ?? this.contentWidth;\n this.root.style.setProperty('--mini-content-width', `${Math.max(0, contentW)}px`);\n }\n\n /** 当前排版结果(纯几何,只读)。宿主可据此画标尺、小地图、叠层。 */\n getLayout(): DocLayout {\n return this.layout;\n }\n\n /** 导出整篇内容,结果可 JSON 序列化。 */\n getContent(): Slice {\n return this.doc.takeSlice(0, this.doc.length);\n }\n\n /** 整篇替换内容,会清空撤销栈。 */\n setContent(slice: Slice) {\n this.doc = documentFromSlice(slice);\n this.applyTextDefaults(this.doc);\n this.refEdit = null;\n this.typingStyle = null;\n this.composeText = '';\n this.composeAnchor = null;\n this.composeLen = 0;\n this.ime.clear();\n this.undoStack.clear();\n this.vblockStack = [];\n this.sel = collapsedSel(Math.max(0, this.doc.length - 1));\n // 文档对象已经换掉,不能拿「刚冷排出来的新 layout」当增量 prev:\n // 那次冷排不会画到 DOM,紧接着的增量又会因哈希命中得到空脏区带,\n // painter 误以为画面已是最新,结果光标/选区跟着新几何走,正文还停在旧 DOM。\n this.relayout({ reuse: false });\n this.emit('change');\n }\n\n /** 直接拿文档模型。需要做批量操作或自定义命令时用。 */\n getDocument(): DocumentModel {\n return this.doc;\n }\n\n /**\n * 在当前选区(或 `at`)插入一份 Slice。模板混排(文案 + 槽 + 胶囊 + 虚拟块)走这条。\n */\n insertSlice(slice: Slice, at?: number) {\n if (at == null && this.selectedRegion()) return;\n this.runEdit('insert.paste', (ctx) => {\n const index = at ?? ctx.selection().focus;\n const nested = (slice.virtualBlocks?.length ?? 0) > 0 || slice.entities.length > 0;\n const slot = at == null ? this.slotToFill(ctx) : ctx.doc.slotAtCaret(index);\n if (!nested && slot && (slot.empty || (at == null && this.selectionCoversSlot(ctx, slot)))) {\n const text = ops.slotInlineText(slice.text);\n if (text) {\n const end = ops.fillSlot(slot.id, text)(ctx);\n if (end != null) ctx.select(collapsedSel(end));\n return;\n }\n }\n this.deleteSelectionIfNeeded(ctx);\n ctx.select(collapsedSel(ops.insertSlice(at ?? ctx.selection().focus, slice)(ctx)));\n });\n this.vblockStack = [];\n }\n\n /** 把指定范围(默认当前选区)包成一层虚拟块。 */\n insertVirtualBlock(spec: Omit<VirtualBlockSpec, 'start' | 'end'> & { start?: number; end?: number }): string | null {\n const start = spec.start ?? selStart(this.targetSel());\n const end = spec.end ?? selEnd(this.targetSel());\n if (end <= start) return null;\n let id: string | null = null;\n this.runEdit('vblock.insert', (ctx) => {\n id = ops.insertVirtualBlock({ ...spec, start, end })(ctx);\n const block = id ? ctx.doc.blockById(id) : null;\n // mark 是纯样式叠层:不改选区、不进选中态。\n if (block && block.kind !== 'mark') ctx.select({ anchor: block.start, focus: block.end });\n });\n if (id && spec.kind !== 'mark') this.selectVblock(id, 'selected');\n return id;\n }\n\n /**\n * 虚拟块当前在屏幕上的位置(clientX/Y 坐标,已含滚动),用来定位业务浮层。\n * `lines` 是每一行的片段(折行的块有多个);`left/top/width/height` 是它们的外接矩形。\n * 块不存在或还没排版出来时返回 null。滚动、重排之后需重新取。\n */\n getVirtualBlockRect(id: string): {\n left: number;\n top: number;\n width: number;\n height: number;\n lines: { left: number; top: number; width: number; height: number }[];\n } | null {\n const origin = this.painter.getSurface().getBoundingClientRect();\n const lines: { left: number; top: number; width: number; height: number }[] = [];\n for (const line of this.layout.lines) {\n for (const vb of line.vblocks ?? []) {\n if (vb.id !== id) continue;\n lines.push({ left: origin.left + vb.x, top: origin.top + vb.y, width: vb.w, height: vb.h });\n }\n }\n if (!lines.length) return null;\n const left = Math.min(...lines.map((r) => r.left));\n const top = Math.min(...lines.map((r) => r.top));\n const right = Math.max(...lines.map((r) => r.left + r.width));\n const bottom = Math.max(...lines.map((r) => r.top + r.height));\n return { left, top, width: right - left, height: bottom - top, lines };\n }\n\n updateVirtualBlock(id: string, chrome: VirtualBlockChrome) {\n this.runEdit('vblock.update', (ctx) => {\n ops.updateVirtualBlockChrome(id, chrome)(ctx);\n });\n }\n\n removeVirtualBlock(id: string) {\n this.runEdit('vblock.remove', (ctx) => {\n ops.removeVirtualBlock(id)(ctx);\n });\n this.vblockStack = this.vblockStack.filter((f) => f.id !== id);\n }\n\n /**\n * 在指定位置插入宿主渲染块。`at` 省略为当前光标(会先删掉非折叠选区)。\n * 插入后选中该占位符,便于缩放框/选中态;宿主若要把光标放到块后,自行折叠到 `focus`。\n */\n insertHostEmbed(\n hostType: string,\n data?: unknown,\n size?: { width: number; height: number },\n at: EmbedInsertAt = 'cursor'\n ) {\n this.insertEmbed(\n {\n id: nextEntityId(),\n kind: 'hostSlot',\n hostType,\n data,\n width: size?.width ?? 120,\n height: size?.height ?? 24\n },\n at\n );\n }\n\n /** 文档里所有嵌入对象(图片占位),按文档下标升序。 */\n listEmbeds(): { index: number; entity: EmbedEntity }[] {\n const out: { index: number; entity: EmbedEntity }[] = [];\n const { spacers } = this.doc;\n for (let i = 0; i < spacers.length; i++) {\n if (spacers[i] !== MARKERS.IMAGE) continue;\n const entity = this.doc.imageAt(i);\n if (entity) out.push({ index: i, entity });\n }\n return out;\n }\n\n /** 每个段落的分组 id,与块序一致;空串表示无分组。 */\n listParagraphGroupIds(): string[] {\n const ids: string[] = [];\n for (const block of parseBlocks(this.doc.spacers)) {\n if (block.kind !== 'paragraph') continue;\n ids.push(this.doc.paragraphPropsAt(block.start).groupId ?? '');\n }\n return ids;\n }\n\n /** 给前 `count` 个段落打上分组(省略则全部)。不进撤销栈。 */\n tagParagraphsWithGroup(groupId: string, count?: number) {\n const id = groupId.trim();\n if (!id) return;\n const paras = parseBlocks(this.doc.spacers).filter((block) => block.kind === 'paragraph');\n const n = count == null ? paras.length : Math.min(Math.max(0, count), paras.length);\n if (!n) return;\n this.applyNow((ctx) => {\n for (let i = 0; i < n; i++) {\n const para = paras[i]!;\n ops.applyParagraphStyle(para.start, para.end, { groupId: id })(ctx);\n }\n });\n this.relayout();\n }\n\n /** 去掉段落分组。传入 id 则只清该组,否则清全部。 */\n clearParagraphGroupIds(groupId?: string) {\n const id = groupId?.trim() ?? '';\n this.applyNow((ctx) => {\n for (const block of parseBlocks(this.doc.spacers)) {\n if (block.kind !== 'paragraph') continue;\n const current = this.doc.paragraphPropsAt(block.start).groupId ?? '';\n if (!current) continue;\n if (id && current !== id) continue;\n ops.applyParagraphStyle(block.start, block.end, { groupId: '' })(ctx);\n }\n });\n this.relayout();\n }\n\n /** 删除指定分组的段落,其余内容保留。会清空撤销栈。 */\n deleteParagraphsWithGroup(groupId: string) {\n const id = groupId.trim();\n if (!id) return;\n this.setContent(sliceWithoutParagraphGroup(this.doc, id));\n }\n\n /** 当前是否正好选中一颗嵌入对象(含 host)。 */\n selectedEmbed(): EmbedEntity | null {\n return this.selectedImage()?.entity ?? null;\n }\n\n /** 按谓词删除嵌入对象,从后往前以免下标错位。返回删除数量。 */\n deleteEmbeds(pred: (entity: EmbedEntity, index: number) => boolean): number {\n const hits = this.listEmbeds()\n .filter((x) => pred(x.entity, x.index))\n .map((x) => x.index)\n .sort((a, b) => b - a);\n if (!hits.length) return 0;\n const caret = hits[hits.length - 1]!;\n this.runEdit('embed.delete', (ctx) => {\n for (const i of hits) ops.deleteRange(i, i + 1)(ctx);\n ctx.select(collapsedSel(caret));\n });\n return hits.length;\n }\n\n /** 按谓词更新嵌入对象属性。`patchFor` 可按实体合并 data。返回更新数量。\n * `history: false` 不进撤销栈(生成中态这类 UI 过程)。 */\n updateEmbeds(\n pred: (entity: EmbedEntity, index: number) => boolean,\n patchFor: ImagePatch | ((entity: EmbedEntity, index: number) => ImagePatch),\n options?: { history?: boolean }\n ): number {\n const hits = this.listEmbeds().filter((x) => pred(x.entity, x.index));\n if (!hits.length) return 0;\n const patches = hits.map((h) => ({\n id: h.entity.id,\n patch: typeof patchFor === 'function' ? patchFor(h.entity, h.index) : patchFor,\n }));\n if (options?.history === false) {\n for (const item of patches) {\n this.applyNow(ops.updateImage(item.id, item.patch));\n }\n this.relayout();\n return hits.length;\n }\n this.runEdit('embed.update', (ctx) => {\n for (const item of patches) ops.updateImage(item.id, item.patch)(ctx);\n });\n return hits.length;\n }\n\n getSelection(): Selection {\n return { ...this.sel };\n }\n\n /** 屏幕坐标落到文档下标,供拖放落点。 */\n indexAtClientPoint(clientX: number, clientY: number): number {\n const { x, y } = this.localPoint({ clientX, clientY } as MouseEvent);\n return nearestSafeIndex(this.doc.spacers, hitTestIndex(this.layout, x, y));\n }\n\n setSelection(next: Selection) {\n this.sel = { ...next };\n this.afterCaretMove();\n }\n\n /** 当前状态快照,用于同步宿主 UI。 */\n getState(): EditorState {\n const text = this.currentTextStyle();\n const para = this.targetDoc().paragraphPropsAt(this.targetSel().focus);\n const embed = this.selectedImage();\n const canPromote =\n !this.refEdit &&\n !isCollapsed(this.sel) &&\n !(selEnd(this.sel) - selStart(this.sel) === 1 && embed?.entity.kind === 'ref');\n return {\n bold: !!text.bold,\n italic: !!text.italic,\n underline: underlineKind(text) !== 'none',\n strikethrough: !!text.strikethrough,\n fontSize: text.fontSize ?? 16,\n color: text.color ?? '#1f2329',\n heading: (para.heading ?? 0) as 0 | 1 | 2 | 3,\n align: para.align ?? 'left',\n list: para.list ?? 'none',\n inTable: !!cellAt(this.targetDoc().spacers, this.targetSel().focus),\n canUndo: this.undoStack.canUndo,\n canRedo: this.undoStack.canRedo,\n paintMode: this.paintMode,\n hasLink: !!this.targetDoc().linkUrlAt(this.targetSel().focus),\n canPromote,\n canInsertRef: !this.refEdit && this.doc.fragments.size > 0,\n canUnlink: !this.refEdit && embed?.entity.kind === 'ref',\n selection: { ...this.sel },\n docLength: this.doc.length,\n inRefEdit: !!this.refEdit,\n refSelection: { ...this.fragSel },\n vblockStack: this.vblockStack.map((f) => ({ ...f }))\n };\n }\n\n /** 订阅事件,返回取消订阅函数。 */\n on(event: EditorEvent, handler: () => void): () => void {\n this.listeners[event].add(handler);\n return () => this.listeners[event].delete(handler);\n }\n\n focus() {\n if (this.disabled) return;\n this.ime.focus();\n }\n\n /** 输入法组合是否进行中(含候选串已镜像进模型、尚未落定)。 */\n composing(): boolean {\n return this.ime.composing || this.composeAnchor !== null;\n }\n\n /** 禁用输入与快捷键。宿主 disabled 不能只靠 CSS pointer-events。 */\n setDisabled(disabled: boolean) {\n this.disabled = disabled;\n this.ime.el.contentEditable = disabled ? 'false' : 'true';\n }\n\n private emit(event: EditorEvent) {\n for (const handler of this.listeners[event]) handler();\n }\n\n // ------------------------------------------------------------------------\n\n private bindSurface() {\n this.painter.getSurface().addEventListener('mousedown', this.onMouseDown);\n this.painter.getSurface().addEventListener('mouseleave', this.onSurfaceLeave);\n }\n\n private unbindSurface() {\n this.painter.getSurface().removeEventListener('mousedown', this.onMouseDown);\n this.painter.getSurface().removeEventListener('mouseleave', this.onSurfaceLeave);\n }\n\n private hoverMarkId: string | null = null;\n\n private onSurfaceLeave = () => {\n this.setHoverMark(null);\n this.painter.getSurface().classList.remove('is-over-slot');\n };\n\n /** 鼠标是否在虚拟块文本槽(输入框)上。 */\n private overVirtualSlot(x: number, y: number): boolean {\n for (const line of this.layout.lines) {\n if (line.y > y) break;\n if (y >= line.y + line.h || !line.vblocks) continue;\n for (const vb of line.vblocks) {\n if (vb.kind === 'virtualSlot' && x >= vb.x && x <= vb.x + vb.w && y >= vb.y && y <= vb.y + vb.h) {\n return true;\n }\n }\n }\n return false;\n }\n\n private setHoverMark(id: string | null) {\n if (id === this.hoverMarkId) return;\n this.hoverMarkId = id;\n this.painter.setHoverBlock?.(id);\n }\n\n /** 鼠标下配置了 hoverBackground 的 mark(折行时命中任一行片段都算)。 */\n private markAt(x: number, y: number): string | null {\n let any = false;\n for (const b of this.doc.virtualBlocks.values()) {\n if (b.kind === 'mark' && b.chrome.hoverBackground) {\n any = true;\n break;\n }\n }\n if (!any) return null;\n for (const line of this.layout.lines) {\n if (line.y > y) break;\n if (y >= line.y + line.h || !line.vblocks) continue;\n for (let i = line.vblocks.length - 1; i >= 0; i--) {\n const vb = line.vblocks[i];\n if (vb.kind !== 'mark' || !vb.chrome.hoverBackground) continue;\n if (x >= vb.x && x <= vb.x + vb.w && y >= vb.y && y <= vb.y + vb.h) return vb.id;\n }\n }\n return null;\n }\n\n private bind() {\n this.bindSurface();\n window.addEventListener('mousemove', this.onMouseMove);\n this.root.addEventListener('contextmenu', this.onContextMenu);\n window.addEventListener('mouseup', this.onMouseUp);\n this.unbindKeyboard = bindKeyboard({\n commands: this.commands,\n accepts: (e) => this.acceptsKey(e),\n composing: () => this.composing(),\n suppressInput: (e) => {\n if (e.target === this.ime.el) this.ime.markKeyConsumed();\n },\n shortcuts: this.shortcutTable,\n track: (fn) => this.perfPanel.track(fn)\n });\n document.addEventListener('mousedown', this.onDocMouseDown, true);\n this.root.addEventListener('mousedown', this.onRootMouseDown);\n this.parent.addEventListener('mousedown', this.onRootMouseDown);\n this.pageInner.addEventListener(EMBED_CHANGE, this.onEmbedChange);\n this.pageInner.addEventListener(EMBED_COMMIT, this.onEmbedCommit);\n this.pageInner.addEventListener(EMBED_MEASURE, this.onEmbedMeasure);\n this.pageInner.addEventListener(EMBED_EXIT_EDIT, this.onEmbedExitEdit);\n this.pageInner.addEventListener(REF_JUMP, this.onRefJump);\n this.pageInner.addEventListener('dblclick', this.onDoubleClick);\n this.root.addEventListener('focusin', this.onFocusChange);\n this.root.addEventListener('focusout', this.onFocusChange);\n this.handle.addEventListener('mousedown', this.onResizeStart);\n window.addEventListener('resize', this.onWindowResize);\n document.addEventListener('scroll', this.onAnyScroll, { capture: true, passive: true });\n window.addEventListener('resize', this.onAnyScroll);\n // 'fill' 模式:监听宿主容器尺寸变化重排。只观察 parent —— 它的宽度由外部布局决定,\n // 不受编辑器内部 surface 尺寸影响,不会形成重排循环。contentWidth 没变时 engine 增量复用。\n if (this.widthMode === 'fill' && typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this.relayout());\n this.resizeObserver.observe(this.parent);\n }\n document.addEventListener('copy', this.onCopy);\n document.addEventListener('cut', this.onCut);\n }\n\n destroy() {\n this.perfPanel.disable();\n this.unbindKeyboard?.();\n document.removeEventListener('mousedown', this.onDocMouseDown, true);\n this.root.removeEventListener('mousedown', this.onRootMouseDown);\n this.parent.removeEventListener('mousedown', this.onRootMouseDown);\n this.root.removeEventListener('focusin', this.onFocusChange);\n this.root.removeEventListener('focusout', this.onFocusChange);\n window.removeEventListener('mousemove', this.onMouseMove);\n this.root.removeEventListener('contextmenu', this.onContextMenu);\n this.endContextMenu();\n window.removeEventListener('mouseup', this.onMouseUp);\n window.removeEventListener('resize', this.onWindowResize);\n document.removeEventListener('scroll', this.onAnyScroll, { capture: true });\n window.removeEventListener('resize', this.onAnyScroll);\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n document.removeEventListener('copy', this.onCopy);\n document.removeEventListener('cut', this.onCut);\n window.cancelAnimationFrame(this.caretRaf);\n this.unbindSurface();\n this.ime.destroy();\n this.painter.destroy();\n this.root.remove();\n }\n\n private onWindowResize = () => this.relayout();\n\n /**\n * 按当前 width 策略算出内容宽度。\n * - 固定像素:直接返回。\n * - 'fill':宿主容器可用宽减去左右版心内边距;容器尚未布局(宽度为 0)时回退默认值,\n * 避免首帧算出负数或零宽。\n */\n private resolveContentWidth(): number {\n if (typeof this.widthMode === 'number') return this.widthMode;\n const avail = this.parent.clientWidth - this.padding.x * 2;\n return avail > 0 ? avail : PAGE_CONTENT_WIDTH;\n }\n\n private commit(edit: EditResult) {\n this.undoStack.push(edit);\n this.typingStyle = null;\n this.keepTypingOnNextClick = false;\n this.relayout();\n // 一次编辑落定后通知外部:内容已变。预览态(applyNow)不走这里,所以\n // 组合中间态、拖拽缩放这类临时改动不会误报 change。\n this.emit('change');\n }\n\n private targetDoc(): DocumentModel {\n return this.refEdit ? this.doc.ensureFragmentModel(this.refEdit.fragmentId) : this.doc;\n }\n\n private targetSel(): Selection {\n return this.refEdit ? this.fragSel : this.sel;\n }\n\n private setTargetSel(next: Selection) {\n if (this.refEdit) this.fragSel = next;\n else this.sel = next;\n }\n\n private syncActiveFragment() {\n if (this.refEdit) this.doc.syncFragment(this.refEdit.fragmentId);\n }\n\n private activeRefBox(): ImageBox | null {\n if (!this.refEdit) return null;\n return this.layout.images.find((b) => b.entity.id === this.refEdit?.entityId) ?? null;\n }\n\n private refreshRefMetrics() {\n const width = this.layout?.contentWidth ?? PAGE_CONTENT_WIDTH;\n for (const entity of this.doc.entities.values()) {\n if (entity.kind !== 'ref') continue;\n const size = measureRef(entity, width, this.doc);\n entity.width = size.width;\n entity.height = size.height;\n }\n }\n\n /**\n * 一次用户操作的事务边界。事务本体在 Edit 层,这里只负责给它当前的选区和\n * 作用域,再把产出的记录送进撤销栈。\n *\n * 同步块内部编辑走的是同一条路,只是作用域换成片段 id —— 发出去的 mutation\n * 自动包上 `scoped`,进的还是同一个撤销栈。\n */\n private runEdit(kind: EditKind, run: (ctx: OperationContext) => void) {\n const scope = this.refEdit?.fragmentId ?? null;\n const { edit, selectionAfter } = runEdit(this.doc, this.targetSel(), { kind, scope }, run);\n this.setTargetSel(selectionAfter);\n if (!edit) {\n this.relayout();\n return;\n }\n this.commit(edit);\n }\n\n /** 立即落一次变更,不进撤销栈。拖拽预览这类「过程中」的改动用它。 */\n private applyNow<R>(op: Operation<R>): R {\n const scope = this.refEdit?.fragmentId ?? null;\n const { run, result } = runScoped(this.doc, this.targetSel(), scope, op);\n this.setTargetSel(run.selectionAfter);\n return result;\n }\n\n /**\n * 把已经预览生效的改动登记成一步可撤销的编辑。\n *\n * 拖拽缩放这类交互会先用 `applyNow` 实时改文档,松手时才落定。这里的做法是\n * 悄悄退回到起点、再用一次真正的编辑走到终点 —— 两步在同一帧内完成,用户看不\n * 出来,换来的是一条正常的、能重放能变换的操作记录,而不是一对手写的闭包。\n */\n private commitPreview(kind: EditKind, revert: Operation, settle: Operation) {\n this.applyNow(revert);\n this.runEdit(kind, (ctx) => settle(ctx));\n }\n\n private deleteSelectionIfNeeded(ctx: OperationContext) {\n const sel = ctx.selection();\n if (isCollapsed(sel)) return;\n const from = selStart(sel);\n const to = selEnd(sel);\n if (!this.refEdit && this.clearCellGrid(ctx, from, to)) {\n ctx.select(collapsedSel(nearestSafeIndex(this.doc.spacers, from)));\n return;\n }\n const selected = this.selectedVblock();\n if (!this.refEdit && this.stackTop()?.mode === 'selected' && selected?.kind === 'region') {\n return;\n }\n if (!this.refEdit && this.stackTop()?.mode === 'selected' && selected?.kind === 'virtualSlot') {\n ops.clearSlot(selected.id)(ctx);\n const next = ctx.doc.blockById(selected.id);\n ctx.select(next ? { anchor: next.start, focus: next.end } : collapsedSel(from));\n return;\n }\n const editing = this.editingSlotIn(ctx.doc);\n if (editing && from <= editing.start && to >= editing.end) {\n ops.clearSlot(editing.id)(ctx);\n const next = ctx.doc.blockById(editing.id);\n ctx.select(collapsedSel(next?.start ?? from));\n return;\n }\n ops.deleteRange(from, to)(ctx);\n ctx.select(collapsedSel(from));\n }\n\n private clearCellGrid(ctx: OperationContext, from: number, to: number): boolean {\n const a = cellAt(this.doc.spacers, from);\n const b = cellAt(this.doc.spacers, Math.max(from, to - 1));\n if (!a || !b || a.table.start !== b.table.start) return false;\n if (a.row === b.row && a.col === b.col && from > a.cell.start) return false;\n const r0 = Math.min(a.row, b.row);\n const r1 = Math.max(a.row, b.row);\n const c0 = Math.min(a.col, b.col);\n const c1 = Math.max(a.col, b.col);\n const cells = [];\n for (let r = r0; r <= r1; r++) {\n for (let c = c0; c <= c1; c++) {\n const cell = a.table.rows[r]?.cells[c];\n if (cell) cells.push(cell);\n }\n }\n if (!cells.length) return false;\n const minStart = Math.min(...cells.map((c) => c.start));\n const maxEnd = Math.max(...cells.map((c) => c.end));\n if (from > minStart + 1 || to < maxEnd) return false;\n for (const cell of [...cells].reverse()) {\n const range = cellContentRange(cell);\n if (range.end > range.start) ops.emitDelete(ctx, range.start, range.end);\n if (this.doc.spacers[range.start] !== MARKERS.PARAGRAPH) {\n ops.emitInsert(ctx, range.start, MARKERS.PARAGRAPH);\n }\n }\n ops.normalizeParagraphs(ctx);\n return true;\n }\n\n /**\n * 处理输入法组合态(拼音/候选的中间态)。\n *\n * 组合串镜像插入文档模型、参与真实排版 —— 每次变化都幂等地「删旧串 → 插新串」,\n * 光标后的内容因此靠正常重排让开,而不是被浮层盖住。整个组合过程用 applyNow\n * 落地、不进撤销栈;最终文字在 compositionend 后由 onInsertText 走一次正常插入\n * 落定成一步可撤销的编辑。组合区外观由白块 overlay 擦白,只留系统输入法的候选串。\n */\n private handleComposition(active: boolean, text: string) {\n if (active && this.composeAnchor === null) {\n // 组合开始:有选区先删掉,落点即组合串的锚点。\n if (!isCollapsed(this.targetSel())) {\n this.applyNow((ctx) => this.deleteSelectionIfNeeded(ctx));\n }\n this.composeAnchor = this.targetSel().focus;\n this.composeLen = 0;\n }\n\n if (active && this.composeAnchor !== null) {\n const anchor = this.composeAnchor;\n const inherit = this.typingStyle ?? this.targetDoc().textPropsAt(anchor);\n this.applyNow((ctx) => {\n const slot = this.editingSlotIn(ctx.doc) ?? ctx.doc.slotAtCaret(anchor);\n const covers =\n !!slot && this.composeLen > 0 && anchor <= slot.start && anchor + this.composeLen >= slot.end;\n if (slot && (slot.empty || covers)) {\n if (!text) {\n ops.clearSlot(slot.id)(ctx);\n const next = ctx.doc.blockById(slot.id);\n this.composeAnchor = next?.start ?? anchor;\n ctx.select(collapsedSel(this.composeAnchor));\n return;\n }\n const end = ops.fillSlot(slot.id, text, inherit)(ctx);\n const next = ctx.doc.blockById(slot.id);\n this.composeAnchor = next?.start ?? anchor;\n ctx.select(collapsedSel(end ?? anchor));\n return;\n }\n if (this.composeLen > 0) ops.deleteRange(anchor, anchor + this.composeLen)(ctx);\n const end = text ? ops.insertText(anchor, text, inherit)(ctx) : anchor;\n ctx.select(collapsedSel(end));\n });\n this.composeLen = text.length;\n } else if (!active && this.composeAnchor !== null) {\n // 组合结束:整槽预览用 clearSlot 留皮,最终文字由 onInsertText 走 fillSlot。\n const anchor = this.composeAnchor;\n const len = this.composeLen;\n this.applyNow((ctx) => {\n const slot = this.editingSlotIn(ctx.doc) ?? ctx.doc.slotAtCaret(anchor);\n const covers = !!slot && len > 0 && anchor <= slot.start && anchor + len >= slot.end;\n if (slot && (slot.empty || covers)) {\n ops.clearSlot(slot.id)(ctx);\n const next = ctx.doc.blockById(slot.id);\n ctx.select(collapsedSel(next?.start ?? slot.start));\n return;\n }\n if (len > 0) ops.deleteRange(anchor, anchor + len)(ctx);\n ctx.select(collapsedSel(anchor));\n });\n this.composeAnchor = null;\n this.composeLen = 0;\n }\n\n this.composeText = text;\n this.relayout();\n }\n\n insertText(text: string) {\n if (!text || this.disabled) return;\n const selected = this.selectedVblock();\n if (this.stackTop()?.mode === 'selected' && selected?.kind === 'region') return;\n this.runEdit('insert.text', (ctx) => {\n const selectedNow = ctx.doc.blockById(selected?.id ?? '');\n if (this.stackTop()?.mode === 'selected' && selectedNow?.kind === 'virtualSlot') {\n const end = ops.fillSlot(selectedNow.id, text)(ctx);\n if (end != null) ctx.select(collapsedSel(end));\n return;\n }\n const slot = this.editingSlotIn(ctx.doc);\n const sel = ctx.selection();\n const covers =\n !!slot && !isCollapsed(sel) && selStart(sel) <= slot.start && selEnd(sel) >= slot.end;\n if (slot && (slot.empty || covers)) {\n const end = ops.fillSlot(slot.id, text)(ctx);\n if (end != null) ctx.select(collapsedSel(end));\n return;\n }\n this.deleteSelectionIfNeeded(ctx);\n const inherit = this.typingStyle ?? ctx.doc.textPropsAt(ctx.selection().focus);\n const at = ctx.selection().focus;\n let next = ops.insertText(at, text, inherit)(ctx);\n if (!this.refEdit && shouldTryMarkdown(text)) next = ops.applyMarkdownShortcut(next)(ctx);\n ctx.select(collapsedSel(next));\n });\n if (this.stackTop()?.mode === 'selected' && selected?.kind === 'virtualSlot') {\n this.selectVblock(selected.id, 'editing');\n }\n }\n\n pasteText(text: string) {\n this.pasteClipboard(text ? fakePlainClipboard(text) : null);\n }\n\n pasteClipboard(data: DataTransfer | null) {\n if (this.selectedRegion()) return;\n const slice = sliceFromClipboard(data);\n const text = data?.getData('text/plain') ?? '';\n if (!slice && !text) return;\n this.runEdit('insert.paste', (ctx) => {\n const nested = (slice?.virtualBlocks?.length ?? 0) > 0 || (slice?.entities.length ?? 0) > 0;\n const payload = ops.slotInlineText(slice?.text ?? text);\n const slot = this.slotToFill(ctx);\n if (slot && payload && !nested) {\n const end = ops.fillSlot(slot.id, payload)(ctx);\n if (end != null) ctx.select(collapsedSel(end));\n return;\n }\n this.deleteSelectionIfNeeded(ctx);\n if (slice) {\n ctx.select(collapsedSel(ops.insertSlice(ctx.selection().focus, slice)(ctx)));\n return;\n }\n const inherit = this.typingStyle ?? ctx.doc.textPropsAt(ctx.selection().focus);\n const next = ops.pasteText(ctx.selection().focus, text, inherit)(ctx);\n ctx.select(collapsedSel(next));\n });\n if (this.stackTop()?.mode === 'selected' && this.selectedVblock()?.kind === 'virtualSlot') {\n const id = this.selectedVblock()?.id;\n if (id) this.selectVblock(id, 'editing');\n }\n }\n\n insertParagraph(opts?: { shift?: boolean }) {\n if (this.disabled) return;\n if (this.enterSelectedVblock()) return;\n if (this.selectedRegion()) return;\n const editing = this.editingSlot();\n const embed = this.selectedImage();\n if (embed?.entity.kind === 'formula' && this.beginFormulaEdit(embed.entity.id)) return;\n if (embed?.entity.kind === 'internalSlot' && this.beginSlotActivate(embed.entity.id)) return;\n if (embed?.entity.kind === 'ref' && this.beginRefEdit(embed.entity.id)) return;\n // 与现网 NodeSelection+Enter 开下拉对齐:仅普通 Enter 激活 host;Shift+Enter 仍在块后换行。\n if (\n embed?.entity.kind === 'hostSlot' &&\n !opts?.shift &&\n activateHostEmbed(embed.entity.id, { key: 'Enter', shift: false })\n ) {\n return;\n }\n const explicit = this.typingStyle ? { ...this.typingStyle } : null;\n const pending = { ...this.currentTextStyle() };\n const host = this.targetDoc();\n const fromHeading = host.paragraphPropsAt(this.targetSel().focus).heading ?? 0;\n this.runEdit('insert.paragraph', (ctx) => {\n if (embed && !this.refEdit) {\n ctx.select(collapsedSel(ops.insertParagraph(embed.index + 1)(ctx)));\n return;\n }\n if (editing) {\n const block = ctx.doc.blockById(editing.id);\n const at = block?.end ?? ctx.selection().focus;\n ctx.select(collapsedSel(ops.insertParagraph(at)(ctx)));\n return;\n }\n this.deleteSelectionIfNeeded(ctx);\n ctx.select(collapsedSel(ops.insertParagraph(ctx.selection().focus)(ctx)));\n });\n if (editing) this.vblockStack = [];\n this.typingStyle = this.inheritedTypingStyle(explicit, pending, fromHeading);\n this.keepTypingOnNextClick = !!this.typingStyle;\n this.syncToolbar();\n }\n\n private inheritedTypingStyle(explicit: TextProps | null, pending: TextProps, fromHeading: number): TextProps | null {\n const toHeading = this.targetDoc().paragraphPropsAt(this.targetSel().focus).heading ?? 0;\n if (fromHeading && toHeading === 0) return explicit;\n return explicit ?? pending;\n }\n\n private beginFormulaEdit(id: string): boolean {\n const node = this.pageInner.querySelector(`[data-entity=\"${CSS.escape(id)}\"]`);\n if (!node) return false;\n node.dispatchEvent(new Event('mini-formula-edit'));\n return true;\n }\n\n private beginSlotActivate(id: string): boolean {\n const node = this.pageInner.querySelector(`[data-entity=\"${CSS.escape(id)}\"]`);\n if (!node) return false;\n node.dispatchEvent(new Event('mini-slot-activate'));\n return true;\n }\n\n backspace() {\n if (this.handleVblockBackspace('backward')) return;\n if (this.deleteSelectedEmbed('backspace')) return;\n if (this.exitRefEditAtStart()) return;\n const sel = this.targetSel();\n const doc = this.targetDoc();\n if (isCollapsed(sel)) {\n const i = sel.focus;\n if (!this.refEdit && i > 0 && this.doc.spacers[i - 1] === MARKERS.TABLE_END) {\n const table = findTableAt(this.doc.spacers, i - 1);\n if (table) {\n this.sel = { anchor: table.start, focus: table.end };\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n return;\n }\n }\n }\n this.runEdit('delete.backward', (ctx) => {\n if (!isCollapsed(ctx.selection())) {\n this.deleteSelectionIfNeeded(ctx);\n return;\n }\n const res = ops.backspace(ctx.selection().focus)(ctx);\n if (res) ctx.select(collapsedSel(res.start));\n });\n }\n\n deleteForward() {\n if (this.handleVblockBackspace('forward')) return;\n if (this.deleteSelectedEmbed('forward')) return;\n this.runEdit('delete.forward', (ctx) => {\n if (!isCollapsed(ctx.selection())) {\n this.deleteSelectionIfNeeded(ctx);\n return;\n }\n ops.deleteForward(ctx.selection().focus)(ctx);\n });\n }\n\n private applyText(patch: TextProps) {\n if (isCollapsed(this.targetSel())) {\n this.typingStyle = { ...this.currentTextStyle(), ...patch };\n this.keepTypingOnNextClick = true;\n this.syncToolbar();\n this.ime.focus();\n return;\n }\n this.runEdit('style.text', (ctx) => {\n const sel = ctx.selection();\n ops.applyTextStyle(selStart(sel), selEnd(sel), patch)(ctx);\n });\n }\n\n private toggleText(key: 'bold' | 'italic' | 'underline' | 'strikethrough') {\n const cur = this.currentTextStyle();\n if (key === 'underline') {\n const on = underlineKind(cur) !== 'none';\n this.applyText(on ? { underline: false, underlineStyle: undefined } : { underline: true, underlineStyle: 'single' });\n return;\n }\n this.applyText({ [key]: !cur[key] });\n }\n\n private applyPara(patch: ParagraphProps) {\n this.runEdit('style.paragraph', (ctx) => {\n const sel = ctx.selection();\n ops.applyParagraphStyle(selStart(sel), selEnd(sel), patch)(ctx);\n });\n }\n\n private toggleLink() {\n const existing = this.targetDoc().linkSpanAt(this.targetSel().focus);\n if (isCollapsed(this.targetSel()) && existing) {\n const next = window.prompt('编辑链接,留空则移除', (existing.props as { url: string }).url);\n if (next === null) return;\n this.runEdit('style.link', (ctx) => {\n if (!next.trim()) ops.removeLink(ctx.selection().focus)(ctx);\n else ops.applyLink(existing.start, existing.end, next.trim())(ctx);\n });\n return;\n }\n const sel = this.targetSel();\n const from = selStart(sel);\n const to = selEnd(sel);\n const initial = existing ? (existing.props as { url: string }).url : 'https://';\n const url = window.prompt('输入链接', initial);\n if (url === null) return;\n const href = url.trim();\n if (!href) {\n if (existing) {\n this.runEdit('style.link', (ctx) => ops.removeLink(ctx.selection().focus)(ctx));\n }\n return;\n }\n this.runEdit('style.link', (ctx) => {\n if (from === to) {\n const next = ops.insertText(from, href)(ctx);\n ops.applyLink(from, next, href)(ctx);\n ctx.select({ anchor: from, focus: next });\n } else {\n ops.applyLink(from, to, href)(ctx);\n }\n });\n }\n\n private toggleList(kind: 'ul' | 'ol') {\n const cur = this.targetDoc().paragraphPropsAt(this.targetSel().focus);\n this.applyPara({ list: cur.list === kind ? 'none' : kind, heading: 0 });\n }\n\n private changeIndent(delta: number) {\n const cur = this.targetDoc().paragraphPropsAt(this.targetSel().focus);\n const next = Math.max(0, Math.min(MAX_LIST_INDENT, (cur.indent ?? 0) + delta));\n if (next === (cur.indent ?? 0)) return;\n this.applyPara({ indent: next });\n }\n\n private insertEmbed(entity: EmbedEntity, at: EmbedInsertAt = 'cursor') {\n if (this.refEdit && entity.kind === 'ref') return;\n if (at === 'cursor' && this.selectedRegion()) return;\n const host = this.targetDoc();\n const sized = { ...entity, ...embedPlugin(entity.kind).measure(entity, this.innerContentWidth(), host) };\n this.runEdit('embed.insert', (ctx) => {\n if (at === 'cursor') {\n this.deleteSelectionIfNeeded(ctx);\n } else {\n ctx.select(collapsedSel(this.resolveInsertIndex(at, ctx.doc)));\n }\n const next = ops.insertImage(ctx.selection().focus, sized)(ctx);\n ctx.select({ anchor: next - 1, focus: next });\n });\n }\n\n private resolveInsertIndex(at: EmbedInsertAt, doc = this.doc): number {\n if (at === 'start') return 0;\n if (at === 'end') return Math.max(0, doc.length - 1);\n if (at === 'cursor') return this.targetSel().focus;\n return doc.clamp(at);\n }\n\n private innerContentWidth(): number {\n if (this.refEdit) {\n const box = this.activeRefBox();\n return Math.max(80, refInnerWidth(box?.w ?? 400));\n }\n return this.layout.contentWidth;\n }\n\n private insertCodeBlock() {\n this.insertEmbed({\n id: nextEntityId(),\n kind: 'code',\n width: this.layout.contentWidth,\n height: 80,\n language: 'plain',\n code: ''\n });\n }\n\n private insertFormula() {\n this.insertEmbed({\n id: nextEntityId(),\n kind: 'formula',\n width: 240,\n height: 56,\n latex: '',\n displayMode: true\n });\n }\n\n private insertSlot(slotKind: SlotKind) {\n const id = nextEntityId();\n this.insertEmbed({\n id,\n kind: 'internalSlot',\n slotKind,\n label: defaultSlotLabel(slotKind),\n slotOptions: slotKind === 'select' ? ['小美', '阿力'] : undefined,\n width: 140,\n height: 28\n });\n queueMicrotask(() => this.beginSlotActivate(id));\n }\n\n private promoteRef() {\n if (this.refEdit) return;\n const from = selStart(this.sel);\n const to = selEnd(this.sel);\n if (from === to) return;\n if (to - from === 1 && this.doc.imageAt(from)?.kind === 'ref') return;\n this.runEdit('ref.promote', (ctx) => {\n const hit = ops.promoteRange(from, to)(ctx);\n if (!hit) return;\n ctx.select({ anchor: hit.index, focus: hit.index + 1 });\n });\n }\n\n private insertExistingRef() {\n if (this.refEdit) return;\n const fragments = this.doc.listFragments();\n if (!fragments.length) return;\n if (fragments.length === 1) {\n this.insertRefAtCaret(fragments[0].id);\n return;\n }\n const picked = window.prompt(\n fragments.map((f, i) => `${i + 1}. ${f.title ?? f.id}`).join('\\n') + '\\n\\n输入序号插入',\n '1'\n );\n const index = Number(picked) - 1;\n if (!Number.isInteger(index) || !fragments[index]) return;\n this.insertRefAtCaret(fragments[index].id);\n }\n\n private insertRefAtCaret(fragmentId: string) {\n if (this.selectedRegion()) return;\n this.runEdit('ref.insert', (ctx) => {\n this.deleteSelectionIfNeeded(ctx);\n const index = ops.insertRef(ctx.selection().focus, fragmentId)(ctx);\n ctx.select({ anchor: index, focus: index + 1 });\n });\n }\n\n private unlinkSelectedRef() {\n const embed = this.selectedImage();\n if (embed?.entity.kind !== 'ref') return;\n this.exitRefEdit();\n this.runEdit('ref.unlink', (ctx) => {\n const next = ops.unlinkRef(embed.index)(ctx);\n if (next !== null) ctx.select(collapsedSel(next));\n });\n }\n\n private selectedEmbedIndex(side: 'backspace' | 'forward'): number | null {\n if (this.refEdit) return null;\n const from = selStart(this.sel);\n const to = selEnd(this.sel);\n // 整块选中(蓝框 / 胶囊 selected)时,退格和 Delete 都删块。\n if (to - from === 1 && this.doc.spacers[from] === MARKERS.IMAGE) return from;\n if (from !== to) return null;\n // 折叠光标在块前:Delete 删块,Backspace 删光标前的字符。\n if (side === 'forward' && this.doc.spacers[from] === MARKERS.IMAGE) return from;\n // 折叠光标在块后:Backspace 删块。\n if (side === 'backspace' && from > 0 && this.doc.spacers[from - 1] === MARKERS.IMAGE) return from - 1;\n return null;\n }\n\n private deleteSelectedEmbed(side: 'backspace' | 'forward'): boolean {\n const index = this.selectedEmbedIndex(side);\n if (index === null) return false;\n this.runEdit('embed.delete', (ctx) => {\n ops.deleteRange(index, index + 1)(ctx);\n ctx.select(collapsedSel(index));\n });\n return true;\n }\n\n private exitRefEditAtStart(): boolean {\n if (!this.refEdit || !isCollapsed(this.fragSel) || this.fragSel.focus !== 0) return false;\n this.exitRefEdit();\n return true;\n }\n\n private refInnerLayout(box: ImageBox): DocLayout | null {\n if (box.inner) return box.inner;\n if (box.entity.kind !== 'ref' || !box.entity.fragmentId) return null;\n const innerW = refInnerWidth(box.w);\n return layoutDocument(this.doc.ensureFragmentModel(box.entity.fragmentId), innerW, undefined, { x: 0, y: 0 }, 1);\n }\n\n private hitRefIndex(box: ImageBox, x: number, y: number): number {\n const inner = this.refInnerLayout(box);\n if (!inner) return 0;\n return hitTestIndex(inner, x - box.x - REF_PAD, y - box.y - REF_HEAD);\n }\n\n private beginRefEdit(id: string, at?: number): boolean {\n const entity = this.doc.entities.get(id);\n if (entity?.kind !== 'ref' || !entity.fragmentId) return false;\n const model = this.doc.ensureFragmentModel(entity.fragmentId);\n this.refEdit = { entityId: id, fragmentId: entity.fragmentId };\n const fallback = Math.max(0, model.length - (model.spacers.endsWith('\\n') ? 1 : 0));\n this.fragSel = collapsedSel(at === undefined ? fallback : Math.max(0, Math.min(at, model.length)));\n this.relayout();\n this.ime.focus();\n return true;\n }\n\n private exitRefEdit(side?: 'before' | 'after') {\n if (!this.refEdit) return;\n const box = this.activeRefBox();\n const index = box?.index ?? selStart(this.sel);\n this.refEdit = null;\n if (side === 'before') this.sel = collapsedSel(index);\n else if (side === 'after') this.sel = collapsedSel(index + 1);\n else this.sel = { anchor: index, focus: index + 1 };\n this.relayout();\n this.ime.focus();\n }\n\n private onRefJump = (e: Event) => {\n const { fragmentId, id } = (e as CustomEvent<RefJumpDetail>).detail;\n const indices = this.doc.refIndices(fragmentId);\n if (indices.length < 2) return;\n const box = this.layout.images.find((b) => b.entity.id === id);\n const here = box?.index ?? -1;\n const pos = Math.max(0, indices.indexOf(here));\n const next = indices[(pos + 1) % indices.length];\n this.exitRefEdit();\n this.sel = { anchor: next, focus: next + 1 };\n this.afterCaretMove();\n };\n\n private onDoubleClick = (e: MouseEvent) => {\n const { x, y } = this.localPoint(e);\n const box = this.hitImage(x, y);\n if (box?.entity.kind !== 'ref') {\n this.selectWordAt(x, y);\n return;\n }\n e.preventDefault();\n this.beginRefEdit(box.entity.id, this.hitRefIndex(box, x, y));\n };\n\n /** 双击选词。点在嵌入对象上、空白或标点上时不处理,保留 mousedown 已定的光标。 */\n private selectWordAt(x: number, y: number) {\n if (!this.refEdit && this.hitImage(x, y)) return;\n const doc = this.targetDoc();\n let index: number;\n if (this.refEdit) {\n const box = this.activeRefBox();\n if (!box?.inner) return;\n index = hitTestIndex(box.inner, x - (box.x + REF_PAD), y - (box.y + REF_HEAD));\n } else {\n index = nearestSafeIndex(doc.spacers, hitTestIndex(this.layout, x, y));\n }\n const range = wordRangeAt(doc.spacers, index);\n if (!range) return;\n if (this.refEdit) {\n this.fragSel = { anchor: range.start, focus: range.end };\n } else {\n const editing = this.editingSlot();\n if (editing?.empty) return;\n const lo = editing ? Math.max(editing.start, range.start) : range.start;\n const hi = editing ? Math.min(editing.end, range.end) : range.end;\n if (lo >= hi) return;\n this.sel = { anchor: lo, focus: hi };\n }\n this.afterCaretMove();\n }\n\n private applyEmbedPatch(id: string, patch: Partial<EmbedEntity>) {\n this.applyNow(ops.updateImage(id, patch));\n const entity = this.doc.entities.get(id);\n if (!entity) return;\n const size = embedPlugin(entity.kind).measure(entity, this.layout.contentWidth);\n this.applyNow(ops.updateImage(id, size));\n this.layout = layoutDocument(this.doc, this.contentWidth, this.layout, this.padding);\n this.painter.paintDoc(this.layout);\n this.paintChrome();\n }\n\n private onEmbedMeasure = (e: Event) => {\n const { id, width, height } = (e as CustomEvent<EmbedMeasureDetail>).detail;\n const entity = this.doc.entities.get(id);\n if (!entity) return;\n // 尺寸没变就不重排;变了只更新布局,不进撤销栈、不开编辑事务。\n if (entity.width === width && entity.height === height) return;\n this.applyEmbedPatch(id, { width, height });\n };\n\n private onEmbedChange = (e: Event) => {\n const { id, patch } = (e as CustomEvent<EmbedChangeDetail>).detail;\n const entity = this.doc.entities.get(id);\n if (!entity) return;\n if (!this.embedEdit || this.embedEdit.id !== id) this.embedEdit = { id, before: cloneEntity(entity) };\n this.applyEmbedPatch(id, patch);\n };\n\n private onEmbedCommit = (e: Event) => {\n const { id, patch } = (e as CustomEvent<EmbedChangeDetail>).detail;\n const before = this.embedEdit?.id === id ? this.embedEdit.before : this.doc.entities.get(id);\n this.applyEmbedPatch(id, patch);\n const after = this.doc.entities.get(id);\n this.embedEdit = null;\n if (!before || !after) return;\n if (\n before.code === after.code &&\n before.latex === after.latex &&\n before.language === after.language &&\n before.width === after.width &&\n before.height === after.height &&\n before.slotValue === after.slotValue &&\n before.src === after.src &&\n before.label === after.label &&\n before.hostType === after.hostType &&\n before.data === after.data\n ) {\n return;\n }\n const prev = cloneEntity(before);\n const next = cloneEntity(after);\n this.commitPreview('embed.update', ops.updateImage(id, prev), ops.updateImage(id, next));\n };\n\n private onEmbedExitEdit = (e: Event) => {\n const { id, side } = (e as CustomEvent<EmbedExitDetail>).detail;\n const box = this.layout.images.find((b) => b.entity.id === id);\n if (!box) return;\n this.sel = collapsedSel(side === 'before' ? box.index : box.index + 1);\n this.afterCaretMove();\n this.ime.focus();\n };\n\n private insertMediaFile(file: File, kind: 'image' | 'video') {\n if (this.selectedRegion()) return;\n const src = URL.createObjectURL(file);\n const commit = (nw: number, nh: number) => {\n if (this.selectedRegion()) return;\n const max = 360;\n const w0 = nw > 0 ? nw : 360;\n const h0 = nh > 0 ? nh : Math.round(w0 / VIDEO_ASPECT);\n const scale = w0 > max ? max / w0 : 1;\n const entity = {\n id: nextEntityId(),\n src,\n width: Math.max(24, Math.round(w0 * scale)),\n height: Math.max(24, Math.round(h0 * scale)),\n kind\n };\n this.runEdit('embed.insert', (ctx) => {\n this.deleteSelectionIfNeeded(ctx);\n const next = ops.insertImage(ctx.selection().focus, entity)(ctx);\n ctx.select({ anchor: next - 1, focus: next });\n });\n };\n if (kind === 'video') {\n const video = document.createElement('video');\n video.preload = 'metadata';\n video.onloadedmetadata = () => commit(video.videoWidth, video.videoHeight);\n video.onerror = () => commit(360, Math.round(360 / VIDEO_ASPECT));\n video.src = src;\n return;\n }\n const img = new Image();\n img.onload = () => commit(img.width, img.height);\n img.onerror = () => commit(360, 360);\n img.src = src;\n }\n\n private insertTable() {\n if (this.selectedRegion()) return;\n this.runEdit('table.insert', (ctx) => {\n this.deleteSelectionIfNeeded(ctx);\n ctx.select(collapsedSel(ops.insertTable(ctx.selection().focus, 2, 2)(ctx)));\n });\n }\n\n private tableOp(op: 'row' | 'col' | 'del-row' | 'del-col') {\n this.runEdit('table.structure', (ctx) => {\n const focus = ctx.selection().focus;\n if (op === 'row') ops.insertTableRow(focus)(ctx);\n if (op === 'col') ops.insertTableCol(focus)(ctx);\n if (op === 'del-row') ops.deleteTableRow(focus)(ctx);\n if (op === 'del-col') ops.deleteTableCol(focus)(ctx);\n });\n }\n\n undo() {\n this.applyHistoryStep(this.undoStack.popForUndo());\n }\n\n redo() {\n this.applyHistoryStep(this.undoStack.popForRedo());\n }\n\n /**\n * 执行撤销栈交回来的一步。\n *\n * 栈给的是一条常规 EditResult:`mutations` 直接应用,选区取 `selectionAfter`。\n * 选区属于哪个坐标空间由 `meta.scope` 说了算 —— 片段里的编辑,撤销时该动的是\n * 片段选区。\n */\n private applyHistoryStep(step: EditResult | null) {\n if (!step) return;\n applyMutations(this.doc, step.mutations);\n if (step.meta.scope) this.fragSel = { ...step.selectionAfter };\n else this.sel = { ...step.selectionAfter };\n this.typingStyle = null;\n this.relayout();\n // 撤销/重做同样改变了文档内容,外部缓存需要随之刷新。\n this.emit('change');\n }\n\n private relayout(opts?: { reuse?: boolean }) {\n // 每次重排前按当前容器宽度更新内容宽度('fill' 模式下会随容器变化)。\n // contentWidth 未变时 engine 内部走增量复用,不会有额外重排开销。\n this.contentWidth = this.resolveContentWidth();\n this.syncActiveFragment();\n this.refreshRefMetrics();\n const prev = opts?.reuse === false ? undefined : this.layout;\n this.layout = layoutDocument(this.doc, this.contentWidth, prev, this.padding);\n this.root.style.setProperty('--mini-content-width', `${Math.max(0, this.layout.contentWidth)}px`);\n this.painter.paintDoc(this.layout);\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n this.scrollCaret();\n // 失焦后不要抢回 IME,否则点到页内其它控件还会看到光标。\n if (document.activeElement === this.ime.el) this.ime.focus();\n this.emit('layoutchange');\n }\n\n private paintChrome() {\n const embed = this.selectedImage();\n if (this.refEdit) {\n const box = this.activeRefBox();\n const origin = box ? { x: box.x + REF_PAD, y: box.y + REF_HEAD } : { x: 0, y: 0 };\n const rects = box?.inner\n ? selectionRects(box.inner, this.fragSel).map((r) => ({ ...r, x: r.x + origin.x, y: r.y + origin.y }))\n : [];\n this.painter.paintSelection(rects);\n } else {\n this.painter.paintSelection(embed ? [] : this.selectionPaintRects());\n }\n this.paintCaretLayer();\n this.updateEmbedChrome(embed);\n this.decorateRefNodes();\n this.decorateHostNodes();\n this.syncPlaceholder();\n }\n\n /**\n * 占位只在「看不见任何正文」时出现。组合一开始(哪怕候选串还是空的)就必须关掉:\n * 中间态走 applyNow,不发 change,宿主叠层会一直以为是空的。\n */\n private syncPlaceholder() {\n const composing = this.ime.composing || this.composeAnchor !== null;\n const show = !!this.placeholderText && !composing && isVisuallyEmptyDoc(this.doc);\n this.placeholderEl.hidden = !show;\n if (!show) return;\n this.placeholderEl.textContent = this.placeholderText;\n const line = this.layout.lines[0];\n const para = this.doc.paragraphPropsAt(0);\n const style = resolvedTextStyle(this.doc, 0, para);\n const size = style.fontSize ?? 16;\n const color = this.chrome.placeholderColor ?? '';\n const opacity =\n this.chrome.placeholderOpacity !== undefined ? String(this.chrome.placeholderOpacity) : '';\n this.placeholderEl.style.cssText = [\n `left:${this.layout.contentX}px`,\n `top:${line?.y ?? this.layout.contentY}px`,\n `max-width:${Math.max(0, this.layout.contentWidth)}px`,\n `font-size:${size}px`,\n `line-height:${line?.h ?? lineHeightOf(style)}px`,\n color ? `color:${color}` : '',\n opacity ? `opacity:${opacity}` : '',\n ]\n .filter(Boolean)\n .join(';');\n }\n\n private decorateHostNodes() {\n syncHostSelected(this.selectedImage()?.entity.id ?? null);\n }\n\n private decorateRefNodes() {\n const selectedId = this.selectedImage()?.entity.id;\n for (const node of this.pageInner.querySelectorAll<HTMLElement>('.mini-ref')) {\n const id = node.dataset.entity;\n const entity = id ? this.doc.entities.get(id) : undefined;\n if (!entity?.fragmentId) continue;\n const fragment = this.doc.fragments.get(entity.fragmentId);\n decorateRefEl(\n node,\n this.doc.refCount(entity.fragmentId),\n fragment?.title ?? '同步块',\n this.refEdit?.entityId === entity.id,\n selectedId === entity.id || this.refEdit?.entityId === entity.id\n );\n }\n }\n\n private paintCaretLayer() {\n const style = this.currentTextStyle();\n const mapped = this.refCaretPos();\n const demoCaret = this.chrome.caret === 'rainbow';\n const caret = {\n ...(mapped ?? caretFromIndex(this.layout, this.sel.focus)),\n italic: demoCaret && !!style.italic,\n bold: demoCaret && !!style.bold\n };\n if (demoCaret) {\n caret.opacity = 0.22 + 0.78 * (0.5 + 0.5 * Math.cos(performance.now() / 180));\n } else if (this.paintMode === 'canvas') {\n // 按墙钟闪,不要跟 rAF 帧数绑:CommandBox canvas 有 host 时帧率会掉,64 帧一圈会变得很慢。\n const period = 1060;\n const posKey = `${caret.x}:${caret.y}:${caret.h}`;\n const now = performance.now();\n if (posKey !== this.blinkPosKey) {\n this.blinkPosKey = posKey;\n this.blinkEpoch = now;\n }\n caret.opacity = (now - this.blinkEpoch) % period < period / 2 ? 1 : 0;\n }\n const key = `${Math.round(caret.x)}:${Math.round(caret.y)}:${Math.round(caret.h)}`;\n if (this.caretTrailEnabled() && key !== this.lastCaretKey) {\n if (this.lastCaretKey) this.caretTrails.unshift({ ...caret, opacity: 0.35 });\n this.caretTrails = this.caretTrails.slice(0, 3);\n this.lastCaretKey = key;\n }\n if (!this.caretTrailEnabled()) this.caretTrails = [];\n const showCaret =\n this.isFocused() &&\n !this.isEmbedChromeFocused() &&\n (this.refEdit ? isCollapsed(this.fragSel) : isCollapsed(this.sel));\n this.painter.paintCaret(\n showCaret ? caret : null,\n showCaret,\n this.caretTrailEnabled() ? this.caretTrails : []\n );\n const imeH = lineHeightOf(style);\n // 系统输入法靶子锚在组合起点,作为候选框的定位点;它本身透明、只占 1px,\n // 不再撑白块盖字(组合串的可见呈现完全交给模型正文)。\n const anchorPos = this.ime.composing ? this.composeCaret() : caret;\n const imeY = anchorPos.y + Math.max(0, (anchorPos.h - imeH) / 2);\n this.ime.moveTo(anchorPos.x, imeY, imeH);\n // 自绘的组合区下划线:从组合起点铺到组合串末尾。组合串在模型里,宽度与正文\n // 同度量,天然对齐。\n const composeW = this.ime.composing && this.composeText ? Math.max(12, measureWidth(this.composeText, style)) : 0;\n this.imeBar.style.display = composeW ? 'block' : 'none';\n if (composeW) {\n const underlineH = this.chrome.composeUnderlineWidth ?? 2;\n this.imeBar.style.left = `${anchorPos.x}px`;\n this.imeBar.style.top = `${anchorPos.y + anchorPos.h - underlineH}px`;\n this.imeBar.style.width = `${composeW}px`;\n }\n }\n\n /** 组合串起点(锚点)的屏幕坐标;主文档与片段内编辑都算对。 */\n private composeCaret(): CaretPos {\n const anchor = this.composeAnchor ?? this.targetSel().focus;\n if (this.refEdit) {\n const box = this.activeRefBox();\n if (box?.inner) {\n const c = caretFromIndex(box.inner, anchor);\n return { ...c, x: c.x + box.x + REF_PAD, y: c.y + box.y + REF_HEAD };\n }\n }\n return caretFromIndex(this.layout, anchor);\n }\n\n private refCaretPos(): CaretPos | null {\n if (!this.refEdit) return null;\n const box = this.activeRefBox();\n if (!box?.inner) return null;\n const caret = caretFromIndex(box.inner, this.fragSel.focus);\n return { ...caret, x: caret.x + box.x + REF_PAD, y: caret.y + box.y + REF_HEAD };\n }\n\n private currentTextStyle(): TextProps {\n const doc = this.targetDoc();\n const sel = this.targetSel();\n if (this.typingStyle) return { ...this.currentParaTextDefaults(), ...this.typingStyle };\n const para = doc.paragraphPropsAt(sel.focus);\n const idx = isCollapsed(sel) ? Math.max(0, sel.focus - 1) : selStart(sel);\n return resolvedTextStyle(doc, idx, para);\n }\n\n private currentParaTextDefaults(): TextProps {\n const doc = this.targetDoc();\n const sel = this.targetSel();\n return resolvedTextStyle(doc, sel.focus, doc.paragraphPropsAt(sel.focus));\n }\n\n private syncToolbar() {\n this.emit('statechange');\n }\n\n private syncStatus() {\n this.emit('selectionchange');\n }\n\n private resetBlink() {\n this.blinkEpoch = performance.now();\n window.cancelAnimationFrame(this.caretRaf);\n this.caretRaf = 0;\n this.paintCaretLayer();\n // HTML 实心光标靠 CSS 闪;每帧写 opacity/display 会把动画掐掉,看起来像闪得很慢。\n if (this.caretIsSolid() && this.paintMode !== 'canvas') return;\n const tick = () => {\n this.paintCaretLayer();\n this.caretRaf = window.requestAnimationFrame(tick);\n };\n this.caretRaf = window.requestAnimationFrame(tick);\n }\n\n /** 从内到外找出真正会滚动的祖先(编辑器自己的 page、宿主限高容器、整页)。 */\n /** scrollParents 结果缓存:祖先链上的 overflow 很少变,300ms 内复用,省掉每次按键的 getComputedStyle。 */\n private scrollParentsCache: { at: number; list: HTMLElement[] } | null = null;\n /**\n * 上次 scrollCaret 真正读到的几何:各滚动容器的可视区与 surface 顶部(client 坐标)。\n * 任何滚动 / 窗口尺寸变化都会清掉;用它先判断光标还在不在可视区里,在就不碰布局。\n */\n private viewGeom: { at: number; surfaceTop: number; views: { sc: HTMLElement; top: number; h: number }[] } | null = null;\n private onAnyScroll = () => {\n this.viewGeom = null;\n };\n\n private scrollParents(): HTMLElement[] {\n const now = performance.now();\n if (this.scrollParentsCache && now - this.scrollParentsCache.at < 300 && this.page.isConnected) {\n return this.scrollParentsCache.list;\n }\n const out: HTMLElement[] = [];\n let el: HTMLElement | null = this.page;\n while (el && el !== document.body && el !== document.documentElement) {\n const oy = getComputedStyle(el).overflowY;\n if ((oy === 'auto' || oy === 'scroll' || oy === 'overlay') && el.scrollHeight > el.clientHeight) {\n out.push(el);\n }\n el = el.parentElement;\n }\n const root = document.scrollingElement as HTMLElement | null;\n if (root && root.scrollHeight > root.clientHeight) out.push(root);\n this.scrollParentsCache = { at: now, list: out };\n return out;\n }\n\n private scrollCaret() {\n const caret = this.refCaretPos() ?? caretFromIndex(this.layout, this.sel.focus);\n const surface = this.painter.getSurface();\n const parents = this.scrollParents();\n const now = performance.now();\n // 快速路径:几何缓存还新鲜(没滚动、没改窗口、300ms 内),且光标按缓存算仍在每个\n // 可视区内,就不读布局。读 getBoundingClientRect 会强制回流,是这里主要的开销。\n const geom = this.viewGeom;\n if (geom && now - geom.at < 300 && geom.views.length === parents.length && geom.views.every((v, i) => v.sc === parents[i])) {\n const top = geom.surfaceTop + caret.y;\n const bottom = top + caret.h;\n const inside = geom.views.every((v) => {\n const margin = Math.max(0, Math.min(40, (v.h - caret.h) / 2));\n return top - margin >= v.top && bottom + margin <= v.top + v.h;\n });\n if (inside) return;\n }\n const views: { sc: HTMLElement; top: number; h: number }[] = [];\n for (const sc of parents) {\n const isRoot = sc === document.scrollingElement;\n const viewTop = isRoot ? 0 : sc.getBoundingClientRect().top;\n const viewH = isRoot ? window.innerHeight : sc.clientHeight;\n const margin = Math.max(0, Math.min(40, (viewH - caret.h) / 2));\n // 每轮重新量:内层滚动之后,外层看到的光标位置也变了。\n const top = surface.getBoundingClientRect().top + caret.y;\n const bottom = top + caret.h;\n if (top - margin < viewTop) sc.scrollTop += top - margin - viewTop;\n else if (bottom + margin > viewTop + viewH) sc.scrollTop += bottom + margin - (viewTop + viewH);\n views.push({ sc, top: viewTop, h: viewH });\n }\n // 滚完再量一次 surface 位置作为缓存基准。程序触发的 scroll 事件下一帧才到,会再清一次缓存,\n // 那只是多读一回,不影响正确性。\n this.viewGeom = { at: now, surfaceTop: surface.getBoundingClientRect().top, views };\n }\n\n private lastDragEvent: MouseEvent | null = null;\n private dragScrollRaf = 0;\n\n /** 拖选时鼠标停在视图外也要持续滚动并扩选,行为同原生。 */\n /** 上下键的目标列:x 是出发时的光标横坐标,focus 是上一次落点,用来判断 goal 是否仍有效 */\n private verticalGoal: { x: number; focus: number } | null = null;\n\n private dragScrollTick = () => {\n this.dragScrollRaf = 0;\n const e = this.lastDragEvent;\n if (!this.dragging || !e) return;\n const sc = this.scrollParents()[0];\n if (!sc) return;\n const r = sc.getBoundingClientRect();\n const edge = 24;\n let dy = 0;\n if (e.clientY < r.top + edge) dy = -Math.min(24, (r.top + edge - e.clientY) / 3 + 2);\n else if (e.clientY > r.bottom - edge) dy = Math.min(24, (e.clientY - (r.bottom - edge)) / 3 + 2);\n if (!dy) return;\n const before = sc.scrollTop;\n sc.scrollTop += dy;\n if (sc.scrollTop !== before) this.extendDragTo(e);\n this.dragScrollRaf = window.requestAnimationFrame(this.dragScrollTick);\n };\n\n private extendDragTo(e: MouseEvent) {\n // 鼠标在滚动视口外时按视口边缘取点,避免一下子选到文末/文首。\n const sc = this.scrollParents()[0];\n let cy = e.clientY;\n if (sc) {\n const r = sc.getBoundingClientRect();\n cy = Math.min(r.bottom - 1, Math.max(r.top + 1, cy));\n }\n const rect = this.painter.getSurface().getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = cy - rect.top;\n const focus = nearestSafeIndex(this.doc.spacers, hitTestIndex(this.layout, x, y));\n this.sel = this.expandSel(this.dragAnchor, this.snapIndexForDrag(this.dragAnchor, focus));\n this.paintChrome();\n this.syncStatus();\n }\n\n private localPoint(e: MouseEvent): { x: number; y: number } {\n const rect = this.painter.getSurface().getBoundingClientRect();\n return { x: e.clientX - rect.left, y: e.clientY - rect.top };\n }\n\n private ctxMenuOrigin: { x: number; y: number } | null = null;\n\n private endContextMenu = () => {\n if (!this.ctxMenuOrigin) return;\n this.ctxMenuOrigin = null;\n this.ime.endContextMenu();\n for (const type of ['mousedown', 'keydown', 'copy', 'cut', 'paste'] as const) {\n document.removeEventListener(type, this.endContextMenuSoon, true);\n }\n window.removeEventListener('mousemove', this.onCtxMenuMove, true);\n this.paintCaretLayer();\n };\n\n /** copy/cut/paste 事件还要送达编辑器自己的处理函数,等它们跑完再收。 */\n private endContextMenuSoon = () => {\n window.setTimeout(this.endContextMenu, 0);\n };\n\n private onCtxMenuMove = (e: MouseEvent) => {\n const o = this.ctxMenuOrigin;\n if (o && Math.hypot(e.clientX - o.x, e.clientY - o.y) > 12) this.endContextMenu();\n };\n\n /**\n * 右键菜单:canvas 上右键会得到“存储图片”菜单,这里改成原生的 剪切/拷贝/粘贴。\n * 嵌入控件里的输入框等保留浏览器默认菜单。\n */\n private onContextMenu = (e: MouseEvent) => {\n if (this.disabled) return;\n const target = e.target as HTMLElement;\n if (target.closest('textarea, input, select, video, math-field, .mini-embed-interactive [contenteditable=\"true\"]')) return;\n const { x, y } = this.localPoint(e);\n if (!this.refEdit) {\n // 右键点在选区外:先把光标挪过去(原生输入框的行为)。点在嵌入对象上不动选区。\n const hit = this.hitImage(x, y);\n if (!hit) {\n const index = nearestSafeIndex(this.doc.spacers, hitTestIndex(this.layout, x, y));\n const lo = Math.min(this.sel.anchor, this.sel.focus);\n const hi = Math.max(this.sel.anchor, this.sel.focus);\n if (isCollapsed(this.sel) || index < lo || index > hi) {\n this.setSel(collapsedSel(index));\n this.afterCaretMove();\n }\n }\n }\n const sel = this.targetSel();\n const from = selStart(sel);\n const to = selEnd(sel);\n const text = from < to ? this.targetDoc().plainText(from, to).slice(0, 2000) : '';\n this.ctxMenuOrigin = { x: e.clientX, y: e.clientY };\n this.ime.beginContextMenu(x, y, text);\n for (const type of ['mousedown', 'keydown', 'copy', 'cut', 'paste'] as const) {\n document.addEventListener(type, this.endContextMenuSoon, true);\n }\n window.addEventListener('mousemove', this.onCtxMenuMove, true);\n };\n\n private onDocMouseDown = (e: MouseEvent) => {\n const t = e.target as Node;\n // parent 是宿主挂载点:空文档时表面比外层 min-height 矮,点到宿主空白\n // 仍应算编辑器内,否则会先 blur,再点也聚焦不住。\n this.keysArmed = this.root.contains(t) || this.parent.contains(t);\n if (!this.keysArmed) {\n this.ime.el.blur();\n this.paintCaretLayer();\n }\n };\n\n private onRootMouseDown = (e: MouseEvent) => {\n if (this.disabled) return;\n const el = e.target as HTMLElement;\n if (el.closest('.mini-embed-interactive') || el.closest('.mini-resize')) return;\n // 点的是非可聚焦层(空表面、占位、页边空白)。不 preventDefault 的话,\n // 浏览器会在 mousedown 默认动作里把刚 focus 的 IME 再 blur 掉。\n e.preventDefault();\n this.ime.focus();\n };\n\n private onFocusChange = () => {\n queueMicrotask(() => this.paintCaretLayer());\n };\n\n private onMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n if ((e.target as HTMLElement).closest('.mini-resize')) return;\n const { x, y } = this.localPoint(e);\n const refBox = this.hitImage(x, y);\n if (!this.refEdit && refBox?.entity.kind === 'ref') {\n e.preventDefault();\n this.setSel({ anchor: refBox.index, focus: refBox.index + 1 });\n this.ime.focus();\n this.resetBlink();\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n return;\n }\n if (this.refEdit) {\n if (refBox?.entity.kind === 'ref' && refBox.entity.fragmentId === this.refEdit.fragmentId) {\n e.preventDefault();\n this.refEdit = { entityId: refBox.entity.id, fragmentId: refBox.entity.fragmentId };\n this.sel = { anchor: refBox.index, focus: refBox.index + 1 };\n const index = this.hitRefIndex(refBox, x, y);\n this.fragSel = e.shiftKey ? { ...this.fragSel, focus: index } : collapsedSel(index);\n this.refDragging = true;\n this.refDragAnchor = e.shiftKey ? this.fragSel.anchor : index;\n this.ime.focus();\n this.resetBlink();\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n return;\n }\n this.exitRefEdit();\n }\n const interactive = (e.target as HTMLElement).closest('.mini-embed-interactive') as HTMLElement | null;\n if (interactive) {\n // 点在 embed 内部的真实交互控件(输入框、下拉、视频、公式域等)上:把焦点\n // 交给该控件本身,编辑器完全不介入——不 preventDefault、不选中整块、不抢焦点。\n // 否则浏览器的默认聚焦被阻止,控件拿不到焦点,键盘输入会落回编辑器(表现为\n // “一输入就替换整块”)。\n const field = (e.target as HTMLElement).closest('textarea, input, select, video, math-field, [contenteditable=\"true\"]');\n if (field) {\n this.keepTypingOnNextClick = false;\n return;\n }\n // 点在 embed 的非交互区域(外框/背景):选中整块。\n e.preventDefault();\n this.keepTypingOnNextClick = false;\n const index = Number(interactive.dataset.index);\n if (Number.isFinite(index)) {\n this.dragging = false;\n this.setSel({ anchor: index, focus: index + 1 });\n this.resetBlink();\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n }\n this.ime.focus();\n return;\n }\n e.preventDefault();\n this.ime.focus();\n if (this.keepTypingOnNextClick && !e.shiftKey && !e.metaKey && !e.ctrlKey) {\n this.keepTypingOnNextClick = false;\n this.resetBlink();\n this.paintChrome();\n this.syncToolbar();\n return;\n }\n const border = hitColBorder(this.layout, x, y);\n if (border) {\n this.colResizing = { tableStart: border.tableStart, col: border.col, startX: e.clientX, widths: border.widths };\n return;\n }\n const index = nearestSafeIndex(this.doc.spacers, hitTestIndex(this.layout, x, y));\n if ((e.metaKey || e.ctrlKey) && !e.shiftKey) {\n const url = this.doc.linkUrlAt(index);\n if (url && openSafeUrl(url)) return;\n }\n const img = this.hitImage(x, y);\n if (img) {\n this.vblockStack = [];\n this.setSel({ anchor: img.index, focus: img.index + 1 });\n } else if (e.shiftKey) {\n this.setSel(this.expandSel(this.sel.anchor, this.snapIndexForDrag(this.sel.anchor, index)));\n } else if (this.hitVblockClick(index)) {\n // stack/selection already updated\n } else {\n this.vblockStack = [];\n this.setSel(collapsedSel(index));\n }\n this.dragAnchor = this.sel.anchor;\n this.dragging = true;\n this.resetBlink();\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n };\n\n private onMouseMove = (e: MouseEvent) => {\n const { x, y } = this.localPoint(e);\n if (this.refDragging && this.refEdit) {\n const box = this.activeRefBox();\n if (box) {\n const index = this.hitRefIndex(box, x, y);\n this.fragSel = { anchor: this.refDragAnchor, focus: index };\n this.paintChrome();\n this.syncStatus();\n }\n return;\n }\n if (this.colResizing) {\n this.applyColResize(e.clientX);\n return;\n }\n if (this.resizing) {\n const dx = e.clientX - this.resizing.startX;\n const w = Math.max(40, this.resizing.startW + dx);\n const entity = this.doc.entities.get(this.resizing.id);\n const plugin = embedPlugin(entity?.kind);\n if (plugin.keepAspectRatio) {\n const ratio = this.resizing.startH / this.resizing.startW;\n this.applyNow(ops.updateImage(this.resizing.id, { width: Math.round(w), height: Math.round(w * ratio) }));\n } else {\n this.applyNow(ops.updateImage(this.resizing.id, { width: Math.round(w) }));\n if (entity) {\n const size = plugin.measure({ ...entity, width: Math.round(w) }, this.layout.contentWidth);\n this.applyNow(ops.updateImage(this.resizing.id, size));\n }\n }\n this.layout = layoutDocument(this.doc, this.contentWidth, this.layout, this.padding);\n this.painter.paintDoc(this.layout);\n this.paintChrome();\n return;\n }\n if (!this.dragging) {\n this.painter.getSurface().classList.toggle('is-col-resize', !!hitColBorder(this.layout, x, y));\n this.setHoverMark(e.buttons ? null : this.markAt(x, y));\n this.painter.getSurface().classList.toggle('is-over-slot', this.overVirtualSlot(x, y));\n return;\n }\n this.setHoverMark(null);\n this.lastDragEvent = e;\n this.extendDragTo(e);\n if (!this.dragScrollRaf) this.dragScrollRaf = window.requestAnimationFrame(this.dragScrollTick);\n };\n\n private onMouseUp = () => {\n if (this.colResizing) {\n const { tableStart, widths } = this.colResizing;\n const next = this.doc.tablePropsAt(tableStart).colWidths ?? widths;\n this.colResizing = null;\n if (next.some((w, i) => w !== widths[i])) {\n this.commitPreview(\n 'table.colWidth',\n ops.setTableColWidths(tableStart, widths),\n ops.setTableColWidths(tableStart, next)\n );\n }\n }\n if (this.resizing) {\n const id = this.resizing.id;\n const entity = this.doc.entities.get(id);\n const startW = this.resizing.startW;\n const startH = this.resizing.startH;\n this.resizing = null;\n if (entity && (entity.width !== startW || entity.height !== startH)) {\n const w = entity.width;\n const h = entity.height;\n this.commitPreview(\n 'embed.resize',\n ops.updateImage(id, { width: startW, height: startH }),\n ops.updateImage(id, { width: w, height: h })\n );\n }\n }\n this.dragging = false;\n this.refDragging = false;\n this.lastDragEvent = null;\n window.cancelAnimationFrame(this.dragScrollRaf);\n this.dragScrollRaf = 0;\n };\n\n private onResizeStart = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n const img = this.selectedImage();\n if (!img || img.entity.kind === 'internalSlot' || img.entity.kind === 'ref') return;\n this.resizing = { id: img.entity.id, startX: e.clientX, startW: img.entity.width, startH: img.entity.height };\n };\n\n private hitImage(x: number, y: number) {\n const hits = this.layout.images.filter((b) => x >= b.x && x <= b.x + b.w && y >= b.y && y <= b.y + b.h);\n return hits.find((b) => b.entity.kind === 'ref') ?? hits[hits.length - 1] ?? null;\n }\n\n private selectedImage() {\n if (selEnd(this.sel) - selStart(this.sel) !== 1) return null;\n const i = selStart(this.sel);\n if (this.doc.spacers[i] !== MARKERS.IMAGE) return null;\n return imageBoxAt(this.layout, i);\n }\n\n private updateEmbedChrome(img = this.selectedImage()) {\n if (!img) {\n this.embedFrame.style.display = 'none';\n this.handle.style.display = 'none';\n return;\n }\n const isSlot = img.entity.kind === 'internalSlot';\n const isRef = img.entity.kind === 'ref';\n const isHost = img.entity.kind === 'hostSlot';\n this.embedFrame.classList.toggle('is-slot', isSlot);\n this.embedFrame.classList.toggle('is-ref', isRef);\n this.embedFrame.classList.toggle('is-image', isSlot && img.entity.slotKind === 'image');\n // host 选中态由宿主组件自己画(如 InlineButton data-selected),不叠 SDK 蓝框。\n this.embedFrame.style.display =\n this.refEdit || isHost ? 'none' : 'block';\n this.embedFrame.style.left = `${img.x}px`;\n this.embedFrame.style.top = `${img.y}px`;\n this.embedFrame.style.width = `${img.w}px`;\n this.embedFrame.style.height = `${img.h}px`;\n // 尺寸由宿主渲染回报决定的 host 块,和插槽/引用一样不提供拖拽缩放手柄。\n this.handle.style.display = isSlot || isRef || isHost ? 'none' : 'block';\n this.handle.style.left = `${img.x + img.w - 5}px`;\n this.handle.style.top = `${img.y + img.h - 5}px`;\n }\n\n private writeClipboard(data: DataTransfer | null) {\n if (!data) return;\n const doc = this.targetDoc();\n const from = selStart(this.targetSel());\n const to = selEnd(this.targetSel());\n const slice = doc.takeSlice(from, to);\n data.setData(SLICE_MIME, serializeSlice(slice));\n data.setData('text/plain', doc.plainText(from, to));\n data.setData('text/html', sliceToHtml(slice));\n }\n\n private onCopy = (e: ClipboardEvent) => {\n if (!this.isFocused() || this.isEmbedChromeFocused()) return;\n if (isCollapsed(this.sel)) return;\n e.preventDefault();\n this.writeClipboard(e.clipboardData);\n };\n\n private onCut = (e: ClipboardEvent) => {\n if (!this.isFocused() || this.isEmbedChromeFocused()) return;\n if (isCollapsed(this.sel)) return;\n if (this.selectedRegion()) {\n e.preventDefault();\n return;\n }\n e.preventDefault();\n this.writeClipboard(e.clipboardData);\n this.backspace();\n };\n\n private isFocused(): boolean {\n return this.root.contains(document.activeElement);\n }\n\n /** 焦点在公式/槽等嵌入控件内时不画外层光标。 */\n private isEmbedChromeFocused(): boolean {\n const el = document.activeElement;\n if (!el || el === this.ime.el) return false;\n return !!el.closest('.mini-embed-interactive');\n }\n\n /**\n * 这次按键归不归本编辑器管。\n *\n * 「哪个键干什么」在 commands/shortcuts.ts 里,门面只回答这一个问题 —— 焦点在\n * 别的输入框、编辑器没装备快捷键、焦点在嵌入对象的字段里,都不接。\n */\n private acceptsKey(e: KeyboardEvent): boolean {\n if (this.disabled) return false;\n const target = e.target as HTMLElement;\n if (target.closest('input, textarea, select, math-field')) return false;\n if (!this.keysArmed && !this.root.contains(target)) return false;\n return !this.isEmbedChromeFocused();\n }\n\n private selectAll() {\n const editing = this.editingSlot();\n if (editing) {\n this.sel = { anchor: editing.start, focus: editing.end };\n this.paintChrome();\n this.syncStatus();\n return;\n }\n const full = { anchor: 0, focus: this.targetDoc().length };\n if (this.refEdit) this.fragSel = full;\n else this.sel = full;\n this.paintChrome();\n this.syncStatus();\n }\n\n /** Escape:先弹出虚拟块一层,再退出同步块内部编辑。 */\n private exitFragmentEdit(): boolean {\n if (this.vblockStack.length) {\n this.popVblock();\n return true;\n }\n if (!this.refEdit) return false;\n this.exitRefEdit();\n return true;\n }\n\n /** Tab:在列表里改嵌套层级,否则在表格里跳到下一格。 */\n private indentOrNextCell(dir: 1 | -1) {\n const inList = this.doc.paragraphPropsAt(this.sel.focus).list !== 'none';\n if (!inList && this.moveTableCell(dir)) return;\n this.changeIndent(dir);\n }\n\n private moveTableCell(dir: 1 | -1): boolean {\n const here = cellAt(this.doc.spacers, this.sel.focus);\n if (!here) return false;\n if (dir > 0 && isLastTableCell(here)) {\n this.runEdit('table.structure', (ctx) => {\n ops.insertTableRow(ctx.selection().focus)(ctx);\n });\n }\n const next = nextCellIndex(this.doc.spacers, this.sel.focus, dir);\n if (next === null) return false;\n const hit = cellAt(this.doc.spacers, next);\n if (!hit) {\n this.sel = collapsedSel(next);\n } else {\n const range = cellContentRange(hit.cell);\n this.sel = { anchor: range.start, focus: range.end };\n }\n this.relayout();\n return true;\n }\n\n private expandSel(anchor: number, focus: number): Selection {\n const a = cellAt(this.doc.spacers, anchor);\n const b = cellAt(this.doc.spacers, focus);\n if (a && b && a.table.start === b.table.start && (a.row !== b.row || a.col !== b.col)) {\n const r0 = Math.min(a.row, b.row);\n const r1 = Math.max(a.row, b.row);\n const c0 = Math.min(a.col, b.col);\n const c1 = Math.max(a.col, b.col);\n let start = Infinity;\n let end = -Infinity;\n for (let r = r0; r <= r1; r++) {\n for (let c = c0; c <= c1; c++) {\n const cell = a.table.rows[r]?.cells[c];\n if (!cell) continue;\n start = Math.min(start, cell.start);\n end = Math.max(end, cell.end);\n }\n }\n if (start < end) return { anchor: start, focus: end };\n }\n return { anchor, focus };\n }\n\n private applyColResize(clientX: number) {\n if (!this.colResizing) return;\n const { tableStart, col, startX, widths } = this.colResizing;\n const next = [...widths];\n const sum = widths[col] + widths[col + 1];\n const w1 = Math.max(MIN_COL_WIDTH, Math.min(sum - MIN_COL_WIDTH, widths[col] + (clientX - startX)));\n next[col] = Math.round(w1);\n next[col + 1] = Math.round(sum - w1);\n this.applyNow(ops.setTableColWidths(tableStart, next));\n this.layout = layoutDocument(this.doc, this.contentWidth, this.layout, this.padding);\n this.painter.paintDoc(this.layout);\n this.paintChrome();\n }\n\n private moveCaret(key: ArrowKey, extend: boolean) {\n if (this.refEdit) {\n this.moveFragmentCaret(key, extend);\n return;\n }\n if (!extend && (key === 'ArrowLeft' || key === 'ArrowRight')) {\n const vnext = this.moveAcrossVblock(key === 'ArrowRight' ? 1 : -1);\n if (vnext) {\n this.sel = vnext;\n this.afterCaretMove();\n return;\n }\n const next = this.moveAcrossEmbed(key === 'ArrowRight' ? 1 : -1);\n if (next) {\n this.sel = next;\n this.afterCaretMove();\n return;\n }\n }\n let index = this.sel.focus;\n const vertical = key === 'ArrowUp' || key === 'ArrowDown';\n // 上下移动要记住\"目标列\":连续按上下键时始终用第一次出发的 x,不然每行吸附一次会越跑越偏。\n // 只要焦点被别的操作挪过(左右键、点击、输入),goal 的 focus 就对不上,自动作废。\n const goalX =\n vertical && this.verticalGoal?.focus === index ? this.verticalGoal.x : this.verticalStartX(index);\n if (key === 'ArrowLeft') index = this.stepIndex(index, -1);\n if (key === 'ArrowRight') index = this.stepIndex(index, 1);\n if (key === 'ArrowUp') index = this.verticalMove(index, -1, goalX);\n if (key === 'ArrowDown') index = this.verticalMove(index, 1, goalX);\n const remember = () => {\n this.verticalGoal = vertical ? { x: goalX, focus: this.sel.focus } : null;\n };\n if (!extend && this.doc.spacers[index] === MARKERS.IMAGE) {\n this.sel = { anchor: index, focus: index + 1 };\n } else if (extend) {\n this.sel = { ...this.sel, focus: this.snapIndexForDrag(this.sel.anchor, index) };\n } else {\n this.sel = collapsedSel(index);\n }\n const editing = this.editingSlot();\n if (editing) {\n const a = Math.min(editing.end, Math.max(editing.start, this.sel.anchor));\n const f = Math.min(editing.end, Math.max(editing.start, this.sel.focus));\n this.sel = editing.empty ? collapsedSel(editing.start) : { anchor: a, focus: f };\n } else if (!extend && (key === 'ArrowUp' || key === 'ArrowDown')) {\n const slot = this.doc.innermostSlotAt(this.sel.focus) ?? this.doc.slotAtCaret(this.sel.focus);\n if (slot) {\n this.selectVblock(slot.id, 'editing');\n remember();\n this.afterCaretMove();\n return;\n }\n }\n remember();\n this.afterCaretMove();\n }\n\n /** 光标所在的可视行(折行边界上的同一下标以光标实际画的那一行为准)。 */\n private lineAt(layout: DocLayout, index: number): LineBox | null {\n const y = caretFromIndex(layout, index).y;\n return (\n layout.lines.find((l) => Math.abs(l.y - y) < 1 && index >= l.start && index <= l.end) ??\n layout.lines.find((l) => index >= l.start && index <= l.end) ??\n null\n );\n }\n\n private motionTarget(unit: MoveUnit, dir: 1 | -1, index: number, doc: DocumentModel, layout: DocLayout): number {\n const spacers = doc.spacers;\n if (unit === 'doc') return dir < 0 ? 0 : maxCaretIndex(spacers);\n if (unit === 'word') return wordTarget(spacers, index, dir);\n if (unit === 'paragraph') return paragraphTarget(spacers, index, dir);\n const line = this.lineAt(layout, index);\n if (!line) return index;\n if (dir < 0) return line.start;\n // 段末那一行的 end 若含段落符,光标应停在它前面。\n return line.end > line.start && spacers[line.end - 1] === '\\n' ? line.end - 1 : line.end;\n }\n\n private moveCaretBy(unit: MoveUnit, dir: 1 | -1, extend: boolean) {\n if (this.refEdit) {\n const box = this.activeRefBox();\n const doc = this.targetDoc();\n if (!box?.inner) return;\n const index = nearestSafeIndex(doc.spacers, this.motionTarget(unit, dir, this.fragSel.focus, doc, box.inner));\n this.fragSel = extend ? { ...this.fragSel, focus: index } : collapsedSel(index);\n this.afterCaretMove();\n return;\n }\n const raw = this.motionTarget(unit, dir, this.sel.focus, this.doc, this.layout);\n const index = nearestSafeIndex(this.doc.spacers, raw);\n this.sel = extend\n ? { ...this.sel, focus: this.snapIndexForDrag(this.sel.anchor, index) }\n : collapsedSel(index);\n const editing = this.editingSlot();\n if (editing) {\n const a = Math.min(editing.end, Math.max(editing.start, this.sel.anchor));\n const f = Math.min(editing.end, Math.max(editing.start, this.sel.focus));\n this.sel = editing.empty ? collapsedSel(editing.start) : { anchor: a, focus: f };\n }\n this.afterCaretMove();\n }\n\n private moveFragmentCaret(key: ArrowKey, extend: boolean) {\n const doc = this.targetDoc();\n const box = this.activeRefBox();\n let index = this.fragSel.focus;\n if (!extend && isCollapsed(this.fragSel) && (key === 'ArrowLeft' || key === 'ArrowRight')) {\n if (key === 'ArrowLeft' && index <= 0) {\n this.exitRefEdit('before');\n return;\n }\n if (key === 'ArrowRight' && index >= Math.max(0, doc.length - (doc.spacers.endsWith('\\n') ? 1 : 0))) {\n this.exitRefEdit('after');\n return;\n }\n }\n if (key === 'ArrowLeft') index = Math.max(0, index - prevCodePointLen(doc.spacers, index));\n if (key === 'ArrowRight') index = Math.min(doc.length, index + nextCodePointLen(doc.spacers, index) || 1);\n if ((key === 'ArrowUp' || key === 'ArrowDown') && box?.inner) {\n const caret = caretFromIndex(box.inner, index);\n const y = caret.y + (key === 'ArrowDown' ? caret.h + 1 : -1);\n index = hitTestIndex(box.inner, caret.x, y);\n }\n this.fragSel = extend ? { ...this.fragSel, focus: index } : collapsedSel(index);\n this.afterCaretMove();\n }\n\n private stackTop(): { id: string; mode: 'selected' | 'editing' } | null {\n return this.vblockStack[this.vblockStack.length - 1] ?? null;\n }\n\n /** 参与选中/进出/吸附的块;mark 是纯样式叠层,交互上当作不存在。 */\n private interactiveBlocks(): VirtualBlock[] {\n return this.doc.listVirtualBlocks().filter((b) => b.kind !== 'mark');\n }\n\n private selectedVblock(): VirtualBlock | null {\n const top = this.stackTop();\n if (!top || top.mode !== 'selected') return null;\n return this.doc.blockById(top.id);\n }\n\n private selectedRegion(): VirtualBlock | null {\n const block = this.selectedVblock();\n return block?.kind === 'region' ? block : null;\n }\n\n private editingSlot(): VirtualBlock | null {\n const top = this.stackTop();\n if (!top || top.mode !== 'editing') return null;\n const block = this.doc.blockById(top.id);\n return block?.kind === 'virtualSlot' ? block : null;\n }\n\n private editingSlotIn(doc: DocumentModel): VirtualBlock | null {\n const top = this.stackTop();\n if (!top || top.mode !== 'editing') return null;\n const block = doc.blockById(top.id);\n return block?.kind === 'virtualSlot' ? block : null;\n }\n\n private selectionCoversSlot(ctx: OperationContext, slot: VirtualBlock): boolean {\n const sel = ctx.selection();\n return !isCollapsed(sel) && selStart(sel) <= slot.start && selEnd(sel) >= slot.end;\n }\n\n /** 选中槽、整槽选区、或空槽编辑:下一次写入应 fillSlot,不要先 clear 再插。 */\n private slotToFill(ctx: OperationContext): VirtualBlock | null {\n if (this.selectedRegion()) return null;\n const selected = ctx.doc.blockById(this.selectedVblock()?.id ?? '');\n if (this.stackTop()?.mode === 'selected' && selected?.kind === 'virtualSlot') return selected;\n const slot = this.editingSlotIn(ctx.doc);\n if (!slot) return null;\n if (slot.empty || this.selectionCoversSlot(ctx, slot)) return slot;\n return null;\n }\n\n private selectVblock(id: string, mode: 'selected' | 'editing') {\n const block = this.doc.blockById(id);\n if (!block) return;\n const chain: { id: string; mode: 'selected' | 'editing' }[] = [];\n const ids: string[] = [];\n let cur: VirtualBlock | null = block;\n const seen = new Set<string>();\n while (cur && !seen.has(cur.id)) {\n seen.add(cur.id);\n ids.unshift(cur.id);\n cur = cur.parentId ? this.doc.blockById(cur.parentId) : null;\n }\n for (let i = 0; i < ids.length; i++) {\n const last = i === ids.length - 1;\n chain.push({ id: ids[i], mode: last ? mode : 'selected' });\n }\n this.vblockStack = chain;\n if (mode === 'editing') {\n const i = Math.min(Math.max(this.sel.focus, block.start), block.end);\n this.setSel(collapsedSel(i));\n } else {\n this.setSel({ anchor: block.start, focus: block.end });\n }\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n }\n\n private popVblock() {\n const top = this.stackTop();\n if (!top) return;\n if (top.mode === 'editing') {\n this.selectVblock(top.id, 'selected');\n return;\n }\n this.vblockStack = this.vblockStack.slice(0, -1);\n const parent = this.stackTop();\n if (parent) {\n const block = this.doc.blockById(parent.id);\n if (block) this.setSel({ anchor: block.start, focus: block.end });\n } else {\n const block = this.doc.blockById(top.id);\n this.setSel(collapsedSel(block?.start ?? this.sel.anchor));\n }\n this.afterCaretMove();\n }\n\n private enterSelectedVblock(): boolean {\n const top = this.stackTop();\n const block = top ? this.doc.blockById(top.id) : null;\n if (!top || top.mode !== 'selected' || !block) return false;\n const children = this\n .interactiveBlocks()\n .filter((b) => b.parentId === block.id)\n .sort((a, b) => a.start - b.start);\n if (block.kind === 'virtualSlot') {\n this.selectVblock(block.id, 'editing');\n return true;\n }\n if (children[0]) {\n this.selectVblock(children[0].id, 'selected');\n return true;\n }\n return true;\n }\n\n private handleVblockBackspace(dir: 'backward' | 'forward'): boolean {\n const selected = this.selectedVblock();\n const top = this.stackTop();\n if (top?.mode === 'selected' && selected) {\n if (selected.kind === 'virtualSlot') {\n this.runEdit('delete.backward', (ctx) => {\n ops.clearSlot(selected.id)(ctx);\n const next = ctx.doc.blockById(selected.id);\n if (next) ctx.select({ anchor: next.start, focus: next.end });\n });\n return true;\n }\n return true;\n }\n const editing = this.editingSlot();\n if (!editing) return false;\n if (editing.empty) {\n this.selectVblock(editing.id, 'selected');\n return true;\n }\n const sel = this.targetSel();\n if (!isCollapsed(sel)) return false;\n const i = sel.focus;\n if (dir === 'backward' && i <= editing.start) {\n this.selectVblock(editing.id, 'selected');\n return true;\n }\n if (dir === 'forward' && i >= editing.end) {\n this.selectVblock(editing.id, 'selected');\n return true;\n }\n const from = dir === 'backward' ? i - prevCodePointLen(this.doc.spacers, i) : i;\n const to = dir === 'backward' ? i : i + nextCodePointLen(this.doc.spacers, i);\n if (from >= editing.start && to <= editing.end && editing.end - editing.start - (to - from) <= 0) {\n this.runEdit('delete.backward', (ctx) => {\n ops.clearSlot(editing.id)(ctx);\n const next = ctx.doc.blockById(editing.id);\n ctx.select(collapsedSel(next?.start ?? editing.start));\n });\n return true;\n }\n return false;\n }\n\n private moveAcrossVblock(dir: 1 | -1): Selection | null {\n const top = this.stackTop();\n const editing = this.editingSlot();\n if (editing) {\n const i = this.sel.focus;\n if (dir < 0 && isCollapsed(this.sel) && i <= editing.start) {\n this.selectVblock(editing.id, 'selected');\n return this.sel;\n }\n if (dir > 0 && isCollapsed(this.sel) && (i >= editing.end || editing.empty)) {\n this.selectVblock(editing.id, 'selected');\n return this.sel;\n }\n return null;\n }\n if (top?.mode === 'selected') {\n const block = this.doc.blockById(top.id);\n if (!block) return null;\n const children = this\n .interactiveBlocks()\n .filter((b) => b.parentId === block.id)\n .sort((a, b) => a.start - b.start);\n const inward = children.length > 0;\n if (inward) {\n const child = dir > 0 ? children[0] : children[children.length - 1];\n this.selectVblock(child.id, 'selected');\n return this.sel;\n }\n this.vblockStack = this.vblockStack.slice(0, -1);\n const parent = this.stackTop();\n if (parent) {\n const pb = this.doc.blockById(parent.id);\n if (pb) {\n this.setSel({ anchor: pb.start, focus: pb.end });\n return this.sel;\n }\n }\n return collapsedSel(dir > 0 ? block.end : block.start);\n }\n if (!isCollapsed(this.sel)) return null;\n const i = this.sel.focus;\n const hit =\n dir > 0\n ? this.outermostStartingAt(i)\n : this.outermostEndingAt(i);\n if (!hit) return null;\n this.selectVblock(hit.id, 'selected');\n return this.sel;\n }\n\n private outermostStartingAt(index: number): VirtualBlock | null {\n const hits = this.interactiveBlocks().filter((b) => b.start === index);\n return hits[0] ?? null;\n }\n\n private outermostEndingAt(index: number): VirtualBlock | null {\n const hits = this.interactiveBlocks().filter((b) => b.end === index);\n return hits[0] ?? null;\n }\n\n private hitVblockClick(index: number): boolean {\n const slot = this.doc.innermostSlotAt(index);\n if (slot) {\n this.selectVblock(slot.id, 'editing');\n // 空槽里的 placeholder 只是占位提示:光标永远停在槽首,不能落进文字中间。\n this.setSel(\n collapsedSel(slot.empty ? slot.start : Math.min(Math.max(index, slot.start), slot.end))\n );\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n return true;\n }\n const chain = this.doc.blocksAt(index).filter((b) => b.kind !== 'mark');\n const inner = chain[chain.length - 1];\n if (inner) {\n this.selectVblock(inner.id, 'selected');\n return true;\n }\n return false;\n }\n\n private snapIndexForDrag(anchor: number, focus: number): number {\n const editing = this.editingSlot();\n if (editing) {\n if (editing.empty) return editing.start;\n return Math.min(editing.end, Math.max(editing.start, focus));\n }\n const from = Math.min(anchor, focus);\n const to = Math.max(anchor, focus);\n if (to === from) return focus;\n const intersecting = this.interactiveBlocks().filter((b) => b.start < to && b.end > from);\n if (!intersecting.length) return focus;\n const ids = new Set(intersecting.map((b) => b.id));\n let common: VirtualBlock | null = null;\n for (const b of intersecting) {\n let p = b.parentId ? this.doc.blockById(b.parentId) : null;\n while (p && !ids.has(p.id)) p = p.parentId ? this.doc.blockById(p.parentId) : null;\n if (p && ids.has(p.id)) {\n if (!common || p.end - p.start > common.end - common.start) common = p;\n }\n }\n if (common) return focus >= anchor ? common.end : common.start;\n let snapped = focus;\n for (const b of intersecting) {\n if (!b.parentId || !ids.has(b.parentId)) {\n if (focus >= anchor) snapped = Math.max(snapped, b.end);\n else snapped = Math.min(snapped, b.start);\n }\n }\n return snapped;\n }\n\n private selectionPaintRects() {\n const top = this.stackTop();\n if (top?.mode === 'selected') {\n const outlines: { x: number; y: number; w: number; h: number; outline: true; radius: number }[] = [];\n for (const line of this.layout.lines) {\n for (const vb of line.vblocks ?? []) {\n if (vb.id !== top.id) continue;\n outlines.push({\n x: vb.x,\n y: vb.y,\n w: vb.w,\n h: vb.h,\n outline: true,\n radius: vb.chrome.radius ?? (vb.kind === 'virtualSlot' ? 4 : 6)\n });\n }\n }\n return outlines;\n }\n if (this.editingSlot()) return selectionRects(this.layout, this.sel);\n return selectionRects(this.layout, this.snapSelIfNeeded(this.sel));\n }\n\n private snapSelIfNeeded(sel: Selection): Selection {\n if (this.stackTop() || isCollapsed(sel)) return sel;\n const from = selStart(sel);\n const to = selEnd(sel);\n const intersecting = this.interactiveBlocks().filter((b) => b.start < to && b.end > from && (from > b.start || to < b.end));\n if (!intersecting.length) return sel;\n let start = from;\n let end = to;\n for (const b of intersecting) {\n start = Math.min(start, b.start);\n end = Math.max(end, b.end);\n }\n if (sel.anchor <= sel.focus) return { anchor: start, focus: end };\n return { anchor: end, focus: start };\n }\n\n /** 对照常见 Docs 行为:先选中嵌入块,再按同一方向才跳过。 */\n private moveAcrossEmbed(dir: 1 | -1): Selection | null {\n const embed = this.selectedImage();\n if (embed) {\n return collapsedSel(dir < 0 ? embed.index : embed.index + 1);\n }\n if (!isCollapsed(this.sel)) return null;\n const i = this.sel.focus;\n if (dir > 0 && this.doc.spacers[i] === MARKERS.IMAGE) {\n return { anchor: i, focus: i + 1 };\n }\n if (dir < 0 && i > 0 && this.doc.spacers[i - 1] === MARKERS.IMAGE) {\n return { anchor: i, focus: i - 1 };\n }\n return null;\n }\n\n private setSel(next: Selection) {\n const moved = next.anchor !== this.sel.anchor || next.focus !== this.sel.focus;\n this.sel = next;\n if (moved) this.typingStyle = null;\n }\n\n private afterCaretMove() {\n this.typingStyle = null;\n this.keepTypingOnNextClick = false;\n // 用户主动挪了光标,下一次输入不该并进上一批:撤销时应该分开退。\n this.undoStack.resetBatching();\n this.resetBlink();\n this.paintChrome();\n this.syncToolbar();\n this.syncStatus();\n this.scrollCaret();\n }\n\n private stepIndex(index: number, dir: 1 | -1): number {\n let i = index;\n for (let n = 0; n < 8; n++) {\n if (dir < 0) {\n if (i <= 0) return 0;\n i -= prevCodePointLen(this.doc.spacers, i);\n } else {\n if (i >= this.doc.length) return this.doc.length;\n i += nextCodePointLen(this.doc.spacers, i);\n }\n const ch = this.doc.spacers[dir < 0 ? i : i - 1];\n if (!ch || ch === MARKERS.PARAGRAPH || ch === MARKERS.IMAGE || !isStructural(ch)) return i;\n if (dir < 0 && i === 0) return 0;\n }\n return i;\n }\n\n /** 上下移动的出发 x:选中的是整个嵌入对象(芯片 / 图片)时取它的中心,否则取光标位置。 */\n private verticalStartX(index: number): number {\n const embed = this.selectedImage();\n if (embed && !embed.entity.float) return embed.x + embed.w / 2;\n return caretFromIndex(this.layout, index).x;\n }\n\n private verticalMove(index: number, dir: 1 | -1, x: number): number {\n const lines = this.layout.lines;\n const idx = lines.findIndex((l) => index >= l.start && index <= l.end);\n const cur = idx >= 0 ? idx : 0;\n const next = Math.max(0, Math.min(lines.length - 1, cur + dir));\n const line = lines[next];\n // 目标列落在某个行内嵌入对象(芯片、图片)的横向范围里,就把它当成命中整个对象:\n // 否则按最近停靠点吸附会随机落到它左边或右边,用户看到的是\"有时选中有时在旁边\"。\n const hitEmbed = line.images.find((img) => !img.entity.float && x >= img.x && x <= img.x + img.w);\n if (hitEmbed) return hitEmbed.index;\n return hitTestIndex(this.layout, x, line.y + 1);\n }\n}\n\n/** canvas 能解析的颜色才可比;var() 非法时不相等,避免误伤。 */\nfunction cssColorsEqual(a: string, b: string): boolean {\n if (a === b) return true;\n const ctx = typeof document === 'undefined' ? null : document.createElement('canvas').getContext('2d');\n if (!ctx) return false;\n ctx.fillStyle = '#000000';\n ctx.fillStyle = a;\n const left = ctx.fillStyle;\n ctx.fillStyle = '#000000';\n ctx.fillStyle = b;\n const right = ctx.fillStyle;\n if (left === '#000000' && a.trim() !== '#000000' && a.trim() !== '#000' && a.trim().toLowerCase() !== 'black' && a.trim() !== 'rgb(0, 0, 0)') {\n return false;\n }\n return left === right;\n}\n\nfunction isStructural(ch: string): boolean {\n return ch === MARKERS.PARAGRAPH || ch === MARKERS.TABLE_START || ch === MARKERS.TABLE_END || ch === MARKERS.TABLE_ROW || ch === MARKERS.TABLE_CELL;\n}\n\nfunction fakePlainClipboard(text: string): DataTransfer {\n const data = new DataTransfer();\n data.setData('text/plain', text);\n return data;\n}\n\nfunction sliceToHtml(slice: Slice): string {\n const esc = (s: string) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n return `<p>${esc(slice.text.replace(/[\\n\\u0010\\u0011\\u0012\\u001c\\u0007]/g, ' '))}</p>`;\n}\n\nfunction openSafeUrl(url: string): boolean {\n let href = url.trim();\n if (/^www\\./i.test(href)) href = `https://${href}`;\n try {\n const parsed = new URL(href);\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') return false;\n window.open(parsed.href, '_blank', 'noopener,noreferrer');\n return true;\n } catch {\n return false;\n }\n}\n\n"],"names":["CODE_LANGUAGES","BAR_H","LINE_H","PAD","measureCode","entity","contentWidth","lines","codePlugin","box","root","bar","sel","lang","opt","input","emitEmbedChange","el","ctx","imagePlugin","node","img","imageOf","src","MARKERS","isTableMarker","ch","prevCodePointLen","text","index","c","p","nextCodePointLen","blockCache","parseBlocks","spacers","blocks","parseBlocksUncached","i","table","parseTable","j","start","rows","rowMarker","cells","cellMarker","paragraphs","paraStart","end","findTableAt","block","isEmptyParagraph","para","isVisuallyEmptyDoc","doc","props","findParagraphAt","clamped","row","cell","paragraphsIntersecting","from","to","out","uniqueRanges","ranges","seen","r","k","cellAt","nearestSafeIndex","cellContentRange","_a","isLastTableCell","hit","lastRow","lastCol","nextCellIndex","dir","here","col","target","expandRangeOverStructures","slice","emptyTableSpacers","cols","s","LINK_COLOR","VIDEO_ASPECT","selStart","selEnd","isCollapsed","DEFAULT_TEXT","DEFAULT_PARAGRAPH","MAX_LIST_INDENT","HEADING_TEXT","hasTextProps","textPropsEqual","a","b","underlineKind","style","cloneStyle","span","cloneEntity","cloneVirtualBlock","chromeTextProps","chrome","shiftVirtualBlocksOnInsert","len","shiftVirtualBlocksOnDelete","rangesOverlap","rangesCross","rangeContains","depthOf","byId","d","id","parent","sortOuterToInner","map","la","lb","ancestorChain","chain","cur","clipVirtualBlocks","hits","ids","FONT_FAMILY","LINE_HEIGHT","PAGE_CONTENT_WIDTH","PAGE_PADDING_X","PAGE_PADDING_Y","LIST_MARKER_WIDTH","INDENT_STEP","CELL_PAD","MIN_COL_WIDTH","COL_BORDER_HIT","widthCache","WIDTH_CACHE_MAX","localeReady","ensureLocale","setLocale","fontFamilyOf","raw","resolveFont","canvasFont","font","measureWidth","key","prepared","prepareWithSegments","w","measureNaturalWidth","glyphCache","GLYPH_CACHE_MAX","naturalWidth","measureGlyphWidths","widths","prevWidth","cp","width","lineHeightOf","REF_PAD","REF_HEAD","refInnerWidth","boxW","chromeFallback","t","inner","innermostEmptySlot","resolvedTextStyle","heading","link","href","_b","_c","_d","HOST_FALLBACK_W","HOST_FALLBACK_H","embedLayoutSize","maxWidth","host","height","embedOccupiesLine","preparedCache","PREPARED_CACHE_MAX","preparedFor","WINDOW_SLACK","nextLineText","rest","size","n","whole","win","line","layoutNextLine","collectRuns","runs","ns","fitPrefix","lo","hi","best","mid","wrapParagraph","items","lineW","lineStart","flush","lineEnd","run","isolated","restIndex","remain","widthForLine","bandSlot","contentX","contentW","bandTop","bandH","obstacles","gap","left","right","f","cursorIndex","fallback","createWrapCursor","skipFloats","wrapCursorDone","wrapCursorIndex","wrapCursorPeek","wrapCursorSkip","consumeWrapLine","UL_MARKERS","listMarkerText","olIndex","layoutParagraph","x","y","paraProps","indent","markerText","markerW","align","floats","allObstacles","useFlow","paragraphHasFloat","lineY","peek","side","fx","slot","buildLine","wrapped","nextOl","counter","maxW","markerX","contentH","item","emptyStyle","dx","glyphs","images","caretStops","cx","local","marker","vblockFragments","lineH","fillRight","sorted","boxes","g","im","top","bottom","padX","continues","boxLeft","boxRight","layoutTable","paraIndex","stored","even","hasStored","colWidths","_","sum","cy","rowCells","maxH","innerW","paras","py","ol","pp","pl","h","fragmentFingerprint","fragmentId","fragment","hostFingerprint","hasImagesCache","hasImages","has","mediaFingerprint","parts","e","StyleIndex","spans","__publicField","running","types","INLINE_STYLES","ParagraphPropsIndex","textDefaultsKey","hashParagraph","styles","floatKey","propsKey","tdKey","vblockFingerprint","hashTable","floatBoxes","paragraphBottom","moveParagraph","dy","di","inPlace","shiftParagraphInPlace","l","v","moveTable","stats","layoutDocument","prev","insets","depth","contentY","tables","topOl","activeFloats","dirtyTop","dirtyBottom","markDirty","styleIndex","prevByHash","entry","inPlaceAllowed","shifted","canShiftInPlace","pickCached","hash","ry","cached","oldY","oldBottom","oldH","now","old","dirty","attachRefInners","model","sortedLinesCache","sortedLines","layout","caretFromIndex","near","caretFromIndexIn","allowNearest","bestLine","bestX","bestIndex","bestDist","exact","stop","dist","earlier","later","hitTestIndex","localX","localY","closestCaretOnLines","bestScore","inY","inX","score","selectionRects","cellRects","cellGridRects","rects","stops","rightCandidates","x0","x1","punchEmbeds","next","overlapY","overlapX","imageBoxAt","r0","r1","c0","c1","hitColBorder","fillOf","rainbowAt","sunsetAt","cssFill","runWidth","fill","canvasFill","glyphIndex","runT","paintCanvasUnderline","kind","color","amp","step","px","up","paintCanvasStrike","groupDecorationRuns","strike","baseline","REF_JUMP","innerUsedSize","measureRef","emptyInner","used","countLabel","paintInner","renderInnerLine","hole","pic","wrap","innerCss","deco","runW","weight","italic","refPlugin","badge","body","paintChip","decorateRefEl","count","title","editing","selected","DEFAULT_SELECT_OPTIONS","FILLED_IMAGE","ICONS","defaultSlotLabel","slotKindOf","slotOptionsOf","slotPlaceholder","slotCaption","slotFilled","measureSlot","label","textW","extra","closeMenus","except","menu","openSelectMenu","name","btn","clear","onDoc","slotEntities","filled","imageFilled","icon","thumb","slotPlugin","file","current","entityId","leaveEdit","startTextEdit","commitText","value","cancelText","activate","EMBED_EXIT_EDIT","applyVideo","videoPlugin","renderer","setHostEmbedRenderer","FALLBACK_SIZE","handles","handlesById","emitMeasure","detail","EMBED_MEASURE","observeSize","rec","ro","syncHostSelected","selectedId","syncRecSelected","contextOf","patch","commit","EMBED_COMMIT","EMBED_CHANGE","mountInto","handle","hostEmbedPlugin","activateHostEmbed","req","destroyHostEmbed","plugins","registerEmbed","plugin","embedPlugin","syncEmbedLayer","cache","canvas","placeEmbed","builtinEmbedPlugins","insertSpacers","insertBeforeIndex","NULL_MUTATION","deleteSpacers","startIndex","endIndex","applyStyle","styleType","addEntity","updateEntity","deleteEntity","addFragment","deleteFragment","addVirtualBlock","deleteVirtualBlock","blockId","updateVirtualBlock","scoped","multi","unwrap","m","commands","flat","mutation","reverse","mutations","appliers","applyMutation","applyMutations","cloneFragment","cloneSlice","previewTitle","max","normalizeFragmentSlice","sliceHasContent","STYLE_TYPES","restoreStyles","type","inverters","_doc","restoredBlocks","before","invertMutation","newRange","min","range","rangeEquals","shiftIndex","shiftPosition","offset","shiftIndexExclusive","shiftRange","leadingLength","position","leadEnd","transformCoordinateAgainstDeletedRange","deleted","transformRangeAgainstDeletedRange","newStart","endpointDeleted","newEnd","insertAgainstInsert","cmd","other","aWins","insertAgainstDelete","length","deleteAgainstInsert","copyWithRange","deleteAgainstDelete","removed","styleAgainstInsert","copyStyleWithRange","styleAgainstDelete","transformers","transform","o","transformBoth","others","transformIndex","shiftedByInserts","transformSelection","MERGEABLE_KINDS","mergeKeyFor","scope","editMeta","init","editResult","flatten","isEmptyEdit","mergeEdits","first","second","invertEdit","Collector","selection","one","scopeContext","outer","runOperation","op","result","resolveTextProps","resolveParagraphProps","rangeIsOnlyMarkers","contentRuns","base","runStart","content","textSegments","points","existing","spanCovering","expectedParagraphSpans","byStart","firstStartAtLeast","inherit","at","EMPTY_SLICE","emitInsert","emitDelete","emitStyle","emitTextStyle","seg","normalizeParagraphs","needed","sameSpans","needKeys","curKeys","differing","guard","grew","pa","pb","ka","ensureParagraphAfter","applyTextStyle","applyLink","url","clearFrom","clearTo","removeLink","applyParagraphStyle","RULES","lastMatch","reg","matchMarkdown","paraText","rule","full","matchStart","matchEnd","shouldTryMarkdown","inserted","entitySeq","fragmentSeq","virtualBlockSeq","nextEntityId","nextFragmentId","nextVirtualBlockId","DocumentModel","initial","shiftStylesOnInsert","shiftStylesOnDelete","kept","snap","entities","fragmentIds","fragments","virtualBlocks","probe","normalized","documentFromSlice","sliceFromDocument","inside","ending","ensure","merged","last","collapsedSel","sliceWithoutParagraphGroup","groupId","keep","insertImage","updateImage","blockMap","validateInsert","inferParentId","selfId","insertVirtualBlock","spec","parentId","placeholder","empty","child","removeVirtualBlock","updateVirtualBlockChrome","restoreChain","snaps","targetId","nextStart","nextEnd","isTarget","clearSlot","slotInlineText","fillSlot","safe","coverAncestorsOf","pid","coverVirtualBlocks","remapIncomingVirtualBlocks","occupied","idMap","remapped","extendMarksAtEnd","nl","isLastParagraphWithGroupId","splitParagraphSpans","cursor","insertText","insertParagraph","oldProps","inList","paraEndContent","atStart","atEnd","exitGroup","leftProps","rightProps","deleteRange","expanded","backspace","prevProps","deleteForward","applyMarkdownShortcut","caret","restyleParagraph","consume","tableSpan","writeColWidths","tableStart","tableEnd","insertTable","insertTableRow","insertTableCol","inserts","deleteTableRow","deleteTableCol","setTableColWidths","looksLikeMarkdown","parseInline","re","blockProps","ul","markdownToSlice","emitPara","tokens","tok","emitEmbed","fence","buf","oneLineMath","materializeSlice","lookup","scratch","source","insertSlice","asCopy","incoming","nested","remap","insertMarkdown","paraEnd","cut","pasteText","promoteRange","insertRef","unlinkRef","runScoped","runEdit","meta","UNDO_BATCH_MS","UndoRedoStack","edit","withinWindow","sameRun","undoStep","intervening","pair","forward","remote","ImeSurface","handler","arrow","modArrow","horizontal","altArrow","navKeys","SHORTCUTS","swallow","INPUT_SHORTCUTS","inputShortcuts","submit","submitUsesShift","matches","sc","stroke","findShortcut","IME_PASSTHROUGH","strokeOf","bindKeyboard","onKeyDown","ENTRY","STAGES","stat","samples","PerfProbe","editor","getPainter","painter","orig","args","tick","rl","self","arr","fr","frames","fps","ms","fn","proto","dt","IDLE_MS","FPS_WINDOW_MS","LIMITS","METRICS","LISTEN","PerfPanel","getStats","t0","ts","eventTs","pick","pad","maxL","maxT","latency","queue","values","mini","chars","miniFps","countParagraphs","segmenter","getSegmenter","maxCaretIndex","wordSpans","wordTarget","paragraphTarget","wordRangeAt","SLICE_MIME","serializeSlice","parseSlice","data","sliceFromClipboard","CANVAS_GUTTER","VIEWPORT_MARGIN","MAX_ZOOM_SHARPNESS","CanvasPainter","dpr","zoom","band","vb","visible","trails","rect","vv","viewTop","viewH","force","vis","margin","wantH","changed","maxTop","legal","covers","scaleChanged","moved","fullW","resized","topCss","editorRoot","family","markerTop","cs","radius","rainbow","grad","alpha","solid","caretW","editorCs","glow","metrics","ascent","descent","fontH","cssText","HtmlPainter","renderTableChrome","renderLine","on","placeCaret","fade","anim","renderVBlock","border","Editor","options","indices","pos","after","ops.updateImage","edge","refBox","interactive","openSafeUrl","ratio","ops.setTableColWidths","startW","startH","level","delta","hostType","opts","extend","unit","track","active","mode","prevColor","nextColor","match","cssColorsEqual","computed","selColor","selRadius","cssFamily","ops.slotInlineText","ops.fillSlot","ops.insertSlice","ops.insertVirtualBlock","origin","ops.updateVirtualBlockChrome","ops.removeVirtualBlock","ops.applyParagraphStyle","pred","ops.deleteRange","patchFor","patches","clientX","clientY","embed","canPromote","event","disabled","any","avail","selectionAfter","revert","settle","ops.clearSlot","minStart","maxEnd","ops.emitDelete","ops.emitInsert","ops.normalizeParagraphs","anchor","ops.insertText","selectedNow","ops.applyMarkdownShortcut","fakePlainClipboard","payload","ops.pasteText","explicit","pending","fromHeading","ops.insertParagraph","toHeading","res","ops.backspace","ops.deleteForward","ops.applyTextStyle","ops.applyLink","ops.removeLink","sized","ops.insertImage","slotKind","ops.promoteRange","picked","ops.insertRef","ops.unlinkRef","nw","nh","w0","h0","scale","video","ops.insertTable","focus","ops.insertTableRow","ops.insertTableCol","ops.deleteTableRow","ops.deleteTableCol","composing","show","opacity","mapped","demoCaret","posKey","showCaret","imeH","anchorPos","imeY","composeW","underlineH","idx","oy","surface","parents","geom","views","isRoot","isSlot","isRef","isHost","sliceToHtml","startX","w1","vnext","vertical","goalX","remember","children","intersecting","common","snapped","outlines","isStructural","hitEmbed","parsed"],"mappings":"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"}