@one2x/medeo-rte 0.4.5 → 0.4.7

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/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 * 虚拟块只有 mark:纯样式区间,交互与普通文本完全一致。\n * 不参与区间树(parentId 恒为 null),可与其它 mark 任意叠放。\n * 空态灰字、点击和生成中的中间态都挂在它上面。\n */\nexport type VirtualBlockKind = '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 /** 水平内边距。不传按 4px,传 0 表示不留。留在底色里面,每行文字都按它缩进;区间真正的首尾这段空白还占排版宽度。贴边处靠编辑器左右多留的 5px,不够会被裁 */\n paddingX?: number;\n color?: string;\n fontSize?: number;\n fontFamily?: string;\n fontWeight?: number;\n bold?: boolean;\n italic?: boolean;\n /** mark 的 placeholder 灰字。不传时用 #c5ccd6 */\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\n/** mark 未配 `chrome.paddingX` 时的水平内边距;没有它内外侧光标会画在同一处,看不出光标在块里还是块外 */\nexport const MARK_DEFAULT_PADDING_X = 4;\n\n/** mark 未配 `chrome.placeholderColor` 时的灰字颜色 */\nexport const MARK_PLACEHOLDER_COLOR = '#c5ccd6';\n\n/** 块实际生效的水平内边距:显式配置优先,mark 缺省 4px,其余缺省 0 */\nexport function paddingXOf(block: Pick<VirtualBlock, 'kind' | 'chrome'>): number {\n return block.chrome.paddingX ?? (block.kind === 'mark' ? MARK_DEFAULT_PADDING_X : 0);\n}\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 docLength?: number\n): VirtualBlock[] {\n const len = end - start;\n if (len <= 0) return [...blocks].map(cloneVirtualBlock);\n // 删的是整篇时,贴在文档首尾的零宽灰字也算落在选区里。\n const wholeDoc = docLength != null && start === 0 && end === docLength;\n const boundaryPlaceholder = (b: VirtualBlock) =>\n wholeDoc && b.kind === 'mark' && !!b.placeholder && b.start === b.end;\n const out: VirtualBlock[] = [];\n for (const b of blocks) {\n if (b.end <= start) {\n if (!boundaryPlaceholder(b)) out.push(cloneVirtualBlock(b));\n } else if (b.start >= end) {\n if (!boundaryPlaceholder(b)) 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 } else if (b.kind === 'mark' && b.placeholder && b.start === start && b.end === end) {\n // 删掉的正好是这块里的字:收成一个点,灰字由排版画出来,不占字符。\n out.push(cloneVirtualBlock({ ...b, start, end: start, empty: true }));\n }\n // 选区比这块更大、又把整段盖住:拆掉,不留灰字。\n }\n return out.filter((b) => b.end > b.start || (b.kind === 'mark' && !!b.placeholder));\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) {\n if (b.kind === 'mark' && b.placeholder && b.start === b.end && b.start >= from && b.start < to) {\n hits.push(cloneVirtualBlock({ ...b, start: b.start - from, end: b.start - from, empty: true }));\n }\n continue;\n }\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 */\nlet paintCtx: { font: string; measureText(text: string): { width: number } } | null | undefined;\n\nfunction paintMeasureContext(): { font: string; measureText(text: string): { width: number } } | null {\n if (paintCtx !== undefined) return paintCtx;\n try {\n const canvas =\n typeof OffscreenCanvas !== 'undefined'\n ? new OffscreenCanvas(1, 1)\n : typeof document !== 'undefined'\n ? document.createElement('canvas')\n : null;\n paintCtx = canvas?.getContext('2d') ?? null;\n } catch {\n paintCtx = null;\n }\n return paintCtx;\n}\n\n/**\n * 和 Canvas `fillText` 同一把尺子:整句一次 `measureText`。\n * 空 mark 的灰字是整句画上去的,底色要用这个宽度,不能用排版的逐字测宽。\n */\nexport function measurePaintWidth(text: string, props: TextProps): number {\n if (!text) return 0;\n const ctx = paintMeasureContext();\n if (!ctx) return measureWidth(text, props);\n const font = canvasFont(props);\n const key = `paint\\0${font}\\0${text}`;\n const hit = widthCache.get(key);\n if (hit !== undefined) return hit;\n ctx.font = font;\n const w = ctx.measureText(text).width;\n if (widthCache.size >= WIDTH_CACHE_MAX) widthCache.clear();\n widthCache.set(key, w);\n return w;\n}\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 } 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 return t;\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 { paddingXOf } from '../model/virtualBlock';\nimport { DEFAULT_TEXT, ImageEntity, ParagraphProps, TextProps, textPropsEqual } from '../model/types';\nimport { canvasFont, ensureLocale, measurePaintWidth, 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 | { kind: 'gap'; index: number; length: 0; endW: number; startW: number }\n | {\n kind: 'hold';\n index: number;\n length: 0;\n id: string;\n width: number;\n padEnd: number;\n /** 这一行要画的占位文字。空 mark 折行后每行一段 */\n text?: string;\n style?: TextProps;\n /** 这一段是占位符的第一行 / 后面还有 */\n head?: boolean;\n continues?: boolean;\n /** 从上一行续下来的,光标仍留在第一行 */\n continued?: boolean;\n }\n /** 折行后续行的行首内边距。只占宽度,不是 mark 边界,不改光标内外侧。 */\n | { kind: 'inset'; index: number; length: 0; w: number };\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 | { kind: 'gap'; index: number; endW: number; startW: number }\n | {\n kind: 'hold';\n index: number;\n id: string;\n width: number;\n padEnd: number;\n text?: string;\n style?: TextProps;\n pad?: number;\n continued?: boolean;\n };\n\n/** 中间态 label 或空 mark 的 placeholder。排版期间由 layoutDocument 设置,用来把行撑到装得下这段字。 */\nexport interface MarkLayoutHint {\n label: string;\n rainbow?: boolean;\n pulse?: boolean;\n}\n\nlet markHints: Map<string, MarkLayoutHint> | null = null;\n\nexport function setMarkLayoutHints(next: Map<string, MarkLayoutHint> | null) {\n markHints = next;\n}\n\nexport function markLayoutHint(id: string): MarkLayoutHint | undefined {\n return markHints?.get(id);\n}\n\ntype MarkGap = { endW: number; startW: number };\n\n/**\n * mark 的 paddingX 在区间真正的首尾占排版宽度(同 CSS 行内元素的 padding),\n * 前后文字不会压在底色上。endW 是在此结束的块、startW 是在此开始的块,多个块同处取最大。\n */\nfunction markGaps(doc: DocumentModel, start: number, end: number): Map<number, MarkGap> {\n const gaps = new Map<number, MarkGap>();\n const add = (i: number, key: keyof MarkGap, w: number) => {\n const g = gaps.get(i) ?? { endW: 0, startW: 0 };\n g[key] = Math.max(g[key], w);\n gaps.set(i, g);\n };\n for (const b of doc.virtualBlocksOverlapping(start, end)) {\n const pad = b.kind === 'mark' ? paddingXOf(b) : 0;\n if (pad <= 0) continue;\n // 空 mark 没有字,左右内边距都落在同一个下标:左边在 placeholder 之前。右边由 hold 的 padEnd 留在灰字之后。\n if (b.end <= b.start) {\n if (!b.placeholder) continue;\n if (b.start >= start && b.start < end && doc.spacers[b.start] !== MARKERS.PARAGRAPH) add(b.start, 'startW', pad);\n continue;\n }\n if (b.start >= start && b.start < end && doc.spacers[b.start] !== MARKERS.PARAGRAPH) add(b.start, 'startW', pad);\n if (b.end > start && b.end <= end && doc.spacers[b.end - 1] !== MARKERS.PARAGRAPH) add(b.end, 'endW', pad);\n }\n return gaps;\n}\n\n/**\n * 空 mark 的 placeholder、或中间态 label 比正文宽出的部分,在落点占一段宽度。\n * 空 mark 落在自己的下标上;有正文时宽出的部分落在终点,避免折行的每一行都加一次。\n */\nfunction markHolds(\n doc: DocumentModel,\n start: number,\n end: number,\n para: ParagraphProps\n): Map<number, { id: string; width: number; padEnd: number; text?: string; style?: TextProps; pad?: number }> {\n const holds = new Map<number, { id: string; width: number; padEnd: number; text?: string; style?: TextProps; pad?: number }>();\n for (const b of doc.virtualBlocksOverlapping(start, end)) {\n if (b.kind !== 'mark') continue;\n const empty = b.start === b.end;\n const shown = markHints?.get(b.id)?.label || (empty ? b.placeholder : undefined);\n if (!shown) continue;\n if (empty && (b.start < start || b.start >= end)) continue;\n const at = empty ? b.start : b.end;\n if (!empty && (at < start || at > end || (at === end && b.end > end))) continue;\n // 空 mark 没有自己的字,灰字跟左侧正文(也就是在这里打字会继承的那套)走。\n const styleAt = empty && b.start > 0 ? b.start - 1 : Math.min(Math.max(b.start, start), end - 1);\n const style = resolvedTextStyle(doc, styleAt, para);\n const content = empty ? '' : doc.spacers.slice(Math.max(b.start, start), Math.min(b.end, end)).replace(/\\n/g, '');\n // 空 mark 的灰字整句一次画上,底色跟 Canvas measureText 走。有正文时仍按排版测宽。\n const shownW = empty ? measurePaintWidth(shown, style) : measureWidth(shown, { ...style, bold: style.bold });\n const slack = shownW - (content ? measureWidth(content, style) : 0);\n // 空 mark 的右内边距留在灰字后面,底色才不会压到后一个字。有正文时这段空白已经在终点的 gap 里。\n const padEnd = empty ? paddingXOf(b) : 0;\n if (slack > 0.5 || padEnd > 0) {\n holds.set(at, {\n id: b.id,\n width: Math.max(0, slack),\n padEnd,\n text: empty ? shown : undefined,\n style: empty ? style : undefined,\n pad: padEnd\n });\n }\n }\n return holds;\n}\n\nfunction collectRuns(doc: DocumentModel, start: number, end: number, para: ParagraphProps): SourceRun[] {\n const runs: SourceRun[] = [];\n const gaps = markGaps(doc, start, end);\n const holds = markHolds(doc, start, end, para);\n const pushGap = (at: number) => {\n const g = gaps.get(at);\n if (g) runs.push({ kind: 'gap', index: at, ...g });\n const h = holds.get(at);\n if (h) runs.push({ kind: 'hold', index: at, ...h });\n };\n let i = start;\n while (i < end) {\n pushGap(i);\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) || gaps.has(j) || holds.has(j)) 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 pushGap(end);\n return runs;\n}\n\n/** mark 盖住 index,且不是这个 mark 的第一个字:折行后的行首要再留一份内边距。 */\nfunction leadingInset(doc: DocumentModel, index: number): number {\n let pad = 0;\n for (const b of doc.virtualBlocksOverlapping(index, index + 1)) {\n if (b.kind !== 'mark' || b.end <= b.start) continue;\n if (index > b.start && index < b.end) pad = Math.max(pad, paddingXOf(b));\n }\n return pad;\n}\n\n/** 这一行放不完 mark 的剩余文字时,行尾留出内边距,底色右缘包在文字外面。 */\nfunction trailingInset(doc: DocumentModel, index: number, length: number): number {\n const end = index + length;\n let pad = 0;\n for (const b of doc.virtualBlocksOverlapping(index, Math.max(end, index + 1))) {\n if (b.kind !== 'mark' || b.end <= b.start) continue;\n if (index >= b.start && index < b.end && b.end > end) pad = Math.max(pad, paddingXOf(b));\n }\n return pad;\n}\n\nfunction fitMarkText(doc: DocumentModel, rest: string, restIndex: number, style: TextProps, budget: number): string {\n const pick = (width: number) => fitPrefix(nextLineText(rest, style, width), style, width) || (rest[0] ?? '');\n let text = pick(budget);\n const pad = trailingInset(doc, restIndex, text.length);\n if (pad > 0.5 && budget - pad >= 1) {\n const again = pick(Math.max(1, budget - pad));\n if (again) text = again;\n }\n return text;\n}\n\n/** 新行的第一个字落在 mark 内部时,行首补上和第一行一样的内边距。 */\nfunction pushLeadingInset(doc: DocumentModel, items: WrapItem[], index: number): number {\n if (hasInk(items) || items.some((it) => it.kind === 'inset')) return 0;\n const w = leadingInset(doc, index);\n if (w <= 0) return 0;\n items.push({ kind: 'inset', index, length: 0, w });\n return w;\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 的 pre-wrap,在词边界断开。\n * 画出来的宽度仍用整段 `measureText`。这一行比预算宽时,按词退回,不从词中间切开。\n * 一个词本身就比行宽长时,整词留在这一行。\n */\nfunction fitPaintLine(text: string, style: TextProps, maxWidth: number): string {\n if (!text) return '';\n if (measurePaintWidth(text, style) <= maxWidth) return text;\n let slice = nextLineText(text, style, maxWidth) || text[0] || '';\n let guard = 0;\n while (guard++ < 32 && slice.length > 1 && measurePaintWidth(slice, style) > maxWidth + 0.5) {\n const trimmed = slice.replace(/[ \\t]+$/, '');\n const space = Math.max(trimmed.lastIndexOf(' '), trimmed.lastIndexOf('\\t'));\n if (space <= 0) break;\n const withSpace = slice.slice(0, space + 1);\n slice = measurePaintWidth(withSpace, style) <= maxWidth + 0.5 ? withSpace : trimmed.slice(0, space);\n }\n return slice || text[0] || '';\n}\n\ntype HoldRun = Extract<SourceRun, { kind: 'hold' }>;\n\n/**\n * 空 mark 的占位文字按行切开。这一行放不下时留下剩余文字并换行;\n * 每一行左右都留出 padding,和有正文的 mark 一样缩在底色里面。\n * 调用方见到 breakLine 就结束这一行,run 上留下还没排的字。\n */\nfunction placePlaceholderHold(run: HoldRun, items: WrapItem[], lineW: number, maxWidth: number): { lineW: number; breakLine: boolean } {\n const style = run.style;\n if (!run.text || !style) {\n items.push({ kind: 'hold', index: run.index, length: 0, id: run.id, width: run.width, padEnd: run.padEnd });\n return { lineW: lineW + run.width + run.padEnd, breakLine: false };\n }\n const pad = run.pad ?? 0;\n let w = lineW;\n const continued = !!run.continued;\n if (continued && !hasInk(items) && pad > 0 && !items.some((it) => it.kind === 'inset')) {\n items.push({ kind: 'inset', index: run.index, length: 0, w: pad });\n w += pad;\n }\n const remain = maxWidth - w;\n const busy = items.some((it) => it.kind === 'text' || it.kind === 'image' || (it.kind === 'hold' && it.id !== run.id));\n if (busy && remain <= pad + 0.5) return { lineW, breakLine: true };\n const whole = measurePaintWidth(run.text, style);\n const head = !continued;\n if (whole + pad <= Math.max(remain, 0) + 0.5) {\n items.push({\n kind: 'hold',\n index: run.index,\n length: 0,\n id: run.id,\n width: whole,\n padEnd: pad,\n text: run.text,\n style,\n head,\n continues: false,\n continued\n });\n return { lineW: w + whole + pad, breakLine: false };\n }\n const budget = Math.max(1, remain - pad);\n const slice = fitPaintLine(run.text, style, budget) || run.text[0] || '';\n if (slice.length >= run.text.length && busy) return { lineW, breakLine: true };\n const more = run.text.slice(slice.length);\n const sliceW = measurePaintWidth(slice, style);\n items.push({\n kind: 'hold',\n index: run.index,\n length: 0,\n id: run.id,\n width: sliceW,\n padEnd: more ? 0 : pad,\n text: slice,\n style,\n head,\n continues: more.length > 0,\n continued\n });\n if (!more) return { lineW: w + sliceW + (more ? 0 : pad), breakLine: false };\n run.text = more;\n run.width = measurePaintWidth(more, style);\n run.continued = true;\n return { lineW: w + sliceW, breakLine: true };\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 === 'gap') {\n items.push({ kind: 'gap', index: run.index, length: 0, endW: run.endW, startW: run.startW });\n lineW += run.endW + run.startW;\n continue;\n }\n if (run.kind === 'hold') {\n if (run.text) {\n for (;;) {\n const placed = placePlaceholderHold(run, items, lineW, maxWidth);\n lineW = placed.lineW;\n if (!placed.breakLine) break;\n if (!items.some((it) => it.kind === 'hold' && it.id === run.id) && !hasInk(items)) break;\n flush(run.index);\n }\n continue;\n }\n items.push({ kind: 'hold', index: run.index, length: 0, id: run.id, width: run.width, padEnd: run.padEnd });\n lineW += run.width + run.padEnd;\n continue;\n }\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 (hasInk(items)) 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 (hasInk(items) && 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 lineW += pushLeadingInset(doc, items, restIndex);\n const remain = maxWidth - lineW;\n if (hasInk(items) && 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 = fitMarkText(doc, rest, restIndex, run.style, widthForLine);\n if (hasInk(items) && 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 (hasInk(items) || lines.length === 0) {\n flush(end);\n } else if (items.length > 0) {\n // 只剩段尾的间隔(mark 结束在整行嵌入对象之后):并进上一行,不单独成空行。\n lines[lines.length - 1].items.push(...items);\n }\n return lines;\n}\n\n/** 行里有字、占位或嵌入对象;只有 mark 间隔不算,不能因此提前折行或单独成行。 */\nfunction hasInk(items: WrapItem[]): boolean {\n return items.some((it) => it.kind === 'text' || it.kind === 'image' || it.kind === 'hold');\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 = { doc: DocumentModel; 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 { doc, 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 === 'gap') {\n items.push({ kind: 'gap', index: run.index, length: 0, endW: run.endW, startW: run.startW });\n lineW += run.endW + run.startW;\n cur.i += 1;\n continue;\n }\n if (run.kind === 'hold') {\n if (run.text) {\n const placed = placePlaceholderHold(run, items, lineW, maxWidth);\n lineW = placed.lineW;\n if (!placed.breakLine) cur.i += 1;\n if (placed.breakLine) break;\n continue;\n }\n items.push({ kind: 'hold', index: run.index, length: 0, id: run.id, width: run.width, padEnd: run.padEnd });\n lineW += run.width + run.padEnd;\n cur.i += 1;\n continue;\n }\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 (hasInk(items)) break;\n items.push({ kind: 'image', index: run.index, length: 1, entity: run.entity });\n cur.i += 1;\n break;\n }\n if (hasInk(items) && 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 const at = run.index + cur.off;\n lineW += pushLeadingInset(cur.doc, items, at);\n const room = maxWidth - lineW;\n if (hasInk(items) && room <= 0) break;\n const widthForLine = items.length > 0 ? Math.max(1, room) : Math.max(1, maxWidth);\n let text = fitMarkText(cur.doc, rest, at, run.style, widthForLine);\n if (hasInk(items) && measureWidth(text, run.style) > room + 0.5 && room < 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, paddingXOf, 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, markLayoutHint, setMarkLayoutHints, wrapCursorDone, wrapCursorIndex, wrapCursorPeek, wrapCursorSkip, wrapParagraph, WrapItem, type MarkLayoutHint } 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 === 'gap') {\n contentW += item.endW + item.startW;\n } else if (item.kind === 'inset') {\n contentW += item.w;\n } else if (item.kind === 'hold') {\n contentW += item.width + item.padEnd;\n if (item.style) contentH = Math.max(contentH, lineHeightOf(item.style));\n } else 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 holds: { id: string; x: number; y: number; w: number; h: number; text?: string; continues?: boolean; head?: boolean }[] = [];\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 === 'gap') {\n const stop = caretStops[caretStops.length - 1];\n if (stop.index === item.index) {\n stop.midX = cx + item.endW;\n stop.fwdX = cx + item.endW + item.startW;\n }\n cx += item.endW + item.startW;\n continue;\n }\n if (item.kind === 'inset') {\n cx += item.w;\n continue;\n }\n if (item.kind === 'hold') {\n holds.push({\n id: item.id,\n x: cx,\n y,\n w: item.width,\n h: contentH,\n text: item.text,\n continues: item.continues,\n head: item.head\n });\n const stop = caretStops.find((s) => s.index === item.index) ?? caretStops[caretStops.length - 1];\n if (stop?.index === item.index && item.continued) {\n stop.placeholderTail = true;\n } else if (stop?.index === item.index && (item.padEnd > 0 || item.text)) {\n // 空 mark 的左内边距在灰字之前,贴前的光标跟灰字对齐,不要停在底色外面。\n stop.x = cx;\n stop.fwdX = cx + item.width;\n stop.midX = cx + item.width;\n }\n cx += item.width + item.padEnd;\n continue;\n }\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, holds, !align || align === 'left' ? x + maxW : null, para)\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 holds: { id: string; x: number; y: number; w: number; h: number; text?: string; continues?: boolean; head?: boolean }[],\n fillRight: number | null,\n para: ParagraphProps\n): VBlockFragment[] {\n const hits = doc.virtualBlocksOverlapping(lineStart, lineEnd);\n for (const hold of holds) {\n if (hits.some((b) => b.id === hold.id)) continue;\n const block = doc.blockById(hold.id);\n if (block) hits.push(block);\n }\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 for (const hold of holds) {\n if (hold.id === b.id) boxes.push(hold);\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 // 结尾和还没写完的每一行,字后也让出 padX。底色从这些空白的外缘画起,不再往文字列外面多画一份。\n const padX = paddingXOf(b);\n // 区间还延续到后面的行(折行或跨段)时,这一行铺满到内容区右缘,各行连成一个整体;\n // 只有最后一行按文字实际宽度。仅左对齐行这样处理,居中/右对齐保持按内容宽度。\n const hint = b.kind === 'mark' ? markLayoutHint(b.id) : undefined;\n const emptyMark = b.kind === 'mark' && b.start === b.end && !!b.placeholder;\n const slice = holds.find((hold) => hold.id === b.id && hold.text);\n const labelText = slice?.text || hint?.label || (emptyMark ? b.placeholder : undefined);\n const styleAt = emptyMark && b.start > 0 ? b.start - 1 : Math.min(Math.max(b.start, lineStart), Math.max(lineStart, lineEnd - 1));\n const atStyle = labelText ? resolvedTextStyle(doc, styleAt, para) : undefined;\n const continues =\n slice?.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) : right + padX;\n const first = slice ? slice.head !== false : b.start >= lineStart || emptyMark;\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 || emptyMark,\n first,\n last: !continues,\n labelText: slice?.text ? labelText : first ? labelText : undefined,\n labelRainbow: first && !!hint?.label && !!hint.rainbow,\n labelColor: hint?.label ? b.chrome.color : b.chrome.placeholderColor,\n labelStyle: atStyle\n ? {\n fontSize: atStyle.fontSize,\n fontFamily: atStyle.fontFamily,\n fontWeight: atStyle.fontWeight,\n bold: atStyle.bold,\n italic: atStyle.italic\n }\n : undefined,\n pulse: !!hint?.pulse,\n hideFrom: hint?.label && b.end > b.start ? b.start : undefined,\n hideTo: hint?.label && b.end > b.start ? b.end : undefined\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) => {\n const hint = markLayoutHint(b.id);\n return `${b.id}:${b.kind}:${b.parentId}:${b.start - start}:${b.end - start}:${b.empty ? 1 : 0}:${b.placeholder ?? ''}:${JSON.stringify(b.chrome)}:${hint ? `${hint.label}:${hint.rainbow ? 1 : 0}:${hint.pulse ? 1 : 0}` : ''}`;\n })\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 markHints?: Map<string, MarkLayoutHint>\n): DocLayout {\n if (depth === 0) {\n stats = { reused: 0, laidOut: 0 };\n setMarkLayoutHints(markHints ?? null);\n }\n try {\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 roundPenultimateMarkCorners(lines);\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 } finally {\n if (depth === 0) setMarkLayoutHints(null);\n }\n}\n\n/** 最后一行比上一行短时,上一行右下角是外角,需要圆角。左右齐平的边不圆,避免直边上缺一角。 */\nfunction roundPenultimateMarkCorners(lines: LineBox[]) {\n const groups = new Map<string, VBlockFragment[]>();\n for (const line of lines) {\n for (const vb of line.vblocks ?? []) {\n vb.roundBottomRight = false;\n const list = groups.get(vb.id) ?? [];\n list.push(vb);\n groups.set(vb.id, list);\n }\n }\n for (const frags of groups.values()) {\n if (frags.length < 2) continue;\n frags.sort((a, b) => a.y - b.y || a.x - b.x);\n const prev = frags[frags.length - 2];\n const last = frags[frags.length - 1];\n if (prev.x + prev.w > last.x + last.w + 0.5) prev.roundBottomRight = true;\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; placeholderTail?: boolean }[] = [];\n for (const line of lines) {\n for (const stop of line.caretStops) {\n if (stop.index === index) exact.push({ line, x: stop.x, placeholderTail: stop.placeholderTail });\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.find((hit) => !hit.placeholderTail) ?? 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 || later.placeholderTail) {\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.min(Math.abs(s.x - localX), s.fwdX == null ? Infinity : Math.abs(s.fwdX - 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 // 选区收到 mark 终点时,右端用贴前位置会停在最后一个字后面,底色的 paddingX 露出来。\n // 收到结束块底色的外缘。起点的贴前位置已经在左内边距外面,不用改。\n const rightEdge = right.index === to && right.midX != null && right.midX > right.x ? right.midX : right.x;\n const x1 = Math.max(left.x, rightEdge);\n if (x1 > x0) {\n rects.push({ x: x0, y: line.y, w: x1 - x0, h: line.h });\n }\n }\n return rects;\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 | 'mark.replace';\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 = marksOnly(initial.virtualBlocks);\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 const docLength = this.spacers.length;\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, docLength));\n }\n\n /** addVirtualBlock 的落地:同 id 则整体替换。非 mark 直接丢掉。 */\n applyAddVirtualBlock(block: VirtualBlock) {\n if (block.kind !== 'mark') return;\n this.virtualBlocks.set(block.id, cloneVirtualBlock({ ...block, parentId: null, kind: 'mark' }));\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) || block.kind !== 'mark') return;\n this.virtualBlocks.set(blockId, cloneVirtualBlock({ ...block, id: blockId, parentId: null, kind: 'mark' }));\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 = marksOnly(snap.virtualBlocks);\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) || (b.start === b.end && b.start >= from && b.start < to))\n .map(cloneVirtualBlock);\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\nfunction marksOnly(blocks: VirtualBlock[] | undefined): Map<string, VirtualBlock> {\n return new Map(\n (blocks ?? [])\n .filter((b) => b.kind === 'mark')\n .map((b) => [b.id, cloneVirtualBlock({ ...b, parentId: null, kind: 'mark' })])\n );\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 = marksOnly(normalized.virtualBlocks);\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 { VirtualBlock, VirtualBlockChrome, VirtualBlockKind } from '../model/types';\nimport { sortOuterToInner } from '../model/virtualBlock';\nimport { nextVirtualBlockId } from '../model/document';\nimport { addVirtualBlock, deleteVirtualBlock, updateVirtualBlock } from '../mutations';\nimport { Operation } from './context';\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.kind !== 'mark') return 'not-mark';\n if (block.end < block.start) return 'empty-range';\n // 带 placeholder 的 mark 可以是零宽:字删光后留在原地,排版画出灰字。\n if (block.end === block.start && !block.placeholder) return 'empty-range';\n return 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 if (spec.kind !== 'mark') return null;\n if (end === start && !spec.placeholder) return null;\n\n const id = spec.id && !doc.virtualBlocks.has(spec.id) ? spec.id : nextVirtualBlockId();\n const block: VirtualBlock = {\n id,\n parentId: null,\n kind: 'mark',\n start,\n end,\n chrome: { ...(spec.chrome ?? {}) },\n placeholder: spec.placeholder,\n empty: start === end ? spec.empty ?? true : spec.empty\n };\n const err = validateInsert(doc, block);\n if (err) return null;\n\n ctx.emit(addVirtualBlock(block));\n return id;\n };\n}\n\n/**\n * 光标正停在零宽 placeholder mark 上时,退格或删除拆掉这些块。\n * 一次拆掉落在同一下标上的全部空 mark。没有这样的块时返回 false。\n */\nexport function dismissEmptyPlaceholderMarks(index: number): Operation<boolean> {\n return (ctx) => {\n const i = ctx.doc.clamp(index);\n const hits = ctx.doc\n .listVirtualBlocks()\n .filter((b) => b.kind === 'mark' && !!b.placeholder && b.start === b.end && b.start === i);\n if (!hits.length) return false;\n for (const b of hits) ctx.emit(deleteVirtualBlock(b.id));\n return true;\n };\n}\n\n/** 拆掉皮,字留下。 */\nexport function removeVirtualBlock(id: string): Operation<boolean> {\n return (ctx) => {\n if (!ctx.doc.blockById(id)) return false;\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\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.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 * 光标亲和:mark 边界上同一个下标有两个光标位置。\n * `backward` 贴前一个字(默认):右边界算块内、左边界算块外;`forward` 贴后一个字,正好相反。\n */\nexport type CaretAffinity = 'backward' | 'forward';\n\n/** 在 index 处插入了 text 之后,按光标亲和把边界上的 mark 撑开。插入本身已由调用方 emit。 */\nexport function extendMarksAt(index: number, text: string, affinity: CaretAffinity): Operation<void> {\n return (ctx) => {\n (affinity === 'forward' ? extendMarksAtStart(index, text) : extendMarksAtEnd(index, text))(ctx);\n // 零宽 mark 在结构上被当成「终点不晚于插入点」而不右移,forward 捞不到它。\n // 它没有内外侧,两种亲和输入都进块。\n if (affinity === 'forward') extendEmptyPlaceholderMarks(index, text)(ctx);\n };\n}\n\nfunction extendEmptyPlaceholderMarks(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.placeholder || b.start !== index || b.end !== index) continue;\n ctx.emit(updateVirtualBlock(b.id, { ...b, end: index + len, empty: false }));\n }\n };\n}\n\n/**\n * 把「原本恰好从 index 开始」的 mark 起点留在新字之前,让左边缘输入算区间内;\n * 遇到换行就断(只从最后一个 \\n 之后算起)。插入后这些 mark 已整体右移到 index + text.length。\n */\nfunction extendMarksAtStart(index: number, text: string): Operation<void> {\n return (ctx) => {\n if (!text || text.endsWith('\\n')) return;\n const shifted = index + text.length;\n const start = index + text.lastIndexOf('\\n') + 1;\n for (const b of ctx.doc.listVirtualBlocks()) {\n if (b.kind !== 'mark' || b.start !== shifted) continue;\n ctx.emit(updateVirtualBlock(b.id, { ...b, start }));\n }\n };\n}\n\n/**\n * 在 index 处插入了 text 之后,把「恰好在 index 结束」的 mark 向右撑开,\n * 让右边缘继续输入算区间内;遇到换行就断(只撑到第一个 \\n 之前)。\n */\nfunction 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, empty: false }));\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 { addVirtualBlock, applyStyle, deleteVirtualBlock, multi, updateVirtualBlock } 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 { CaretAffinity, extendMarksAt } 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/**\n * 在 index 处插入文本,继承左侧文字样式(或调用方指定的样式)。返回新光标位置。\n *\n * `affinity` 决定 index 恰好是 mark 边界时新字进不进块,见 {@link CaretAffinity}。\n */\nexport function insertText(\n index: number,\n text: string,\n inherit?: TextProps,\n affinity: CaretAffinity = 'backward'\n): 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 left = inherit ?? resolveTextProps(ctx.doc, i);\n\n emitInsert(ctx, i, safe);\n extendMarksAt(i, safe, affinity)(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 normalizeParagraphs(ctx);\n return i + safe.length;\n };\n}\n\n/**\n * 替换 mark 里的文字,块本身留下,整步一次撤销。\n * 换成空串时:有 placeholder 就收成零宽,没有就拆掉这块。\n * 返回新文字之后的下标;id 不是 mark 时返回 null。\n */\nexport function replaceMarkText(id: string, text: string): Operation<number | null> {\n return (ctx) => {\n const block = ctx.doc.blockById(id);\n if (!block || block.kind !== 'mark') return null;\n const at = block.start;\n const placeholder = block.placeholder;\n const chrome = { ...block.chrome };\n if (block.end > at) deleteRange(at, block.end)(ctx);\n const safe = text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n if (!safe && !placeholder) {\n if (ctx.doc.blockById(id)) ctx.emit(deleteVirtualBlock(id));\n return at;\n }\n const end = safe ? insertText(at, safe)(ctx) : at;\n const current = ctx.doc.blockById(id);\n const nextEnd = safe ? end : at;\n if (!current) {\n ctx.emit(\n addVirtualBlock({\n id,\n parentId: null,\n kind: 'mark',\n start: at,\n end: nextEnd,\n chrome,\n placeholder,\n empty: !safe\n })\n );\n } else if (current.start !== at || current.end !== nextEnd || !!current.empty === !!safe) {\n ctx.emit(updateVirtualBlock(id, { ...current, start: at, end: nextEnd, empty: !safe }));\n }\n return nextEnd;\n };\n}\n\n/** 回车。空列表项上先降缩进再退出列表;否则切段,两段各自继承合适的属性。 */\nexport function insertParagraph(index: number): Operation<number> {\n return (ctx) => {\n const i = ctx.doc.clamp(index);\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 { CaretAffinity, extendMarksAt, insertVirtualBlock, remapIncomingVirtualBlocks } 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(\n index: number,\n slice: Slice,\n asCopy = true,\n affinity: CaretAffinity = 'backward'\n): 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 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 extendMarksAt(i, incoming.text, affinity)(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 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 normalizeParagraphs(ctx);\n return i + incoming.text.length;\n };\n}\n\n/** 把一段 Markdown 原文导入到 index 处。段落中间导入时先把段切开。 */\nexport function insertMarkdown(index: number, raw: string, affinity: CaretAffinity = 'backward'): 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 }, true, affinity)(ctx);\n return at + text.length;\n };\n}\n\n/** 粘贴纯文本。看起来像 Markdown 就走导入,否则当普通文字插入。 */\nexport function pasteText(\n index: number,\n raw: string,\n inherit?: TextProps,\n affinity: CaretAffinity = 'backward'\n): Operation<number> {\n return (ctx) =>\n looksLikeMarkdown(raw)\n ? insertMarkdown(index, raw, affinity)(ctx)\n : insertText(index, raw, inherit, affinity)(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 { MARK_PLACEHOLDER_COLOR } from '../model/virtualBlock';\nimport { canvasFont, FONT_FAMILY } from '../layout/measure';\nimport { CaretPos, DocLayout, GlyphBox, SelRect, VBlockFragment } 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 focusMark: CaretPos | null = null;\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 // 行内样式压过宿主写在祖先上的 letter-spacing,避免 fillText 比测宽更宽。\n const lock = 'letter-spacing:0;word-spacing:0;font-kerning:normal;font-feature-settings:normal;font-variant:normal;font-variant-numeric:normal;';\n this.canvas.style.cssText = lock;\n this.chrome.style.cssText = lock;\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 paintMarkEffects() {\n const layout = this.layout;\n if (!layout) return;\n const vis = this.visibleRange(layout);\n this.redrawContent({ top: vis.top, bottom: vis.bottom });\n }\n\n paintFocusMark(mark: CaretPos | null) {\n const prev = this.focusMark;\n if (prev === mark || (prev && mark && prev.x === mark.x && prev.y === mark.y && prev.h === mark.h)) return;\n this.focusMark = mark;\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) {\n const hidden = (line.vblocks ?? []).some(\n (v) => v.hideFrom != null && v.hideTo != null && g.index >= v.hideFrom && g.index < v.hideTo\n );\n if (!hidden) this.paintGlyph(ctx, g);\n }\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 if (this.focusMark) this.drawFocusMark(ctx, this.focusMark);\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(ctx: CanvasRenderingContext2D, vb: VBlockFragment) {\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 === 'mark' ? 3 : 6);\n // 首行上两角圆、末行下两角圆,其余角方;单行自然四角全圆。\n const top = vb.first ? base : 0;\n const bottom = vb.last ? base : 0;\n const bottomRight = bottom || (vb.roundBottomRight ? base : 0);\n const radius: number[] = [top, top, bottomRight, 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 if (vb.pulse) {\n const alpha = 0.35 + 0.6 * (0.5 + 0.5 * Math.sin(performance.now() / 190));\n ctx.save();\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 = `rgba(134, 61, 251, ${alpha})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n ctx.restore();\n }\n if (vb.labelText) {\n const pad = vb.chrome.paddingX ?? (vb.kind === 'mark' ? 4 : 0);\n const size = vb.labelStyle?.fontSize ?? 16;\n ctx.save();\n ctx.font = canvasFont(vb.labelStyle ?? {});\n ctx.textBaseline = 'alphabetic';\n if (vb.labelRainbow) {\n const shift = (performance.now() / 8) % 240;\n const grad = ctx.createLinearGradient(vb.x - shift, vb.y, vb.x - shift + 240, vb.y);\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 } else {\n ctx.fillStyle = vb.labelColor || (vb.empty ? MARK_PLACEHOLDER_COLOR : '#1f2329');\n }\n const metrics = ctx.measureText(vb.labelText || '汉');\n const ascent = metrics.fontBoundingBoxAscent || size * 0.8;\n const descent = metrics.fontBoundingBoxDescent || size * 0.2;\n const baseline = vb.y + (vb.h - (ascent + descent)) / 2 + ascent;\n ctx.fillText(vb.labelText, vb.x + pad, baseline);\n ctx.restore();\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 /** 与 `.mini-focus-mark` 同形:2px 竖线 + 贴着行顶、整颗落在行内的 6px 圆点 */\n private drawFocusMark(ctx: CanvasRenderingContext2D, mark: CaretPos) {\n const editorRoot = this.host?.closest('.mini-editor') as HTMLElement | null;\n const color = editorRoot ? getComputedStyle(editorRoot).getPropertyValue('--mini-sel-focus-color').trim() : '';\n const { x, y, h } = mark;\n ctx.save();\n ctx.fillStyle = color || '#2b6cff';\n ctx.fillRect(x, y, 2, h);\n ctx.beginPath();\n ctx.arc(x + 1, y + 3, 3, 0, Math.PI * 2);\n ctx.fill();\n ctx.restore();\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 { MARK_PLACEHOLDER_COLOR } from '../model/virtualBlock';\nimport { syncEmbedLayer } from '../embed';\nimport { measurePaintWidth } from '../layout/measure';\nimport { CaretPos, DocLayout, LineBox, SelRect, TableLayout, VBlockFragment } from '../layout/types';\nimport { cssFill, fillOf } from './decorations';\nimport { PaintBackend } from './types';\n\nfunction cssFont(style: { fontSize?: number; fontWeight?: number; bold?: boolean; italic?: boolean } | undefined): 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 // 与正文 run 一样只走编辑器字体变量。span 上的 fontFamily 交给这个变量,避免灰字单独解析成另一套字体。\n return `font-style:${italic};font-weight:${weight};font-size:${size}px;font-family:var(--mini-font-family);`;\n}\n\nfunction cssText(style: LineBox['glyphs'][0]['style'], runW: number): string {\n const color = style.color ?? '#1f2329';\n const fill = cssFill(style, runW);\n return `${cssFont(style)}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 focusMark: 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.focusMark = document.createElement('div');\n this.focusMark.className = 'mini-focus-mark';\n this.focusMark.style.display = 'none';\n this.surface.append(this.selection, this.content, this.embeds, ...this.trails, this.focusMark, 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 paintFocusMark(mark: CaretPos | null) {\n const el = this.focusMark;\n if (!el) return;\n if (!mark) {\n if (el.style.display !== 'none') el.style.display = 'none';\n return;\n }\n const css = `left:${mark.x}px;top:${mark.y}px;height:${mark.h}px;`;\n if (el.style.cssText !== css) el.style.cssText = css;\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.focusMark = 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 const hidden = (index: number) =>\n (line.vblocks ?? []).some((v) => v.hideFrom != null && v.hideTo != null && index >= v.hideFrom && index < v.hideTo);\n for (const g of line.glyphs) {\n if (hidden(g.index)) {\n flush();\n continue;\n }\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 Math.abs(run.x + run.w - g.x) < 0.01\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${vb.pulse ? ' is-pulse' : ''}`;\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 === 'mark' ? 3 : 6);\n // 首行上两角圆、末行下两角圆,其余角方;单行自然四角全圆。\n const top = vb.first ? base : 0;\n const bottom = vb.last ? base : 0;\n const bottomRight = bottom || (vb.roundBottomRight ? base : 0);\n const radius = `${top}px ${top}px ${bottomRight}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 if (vb.labelText) appendMarkLabel(el, vb);\n return el;\n}\n\n/** 灰字和正文同一套:整段测一次宽,再整段画成一个 run。样式全篇一致,不用逐字测。 */\nfunction appendMarkLabel(parent: HTMLElement, vb: VBlockFragment) {\n const pad = vb.chrome.paddingX ?? (vb.kind === 'mark' ? 4 : 0);\n const text = vb.labelText ?? '';\n const style = vb.labelStyle ?? {};\n const w = measurePaintWidth(text, style);\n const color = vb.labelRainbow ? '' : vb.labelColor || (vb.empty ? MARK_PLACEHOLDER_COLOR : '#1f2329');\n const span = document.createElement('span');\n span.className = `mini-run${vb.labelRainbow ? ' mini-mark-label is-rainbow' : ''}`;\n span.textContent = text;\n span.style.cssText = `left:${pad}px;top:0;width:${w}px;height:${vb.h}px;line-height:${vb.h}px;${cssFont(style)}${color ? `color:${color};` : ''}`;\n parent.appendChild(span);\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 * 选区焦点端的标记(竖线 + 顶部圆点)固定为 {@link FOCUS_MARK_COLOR},不跟本色变化。\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\n/** mark 的中间态。只活在编辑器里,不进文档、撤销栈、复制和保存。 */\nexport interface MarkStatus {\n /** 盖住这段正文(或 placeholder)的文字,比如 `Generating…`。 */\n label?: string;\n /** 为真时,块内和内侧边界上的输入、删除、粘贴不生效,点击也不发 `markclick`。 */\n locked?: boolean;\n /** `label` 用彩虹渐变。 */\n text?: 'rainbow';\n /** 底色边缘一圈呼吸描边。 */\n border?: 'pulse';\n}\n\nexport interface MarkEvent {\n id: string;\n}\n\n/**\n * - `change`:文档内容变化\n * - `selectionchange`:选区或光标移动\n * - `statechange`:{@link EditorState} 任一字段可能已变,用于同步工具栏\n * - `layoutchange`:重新排版完成,可从 {@link Editor.getLayout} 取新几何\n * - `markclick`:点击某个 mark,参数是块 id。锁定中不发\n * - `markenter` / `markleave`:光标进入或离开 mark(含空 mark 和内侧边界)\n */\nexport type EditorEventMap = {\n change: void;\n selectionchange: void;\n statechange: void;\n layoutchange: void;\n markclick: MarkEvent;\n markenter: MarkEvent;\n markleave: MarkEvent;\n};\n\nexport type EditorEvent = keyof EditorEventMap;\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<(payload?: MarkEvent) => void> } = {\n change: new Set(),\n selectionchange: new Set(),\n statechange: new Set(),\n layoutchange: new Set(),\n markclick: new Set(),\n markenter: new Set(),\n markleave: new Set()\n };\n /** 中间态。键是 mark id。 */\n private markStatus = new Map<string, MarkStatus>();\n /** 光标当前所在的 mark,用来发进入/离开。 */\n private markCaretIds: string[] = [];\n private markEffectRaf = 0;\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 composeAffinity: ops.CaretAffinity = 'backward';\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 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, 0, this.markHintMap());\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 this.root.style.setProperty('--mini-sel-focus-color', FOCUS_MARK_COLOR);\n const selRadius = this.chrome.selectionRadius ?? 0;\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.markStatus.clear();\n this.markCaretIds = [];\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.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 this.runEdit('insert.paste', (ctx) => {\n this.deleteSelectionIfNeeded(ctx);\n ctx.select(collapsedSel(ops.insertSlice(at ?? ctx.selection().focus, slice)(ctx)));\n });\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 && !(spec.kind === 'mark' && spec.placeholder)) return null;\n let id: string | null = null;\n this.runEdit('vblock.insert', (ctx) => {\n id = ops.insertVirtualBlock({ ...spec, start, end })(ctx);\n });\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 /**\n * 设置或清掉 mark 的中间态。`null` 恢复正常。\n * 不进文档、不进撤销栈,也不触发 `change`。label 比正文宽时,这一行会临时撑开。\n */\n setMarkStatus(id: string, status: MarkStatus | null) {\n if (status) {\n const block = this.doc.blockById(id);\n if (!block || block.kind !== 'mark') return;\n this.markStatus.set(id, status);\n } else {\n this.markStatus.delete(id);\n }\n this.relayout();\n }\n\n /**\n * 替换 mark 里的文字,块留着,整步算一次撤销。\n * 换成空串时,有 placeholder 就变回灰字,没有就把块拆掉。\n * 返回块是否存在。\n */\n replaceMarkText(id: string, text: string): boolean {\n let ok = false;\n this.runEdit('mark.replace', (ctx) => {\n const end = ops.replaceMarkText(id, text)(ctx);\n ok = end != null;\n if (end != null) ctx.select(collapsedSel(end));\n });\n return ok;\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 }\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.affinity = null;\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 };\n }\n\n /**\n * 订阅事件,返回取消订阅函数。\n * `change` 等四个原有事件没有参数;`markclick` / `markenter` / `markleave` 收到 `{ id }`。\n */\n on<K extends EditorEvent>(\n event: K,\n handler: EditorEventMap[K] extends void ? () => void : (payload: EditorEventMap[K]) => void\n ): () => void {\n this.listeners[event].add(handler as (payload?: MarkEvent) => void);\n return () => this.listeners[event].delete(handler as (payload?: MarkEvent) => void);\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<K extends EditorEvent>(event: K, ...args: EditorEventMap[K] extends void ? [] : [EditorEventMap[K]]) {\n const payload = args[0] as MarkEvent | undefined;\n for (const handler of this.listeners[event]) handler(payload);\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 };\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 /** 鼠标下最上面的 mark,不要求配了 hoverBackground。 */\n private markUnderPoint(x: number, y: number): string | 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') 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 /** 鼠标下配置了 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 window.cancelAnimationFrame(this.markEffectRaf);\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 {\n this.markArmedId = null;\n this.sel = next;\n }\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 /** 光标停在零宽灰字上:退格和删除拆掉这块,不顺手删掉旁边的字。锁定中的不拆。 */\n private dismissEmptyPlaceholderAtCaret(): boolean {\n if (this.refEdit || !isCollapsed(this.sel)) return false;\n const i = this.sel.focus;\n const hits = this.doc\n .listVirtualBlocks()\n .filter(\n (b) =>\n b.kind === 'mark' &&\n !!b.placeholder &&\n b.start === b.end &&\n b.start === i &&\n !this.markStatus.get(b.id)?.locked\n );\n if (!hits.length) return false;\n this.runEdit('vblock.remove', (ctx) => {\n for (const b of hits) ops.removeVirtualBlock(b.id)(ctx);\n });\n return true;\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 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 && this.markEditBlocked('insert')) return;\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 this.composeAffinity = this.caretAffinity();\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 if (this.composeLen > 0) ops.deleteRange(anchor, anchor + this.composeLen)(ctx);\n const end = text ? ops.insertText(anchor, text, inherit, this.composeAffinity)(ctx) : anchor;\n ctx.select(collapsedSel(end));\n });\n this.composeLen = text.length;\n } else if (!active && this.composeAnchor !== null) {\n const anchor = this.composeAnchor;\n const len = this.composeLen;\n this.applyNow((ctx) => {\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 if (this.markEditBlocked('insert')) return;\n const affinity = this.caretAffinity();\n this.runEdit('insert.text', (ctx) => {\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, affinity)(ctx);\n if (!this.refEdit && shouldTryMarkdown(text)) next = ops.applyMarkdownShortcut(next)(ctx);\n ctx.select(collapsedSel(next));\n });\n }\n\n pasteText(text: string) {\n this.pasteClipboard(text ? fakePlainClipboard(text) : null);\n }\n\n pasteClipboard(data: DataTransfer | null) {\n if (this.markEditBlocked('insert')) return;\n const slice = sliceFromClipboard(data);\n const text = data?.getData('text/plain') ?? '';\n if (!slice && !text) return;\n const affinity = this.caretAffinity();\n this.runEdit('insert.paste', (ctx) => {\n this.deleteSelectionIfNeeded(ctx);\n if (slice) {\n ctx.select(collapsedSel(ops.insertSlice(ctx.selection().focus, slice, true, affinity)(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, affinity)(ctx);\n ctx.select(collapsedSel(next));\n });\n }\n\n insertParagraph(opts?: { shift?: boolean }) {\n if (this.disabled) return;\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 if (this.markEditBlocked('insert')) return;\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 this.deleteSelectionIfNeeded(ctx);\n ctx.select(collapsedSel(ops.insertParagraph(ctx.selection().focus)(ctx)));\n });\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.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 if (this.markEditBlocked('backspace')) return;\n if (this.dismissEmptyPlaceholderAtCaret()) return;\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.deleteSelectedEmbed('forward')) return;\n if (this.markEditBlocked('delete')) return;\n if (this.dismissEmptyPlaceholderAtCaret()) 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 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 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 lo = range.start;\n const hi = 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, 0, this.markHintMap());\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 const src = URL.createObjectURL(file);\n const commit = (nw: number, nh: number) => {\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 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, 0, this.markHintMap());\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 this.syncMarkEffects();\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 ?? this.mainCaretPos()),\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 this.painter.paintFocusMark(this.focusMarkPos());\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 * 文字选区焦点端的标记位置。整块选中的嵌入对象不画:那是选中一个对象,没有可挪动的一端。\n */\n private focusMarkPos(): CaretPos | null {\n if (!this.isFocused() || this.isEmbedChromeFocused() || this.ime.composing) return null;\n if (this.refEdit) return isCollapsed(this.fragSel) ? null : this.refCaretPos();\n if (isCollapsed(this.sel) || this.selectedImage()) return null;\n const cache = this.focusMarkCache;\n if (cache && cache.layout === this.layout && cache.anchor === this.sel.anchor && cache.focus === this.sel.focus) {\n return cache.pos;\n }\n const sel = this.sel;\n let pos = caretFromIndex(this.layout, sel.focus);\n const whole = this.wholeMarkSelect ? this.wholeSelectedMark() : null;\n // 整段选中时焦点留在进入的那一侧:右边界的贴前位置在块内,要改画到外侧。\n if (whole && sel.focus === whole.end) {\n const fwdX = this.caretStopAt(sel.focus)?.fwdX;\n if (fwdX != null) pos = { ...pos, x: fwdX };\n } else if (sel.focus > sel.anchor) {\n // 往下扩选时,行尾下标和下一行行首是同一个点。普通折行要把焦点留在上一行末尾。\n // 下一行是空行时留在空行上,否则焦点画在上一行末尾,空行上看起来被跳过了。\n const onEmptyLine = this.layout.lines.some(\n (l) => l.start === sel.focus && l.end > l.start && l.glyphs.length === 0 && l.images.length === 0\n );\n if (!onEmptyLine) {\n const line = this.layout.lines.find((l) => l.end === sel.focus && l.caretStops.some((s) => s.index === sel.focus));\n const stop = line?.caretStops.find((s) => s.index === sel.focus);\n if (line && stop) pos = { x: stop.x, y: line.y, h: line.h, index: sel.focus };\n }\n }\n this.focusMarkCache = { layout: this.layout, anchor: this.sel.anchor, focus: this.sel.focus, pos };\n return pos;\n }\n\n private focusMarkCache: { layout: DocLayout; anchor: number; focus: number; pos: CaretPos } | null = null;\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.syncMarkCaret();\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 * mark 边界上的光标亲和。块内最后一个字后面和块外第一个位置是同一个下标(左边界同理),\n * 只能靠它区分:backward 贴前一个字(右边界在块内、左边界在块外),forward 贴后一个字。\n * index 对不上或不再是边界就作废,按 backward 算。\n */\n private affinity: { index: number; dir: ops.CaretAffinity } | null = null;\n /**\n * 从外侧移入 mark 时先整段选中。关闭后方向键按字符流进出:\n * 边界上先换内外侧,再按一次才走进或走出。\n */\n private readonly wholeMarkSelect = true;\n /** 这次整段高亮是方向键撞上 mark 产生的选中态。拖选和 Shift 拉出的选区不记。 */\n private markArmedId: string | null = null;\n\n /** index 恰好是某个 mark 的起点或终点 */\n private isMarkBoundary(index: number): boolean {\n if (this.refEdit) return false;\n return this.doc\n .listVirtualBlocks()\n .some((b) => b.kind === 'mark' && b.start < b.end && (b.end === index || b.start === index));\n }\n\n /** 光标算在这块 mark 里面:空 mark 的落点、区间内部、以及左右内侧边界。 */\n private caretInsideMark(block: VirtualBlock, index: number): boolean {\n if (block.kind !== 'mark') return false;\n if (block.start === block.end) return !!block.placeholder && block.start === index;\n if (index > block.start && index < block.end) return true;\n if (index === block.end) return this.caretAffinity() !== 'forward';\n if (index === block.start) return this.caretAffinity() === 'forward';\n return false;\n }\n\n private lockedMarkBlocks(): VirtualBlock[] {\n const out: VirtualBlock[] = [];\n for (const [id, status] of this.markStatus) {\n if (!status.locked) continue;\n const block = this.doc.blockById(id);\n if (block?.kind === 'mark') out.push(block);\n }\n return out;\n }\n\n /** 这个下标上的字符属于锁定中的 mark。 */\n private indexCoveredByLockedMark(index: number): boolean {\n return this.lockedMarkBlocks().some((b) => b.start <= index && index < b.end);\n }\n\n private rangeHitsLockedMark(from: number, to: number): boolean {\n return this.lockedMarkBlocks().some((b) => {\n if (b.start === b.end) return from <= b.start && b.start < to;\n return b.start < to && b.end > from;\n });\n }\n\n /**\n * 锁定中的 mark:内侧和块内不能输入、粘贴、回车;\n * 退格删到块内的字、向前删到块内的字也不行。外侧边界上的输入仍然有效。\n */\n private markEditBlocked(kind: 'insert' | 'backspace' | 'delete'): boolean {\n if (this.refEdit || !this.markStatus.size) return false;\n const sel = this.sel;\n if (!isCollapsed(sel)) return this.rangeHitsLockedMark(selStart(sel), selEnd(sel));\n const i = sel.focus;\n if (kind === 'insert') return this.lockedMarkBlocks().some((b) => this.caretInsideMark(b, i));\n if (kind === 'backspace') return i > 0 && this.indexCoveredByLockedMark(i - 1);\n return this.indexCoveredByLockedMark(i) || this.lockedMarkBlocks().some((b) => b.start === b.end && !!b.placeholder && b.start === i);\n }\n\n /** 中间态里要交给排版的部分。块已经没了就丢掉。 */\n private markHintMap() {\n for (const id of [...this.markStatus.keys()]) {\n const block = this.doc.blockById(id);\n if (!block || block.kind !== 'mark') this.markStatus.delete(id);\n }\n if (!this.markStatus.size) return undefined;\n const map = new Map<string, { label: string; rainbow?: boolean; pulse?: boolean }>();\n for (const [id, status] of this.markStatus) {\n map.set(id, {\n label: status.label ?? '',\n rainbow: status.text === 'rainbow',\n pulse: status.border === 'pulse'\n });\n }\n return map;\n }\n\n private syncMarkCaret() {\n const next: string[] = [];\n if (!this.refEdit && isCollapsed(this.sel)) {\n for (const block of this.doc.listVirtualBlocks()) {\n if (this.caretInsideMark(block, this.sel.focus)) next.push(block.id);\n }\n }\n for (const id of this.markCaretIds) {\n if (!next.includes(id)) this.emit('markleave', { id });\n }\n for (const id of next) {\n if (!this.markCaretIds.includes(id)) this.emit('markenter', { id });\n }\n this.markCaretIds = next;\n }\n\n /** canvas 上的彩虹字和呼吸边要逐帧重画;HTML 走 CSS 动画。 */\n private syncMarkEffects() {\n const animated =\n this.paintMode === 'canvas' &&\n [...this.markStatus.values()].some((s) => s.border === 'pulse' || (s.text === 'rainbow' && !!s.label));\n if (!animated) {\n if (this.markEffectRaf) {\n window.cancelAnimationFrame(this.markEffectRaf);\n this.markEffectRaf = 0;\n }\n return;\n }\n if (this.markEffectRaf) return;\n const tick = () => {\n this.painter.paintMarkEffects?.();\n this.markEffectRaf = window.requestAnimationFrame(tick);\n };\n this.markEffectRaf = window.requestAnimationFrame(tick);\n }\n\n private caretAffinity(): ops.CaretAffinity {\n const i = this.sel.focus;\n const forward =\n isCollapsed(this.sel) && this.affinity?.index === i && this.affinity.dir === 'forward' && this.isMarkBoundary(i);\n return forward ? 'forward' : 'backward';\n }\n\n /** 光标所在行上该下标的停靠点 */\n private caretStopAt(index: number) {\n return this.lineAt(this.layout, index)?.caretStops.find((s) => s.index === index) ?? null;\n }\n\n /** 点击或上下键落到 mark 边界时按横坐标定亲和:越过两侧底色的分界算贴后一个字 */\n private setAffinityByX(index: number, x: number) {\n const stop = this.isMarkBoundary(index) ? this.caretStopAt(index) : null;\n this.affinity = stop ? { index, dir: x > (stop.midX ?? stop.x) ? 'forward' : 'backward' } : null;\n }\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.markArmedId = null;\n this.sel = this.expandSel(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 const clickedMark = this.markUnderPoint(x, y);\n if (clickedMark && !this.markStatus.get(clickedMark)?.locked) this.emit('markclick', { id: clickedMark });\n this.affinity = null;\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.setSel({ anchor: img.index, focus: img.index + 1 });\n } else if (e.shiftKey) {\n this.setSel(this.expandSel(this.sel.anchor, index));\n } else {\n this.setSel(collapsedSel(index));\n }\n if (isCollapsed(this.sel) && this.sel.focus === index) this.setAffinityByX(index, x);\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, 0, this.markHintMap());\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 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.markEditBlocked('backspace')) {\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 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.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, 0, this.markHintMap());\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 dir: 1 | -1 = key === 'ArrowRight' ? 1 : -1;\n const next = this.moveAcrossEmbed(dir);\n if (next) {\n this.sel = next;\n this.afterCaretMove();\n return;\n }\n if (this.wholeMarkSelect) {\n const whole = this.wholeSelectedMark();\n if (whole && this.markArmedId === whole.id) {\n this.stepArmedMark(whole, dir);\n return;\n }\n // 用户自己拉出的选区不走这里。先看正在离开的块,再看外侧撞上的块。\n if (!whole) {\n const leaving = this.markLeaving(dir);\n if (leaving) {\n this.selectWholeMark(leaving, dir > 0 ? -1 : 1);\n return;\n }\n const entering = this.markEntering(dir);\n if (entering) {\n this.selectWholeMark(entering, dir);\n return;\n }\n }\n }\n // 边界上先换内外侧、不挪下标。贴前时按 → 改贴后,贴后时按 ← 改回贴前。\n if (isCollapsed(this.sel) && this.isMarkBoundary(this.sel.focus)) {\n const affinity = this.caretAffinity();\n if ((key === 'ArrowRight') === (affinity === 'backward')) {\n this.affinity = { index: this.sel.focus, dir: affinity === 'backward' ? 'forward' : 'backward' };\n this.verticalGoal = null;\n this.afterCaretMove();\n return;\n }\n }\n }\n let index = this.sel.focus;\n const vertical = key === 'ArrowUp' || key === 'ArrowDown';\n // 已有选区时左右键收到选区头/尾,不再从 focus 多跳一格(与浏览器、Word 一致)。\n const collapseRange = !extend && !isCollapsed(this.sel) && (key === 'ArrowLeft' || key === 'ArrowRight');\n if (collapseRange) {\n const lo = Math.min(this.sel.anchor, this.sel.focus);\n const hi = Math.max(this.sel.anchor, this.sel.focus);\n index = key === 'ArrowLeft' ? lo : hi;\n }\n // 上下移动要记住\"目标列\":连续按上下键时始终用第一次出发的 x,不然每行吸附一次会越跑越偏。\n // 只要焦点被别的操作挪过(左右键、点击、输入),goal 的 focus 就对不上,自动作废。\n const goalX =\n vertical && this.verticalGoal?.focus === index ? this.verticalGoal.x : this.verticalStartX(index);\n if (!collapseRange && key === 'ArrowLeft') index = this.stepIndex(index, -1);\n if (!collapseRange && key === 'ArrowRight') index = this.stepIndex(index, 1);\n if (key === 'ArrowUp' || key === 'ArrowDown') {\n index = this.verticalMove(index, key === 'ArrowDown' ? 1 : -1, goalX);\n }\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: index };\n } else {\n this.sel = collapsedSel(index);\n }\n // 向右走到 mark 边界先贴前一个字,向左走到先贴后一个字,再按一次才换侧;上下键按目标列定。\n if (extend || !isCollapsed(this.sel) || collapseRange) this.affinity = null;\n else if (vertical) this.setAffinityByX(index, goalX);\n else this.affinity = { index, dir: key === 'ArrowLeft' ? 'forward' : 'backward' };\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 ? { ...this.sel, focus: index } : collapsedSel(index);\n this.affinity = null;\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 selectionPaintRects() {\n return selectionRects(this.layout, this.sel);\n }\n\n /** 左右方向键从内侧离开 mark 时,选范围最小的那一块。零宽占位没有字,不走这条。 */\n private markLeaving(dir: 1 | -1): VirtualBlock | null {\n if (!isCollapsed(this.sel)) return null;\n const index = this.sel.focus;\n let best: VirtualBlock | null = null;\n for (const block of this.doc.listVirtualBlocks()) {\n if (block.kind !== 'mark' || block.start >= block.end) continue;\n const atEdge = dir > 0 ? block.end === index : block.start === index;\n if (!atEdge || !this.caretInsideMark(block, index)) continue;\n if (!best || block.end - block.start < best.end - best.start) best = block;\n }\n return best;\n }\n\n /** 左右方向键从外侧撞上 mark 时,选范围最大的那一块。零宽占位没有字,不走这条。 */\n private markEntering(dir: 1 | -1): VirtualBlock | null {\n if (!isCollapsed(this.sel)) return null;\n const index = this.sel.focus;\n let best: VirtualBlock | null = null;\n for (const block of this.doc.listVirtualBlocks()) {\n if (block.kind !== 'mark' || block.start >= block.end) continue;\n const atEdge = dir > 0 ? block.start === index : block.end === index;\n if (!atEdge || this.caretInsideMark(block, index)) continue;\n if (!best || block.end - block.start > best.end - best.start) best = block;\n }\n return best;\n }\n\n /** 当前选区正好盖住某一块 mark 的全部文字。 */\n private wholeSelectedMark(): VirtualBlock | null {\n if (isCollapsed(this.sel)) return null;\n const from = Math.min(this.sel.anchor, this.sel.focus);\n const to = Math.max(this.sel.anchor, this.sel.focus);\n for (const block of this.doc.listVirtualBlocks()) {\n if (block.kind === 'mark' && block.start === from && block.end === to && block.end > block.start) return block;\n }\n return null;\n }\n\n /** 焦点留在进入的这一侧,锚点在另一端。记成选中态,和用户拉出的选区分开。 */\n private selectWholeMark(block: VirtualBlock, dir: 1 | -1) {\n this.sel = dir > 0 ? { anchor: block.end, focus: block.start } : { anchor: block.start, focus: block.end };\n this.affinity = null;\n this.verticalGoal = null;\n this.afterCaretMove();\n this.markArmedId = block.id;\n }\n\n /**\n * 选中态下的左右键。朝块内进入这一侧的内侧,朝回来的方向回到这一侧的外侧。\n * 焦点在起点表示从左边进入。\n */\n private stepArmedMark(block: VirtualBlock, dir: 1 | -1) {\n const fromLeft = this.sel.focus <= this.sel.anchor;\n const inward = fromLeft ? dir > 0 : dir < 0;\n if (fromLeft) {\n this.sel = collapsedSel(block.start);\n this.affinity = { index: block.start, dir: inward ? 'forward' : 'backward' };\n } else {\n this.sel = collapsedSel(block.end);\n this.affinity = { index: block.end, dir: inward ? 'backward' : 'forward' };\n }\n this.verticalGoal = null;\n this.afterCaretMove();\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.markArmedId = null;\n this.sel = next;\n if (moved) this.typingStyle = null;\n }\n\n private afterCaretMove() {\n this.markArmedId = null;\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 index === this.sel.focus ? this.mainCaretPos().x : caretFromIndex(this.layout, index).x;\n }\n\n /** 主文档光标的绘制位置;贴后一个字时画在 mark 内边距空白的另一侧,正是下一个字落下的地方。 */\n private mainCaretPos() {\n const caret = caretFromIndex(this.layout, this.sel.focus);\n if (this.caretAffinity() !== 'forward') return caret;\n const fwdX = this.caretStopAt(this.sel.focus)?.fwdX;\n return fwdX == null ? caret : { ...caret, x: fwdX };\n }\n\n private verticalMove(index: number, dir: 1 | -1, x: number): number {\n const lines = this.layout.lines;\n // 空行与上一行共享段尾下标(上一行 end == 空行 start)。findIndex 会命中上一行,\n // 再按下键等于“走到当前空行”,光标原地不动。以光标实际绘制的那一行为准。\n const curLine = this.lineAt(this.layout, index);\n let idx = curLine ? lines.indexOf(curLine) : lines.findIndex((l) => index >= l.start && index <= l.end);\n if (idx < 0) idx = 0;\n for (let next = idx + dir; next >= 0 && next < lines.length; next += 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 const at = hitTestIndex(this.layout, x, line.y + 1);\n if (at !== index) return at;\n }\n return index;\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\n/** 选区焦点标记色:默认选区蓝去掉透明度后的实色。 */\nconst FOCUS_MARK_COLOR = '#2b6cff';\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","MARK_DEFAULT_PADDING_X","MARK_PLACEHOLDER_COLOR","paddingXOf","shiftVirtualBlocksOnInsert","len","shiftVirtualBlocksOnDelete","docLength","wholeDoc","boundaryPlaceholder","depthOf","byId","d","id","parent","sortOuterToInner","map","la","lb","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","paintCtx","paintMeasureContext","canvas","measurePaintWidth","measureWidth","key","w","prepared","prepareWithSegments","measureNaturalWidth","glyphCache","GLYPH_CACHE_MAX","naturalWidth","measureGlyphWidths","widths","prevWidth","cp","width","lineHeightOf","REF_PAD","REF_HEAD","refInnerWidth","boxW","chromeFallback","chain","t","resolvedTextStyle","heading","link","chrome","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","markHints","setMarkLayoutHints","next","markLayoutHint","markGaps","gaps","add","g","pad","markHolds","holds","empty","shown","at","styleAt","content","slack","padEnd","collectRuns","runs","pushGap","ns","leadingInset","trailingInset","length","fitMarkText","restIndex","budget","pick","fitPrefix","again","pushLeadingInset","items","hasInk","it","lo","hi","best","mid","fitPaintLine","guard","trimmed","space","withSpace","placePlaceholderHold","run","lineW","continued","remain","busy","head","more","sliceW","wrapParagraph","lineStart","flush","lineEnd","placed","isolated","widthForLine","bandSlot","contentX","contentW","bandTop","bandH","obstacles","gap","left","right","f","cursorIndex","cur","fallback","createWrapCursor","skipFloats","wrapCursorDone","wrapCursorIndex","wrapCursorPeek","wrapCursorSkip","consumeWrapLine","room","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","stop","local","marker","vblockFragments","lineH","fillRight","hold","sorted","boxes","im","top","bottom","padX","hint","emptyMark","labelText","atStyle","continues","boxLeft","boxRight","first","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","roundPenultimateMarkCorners","groups","vb","list","frags","last","model","sortedLinesCache","sortedLines","layout","caretFromIndex","near","caretFromIndexIn","allowNearest","bestLine","bestX","bestIndex","bestDist","exact","dist","earlier","later","hitTestIndex","localX","localY","closestCaretOnLines","bestScore","inY","inX","score","selectionRects","cellRects","cellGridRects","rects","stops","rightCandidates","x0","rightEdge","x1","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","inner","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","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","rangeContains","range","rangeEquals","shiftIndex","shiftPosition","offset","shiftIndexExclusive","shiftRange","leadingLength","position","leadEnd","transformCoordinateAgainstDeletedRange","deleted","transformRangeAgainstDeletedRange","newStart","endpointDeleted","newEnd","insertAgainstInsert","cmd","other","aWins","insertAgainstDelete","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","second","invertEdit","Collector","selection","one","scopeContext","outer","runOperation","op","result","resolveTextProps","resolveParagraphProps","rangeIsOnlyMarkers","contentRuns","base","runStart","textSegments","points","existing","spanCovering","expectedParagraphSpans","byStart","firstStartAtLeast","inherit","EMPTY_SLICE","emitInsert","emitDelete","emitStyle","emitTextStyle","seg","normalizeParagraphs","needed","sameSpans","needKeys","curKeys","differing","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","marksOnly","shiftStylesOnInsert","shiftStylesOnDelete","kept","snap","entities","fragmentIds","fragments","virtualBlocks","probe","normalized","documentFromSlice","sliceFromDocument","ensure","merged","collapsedSel","sliceWithoutParagraphGroup","groupId","keep","insertImage","updateImage","blockMap","validateInsert","insertVirtualBlock","spec","dismissEmptyPlaceholderMarks","removeVirtualBlock","updateVirtualBlockChrome","coverAncestorsOf","pid","coverVirtualBlocks","remapIncomingVirtualBlocks","occupied","idMap","remapped","extendMarksAt","affinity","extendMarksAtStart","extendMarksAtEnd","extendEmptyPlaceholderMarks","nl","isLastParagraphWithGroupId","splitParagraphSpans","cursor","insertText","safe","replaceMarkText","placeholder","deleteRange","nextEnd","insertParagraph","oldProps","inList","paraEndContent","atStart","atEnd","exitGroup","leftProps","rightProps","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","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","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","lock","dpr","zoom","band","visible","trails","vis","mark","rect","vv","viewTop","viewH","force","margin","wantH","changed","maxTop","legal","covers","scaleChanged","moved","fullW","resized","topCss","editorRoot","family","markerTop","cs","radius","rainbow","grad","bottomRight","alpha","shift","metrics","ascent","descent","solid","caretW","editorCs","glow","fontH","cssFont","cssText","HtmlPainter","child","renderTableChrome","renderLine","on","placeCaret","css","fade","anim","renderVBlock","hidden","border","appendMarkLabel","Editor","options","indices","pos","after","ops.updateImage","edge","refBox","interactive","clickedMark","openSafeUrl","ratio","ops.setTableColWidths","startW","startH","level","delta","hostType","opts","extend","unit","track","active","mode","prevColor","nextColor","match","cssColorsEqual","computed","selColor","FOCUS_MARK_COLOR","selRadius","cssFamily","ops.insertSlice","ops.insertVirtualBlock","origin","status","ok","ops.replaceMarkText","ops.updateVirtualBlockChrome","ops.removeVirtualBlock","ops.applyParagraphStyle","pred","ops.deleteRange","patchFor","patches","clientX","clientY","embed","canPromote","event","disabled","payload","any","avail","selectionAfter","revert","settle","minStart","maxEnd","ops.emitDelete","ops.emitInsert","ops.normalizeParagraphs","anchor","ops.insertText","ops.applyMarkdownShortcut","fakePlainClipboard","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","fwdX","idx","oy","surface","parents","geom","views","isRoot","isSlot","isRef","isHost","sliceToHtml","startX","w1","leaving","entering","vertical","collapseRange","goalX","remember","fromLeft","inward","isStructural","curLine","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/markBox.ts","../src/paint/types.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 * 行高。数字是字号的倍数(同 CSS 无单位 line-height),`'24px'` 这类字符串是固定像素。\n * 只在 `textDefaults` 上生效(整篇统一),文字 span 上的这个字段会被忽略。\n * 不传按 1.6 倍字号取整,与旧版一致。\n */\n lineHeight?: number | `${number}px`;\n /**\n * 行与行之间的额外间距,像素。留在行盒外面,下一行整行下移,底色和边框不再贴在一起。\n * 只在 `textDefaults` 上生效(整篇统一),文字 span 上的这个字段会被忽略。不传是 0。\n */\n lineGap?: number;\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 * 与 mark 共用 {@link VirtualBlockChrome}。\n * 芯片比盖住它的 mark 更靠上:指针在芯片上时 mark 不换悬停皮,光标在芯片上时 mark 不换选中皮。\n * SDK 把底色、边框、圆角和字体画在芯片外框上。`paddingX` / `paddingY` / `marginX` 和占位灰字只参与 mark 的排版。\n */\n chrome?: VirtualBlockChrome;\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 * 虚拟块只有 mark:纯样式区间,交互与普通文本完全一致。\n * 不参与区间树(parentId 恒为 null),可与其它 mark 任意叠放。\n * 空态灰字、点击和生成中的中间态都挂在它上面。\n */\nexport type VirtualBlockKind = 'mark';\n\n/** mark 的边。不传 `border` 就没有边框。`width` 不传是 1。 */\nexport interface MarkBorder {\n color: string;\n width?: number;\n}\n\n/**\n * 虚拟块的皮和文字缺省。块皮(底、边、圆角、内边距)只能放这里;\n * 文字字段与 {@link TextProps} 对齐。字号、字体、字重、加粗、斜体:业务传了就盖过正文,没传才继承正文。颜色仍是正文优先。不是 applyStyle 轨道。\n */\nexport interface VirtualBlockChrome {\n background?: string;\n /** 仅 mark:鼠标悬停在这一层上时用这个底色替换 background。只有指针下最上面那一块换,它的每一行一起换 */\n hoverBackground?: string;\n /** 静态边。不传就没有边框。悬停时若配了 `hoverBorder`,换成那一圈 */\n border?: MarkBorder;\n /** 仅 mark:鼠标悬停在这一层上时换成这圈边。只有指针下最上面那一块换,它的每一行一起换。只画在屏幕上,不进撤销。不传则悬停仍用 `border` */\n hoverBorder?: MarkBorder;\n /** 方向键整段选中这块时的底色,替换 `background`。光标只是停在里面不换。只画在屏幕上,不进撤销 */\n selectedBackground?: string;\n /** 方向键整段选中这块时换成这圈边。不传则仍用 `border`。光标只是停在里面不换。只画在屏幕上,不进撤销 */\n selectedBorder?: MarkBorder;\n /** 圆角,不传是 3。首段左侧两角、末段右侧两角;单段四角。中间段不圆 */\n radius?: number;\n /** 水平内边距。不传按 4px,传 0 表示不留。留在底色里面,每行文字都按它缩进;区间真正的首尾这段空白还占排版宽度。贴边处靠编辑器左右多留的 5px,不够会被裁 */\n paddingX?: number;\n /** 底色边缘到外面文字的间距,前后一样。不传是 0。只留在区间真正的首尾,折行的中间段不加 */\n marginX?: number;\n /** 上下内边距。不传是 0。留在这块自己的底色里;盖住的行按同一行里最大的值变高,不画进相邻行 */\n paddingY?: number;\n color?: string;\n fontSize?: number;\n fontFamily?: string;\n fontWeight?: number;\n bold?: boolean;\n italic?: boolean;\n /** mark 的 placeholder 灰字。不传时用 #c5ccd6。透明度写在颜色里,如 rgba(...) */\n placeholderColor?: string;\n /** 仅 mark:鼠标悬停时 placeholder 灰字换成这个颜色。只影响绘制,不进撤销。生成中的文案不换 */\n hoverPlaceholderColor?: string;\n /**\n * 光标能否进入。不传或 `true` 与现在一样。\n * `false` 时光标不能落在里面,左右和上下移动都会跳过:mark 跳过整段,芯片不选中、停在旁边。\n */\n selectable?: boolean;\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\n/** mark 未配 `chrome.paddingX` 时的水平内边距;没有它内外侧光标会画在同一处,看不出光标在块里还是块外 */\nexport const MARK_DEFAULT_PADDING_X = 4;\n\n/** mark 未配 `chrome.placeholderColor` 时的灰字颜色 */\nexport const MARK_PLACEHOLDER_COLOR = '#c5ccd6';\n\n/** 块实际生效的水平内边距:显式配置优先,mark 缺省 4px,其余缺省 0 */\nexport function paddingXOf(block: Pick<VirtualBlock, 'kind' | 'chrome'>): number {\n return block.chrome.paddingX ?? (block.kind === 'mark' ? MARK_DEFAULT_PADDING_X : 0);\n}\n\n/** 底色边缘到外面文字的间距。不传或小于 0 都是 0。只作用在区间真正的首尾。 */\nexport function marginXOf(block: Pick<VirtualBlock, 'kind' | 'chrome'>): number {\n if (block.kind !== 'mark') return 0;\n const margin = block.chrome.marginX;\n return margin != null && margin > 0 ? margin : 0;\n}\n\n/** 上下内边距。不传或小于 0 都是 0。留在这块自己的底色里,并把它盖住的行撑高。 */\nexport function paddingYOf(block: Pick<VirtualBlock, 'kind' | 'chrome'>): number {\n if (block.kind !== 'mark') return 0;\n const pad = block.chrome.paddingY;\n return pad != null && pad > 0 ? pad : 0;\n}\n\n/** 不传或 true 都可以进入。只有显式 false 才让光标跳过。 */\nexport function isSelectable(chrome: { selectable?: boolean } | null | undefined): boolean {\n return chrome?.selectable !== false;\n}\n\n/**\n * `index` 落在不可选中的 mark 里面(不含两端)时,沿 `dir` 跳到这块外面。\n * 往右停在 `end`,往左停在 `start`。嵌套时跳到最外层的那一侧。\n */\nexport function indexOutsideUnselectableMarks(\n index: number,\n dir: 1 | -1,\n blocks: Iterable<Pick<VirtualBlock, 'kind' | 'start' | 'end' | 'chrome'>>\n): number {\n let i = index;\n for (let n = 0; n < 16; n++) {\n let edge: number | null = null;\n for (const b of blocks) {\n if (b.kind !== 'mark' || isSelectable(b.chrome) || b.end <= b.start) continue;\n if (!(b.start < i && i < b.end)) continue;\n const next = dir > 0 ? b.end : b.start;\n edge = edge == null ? next : dir > 0 ? Math.max(edge, next) : Math.min(edge, next);\n }\n if (edge == null || edge === i) return i;\n i = edge;\n }\n return i;\n}\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 docLength?: number\n): VirtualBlock[] {\n const len = end - start;\n if (len <= 0) return [...blocks].map(cloneVirtualBlock);\n // 删的是整篇时,贴在文档首尾的零宽灰字也算落在选区里。\n const wholeDoc = docLength != null && start === 0 && end === docLength;\n const boundaryPlaceholder = (b: VirtualBlock) =>\n wholeDoc && b.kind === 'mark' && !!b.placeholder && b.start === b.end;\n const out: VirtualBlock[] = [];\n for (const b of blocks) {\n if (b.end <= start) {\n if (!boundaryPlaceholder(b)) out.push(cloneVirtualBlock(b));\n } else if (b.start >= end) {\n if (!boundaryPlaceholder(b)) 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 } else if (b.kind === 'mark' && b.placeholder && b.start === start && b.end === end) {\n // 删掉的正好是这块里的字:收成一个点,灰字由排版画出来,不占字符。\n out.push(cloneVirtualBlock({ ...b, start, end: start, empty: true }));\n }\n // 选区比这块更大、又把整段盖住:拆掉,不留灰字。\n }\n return out.filter((b) => b.end > b.start || (b.kind === 'mark' && !!b.placeholder));\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) {\n if (b.kind === 'mark' && b.placeholder && b.start === b.end && b.start >= from && b.start < to) {\n hits.push(cloneVirtualBlock({ ...b, start: b.start - from, end: b.start - from, empty: true }));\n }\n continue;\n }\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 */\nlet paintCtx: { font: string; measureText(text: string): { width: number } } | null | undefined;\n\nfunction paintMeasureContext(): { font: string; measureText(text: string): { width: number } } | null {\n if (paintCtx !== undefined) return paintCtx;\n try {\n const canvas =\n typeof OffscreenCanvas !== 'undefined'\n ? new OffscreenCanvas(1, 1)\n : typeof document !== 'undefined'\n ? document.createElement('canvas')\n : null;\n paintCtx = canvas?.getContext('2d') ?? null;\n } catch {\n paintCtx = null;\n }\n return paintCtx;\n}\n\n/**\n * 和 Canvas `fillText` 同一把尺子:整句一次 `measureText`。\n * 空 mark 的灰字是整句画上去的,底色要用这个宽度,不能用排版的逐字测宽。\n */\nexport function measurePaintWidth(text: string, props: TextProps): number {\n if (!text) return 0;\n const ctx = paintMeasureContext();\n if (!ctx) return measureWidth(text, props);\n const font = canvasFont(props);\n const key = `paint\\0${font}\\0${text}`;\n const hit = widthCache.get(key);\n if (hit !== undefined) return hit;\n ctx.font = font;\n const w = ctx.measureText(text).width;\n if (widthCache.size >= WIDTH_CACHE_MAX) widthCache.clear();\n widthCache.set(key, w);\n return w;\n}\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\n/**\n * 行高(px)。`props.lineHeight` 是倍数或 `'24px'`;缺省、非法值按 {@link LINE_HEIGHT} 倍字号取整。\n */\nexport function lineHeightOf(props: TextProps): number {\n const size = props.fontSize ?? DEFAULT_TEXT.fontSize;\n const lh = props.lineHeight;\n if (typeof lh === 'number') {\n if (Number.isFinite(lh) && lh > 0) return Math.round(size * lh);\n } else if (typeof lh === 'string') {\n const m = /^\\s*(\\d+(?:\\.\\d+)?)px\\s*$/.exec(lh);\n const px = m ? Number(m[1]) : NaN;\n if (Number.isFinite(px) && px > 0) return Math.round(px);\n }\n return Math.round(size * 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, VirtualBlockChrome } 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 return t;\n}\n\n/** 业务在这块上写了的字体字段盖过已有样式;没写的保持原样。 */\nexport function preferChromeText(style: TextProps, chrome: VirtualBlockChrome): TextProps {\n return {\n ...style,\n ...(chrome.bold !== undefined ? { bold: chrome.bold } : {}),\n ...(chrome.italic !== undefined ? { italic: chrome.italic } : {}),\n ...(chrome.fontSize !== undefined ? { fontSize: chrome.fontSize } : {}),\n ...(chrome.fontFamily !== undefined ? { fontFamily: chrome.fontFamily } : {}),\n ...(chrome.fontWeight !== undefined ? { fontWeight: chrome.fontWeight } : {})\n };\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 const body: TextProps = {\n bold: t.bold ?? heading.bold ?? false,\n italic: t.italic ?? false,\n underline: t.underline ?? (href ? true : false),\n underlineStyle: t.underlineStyle,\n strikethrough: t.strikethrough ?? false,\n fontSize:\n t.fontSize ??\n ((para.heading ?? 0) > 0 ? heading.fontSize : undefined) ??\n doc.textDefaults?.fontSize ??\n DEFAULT_TEXT.fontSize,\n fontFamily: t.fontFamily ?? doc.textDefaults?.fontFamily,\n fontWeight: t.fontWeight ?? doc.textDefaults?.fontWeight,\n color: t.color ?? chrome.color ?? (href ? LINK_COLOR : doc.textDefaults?.color ?? DEFAULT_TEXT.color),\n fill: t.fill,\n // 行高只认 textDefaults(整篇统一);不传时不写这个键,保持旧的样式对象形状\n ...(doc.textDefaults?.lineHeight != null ? { lineHeight: doc.textDefaults.lineHeight } : {})\n };\n // 字体五项以盖住这个字的 mark 为准,没传的才留正文。颜色仍是正文优先。\n return preferChromeText(body, {\n bold: chrome.bold,\n italic: chrome.italic,\n fontSize: chrome.fontSize,\n fontFamily: chrome.fontFamily,\n fontWeight: chrome.fontWeight\n });\n}\n","import { layoutNextLine, prepareWithSegments, type PreparedTextWithSegments } from '@chenglou/pretext';\nimport { DocumentModel } from '../model/document';\nimport { isTableMarker, MARKERS } from '../model/markers';\nimport { marginXOf, paddingXOf } from '../model/virtualBlock';\nimport { DEFAULT_TEXT, ImageEntity, ParagraphProps, TextProps, textPropsEqual } from '../model/types';\nimport { canvasFont, ensureLocale, measurePaintWidth, measureWidth } from './measure';\nimport { resolvedTextStyle, preferChromeText } 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 | { kind: 'gap'; index: number; length: 0; endW: number; startW: number; endMargin: number; startMargin: number; trailing?: boolean }\n | {\n kind: 'hold';\n index: number;\n length: 0;\n id: string;\n width: number;\n padEnd: number;\n /** 这一行要画的占位文字。空 mark 折行后每行一段 */\n text?: string;\n style?: TextProps;\n /** 这一段是占位符的第一行 / 后面还有 */\n head?: boolean;\n continues?: boolean;\n /** 从上一行续下来的,光标仍留在第一行 */\n continued?: boolean;\n }\n /** 折行后续行的行首内边距。只占宽度,不是 mark 边界,不改光标内外侧。 */\n | { kind: 'inset'; index: number; length: 0; w: number };\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 | { kind: 'gap'; index: number; endW: number; startW: number; endMargin: number; startMargin: number; trailing?: boolean }\n | {\n kind: 'hold';\n index: number;\n id: string;\n width: number;\n padEnd: number;\n text?: string;\n style?: TextProps;\n pad?: number;\n continued?: boolean;\n };\n\n/** 中间态 label 或空 mark 的 placeholder。排版期间由 layoutDocument 设置,用来把行撑到装得下这段字。 */\nexport interface MarkLayoutHint {\n label: string;\n rainbow?: boolean;\n pulse?: boolean;\n}\n\nlet markHints: Map<string, MarkLayoutHint> | null = null;\n\nexport function setMarkLayoutHints(next: Map<string, MarkLayoutHint> | null) {\n markHints = next;\n}\n\nexport function markLayoutHint(id: string): MarkLayoutHint | undefined {\n return markHints?.get(id);\n}\n\ntype MarkSide = { pad: number; margin: number };\ntype MarkGap = { end: MarkSide; start: MarkSide };\n\n/**\n * mark 真正的首尾占排版宽度:紧挨文字的是 paddingX,再外面是 marginX。\n * 底色画到 padding 的外缘,所以 marginX 就是底色边缘到外面文字的间距。折行中间段不加。\n * 同一下标有多块时,这一侧取 padding + margin 更大的那块。\n */\nfunction markGaps(doc: DocumentModel, start: number, end: number): Map<number, MarkGap> {\n const gaps = new Map<number, MarkGap>();\n const empty = (): MarkSide => ({ pad: 0, margin: 0 });\n const add = (i: number, key: keyof MarkGap, pad: number, margin: number) => {\n const g = gaps.get(i) ?? { end: empty(), start: empty() };\n if (pad + margin > g[key].pad + g[key].margin) g[key] = { pad, margin };\n gaps.set(i, g);\n };\n for (const b of doc.virtualBlocksOverlapping(start, end)) {\n if (b.kind !== 'mark') continue;\n const pad = paddingXOf(b);\n const margin = marginXOf(b);\n if (pad + margin <= 0) continue;\n // 空 mark 没有字,左边距落在 placeholder 之前。右边由 hold 的 padEnd 留在灰字之后。\n if (b.end <= b.start) {\n if (!b.placeholder) continue;\n // 落在段尾标记上时也要留出左边距,否则末尾灰字的内边距会盖住前一个字。\n if (b.start >= start && b.start < end) add(b.start, 'start', pad, margin);\n continue;\n }\n if (b.start >= start && b.start < end && doc.spacers[b.start] !== MARKERS.PARAGRAPH) add(b.start, 'start', pad, margin);\n if (b.end > start && b.end <= end && doc.spacers[b.end - 1] !== MARKERS.PARAGRAPH) add(b.end, 'end', pad, margin);\n }\n return gaps;\n}\n\n/**\n * 空 mark 的 placeholder、或中间态 label 比正文宽出的部分,在落点占一段宽度。\n * 空 mark 落在自己的下标上;有正文时宽出的部分落在终点,避免折行的每一行都加一次。\n */\nfunction markHolds(\n doc: DocumentModel,\n start: number,\n end: number,\n para: ParagraphProps\n): Map<number, { id: string; width: number; padEnd: number; text?: string; style?: TextProps; pad?: number }[]> {\n const holds = new Map<number, { id: string; width: number; padEnd: number; text?: string; style?: TextProps; pad?: number }[]>();\n for (const b of doc.virtualBlocksOverlapping(start, end)) {\n if (b.kind !== 'mark') continue;\n const empty = b.start === b.end;\n const shown = markHints?.get(b.id)?.label || (empty ? b.placeholder : undefined);\n if (!shown) continue;\n if (empty && (b.start < start || b.start >= end)) continue;\n const at = empty ? b.start : b.end;\n if (!empty && (at < start || at > end || (at === end && b.end > end))) continue;\n // 空 mark 没有自己的字,灰字跟左侧正文(也就是在这里打字会继承的那套)走。\n const styleAt = empty && b.start > 0 ? b.start - 1 : Math.min(Math.max(b.start, start), end - 1);\n const style = preferChromeText(resolvedTextStyle(doc, styleAt, para), b.chrome);\n const content = empty ? '' : doc.spacers.slice(Math.max(b.start, start), Math.min(b.end, end)).replace(/\\n/g, '');\n // 空 mark 的灰字整句一次画上,底色跟 Canvas measureText 走。有正文时仍按排版测宽。\n const shownW = empty ? measurePaintWidth(shown, style) : measureWidth(shown, { ...style, bold: style.bold });\n const slack = shownW - (content ? measureWidth(content, style) : 0);\n // 空 mark 的右内边距留在灰字后面,底色才不会压到后一个字。有正文时这段空白已经在终点的 gap 里。\n const padEnd = empty ? paddingXOf(b) + marginXOf(b) : 0;\n if (slack > 0.5 || padEnd > 0) {\n const list = holds.get(at) ?? [];\n list.push({\n id: b.id,\n width: Math.max(0, slack),\n padEnd,\n text: empty ? shown : undefined,\n style: empty ? style : undefined,\n pad: padEnd\n });\n holds.set(at, list);\n }\n }\n return holds;\n}\n\nfunction collectRuns(doc: DocumentModel, start: number, end: number, para: ParagraphProps): SourceRun[] {\n const runs: SourceRun[] = [];\n const gaps = markGaps(doc, start, end);\n const holds = markHolds(doc, start, end, para);\n const pushGap = (at: number) => {\n const g = gaps.get(at);\n const list = holds.get(at) ?? [];\n // 空 mark 落在外层 end 上时,外层的右内边距要留在灰字后面。插在灰字前面的话,删掉末尾文字后黄框会和前面的字拉开。\n const endAfterHold = list.some((h) => h.text) && !!g && g.end.pad + g.end.margin > 0;\n if (g && !endAfterHold) {\n runs.push({\n kind: 'gap',\n index: at,\n endW: g.end.pad + g.end.margin,\n startW: g.start.margin + g.start.pad,\n endMargin: g.end.margin,\n startMargin: g.start.margin\n });\n } else if (g && g.start.pad + g.start.margin > 0) {\n runs.push({\n kind: 'gap',\n index: at,\n endW: 0,\n startW: g.start.margin + g.start.pad,\n endMargin: 0,\n startMargin: g.start.margin\n });\n }\n for (const h of list) runs.push({ kind: 'hold', index: at, ...h });\n if (endAfterHold && g) {\n runs.push({\n kind: 'gap',\n index: at,\n endW: g.end.pad + g.end.margin,\n startW: 0,\n endMargin: g.end.margin,\n startMargin: 0,\n trailing: true\n });\n }\n };\n let i = start;\n while (i < end) {\n pushGap(i);\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) || gaps.has(j) || holds.has(j)) 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 pushGap(end);\n return runs;\n}\n\n/** mark 盖住 index,且不是这个 mark 的第一个字:折行后的行首要再留一份内边距。 */\nfunction leadingInset(doc: DocumentModel, index: number): number {\n let pad = 0;\n for (const b of doc.virtualBlocksOverlapping(index, index + 1)) {\n if (b.kind !== 'mark' || b.end <= b.start) continue;\n if (index > b.start && index < b.end) pad = Math.max(pad, paddingXOf(b));\n }\n return pad;\n}\n\n/** 这一行放不完 mark 的剩余文字时,行尾留出内边距,底色右缘包在文字外面。 */\nfunction trailingInset(doc: DocumentModel, index: number, length: number): number {\n const end = index + length;\n let pad = 0;\n for (const b of doc.virtualBlocksOverlapping(index, Math.max(end, index + 1))) {\n if (b.kind !== 'mark' || b.end <= b.start) continue;\n if (index >= b.start && index < b.end && b.end > end) pad = Math.max(pad, paddingXOf(b));\n }\n return pad;\n}\n\nfunction fitMarkText(doc: DocumentModel, rest: string, restIndex: number, style: TextProps, budget: number): string {\n const pick = (width: number) => fitPrefix(nextLineText(rest, style, width), style, width) || (rest[0] ?? '');\n let text = pick(budget);\n const pad = trailingInset(doc, restIndex, text.length);\n if (pad > 0.5 && budget - pad >= 1) {\n const again = pick(Math.max(1, budget - pad));\n if (again) text = again;\n }\n return text;\n}\n\n/** 新行的第一个字落在 mark 内部时,行首补上和第一行一样的内边距。 */\nfunction pushLeadingInset(doc: DocumentModel, items: WrapItem[], index: number): number {\n if (hasInk(items) || items.some((it) => it.kind === 'inset')) return 0;\n const w = leadingInset(doc, index);\n if (w <= 0) return 0;\n items.push({ kind: 'inset', index, length: 0, w });\n return w;\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 的 pre-wrap,在词边界断开。\n * 画出来的宽度仍用整段 `measureText`。这一行比预算宽时,按词退回,不从词中间切开。\n * 一个词本身就比行宽长时,整词留在这一行。\n */\nfunction fitPaintLine(text: string, style: TextProps, maxWidth: number): string {\n if (!text) return '';\n if (measurePaintWidth(text, style) <= maxWidth) return text;\n let slice = nextLineText(text, style, maxWidth) || text[0] || '';\n let guard = 0;\n while (guard++ < 32 && slice.length > 1 && measurePaintWidth(slice, style) > maxWidth + 0.5) {\n const trimmed = slice.replace(/[ \\t]+$/, '');\n const space = Math.max(trimmed.lastIndexOf(' '), trimmed.lastIndexOf('\\t'));\n if (space <= 0) break;\n const withSpace = slice.slice(0, space + 1);\n slice = measurePaintWidth(withSpace, style) <= maxWidth + 0.5 ? withSpace : trimmed.slice(0, space);\n }\n return slice || text[0] || '';\n}\n\ntype HoldRun = Extract<SourceRun, { kind: 'hold' }>;\n\n/**\n * 空 mark 的占位文字按行切开。这一行放不下时留下剩余文字并换行;\n * 每一行左右都留出 padding,和有正文的 mark 一样缩在底色里面。\n * 调用方见到 breakLine 就结束这一行,run 上留下还没排的字。\n */\nfunction placePlaceholderHold(run: HoldRun, items: WrapItem[], lineW: number, maxWidth: number): { lineW: number; breakLine: boolean } {\n const style = run.style;\n if (!run.text || !style) {\n items.push({ kind: 'hold', index: run.index, length: 0, id: run.id, width: run.width, padEnd: run.padEnd });\n return { lineW: lineW + run.width + run.padEnd, breakLine: false };\n }\n const pad = run.pad ?? 0;\n let w = lineW;\n const continued = !!run.continued;\n if (continued && !hasInk(items) && pad > 0 && !items.some((it) => it.kind === 'inset')) {\n items.push({ kind: 'inset', index: run.index, length: 0, w: pad });\n w += pad;\n }\n const remain = maxWidth - w;\n const busy = items.some((it) => it.kind === 'text' || it.kind === 'image' || (it.kind === 'hold' && it.id !== run.id));\n if (busy && remain <= pad + 0.5) return { lineW, breakLine: true };\n const whole = measurePaintWidth(run.text, style);\n const head = !continued;\n if (whole + pad <= Math.max(remain, 0) + 0.5) {\n items.push({\n kind: 'hold',\n index: run.index,\n length: 0,\n id: run.id,\n width: whole,\n padEnd: pad,\n text: run.text,\n style,\n head,\n continues: false,\n continued\n });\n return { lineW: w + whole + pad, breakLine: false };\n }\n const budget = Math.max(1, remain - pad);\n const slice = fitPaintLine(run.text, style, budget) || run.text[0] || '';\n if (slice.length >= run.text.length && busy) return { lineW, breakLine: true };\n const more = run.text.slice(slice.length);\n const sliceW = measurePaintWidth(slice, style);\n items.push({\n kind: 'hold',\n index: run.index,\n length: 0,\n id: run.id,\n width: sliceW,\n padEnd: more ? 0 : pad,\n text: slice,\n style,\n head,\n continues: more.length > 0,\n continued\n });\n if (!more) return { lineW: w + sliceW + (more ? 0 : pad), breakLine: false };\n run.text = more;\n run.width = measurePaintWidth(more, style);\n run.continued = true;\n return { lineW: w + sliceW, breakLine: true };\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 === 'gap') {\n items.push({\n kind: 'gap',\n index: run.index,\n length: 0,\n endW: run.endW,\n startW: run.startW,\n endMargin: run.endMargin,\n startMargin: run.startMargin,\n trailing: run.trailing\n });\n lineW += run.endW + run.startW;\n continue;\n }\n if (run.kind === 'hold') {\n if (run.text) {\n for (;;) {\n const placed = placePlaceholderHold(run, items, lineW, maxWidth);\n lineW = placed.lineW;\n if (!placed.breakLine) break;\n if (!items.some((it) => it.kind === 'hold' && it.id === run.id) && !hasInk(items)) break;\n flush(run.index);\n }\n continue;\n }\n items.push({ kind: 'hold', index: run.index, length: 0, id: run.id, width: run.width, padEnd: run.padEnd });\n lineW += run.width + run.padEnd;\n continue;\n }\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 (hasInk(items)) flush(run.index);\n lineW += pushLeadingInset(doc, items, 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 (hasInk(items) && lineW + w > maxWidth) flush(run.index);\n lineW += pushLeadingInset(doc, items, 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 lineW += pushLeadingInset(doc, items, restIndex);\n const remain = maxWidth - lineW;\n if (hasInk(items) && 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 = fitMarkText(doc, rest, restIndex, run.style, widthForLine);\n if (hasInk(items) && 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 (hasInk(items) || lines.length === 0) {\n flush(end);\n } else if (items.length > 0) {\n // 只剩段尾的间隔(mark 结束在整行嵌入对象之后):并进上一行,不单独成空行。\n lines[lines.length - 1].items.push(...items);\n }\n return lines;\n}\n\n/** 行里有字、占位或嵌入对象;只有 mark 间隔不算,不能因此提前折行或单独成行。 */\nfunction hasInk(items: WrapItem[]): boolean {\n return items.some((it) => it.kind === 'text' || it.kind === 'image' || it.kind === 'hold');\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 = { doc: DocumentModel; 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 { doc, 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 === 'gap') {\n items.push({\n kind: 'gap',\n index: run.index,\n length: 0,\n endW: run.endW,\n startW: run.startW,\n endMargin: run.endMargin,\n startMargin: run.startMargin,\n trailing: run.trailing\n });\n lineW += run.endW + run.startW;\n cur.i += 1;\n continue;\n }\n if (run.kind === 'hold') {\n if (run.text) {\n const placed = placePlaceholderHold(run, items, lineW, maxWidth);\n lineW = placed.lineW;\n if (!placed.breakLine) cur.i += 1;\n if (placed.breakLine) break;\n continue;\n }\n items.push({ kind: 'hold', index: run.index, length: 0, id: run.id, width: run.width, padEnd: run.padEnd });\n lineW += run.width + run.padEnd;\n cur.i += 1;\n continue;\n }\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 (hasInk(items)) break;\n lineW += pushLeadingInset(cur.doc, items, run.index);\n items.push({ kind: 'image', index: run.index, length: 1, entity: run.entity });\n cur.i += 1;\n break;\n }\n if (hasInk(items) && w > remain) break;\n lineW += pushLeadingInset(cur.doc, items, run.index);\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 const at = run.index + cur.off;\n lineW += pushLeadingInset(cur.doc, items, at);\n const room = maxWidth - lineW;\n if (hasInk(items) && room <= 0) break;\n const widthForLine = items.length > 0 ? Math.max(1, room) : Math.max(1, maxWidth);\n let text = fitMarkText(cur.doc, rest, at, run.style, widthForLine);\n if (hasInk(items) && measureWidth(text, run.style) > room + 0.5 && room < 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, marginXOf, paddingXOf, paddingYOf, 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, preferChromeText } from './style';\nimport { CaretPos, CaretStop, CellLayout, DocLayout, GlyphBox, ImageBox, LineBox, ParagraphLayout, SelRect, TableLayout, VBlockFragment } from './types';\nimport { bandSlot, consumeWrapLine, createWrapCursor, embedLayoutSize, FlowObstacle, markLayoutHint, setMarkLayoutHints, wrapCursorDone, wrapCursorIndex, wrapCursorPeek, wrapCursorSkip, wrapParagraph, WrapItem, type MarkLayoutHint } 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 + (i < wrapped.length - 1 ? lineGapOf(doc) : 0);\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 const last = wrapCursorDone(cur);\n lineY += line.h + (last ? 0 : lineGapOf(doc));\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 === 'gap') {\n contentW += item.endW + item.startW;\n } else if (item.kind === 'inset') {\n contentW += item.w;\n } else if (item.kind === 'hold') {\n contentW += item.width + item.padEnd;\n if (item.style) contentH = Math.max(contentH, lineHeightOf(item.style));\n } else 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 // paddingY 留在底色里面。行按这一行里最大的值上下撑开,文字仍按原来的行高居中。\n const padY = linePaddingY(doc, lineStart, lineEnd, items);\n const lineH = contentH + padY * 2;\n const contentY = y + padY;\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 holds: { id: string; index: number; x: number; y: number; w: number; h: number; text?: string; continues?: boolean; head?: boolean }[] = [];\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 === 'gap') {\n const stop = caretStops[caretStops.length - 1];\n const endMargin = item.endMargin;\n const startMargin = item.startMargin;\n const endPad = item.endW - endMargin;\n const startPad = item.startW - startMargin;\n const endBox = cx + endPad;\n const afterEnd = endBox + endMargin;\n const startBox = afterEnd + startMargin;\n const afterAll = startBox + startPad;\n if (item.trailing && stop.index === item.index && item.endW > 0) {\n // 空 mark 落在外层末尾时,贴前的光标仍留在灰字上。贴后停在外层右缘,往右才去下一行。\n stop.boxEndX = endBox;\n stop.fwdX = afterAll;\n } else if (!item.trailing && stop.index === item.index) {\n const hasEnd = item.endW > 0;\n const hasStart = item.startW > 0;\n stop.fwdX = afterAll;\n if (hasEnd && hasStart) stop.midX = afterEnd;\n else if (hasEnd) stop.midX = endBox;\n else stop.midX = startBox;\n if (hasEnd) stop.boxEndX = endBox;\n if (hasStart) stop.boxStartX = startBox;\n }\n cx = afterAll;\n continue;\n }\n if (item.kind === 'inset') {\n cx += item.w;\n continue;\n }\n if (item.kind === 'hold') {\n holds.push({\n id: item.id,\n index: item.index,\n x: cx,\n y: contentY,\n w: item.width,\n h: contentH,\n text: item.text,\n continues: item.continues,\n head: item.head\n });\n const stop = caretStops.find((s) => s.index === item.index) ?? caretStops[caretStops.length - 1];\n if (stop?.index === item.index && item.continued) {\n stop.placeholderTail = true;\n } else if (stop?.index === item.index && (item.padEnd > 0 || item.text)) {\n // 空 mark 的左内边距在灰字之前,贴前的光标跟灰字对齐,不要停在底色外面。\n stop.x = cx;\n stop.fwdX = cx + item.width;\n stop.midX = cx + item.width;\n }\n cx += item.width + item.padEnd;\n continue;\n }\n if (item.kind === 'image') {\n const size = embedLayoutSize(item.entity, maxW);\n images.push({\n index: item.index,\n x: cx,\n y: contentY + 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: contentY,\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: contentY,\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: lineH,\n ascent: contentH,\n align: align ?? 'left',\n glyphs,\n images,\n marker,\n caretStops,\n vblocks: vblockFragments(doc, lineStart, lineEnd, glyphs, images, holds, !align || align === 'left' ? x + maxW : null, para)\n };\n}\n\n/** 整篇统一的行间距。不传、非数字或小于 0 都是 0。加在行盒外面。 */\nfunction lineGapOf(doc: DocumentModel): number {\n const gap = doc.textDefaults?.lineGap;\n return typeof gap === 'number' && Number.isFinite(gap) && gap > 0 ? gap : 0;\n}\n\nfunction linePaddingY(doc: DocumentModel, lineStart: number, lineEnd: number, items: WrapItem[]): number {\n let pad = 0;\n const to = lineEnd > lineStart ? lineEnd : lineStart + 1;\n for (const b of doc.virtualBlocksOverlapping(lineStart, to)) {\n if (b.end <= lineStart || (lineEnd > lineStart && b.start >= lineEnd)) continue;\n pad = Math.max(pad, paddingYOf(b));\n }\n // 空 mark 不占字符,区间重叠判不到。占位真画在这一行上时,行也要按它的 paddingY 撑高。\n for (const item of items) {\n if (item.kind !== 'hold') continue;\n const block = doc.blockById(item.id);\n if (block) pad = Math.max(pad, paddingYOf(block));\n }\n return pad;\n}\n\nfunction vblockFragments(\n doc: DocumentModel,\n lineStart: number,\n lineEnd: number,\n glyphs: GlyphBox[],\n images: ImageBox[],\n holds: { id: string; index: number; x: number; y: number; w: number; h: number; text?: string; continues?: boolean; head?: boolean }[],\n fillRight: number | null,\n para: ParagraphProps\n): VBlockFragment[] {\n const hits = doc.virtualBlocksOverlapping(lineStart, lineEnd);\n for (const hold of holds) {\n if (!hits.some((b) => b.id === hold.id)) {\n const block = doc.blockById(hold.id);\n if (block) hits.push(block);\n }\n // 空 mark 落在外层 end 上时,折到后面的行已经没有外层的字符,外层也要跟着画。\n if (!hold.text) continue;\n for (const outer of doc.listVirtualBlocks()) {\n if (outer.kind !== 'mark' || outer.id === hold.id || outer.start === outer.end) continue;\n if (outer.end !== hold.index) continue;\n if (hits.some((b) => b.id === outer.id)) continue;\n hits.push(outer);\n }\n }\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 for (const hold of holds) {\n if (hold.id === b.id) {\n boxes.push(hold);\n continue;\n }\n // 空 mark 的灰字不占字符。区间内部的占位要算进外层盒子,否则最后一行会把灰字留在底色外面。\n // 末尾文字删掉后,空 mark 会落在外层 end 上,同样算进去。外层自己的 paddingX 仍加在盒子右侧。\n const atEnd = hold.index === b.end && !!hold.text;\n if (hold.index < b.start || (hold.index >= b.end && !atEnd)) continue;\n const nested = doc.blockById(hold.id);\n if (!nested || nested.kind !== 'mark') continue;\n const pad = paddingXOf(nested);\n const outerPad = paddingXOf(b);\n if (atEnd) {\n const margin = marginXOf(nested);\n boxes.push({ x: hold.x - pad, y: hold.y, w: hold.w + pad * 2 + margin, h: hold.h });\n } else {\n boxes.push({ x: hold.x - pad + outerPad, y: hold.y, w: hold.w + pad * 2 - outerPad * 2, h: hold.h });\n }\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 // 结尾和还没写完的每一行,字后也让出 padX。底色从这些空白的外缘画起,不再往文字列外面多画一份。\n const padX = paddingXOf(b);\n const padY = paddingYOf(b);\n // 区间还延续到后面的行(折行或跨段)时,这一行铺满到内容区右缘,各行连成一个整体;\n // 只有最后一行按文字实际宽度。仅左对齐行这样处理,居中/右对齐保持按内容宽度。\n const hint = b.kind === 'mark' ? markLayoutHint(b.id) : undefined;\n const emptyMark = b.kind === 'mark' && b.start === b.end && !!b.placeholder;\n const slice = holds.find((hold) => hold.id === b.id && hold.text);\n const labelText = slice?.text || hint?.label || (emptyMark ? b.placeholder : undefined);\n const styleAt = emptyMark && b.start > 0 ? b.start - 1 : Math.min(Math.max(b.start, lineStart), Math.max(lineStart, lineEnd - 1));\n const atStyle = labelText ? preferChromeText(resolvedTextStyle(doc, styleAt, para), b.chrome) : undefined;\n const continues =\n slice?.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) : right + padX;\n const first = slice ? slice.head !== false : b.start >= lineStart || emptyMark;\n out.push({\n id: b.id,\n kind: b.kind,\n depth: depthOf(b, doc.virtualBlocks),\n x: boxLeft,\n y: top - padY,\n w: Math.max(0, boxRight - boxLeft),\n h: Math.max(0, bottom - top + padY * 2),\n chrome: { ...b.chrome },\n empty: b.empty || emptyMark,\n first,\n last: !continues,\n rangeStart: b.start,\n rangeEnd: b.end,\n labelText: slice?.text ? labelText : first ? labelText : undefined,\n labelRainbow: first && !!hint?.label && !!hint.rainbow,\n labelColor: hint?.label ? b.chrome.color : b.chrome.placeholderColor,\n labelHoverColor: hint?.label ? undefined : b.chrome.hoverPlaceholderColor,\n labelStyle: atStyle\n ? {\n fontSize: atStyle.fontSize,\n fontFamily: atStyle.fontFamily,\n fontWeight: atStyle.fontWeight,\n bold: atStyle.bold,\n italic: atStyle.italic\n }\n : undefined,\n pulse: !!hint?.pulse,\n hideFrom: hint?.label && b.end > b.start ? b.start : undefined,\n hideTo: hint?.label && b.end > b.start ? b.end : undefined\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 if (paras.length) py += lineGapOf(doc);\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({\n f: doc.textDefaults?.fontFamily,\n w: doc.textDefaults?.fontWeight,\n s: doc.textDefaults?.fontSize,\n lh: doc.textDefaults?.lineHeight,\n lg: doc.textDefaults?.lineGap\n });\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) => {\n const hint = markLayoutHint(b.id);\n return `${b.id}:${b.kind}:${b.parentId}:${b.start - start}:${b.end - start}:${b.empty ? 1 : 0}:${b.placeholder ?? ''}:${JSON.stringify(b.chrome)}:${hint ? `${hint.label}:${hint.rainbow ? 1 : 0}:${hint.pulse ? 1 : 0}` : ''}`;\n })\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 markHints?: Map<string, MarkLayoutHint>\n): DocLayout {\n if (depth === 0) {\n stats = { reused: 0, laidOut: 0 };\n setMarkLayoutHints(markHints ?? null);\n }\n try {\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 let separated = false;\n for (const block of parseBlocks(doc.spacers)) {\n if (block.kind === 'paragraph') {\n if (separated) y += lineGapOf(doc);\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 separated = p.lines.length > 0;\n } else {\n separated = false;\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 } finally {\n if (depth === 0) setMarkLayoutHints(null);\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; placeholderTail?: boolean }[] = [];\n for (const line of lines) {\n for (const stop of line.caretStops) {\n if (stop.index === index) exact.push({ line, x: stop.x, placeholderTail: stop.placeholderTail });\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.find((hit) => !hit.placeholderTail) ?? 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 || later.placeholderTail) {\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.min(Math.abs(s.x - localX), s.fwdX == null ? Infinity : Math.abs(s.fwdX - 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 leftEdge = left.index === from && left.boxStartX != null ? left.boxStartX : left.x;\n const x0 = Math.min(leftEdge, right.x);\n // 选区收到 mark 终点时,右端收到底色外缘,不把 margin 算进去。起点从底色左缘起算。\n const rightEdge =\n right.index === to && right.boxEndX != null\n ? right.boxEndX\n : right.index === to && right.boxStartX == null && right.midX != null && right.midX > right.x\n ? right.midX\n : right.x;\n const x1 = Math.max(left.x, rightEdge);\n const hasText = x1 > x0;\n let x0b = hasText ? x0 : Infinity;\n let x1b = hasText ? x1 : -Infinity;\n let y0 = hasText ? line.y : Infinity;\n let y1 = hasText ? line.y + line.h : -Infinity;\n // 选区把整块 mark 盖住时,高亮扩到这块的绘制盒子,和悬停框同一圈,padding 算在里面。\n for (const vb of line.vblocks ?? []) {\n if (vb.kind !== 'mark' || vb.rangeEnd <= vb.rangeStart) continue;\n if (from > vb.rangeStart || to < vb.rangeEnd) continue;\n x0b = Math.min(x0b, vb.x);\n x1b = Math.max(x1b, vb.x + vb.w);\n y0 = Math.min(y0, vb.y);\n y1 = Math.max(y1, vb.y + vb.h);\n }\n if (x1b > x0b) {\n rects.push({ x: x0b, y: y0, w: x1b - x0b, h: y1 - y0 });\n }\n }\n return rects;\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, lineHeightOf } 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:${lineHeightOf(style)}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 | 'mark.replace';\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 = marksOnly(initial.virtualBlocks);\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 const docLength = this.spacers.length;\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, docLength));\n }\n\n /** addVirtualBlock 的落地:同 id 则整体替换。非 mark 直接丢掉。 */\n applyAddVirtualBlock(block: VirtualBlock) {\n if (block.kind !== 'mark') return;\n this.virtualBlocks.set(block.id, cloneVirtualBlock({ ...block, parentId: null, kind: 'mark' }));\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) || block.kind !== 'mark') return;\n this.virtualBlocks.set(blockId, cloneVirtualBlock({ ...block, id: blockId, parentId: null, kind: 'mark' }));\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 = marksOnly(snap.virtualBlocks);\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) || (b.start === b.end && b.start >= from && b.start < to))\n .map(cloneVirtualBlock);\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\nfunction marksOnly(blocks: VirtualBlock[] | undefined): Map<string, VirtualBlock> {\n return new Map(\n (blocks ?? [])\n .filter((b) => b.kind === 'mark')\n .map((b) => [b.id, cloneVirtualBlock({ ...b, parentId: null, kind: 'mark' })])\n );\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 = marksOnly(normalized.virtualBlocks);\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 { VirtualBlock, VirtualBlockChrome, VirtualBlockKind } from '../model/types';\nimport { sortOuterToInner } from '../model/virtualBlock';\nimport { nextVirtualBlockId } from '../model/document';\nimport { addVirtualBlock, deleteVirtualBlock, updateVirtualBlock } from '../mutations';\nimport { Operation } from './context';\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.kind !== 'mark') return 'not-mark';\n if (block.end < block.start) return 'empty-range';\n // 带 placeholder 的 mark 可以是零宽:字删光后留在原地,排版画出灰字。\n if (block.end === block.start && !block.placeholder) return 'empty-range';\n return 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 if (spec.kind !== 'mark') return null;\n if (end === start && !spec.placeholder) return null;\n\n const id = spec.id && !doc.virtualBlocks.has(spec.id) ? spec.id : nextVirtualBlockId();\n const block: VirtualBlock = {\n id,\n parentId: null,\n kind: 'mark',\n start,\n end,\n chrome: { ...(spec.chrome ?? {}) },\n placeholder: spec.placeholder,\n empty: start === end ? spec.empty ?? true : spec.empty\n };\n const err = validateInsert(doc, block);\n if (err) return null;\n\n ctx.emit(addVirtualBlock(block));\n return id;\n };\n}\n\n/**\n * 光标正停在零宽 placeholder mark 上时,退格或删除拆掉这些块。\n * 一次拆掉落在同一下标上的全部空 mark。没有这样的块时返回 false。\n */\nexport function dismissEmptyPlaceholderMarks(index: number): Operation<boolean> {\n return (ctx) => {\n const i = ctx.doc.clamp(index);\n const hits = ctx.doc\n .listVirtualBlocks()\n .filter((b) => b.kind === 'mark' && !!b.placeholder && b.start === b.end && b.start === i);\n if (!hits.length) return false;\n for (const b of hits) ctx.emit(deleteVirtualBlock(b.id));\n return true;\n };\n}\n\n/** 拆掉皮,字留下。 */\nexport function removeVirtualBlock(id: string): Operation<boolean> {\n return (ctx) => {\n if (!ctx.doc.blockById(id)) return false;\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\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.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 * 光标亲和:mark 边界上同一个下标有两个光标位置。\n * `backward` 贴前一个字(默认):右边界算块内、左边界算块外;`forward` 贴后一个字,正好相反。\n */\nexport type CaretAffinity = 'backward' | 'forward';\n\n/** 在 index 处插入了 text 之后,按光标亲和把边界上的 mark 撑开。插入本身已由调用方 emit。 */\nexport function extendMarksAt(index: number, text: string, affinity: CaretAffinity): Operation<void> {\n return (ctx) => {\n (affinity === 'forward' ? extendMarksAtStart(index, text) : extendMarksAtEnd(index, text))(ctx);\n // 零宽 mark 没有内外侧,单独一个时两种亲和都进块。\n // 它若落在某个有字 mark 的右缘上,而光标贴在那块外侧,新字属于外面,不进这个空 mark。\n if (affinity === 'forward' && !nonEmptyMarkEndsAt(ctx.doc, index)) extendEmptyPlaceholderMarks(index, text)(ctx);\n };\n}\n\nfunction nonEmptyMarkEndsAt(doc: { listVirtualBlocks(): VirtualBlock[] }, index: number): boolean {\n return doc.listVirtualBlocks().some((b) => b.kind === 'mark' && b.start < b.end && b.end === index);\n}\n\nfunction extendEmptyPlaceholderMarks(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.placeholder || b.start !== index || b.end !== index) continue;\n ctx.emit(updateVirtualBlock(b.id, { ...b, end: index + len, empty: false }));\n }\n };\n}\n\n/**\n * 把「原本恰好从 index 开始」的 mark 起点留在新字之前,让左边缘输入算区间内;\n * 遇到换行就断(只从最后一个 \\n 之后算起)。插入后这些 mark 已整体右移到 index + text.length。\n */\nfunction extendMarksAtStart(index: number, text: string): Operation<void> {\n return (ctx) => {\n if (!text || text.endsWith('\\n')) return;\n const shifted = index + text.length;\n const start = index + text.lastIndexOf('\\n') + 1;\n for (const b of ctx.doc.listVirtualBlocks()) {\n if (b.kind !== 'mark' || b.start !== shifted) continue;\n ctx.emit(updateVirtualBlock(b.id, { ...b, start }));\n }\n };\n}\n\n/**\n * 在 index 处插入了 text 之后,把「恰好在 index 结束」的 mark 向右撑开,\n * 让右边缘继续输入算区间内;遇到换行就断(只撑到第一个 \\n 之前)。\n */\nfunction 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, empty: false }));\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 { addVirtualBlock, applyStyle, deleteVirtualBlock, multi, updateVirtualBlock } 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 { CaretAffinity, extendMarksAt } 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/**\n * 在 index 处插入文本,继承左侧文字样式(或调用方指定的样式)。返回新光标位置。\n *\n * `affinity` 决定 index 恰好是 mark 边界时新字进不进块,见 {@link CaretAffinity}。\n */\nexport function insertText(\n index: number,\n text: string,\n inherit?: TextProps,\n affinity: CaretAffinity = 'backward'\n): 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 left = inherit ?? resolveTextProps(ctx.doc, i);\n\n emitInsert(ctx, i, safe);\n extendMarksAt(i, safe, affinity)(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 normalizeParagraphs(ctx);\n return i + safe.length;\n };\n}\n\n/**\n * 替换 mark 里的文字,块本身留下,整步一次撤销。\n * 换成空串时:有 placeholder 就收成零宽,没有就拆掉这块。\n * 返回新文字之后的下标;id 不是 mark 时返回 null。\n */\nexport function replaceMarkText(id: string, text: string): Operation<number | null> {\n return (ctx) => {\n const block = ctx.doc.blockById(id);\n if (!block || block.kind !== 'mark') return null;\n const at = block.start;\n const placeholder = block.placeholder;\n const chrome = { ...block.chrome };\n if (block.end > at) deleteRange(at, block.end)(ctx);\n const safe = text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n if (!safe && !placeholder) {\n if (ctx.doc.blockById(id)) ctx.emit(deleteVirtualBlock(id));\n return at;\n }\n const end = safe ? insertText(at, safe)(ctx) : at;\n const current = ctx.doc.blockById(id);\n const nextEnd = safe ? end : at;\n if (!current) {\n ctx.emit(\n addVirtualBlock({\n id,\n parentId: null,\n kind: 'mark',\n start: at,\n end: nextEnd,\n chrome,\n placeholder,\n empty: !safe\n })\n );\n } else if (current.start !== at || current.end !== nextEnd || !!current.empty === !!safe) {\n ctx.emit(updateVirtualBlock(id, { ...current, start: at, end: nextEnd, empty: !safe }));\n }\n return nextEnd;\n };\n}\n\n/** 回车。空列表项上先降缩进再退出列表;否则切段,两段各自继承合适的属性。 */\nexport function insertParagraph(index: number): Operation<number> {\n return (ctx) => {\n const i = ctx.doc.clamp(index);\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 { CaretAffinity, extendMarksAt, insertVirtualBlock, remapIncomingVirtualBlocks } 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(\n index: number,\n slice: Slice,\n asCopy = true,\n affinity: CaretAffinity = 'backward'\n): 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 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 extendMarksAt(i, incoming.text, affinity)(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 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 normalizeParagraphs(ctx);\n return i + incoming.text.length;\n };\n}\n\n/** 把一段 Markdown 原文导入到 index 处。段落中间导入时先把段切开。 */\nexport function insertMarkdown(index: number, raw: string, affinity: CaretAffinity = 'backward'): 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 }, true, affinity)(ctx);\n return at + text.length;\n };\n}\n\n/** 粘贴纯文本。看起来像 Markdown 就走导入,否则当普通文字插入。 */\nexport function pasteText(\n index: number,\n raw: string,\n inherit?: TextProps,\n affinity: CaretAffinity = 'backward'\n): Operation<number> {\n return (ctx) =>\n looksLikeMarkdown(raw)\n ? insertMarkdown(index, raw, affinity)(ctx)\n : insertText(index, raw, inherit, affinity)(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 { VBlockFragment } from '../layout/types';\nimport { MarkBorder, VirtualBlockChrome } from '../model/types';\nimport { paddingXOf, paddingYOf } from '../model/virtualBlock';\n\n/** 圆角顺序同 canvas `roundRect`:左上、右上、右下、左下 */\nexport type MarkRadii = [number, number, number, number];\n\nexport interface MarkSides {\n top: boolean;\n right: boolean;\n bottom: boolean;\n left: boolean;\n}\n\n/**\n * 首段左侧两角、末段右侧两角;单段四角。中间段没有圆角。\n */\nexport function markRadii(vb: Pick<VBlockFragment, 'kind' | 'chrome' | 'first' | 'last'>): MarkRadii {\n const base = vb.chrome.radius ?? (vb.kind === 'mark' ? 3 : 6);\n const left = vb.first ? base : 0;\n const right = vb.last ? base : 0;\n return [left, right, right, left];\n}\n\n/** 非首段不画左边,非末段不画右边,上下边每段都画 */\nexport function markSides(vb: Pick<VBlockFragment, 'first' | 'last'>): MarkSides {\n return { top: true, right: vb.last, bottom: true, left: vb.first };\n}\n\n/**\n * 这块是不是指针下最上面、并且配了悬停皮的那一个 mark。\n * 是的话,它的每一行都换悬停底色和悬停边框。压在下面的 mark 不换,包括它露在外面的其它行。\n */\nexport function paintsHoverSkin(vb: { id: string }, skinId: string | null): boolean {\n return skinId != null && vb.id === skinId;\n}\n\nexport type MarkSkin = 'hover' | 'selected' | null;\n\n/** 悬停皮优先于选中皮,都没有就用静态边。都没有颜色就不画。 */\nexport function resolveMarkBorder(chrome: VirtualBlockChrome, skin: MarkSkin): { color: string; width: number } | null {\n const spec: MarkBorder | undefined =\n (skin === 'hover' && chrome.hoverBorder) || (skin === 'selected' && chrome.selectedBorder) || chrome.border;\n if (!spec?.color) return null;\n const width = spec.width ?? 1;\n return width > 0 ? { color: spec.color, width } : null;\n}\n\n/** 悬停底色优先于选中底色,都没有就用静态底色。 */\nexport function resolveMarkFill(chrome: VirtualBlockChrome, skin: MarkSkin): string | undefined {\n if (skin === 'hover' && chrome.hoverBackground) return chrome.hoverBackground;\n if (skin === 'selected' && chrome.selectedBackground) return chrome.selectedBackground;\n return chrome.background;\n}\n\nfunction containsPoint(x: number, y: number, left: number, top: number, right: number, bottom: number): boolean {\n return right >= left && bottom >= top && x >= left && x <= right && y >= top && y <= bottom;\n}\n\n/** 绘制盒子去掉 padding 后的内容盒。折行尚未结束的那一行右边没有 padding。 */\nfunction contentEdges(vb: VBlockFragment): { left: number; top: number; right: number; bottom: number } {\n const padX = paddingXOf(vb);\n const padY = paddingYOf(vb);\n return {\n left: vb.x + padX,\n top: vb.y + padY,\n right: vb.x + vb.w - (vb.last ? padX : 0),\n bottom: vb.y + vb.h - padY\n };\n}\n\n/** 内层区间严格落在外层里面。零宽 mark 只算卡在外层区间内的那一个下标。 */\nfunction rangeInside(outer: VBlockFragment, inner: VBlockFragment): boolean {\n if (inner.id === outer.id || inner.kind !== 'mark') return false;\n if (inner.rangeStart < outer.rangeStart || inner.rangeEnd > outer.rangeEnd) return false;\n if (inner.rangeStart === inner.rangeEnd) return inner.rangeStart < outer.rangeEnd;\n return inner.rangeStart > outer.rangeStart || inner.rangeEnd < outer.rangeEnd;\n}\n\n/**\n * `top` 是几何上包住指针的最上层 mark。指针在它的内容盒里,悬停就是它。\n * 指针只在它的 padding 上,并且这圈 padding 贴着同一行里更内层的 mark 时,从最里面往外找。\n * `prefer` 为 false 的内层跳过,停在最近一块接受的 mark 上,避免没配悬停的里层把悬停退回更外层。\n * 离内层较远的 padding 仍算外层。\n */\nexport function hoverSkinMarkId(\n fragments: readonly VBlockFragment[],\n top: VBlockFragment,\n x: number,\n y: number,\n prefer: (id: string) => boolean = () => true\n): string {\n const padX = paddingXOf(top);\n const padY = paddingYOf(top);\n const content = contentEdges(top);\n if (containsPoint(x, y, content.left, content.top, content.right, content.bottom)) return top.id;\n for (let i = fragments.length - 1; i >= 0; i--) {\n const inner = fragments[i];\n if (!rangeInside(top, inner) || !prefer(inner.id)) continue;\n if (\n containsPoint(\n x,\n y,\n inner.x - padX,\n inner.y - padY,\n inner.x + inner.w + padX,\n inner.y + inner.h + padY\n )\n ) {\n return inner.id;\n }\n }\n return top.id;\n}\n\nexport interface HoverSlotBox {\n id: string;\n index: number;\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/**\n * 指针横向贴着外层 mark 里的 slot 时,这颗 slot 和内层 mark 一样吃掉外层的 padding。\n * 芯片往往比行矮,上下不从芯片边再加 padding,而是铺满这块 mark 的高度,否则外层边框仍会先亮。\n * `prefer` 为 false 的 slot 跳过,调用方继续按 mark 往外找。\n */\nexport function hoverSlotInPadding(\n slots: readonly HoverSlotBox[],\n top: VBlockFragment,\n x: number,\n y: number,\n prefer: (id: string) => boolean = () => true\n): string | null {\n const padX = paddingXOf(top);\n for (let i = slots.length - 1; i >= 0; i--) {\n const slot = slots[i];\n if (slot.index < top.rangeStart || slot.index >= top.rangeEnd || !prefer(slot.id)) continue;\n if (containsPoint(x, y, slot.x - padX, top.y, slot.x + slot.w + padX, top.y + top.h)) return slot.id;\n }\n return null;\n}\n\ntype FrameLine = { x1: number; y1: number; x2: number; y2: number };\ntype FrameArc = { cx: number; cy: number; r: number; a0: number; a1: number };\n\n/**\n * 边框落在框内(向内收半个线宽)。四边齐全时是圆角矩形。\n * 缺边时拆成直线和角弧:只有相邻两边都在的角才画弧,缺边的一端画到框外缘,和下一行接上。\n */\nexport function frameGeometry(\n x: number,\n y: number,\n w: number,\n h: number,\n lineWidth: number,\n radii: MarkRadii,\n sides: MarkSides\n): { rect?: { x: number; y: number; w: number; h: number; radii: MarkRadii }; lines: FrameLine[]; arcs: FrameArc[] } {\n const hw = lineWidth / 2;\n const x0 = x + hw;\n const y0 = y + hw;\n const x1 = x + w - hw;\n const y1 = y + h - hw;\n const maxR = Math.max(0, Math.min((x1 - x0) / 2, (y1 - y0) / 2));\n const clampR = (r: number) => Math.max(0, Math.min(r - hw, maxR));\n if (sides.top && sides.right && sides.bottom && sides.left) {\n const r = radii.map(clampR) as MarkRadii;\n return { rect: { x: x0, y: y0, w: Math.max(0, x1 - x0), h: Math.max(0, y1 - y0), radii: r }, lines: [], arcs: [] };\n }\n const { top, right, bottom, left } = sides;\n const tl = top && left ? clampR(radii[0]) : 0;\n const tr = top && right ? clampR(radii[1]) : 0;\n const br = bottom && right ? clampR(radii[2]) : 0;\n const bl = bottom && left ? clampR(radii[3]) : 0;\n const lines: FrameLine[] = [];\n const arcs: FrameArc[] = [];\n if (top) {\n const sx = left ? (tl > 0 ? x0 + tl : x0 - hw) : x;\n const ex = right ? (tr > 0 ? x1 - tr : x1 + hw) : x + w;\n lines.push({ x1: sx, y1: y0, x2: ex, y2: y0 });\n }\n if (bottom) {\n const sx = left ? (bl > 0 ? x0 + bl : x0 - hw) : x;\n const ex = right ? (br > 0 ? x1 - br : x1 + hw) : x + w;\n lines.push({ x1: sx, y1: y1, x2: ex, y2: y1 });\n }\n if (left) {\n const sy = top ? (tl > 0 ? y0 + tl : y0) : y;\n const ey = bottom ? (bl > 0 ? y1 - bl : y1) : y + h;\n lines.push({ x1: x0, y1: sy, x2: x0, y2: ey });\n }\n if (right) {\n const sy = top ? (tr > 0 ? y0 + tr : y0) : y;\n const ey = bottom ? (br > 0 ? y1 - br : y1) : y + h;\n lines.push({ x1: x1, y1: sy, x2: x1, y2: ey });\n }\n const P = Math.PI;\n if (tl > 0) arcs.push({ cx: x0 + tl, cy: y0 + tl, r: tl, a0: P, a1: 1.5 * P });\n if (tr > 0) arcs.push({ cx: x1 - tr, cy: y0 + tr, r: tr, a0: 1.5 * P, a1: 2 * P });\n if (br > 0) arcs.push({ cx: x1 - br, cy: y1 - br, r: br, a0: 0, a1: 0.5 * P });\n if (bl > 0) arcs.push({ cx: x0 + bl, cy: y1 - bl, r: bl, a0: 0.5 * P, a1: P });\n return { lines, arcs };\n}\n\n/** canvas 上描边。缺边的各段一次 stroke,半透明边不会在接头叠深。 */\nexport function strokeFrame(\n ctx: Pick<CanvasRenderingContext2D, 'beginPath' | 'moveTo' | 'lineTo' | 'arc' | 'roundRect' | 'stroke'> & {\n strokeStyle: CanvasRenderingContext2D['strokeStyle'];\n lineWidth: number;\n lineCap: CanvasLineCap;\n },\n x: number,\n y: number,\n w: number,\n h: number,\n color: string,\n lineWidth: number,\n radii: MarkRadii,\n sides: MarkSides\n) {\n const g = frameGeometry(x, y, w, h, lineWidth, radii, sides);\n ctx.beginPath();\n if (g.rect) {\n ctx.roundRect(g.rect.x, g.rect.y, g.rect.w, g.rect.h, g.rect.radii);\n } else {\n for (const l of g.lines) {\n ctx.moveTo(l.x1, l.y1);\n ctx.lineTo(l.x2, l.y2);\n }\n for (const a of g.arcs) {\n ctx.moveTo(a.cx + a.r * Math.cos(a.a0), a.cy + a.r * Math.sin(a.a0));\n ctx.arc(a.cx, a.cy, a.r, a.a0, a.a1);\n }\n }\n ctx.strokeStyle = color;\n ctx.lineWidth = lineWidth;\n ctx.lineCap = 'butt';\n ctx.stroke();\n}\n\n/** DOM 边框:按边给宽度,圆角和 canvas 同一套。 */\nexport function frameCss(color: string, width: number, radii: MarkRadii, sides: MarkSides): string {\n const side = (on: boolean) => (on ? `${width}px` : '0');\n return [\n 'border-style:solid',\n `border-color:${color}`,\n `border-width:${side(sides.top)} ${side(sides.right)} ${side(sides.bottom)} ${side(sides.left)}`,\n `border-radius:${radii.map((r) => `${r}px`).join(' ')}`\n ].join(';');\n}\n","import { CaretPos, DocLayout, SelRect } from '../layout/types';\n\n/**\n * PaintBackend 只消费 layout 几何,不读 Document / DOM 选区。\n *\n * 换 Canvas 时实现同一接口即可,例如:\n *\n * class CanvasPainter implements PaintBackend {\n * paintDoc(layout) {\n * ctx.clearRect(...)\n * for (const line of layout.lines) {\n * for (const g of line.glyphs) ctx.fillText(g.text, g.x, g.y)\n * for (const img of line.images) ctx.drawImage(...)\n * }\n * // 表格线:layout.tables\n * }\n * paintSelection(rects) { for (const r of rects) ctx.fillRect(r.x, r.y, r.w, r.h) }\n * paintCaret(caret) { ctx.fillRect(caret.x, caret.y, 2, caret.h) }\n * }\n *\n * 模型、命令、布局、命中测试和 IME 都不必改。\n */\nexport interface PaintBackend {\n mount(host: HTMLElement): void;\n paintDoc(layout: DocLayout): void;\n paintSelection(rects: SelRect[]): void;\n paintCaret(caret: CaretPos | null, visible: boolean, trails?: CaretPos[]): void;\n /** 有文字选区时焦点那端的标记(竖线 + 顶部圆点,不闪烁);null 隐藏 */\n paintFocusMark(mark: CaretPos | null): void;\n /** 悬停中的 mark。光标底下每一块都算,折行各行一起换;空数组取消。只重画受影响的块。 */\n setHoverBlock?(ids: readonly string[], skinId: string | null): void;\n /** 光标所在最上层 mark 的选中皮。`null` 取消。只重画受影响的块。 */\n setSelectedBlock?(id: string | null): void;\n /** 重画中间态的彩虹字和边框动效。HTML 模式用 CSS,不必实现。 */\n paintMarkEffects?(): void;\n getSurface(): HTMLElement;\n destroy(): void;\n}\n\nexport interface PaintHost {\n surface: HTMLElement;\n content: HTMLElement;\n selection: HTMLElement;\n caret: HTMLElement;\n}\n\n/** 两组悬停 id 是否相同,不看顺序。 */\nexport function sameHoverIds(ids: readonly string[], current: ReadonlySet<string> | readonly string[]): boolean {\n if ('has' in current) {\n if (ids.length !== current.size) return false;\n return ids.every((id) => current.has(id));\n }\n if (ids.length !== current.length) return false;\n return ids.every((id) => current.includes(id));\n}\n","import { embedPlugin, syncEmbedLayer } from '../embed';\nimport { MARK_PLACEHOLDER_COLOR } from '../model/virtualBlock';\nimport { canvasFont, FONT_FAMILY } from '../layout/measure';\nimport { CaretPos, DocLayout, GlyphBox, SelRect, VBlockFragment } from '../layout/types';\nimport { canvasFill, groupDecorationRuns, paintCanvasStrike, paintCanvasUnderline } from './decorations';\nimport { markRadii, markSides, paintsHoverSkin, resolveMarkBorder, resolveMarkFill, strokeFrame } from './markBox';\nimport { PaintBackend, sameHoverIds } 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 focusMark: CaretPos | null = null;\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 hoverIds = new Set<string>();\n private hoverSkinId: string | null = null;\n private selectedId: 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 // 行内样式压过宿主写在祖先上的 letter-spacing,避免 fillText 比测宽更宽。\n const lock = 'letter-spacing:0;word-spacing:0;font-kerning:normal;font-feature-settings:normal;font-variant:normal;font-variant-numeric:normal;';\n this.canvas.style.cssText = lock;\n this.chrome.style.cssText = lock;\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(ids: readonly string[], skinId: string | null) {\n if (sameHoverIds(ids, this.hoverIds) && skinId === this.hoverSkinId) return;\n const prev = this.hoverIds;\n const prevSkin = this.hoverSkinId;\n this.hoverIds = new Set(ids);\n this.hoverSkinId = skinId;\n const layout = this.layout;\n if (!layout) return;\n const targets = new Set([...prev, ...this.hoverIds]);\n if (prevSkin) targets.add(prevSkin);\n if (skinId) targets.add(skinId);\n for (const target of targets) {\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 setSelectedBlock(id: string | null) {\n if (id === this.selectedId) return;\n const prev = this.selectedId;\n this.selectedId = 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 paintMarkEffects() {\n const layout = this.layout;\n if (!layout) return;\n const vis = this.visibleRange(layout);\n this.redrawContent({ top: vis.top, bottom: vis.bottom });\n }\n\n paintFocusMark(mark: CaretPos | null) {\n const prev = this.focusMark;\n if (prev === mark || (prev && mark && prev.x === mark.x && prev.y === mark.y && prev.h === mark.h)) return;\n this.focusMark = mark;\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) {\n const hidden = (line.vblocks ?? []).some(\n (v) => v.hideFrom != null && v.hideTo != null && g.index >= v.hideFrom && g.index < v.hideTo\n );\n if (!hidden) this.paintGlyph(ctx, g);\n }\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 if (this.focusMark) this.drawFocusMark(ctx, this.focusMark);\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 // 可选:`--mini-sel-height`(px)只画行内居中的一段;不设时铺满行高。\n const capH = cs ? parseFloat(cs.getPropertyValue('--mini-sel-height')) : NaN;\n const h = Number.isFinite(capH) && capH > 0 && capH < r.h ? capH : r.h;\n const y = r.y + (r.h - h) / 2;\n ctx.beginPath();\n ctx.roundRect(r.x, y, r.w, 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(ctx: CanvasRenderingContext2D, vb: VBlockFragment) {\n const c = vb.chrome;\n const radii = markRadii(vb);\n const sides = markSides(vb);\n const hoverSkin = paintsHoverSkin(vb, this.hoverSkinId);\n const skin = hoverSkin ? 'hover' : vb.id === this.selectedId ? 'selected' : null;\n const fill = resolveMarkFill(c, skin);\n if (fill) {\n ctx.beginPath();\n ctx.roundRect(vb.x, vb.y, vb.w, vb.h, radii);\n ctx.fillStyle = fill;\n ctx.fill();\n }\n const border = resolveMarkBorder(c, skin);\n if (border) strokeFrame(ctx, vb.x, vb.y, vb.w, vb.h, border.color, border.width, radii, sides);\n if (vb.pulse) {\n const alpha = 0.35 + 0.6 * (0.5 + 0.5 * Math.sin(performance.now() / 190));\n ctx.save();\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), radii);\n ctx.strokeStyle = `rgba(134, 61, 251, ${alpha})`;\n ctx.lineWidth = 1;\n ctx.stroke();\n ctx.restore();\n }\n if (vb.labelText) {\n const pad = vb.chrome.paddingX ?? (vb.kind === 'mark' ? 4 : 0);\n const size = vb.labelStyle?.fontSize ?? 16;\n ctx.save();\n ctx.font = canvasFont(vb.labelStyle ?? {});\n ctx.textBaseline = 'alphabetic';\n if (vb.labelRainbow) {\n const shift = (performance.now() / 8) % 240;\n const grad = ctx.createLinearGradient(vb.x - shift, vb.y, vb.x - shift + 240, vb.y);\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 } else {\n const hoverLabel = this.hoverIds.has(vb.id) ? vb.labelHoverColor : undefined;\n ctx.fillStyle = hoverLabel || vb.labelColor || (vb.empty ? MARK_PLACEHOLDER_COLOR : '#1f2329');\n }\n const metrics = ctx.measureText(vb.labelText || '汉');\n const ascent = metrics.fontBoundingBoxAscent || size * 0.8;\n const descent = metrics.fontBoundingBoxDescent || size * 0.2;\n const baseline = vb.y + (vb.h - (ascent + descent)) / 2 + ascent;\n ctx.fillText(vb.labelText, vb.x + pad, baseline);\n ctx.restore();\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 /** 与 `.mini-focus-mark` 同形:2px 竖线 + 贴着行顶、整颗落在行内的 6px 圆点 */\n private drawFocusMark(ctx: CanvasRenderingContext2D, mark: CaretPos) {\n const editorRoot = this.host?.closest('.mini-editor') as HTMLElement | null;\n const color = editorRoot ? getComputedStyle(editorRoot).getPropertyValue('--mini-sel-focus-color').trim() : '';\n const { x, y: lineY, h: lineH } = mark;\n // 与选区同高:`--mini-sel-height` 设了就居中收短,圆点跟着落在收短后的顶端。\n const capH = editorRoot ? parseFloat(getComputedStyle(editorRoot).getPropertyValue('--mini-sel-height')) : NaN;\n const h = Number.isFinite(capH) && capH > 0 && capH < lineH ? capH : lineH;\n const y = lineY + (lineH - h) / 2;\n ctx.save();\n ctx.fillStyle = color || '#2b6cff';\n ctx.fillRect(x, y, 2, h);\n ctx.beginPath();\n ctx.arc(x + 1, y + 3, 3, 0, Math.PI * 2);\n ctx.fill();\n ctx.restore();\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 // 可选:`--mini-caret-height`(px)让实心光标只画行内居中的一段;不设时铺满行高。\n const capH = solid ? parseFloat(editorCs?.getPropertyValue('--mini-caret-height') ?? '') : NaN;\n const drawH = Number.isFinite(capH) && capH > 0 && capH < h ? capH : h;\n ctx.fillRect(x, y + (h - drawH) / 2, w, drawH);\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 { MARK_PLACEHOLDER_COLOR } from '../model/virtualBlock';\nimport { syncEmbedLayer } from '../embed';\nimport { measurePaintWidth } from '../layout/measure';\nimport { CaretPos, DocLayout, LineBox, SelRect, TableLayout, VBlockFragment } from '../layout/types';\nimport { cssFill, fillOf } from './decorations';\nimport { frameCss, markRadii, markSides, resolveMarkBorder } from './markBox';\nimport { PaintBackend, sameHoverIds } from './types';\n\nfunction cssFont(style: { fontSize?: number; fontWeight?: number; bold?: boolean; italic?: boolean } | undefined): 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 // 与正文 run 一样只走编辑器字体变量。span 上的 fontFamily 交给这个变量,避免灰字单独解析成另一套字体。\n return `font-style:${italic};font-weight:${weight};font-size:${size}px;font-family:var(--mini-font-family);`;\n}\n\nfunction cssText(style: LineBox['glyphs'][0]['style'], runW: number): string {\n const color = style.color ?? '#1f2329';\n const fill = cssFill(style, runW);\n return `${cssFont(style)}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 focusMark: HTMLElement | null = null;\n private trails: HTMLElement[] = [];\n private embeds: HTMLElement | null = null;\n private embedCache = new Map<string, HTMLElement>();\n private hoverIds = new Set<string>();\n private hoverSkinId: string | null = null;\n private selectedId: 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.focusMark = document.createElement('div');\n this.focusMark.className = 'mini-focus-mark';\n this.focusMark.style.display = 'none';\n this.surface.append(this.selection, this.content, this.embeds, ...this.trails, this.focusMark, 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.hoverIds.size || this.selectedId) this.applyMarkSkin();\n }\n\n setHoverBlock(ids: readonly string[], skinId: string | null) {\n if (sameHoverIds(ids, this.hoverIds) && skinId === this.hoverSkinId) return;\n this.hoverIds = new Set(ids);\n this.hoverSkinId = skinId;\n this.applyMarkSkin();\n }\n\n setSelectedBlock(id: string | null) {\n if (id === this.selectedId) return;\n this.selectedId = id;\n this.applyMarkSkin();\n }\n\n private applyMarkSkin() {\n if (!this.content) return;\n for (const node of this.content.querySelectorAll<HTMLElement>('.mini-vblock')) {\n const id = node.dataset.id;\n const hover = !!id && id === this.hoverSkinId;\n const selected = !!id && id === this.selectedId && !hover;\n if (node.dataset.hoverBg || node.dataset.selectedBg) {\n node.style.background = hover\n ? node.dataset.hoverBg ?? node.dataset.bg ?? 'transparent'\n : selected\n ? node.dataset.selectedBg ?? node.dataset.bg ?? 'transparent'\n : node.dataset.bg ?? 'transparent';\n }\n if (node.dataset.hoverBorderColor || node.dataset.selectedBorderColor) {\n const color = hover\n ? node.dataset.hoverBorderColor\n : selected\n ? node.dataset.selectedBorderColor\n : node.dataset.borderColor;\n const width = hover\n ? node.dataset.hoverBorderWidth\n : selected\n ? node.dataset.selectedBorderWidth\n : node.dataset.borderWidth;\n node.style.borderColor = color ?? 'transparent';\n node.style.borderWidth = width ?? '0';\n }\n const label = node.querySelector<HTMLElement>('.mini-run[data-hover-color]');\n if (label) label.style.color = id && this.hoverIds.has(id) ? label.dataset.hoverColor! : label.dataset.color ?? '';\n }\n }\n\n paintSelection(rects: SelRect[]) {\n if (!this.selection) return;\n this.selection.replaceChildren();\n const cap = readPxVar(this.host, '--mini-sel-height');\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 box = r.outline ? { y: r.y, h: r.h } : capBox(r.y, r.h, cap);\n const radius = r.radius ?? 0;\n el.style.cssText = `left:${r.x}px;top:${box.y}px;width:${r.w}px;height:${box.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 paintFocusMark(mark: CaretPos | null) {\n const el = this.focusMark;\n if (!el) return;\n if (!mark) {\n if (el.style.display !== 'none') el.style.display = 'none';\n return;\n }\n const box = capBox(mark.y, mark.h, readPxVar(this.host, '--mini-sel-height'));\n const css = `left:${mark.x}px;top:${box.y}px;height:${box.h}px;`;\n if (el.style.cssText !== css) el.style.cssText = css;\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.focusMark = null;\n this.trails = [];\n this.embeds = null;\n this.embedCache.clear();\n }\n}\n\nfunction readPxVar(root: HTMLElement | null, name: string): number {\n if (!root) return NaN;\n return parseFloat(getComputedStyle(root).getPropertyValue(name));\n}\n\n/** 设了正的像素且比行高矮时,在行内居中收短;否则铺满。 */\nfunction capBox(y: number, h: number, cap: number): { y: number; h: number } {\n if (!Number.isFinite(cap) || cap <= 0 || cap >= h) return { y, h };\n return { y: y + (h - cap) / 2, h: cap };\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 const root = el.closest('.mini-editor') as HTMLElement | null;\n const solid = root?.dataset.caret !== 'rainbow';\n const box = capBox(caret.y, caret.h, solid ? readPxVar(root, '--mini-caret-height') : NaN);\n // 光标移动时重启 CSS 闪烁动画,让它每次移动后都先亮(原生光标的表现)。\n // 不用 `void el.offsetWidth` 强制回流:长文档里一次回流要几十毫秒,而这里每帧都会跑。\n if (el.style.left !== `${caret.x}px` || el.style.top !== `${box.y}px`) {\n for (const anim of el.getAnimations()) anim.currentTime = 0;\n }\n el.style.left = `${caret.x}px`;\n el.style.top = `${box.y}px`;\n el.style.height = `${box.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 const hidden = (index: number) =>\n (line.vblocks ?? []).some((v) => v.hideFrom != null && v.hideTo != null && index >= v.hideFrom && index < v.hideTo);\n for (const g of line.glyphs) {\n if (hidden(g.index)) {\n flush();\n continue;\n }\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 Math.abs(run.x + run.w - g.x) < 0.01\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 borderWidthCss(width: number, sides: { top: boolean; right: boolean; bottom: boolean; left: boolean }): string {\n const side = (on: boolean) => (on ? `${width}px` : '0');\n return `${side(sides.top)} ${side(sides.right)} ${side(sides.bottom)} ${side(sides.left)}`;\n}\n\nfunction renderVBlock(vb: VBlockFragment): HTMLElement {\n const el = document.createElement('span');\n el.className = `mini-vblock${vb.pulse ? ' is-pulse' : ''}`;\n el.dataset.id = vb.id;\n const c = vb.chrome;\n const radii = markRadii(vb);\n const sides = markSides(vb);\n const border = resolveMarkBorder(c, null);\n const hoverBorder = resolveMarkBorder(c, 'hover');\n const selectedBorder = c.selectedBorder?.color ? resolveMarkBorder(c, 'selected') : null;\n if (c.hoverBackground || c.selectedBackground) {\n if (c.hoverBackground) el.dataset.hoverBg = c.hoverBackground;\n if (c.selectedBackground) el.dataset.selectedBg = c.selectedBackground;\n el.dataset.bg = c.background ?? 'transparent';\n }\n if (hoverBorder && (hoverBorder.color !== border?.color || hoverBorder.width !== border?.width)) {\n el.dataset.hoverBorderColor = hoverBorder.color;\n el.dataset.hoverBorderWidth = borderWidthCss(hoverBorder.width, sides);\n el.dataset.borderColor = border?.color ?? 'transparent';\n el.dataset.borderWidth = border ? borderWidthCss(border.width, sides) : borderWidthCss(0, sides);\n }\n if (selectedBorder && (selectedBorder.color !== border?.color || selectedBorder.width !== border?.width)) {\n el.dataset.selectedBorderColor = selectedBorder.color;\n el.dataset.selectedBorderWidth = borderWidthCss(selectedBorder.width, sides);\n el.dataset.borderColor = border?.color ?? 'transparent';\n el.dataset.borderWidth = border ? borderWidthCss(border.width, sides) : borderWidthCss(0, sides);\n }\n const frame = border || hoverBorder\n ? frameCss(border?.color ?? 'transparent', border?.width ?? 0, radii, sides)\n : `border:none;border-radius:${radii.map((r) => `${r}px`).join(' ')}`;\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 frame\n ].join(';');\n if (vb.labelText) appendMarkLabel(el, vb);\n return el;\n}\n\n/** 灰字和正文同一套:整段测一次宽,再整段画成一个 run。样式全篇一致,不用逐字测。 */\nfunction appendMarkLabel(parent: HTMLElement, vb: VBlockFragment) {\n const pad = vb.chrome.paddingX ?? (vb.kind === 'mark' ? 4 : 0);\n const text = vb.labelText ?? '';\n const style = vb.labelStyle ?? {};\n const w = measurePaintWidth(text, style);\n const color = vb.labelRainbow ? '' : vb.labelColor || (vb.empty ? MARK_PLACEHOLDER_COLOR : '#1f2329');\n const span = document.createElement('span');\n span.className = `mini-run${vb.labelRainbow ? ' mini-mark-label is-rainbow' : ''}`;\n span.textContent = text;\n if (vb.labelHoverColor && color) {\n span.dataset.hoverColor = vb.labelHoverColor;\n span.dataset.color = color;\n }\n span.style.cssText = `left:${pad}px;top:0;width:${w}px;height:${vb.h}px;line-height:${vb.h}px;${cssFont(style)}${color ? `color:${color};` : ''}`;\n parent.appendChild(span);\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, CaretStop, DocLayout, ImageBox, LineBox, VBlockFragment } 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 { indexOutsideUnselectableMarks, isSelectable } from './model/virtualBlock';\nimport { CanvasPainter } from './paint/canvasPainter';\nimport { HtmlPainter } from './paint/htmlPainter';\nimport { hoverSkinMarkId, hoverSlotInPadding } from './paint/markBox';\nimport { PaintBackend, sameHoverIds } from './paint/types';\nimport { resolveMarkBorder, resolveMarkFill } from './paint/markBox';\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 * 选区焦点端的标记(竖线 + 顶部圆点)固定为 {@link FOCUS_MARK_COLOR},不跟本色变化。\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\n/** mark 的中间态。只活在编辑器里,不进文档、撤销栈、复制和保存。 */\nexport interface MarkStatus {\n /** 盖住这段正文(或 placeholder)的文字,比如 `Generating…`。 */\n label?: string;\n /** 为真时,块内和内侧边界上的输入、删除、粘贴不生效,点击也不发 `markclick`。 */\n locked?: boolean;\n /** `label` 用彩虹渐变。 */\n text?: 'rainbow';\n /** 底色边缘一圈呼吸描边。 */\n border?: 'pulse';\n}\n\nexport interface MarkEvent {\n id: string;\n}\n\nexport interface MarkSelectEvent {\n id: string | null;\n}\n\n/**\n * - `change`:文档内容变化\n * - `selectionchange`:选区或光标移动\n * - `statechange`:{@link EditorState} 任一字段可能已变,用于同步工具栏\n * - `layoutchange`:重新排版完成,可从 {@link Editor.getLayout} 取新几何\n * - `markclick`:点击某个 mark,参数是块 id。锁定中不发\n * - `markenter` / `markleave`:光标进入或离开 mark(含空 mark 和内侧边界)\n * - `markselect`:方向键整段选中的 mark 变了。光标只是停在里面不算。`id` 为 `null` 表示没有这块选中\n * - `slotselect`:光标落到芯片上或离开。芯片比 mark 更靠上\n */\nexport type EditorEventMap = {\n change: void;\n selectionchange: void;\n statechange: void;\n layoutchange: void;\n markclick: MarkEvent;\n markenter: MarkEvent;\n markleave: MarkEvent;\n /** 光标落到最上层 mark 时发出;离开所有 mark,或改落到芯片上时 `id` 为 `null` */\n markselect: MarkSelectEvent;\n /** 光标落到芯片上时发出;离开时 `id` 为 `null` */\n slotselect: MarkSelectEvent;\n};\n\nexport type EditorEvent = keyof EditorEventMap;\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<(payload?: MarkEvent | MarkSelectEvent) => void> } = {\n change: new Set(),\n selectionchange: new Set(),\n statechange: new Set(),\n layoutchange: new Set(),\n markclick: new Set(),\n markenter: new Set(),\n markleave: new Set(),\n markselect: new Set(),\n slotselect: new Set()\n };\n /** 中间态。键是 mark id。 */\n private markStatus = new Map<string, MarkStatus>();\n /** 光标当前所在的 mark,用来发进入/离开。 */\n private markCaretIds: string[] = [];\n private markEffectRaf = 0;\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 composeAffinity: ops.CaretAffinity = 'backward';\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 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, 0, this.markHintMap());\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 this.root.style.setProperty('--mini-sel-focus-color', FOCUS_MARK_COLOR);\n const selRadius = this.chrome.selectionRadius ?? 0;\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.markStatus.clear();\n this.markCaretIds = [];\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.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 this.runEdit('insert.paste', (ctx) => {\n this.deleteSelectionIfNeeded(ctx);\n ctx.select(collapsedSel(ops.insertSlice(at ?? ctx.selection().focus, slice)(ctx)));\n });\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 && !(spec.kind === 'mark' && spec.placeholder)) return null;\n let id: string | null = null;\n this.runEdit('vblock.insert', (ctx) => {\n id = ops.insertVirtualBlock({ ...spec, start, end })(ctx);\n });\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 /**\n * 设置或清掉 mark 的中间态。`null` 恢复正常。\n * 不进文档、不进撤销栈,也不触发 `change`。label 比正文宽时,这一行会临时撑开。\n */\n setMarkStatus(id: string, status: MarkStatus | null) {\n if (status) {\n const block = this.doc.blockById(id);\n if (!block || block.kind !== 'mark') return;\n this.markStatus.set(id, status);\n } else {\n this.markStatus.delete(id);\n }\n this.relayout();\n }\n\n /**\n * 替换 mark 里的文字,块留着,整步算一次撤销。\n * 换成空串时,有 placeholder 就变回灰字,没有就把块拆掉。\n * 返回块是否存在。\n */\n replaceMarkText(id: string, text: string): boolean {\n let ok = false;\n this.runEdit('mark.replace', (ctx) => {\n const end = ops.replaceMarkText(id, text)(ctx);\n ok = end != null;\n if (end != null) ctx.select(collapsedSel(end));\n });\n return ok;\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 }\n\n /** 删掉一段文字,并拆掉若干 mark。记成一步撤销。 */\n deleteRangeRemovingMarks(from: number, to: number, markIds: readonly string[]) {\n this.sel = { anchor: from, focus: to };\n // 不用 delete.backward:那种会和前面的逐字退格并成一步,撤销时会把刚删掉的字也找回来。\n this.runEdit('delete.selection', (ctx) => {\n for (const id of markIds) ops.removeVirtualBlock(id)(ctx);\n this.deleteSelectionIfNeeded(ctx);\n });\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 chrome?: EmbedEntity['chrome']\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 chrome\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.affinity = null;\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 };\n }\n\n /**\n * 订阅事件,返回取消订阅函数。\n * `change` 等四个原有事件没有参数;`markclick` / `markenter` / `markleave` 收到 `{ id }`。\n * `markselect` / `slotselect` 收到 `{ id }`,没有选中时 `id` 为 `null`。\n */\n on<K extends EditorEvent>(\n event: K,\n handler: EditorEventMap[K] extends void ? () => void : (payload: EditorEventMap[K]) => void\n ): () => void {\n this.listeners[event].add(handler as (payload?: MarkEvent | MarkSelectEvent) => void);\n return () => this.listeners[event].delete(handler as (payload?: MarkEvent | MarkSelectEvent) => void);\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<K extends EditorEvent>(event: K, ...args: EditorEventMap[K] extends void ? [] : [EditorEventMap[K]]) {\n const payload = args[0] as MarkEvent | MarkSelectEvent | undefined;\n for (const handler of this.listeners[event]) handler(payload);\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 hoverMarkIds: string[] = [];\n private hoverSkinId: string | null = null;\n\n private onSurfaceLeave = () => {\n this.setHoverMark([], null);\n this.setHoverSlot(null);\n };\n\n private setHoverMark(ids: readonly string[], skinId: string | null) {\n if (sameHoverIds(ids, this.hoverMarkIds) && skinId === this.hoverSkinId) return;\n this.hoverMarkIds = [...ids];\n this.hoverSkinId = skinId;\n this.painter.setHoverBlock?.(this.hoverMarkIds, this.hoverSkinId);\n }\n\n /**\n * 指针没贴到芯片上,但落在包住它的 mark 里、并且横向贴着这颗芯片。\n * 和内层 mark 一样:这圈算 slot,外层边框不先亮。没配悬停皮的芯片不抢。\n */\n private slotBesideMark(x: number, y: number): EmbedEntity | null {\n const hit = this.markFragmentUnderPoint(x, y);\n if (!hit) return null;\n const slots = [];\n for (const line of this.layout.lines) {\n if (line.y > y) break;\n if (y >= line.y + line.h) continue;\n for (const im of line.images) {\n const kind = im.entity.kind;\n if (kind !== 'internalSlot' && kind !== 'hostSlot') continue;\n slots.push({ id: im.entity.id, index: im.index, x: im.x, y: im.y, w: im.w, h: im.h });\n }\n }\n const id = hoverSlotInPadding(slots, hit.vb, x, y, (slotId) => this.slotStealsMarkHover(this.doc.entities.get(slotId) ?? null));\n return id ? (this.doc.entities.get(id) ?? null) : null;\n }\n\n /** 指针落在芯片上。芯片自己有悬停皮时,mark 的悬停让给它。没有悬停皮的 host 不抢,mark 继续画。 */\n private slotUnderPoint(x: number, y: number): EmbedEntity | null {\n const hit = this.hitImage(x, y);\n const kind = hit?.entity.kind;\n if (kind !== 'internalSlot' && kind !== 'hostSlot') return null;\n return hit.entity;\n }\n\n private slotStealsMarkHover(entity: EmbedEntity | null): boolean {\n const chrome = entity?.chrome;\n if (!chrome) return false;\n return !!(chrome.hoverBackground || chrome.hoverPlaceholderColor || chrome.hoverBorder);\n }\n\n /** 鼠标下最上面的 mark 碎片,不要求配了 hoverBackground。 */\n private markFragmentUnderPoint(x: number, y: number): { vb: VBlockFragment; siblings: readonly VBlockFragment[] } | 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') continue;\n if (x >= vb.x && x <= vb.x + vb.w && y >= vb.y && y <= vb.y + vb.h) return { vb, siblings: line.vblocks };\n }\n }\n return null;\n }\n\n /** 鼠标下最上面的 mark,不要求配了 hoverBackground。点击用这个,padding 仍算外层。 */\n private markUnderPoint(x: number, y: number): string | null {\n return this.markFragmentUnderPoint(x, y)?.vb.id ?? null;\n }\n\n /**\n * 指针下要换悬停皮的那块。几何最上层在内容盒里就用它。\n * 指针只擦过它的 padding、并且这圈贴着更内层的 mark 时,改记内层,避免外层边框闪一下。\n */\n private hoverSkinAt(x: number, y: number): string | null {\n const hit = this.markFragmentUnderPoint(x, y);\n if (!hit) return null;\n const skinned = (markId: string) => {\n const block = this.doc.virtualBlocks.get(markId);\n const c = block?.chrome;\n return !!(block?.kind === 'mark' && c && (c.hoverBackground || c.hoverBorder || c.hoverPlaceholderColor));\n };\n const id = hoverSkinMarkId(hit.siblings, hit.vb, x, y, skinned);\n if (skinned(id)) return id;\n // 最上层没有悬停皮(文本槽里的灰字 mark)时,改用包住这个点、并且有悬停皮的外层。\n const start = hit.siblings.findIndex((vb) => vb.id === id);\n for (let i = (start < 0 ? hit.siblings.length : start) - 1; i >= 0; i--) {\n const vb = hit.siblings[i];\n if (vb.kind !== 'mark') continue;\n if (x < vb.x || x > vb.x + vb.w || y < vb.y || y > vb.y + vb.h) continue;\n if (skinned(vb.id)) return vb.id;\n }\n return null;\n }\n\n /** 这一点上该亮的悬停。slot 有悬停皮时 mark 让位。 */\n private resolveHover(x: number, y: number): { ids: readonly string[]; skin: string | null; slot: EmbedEntity | null } {\n const slot = this.slotUnderPoint(x, y) ?? this.slotBesideMark(x, y);\n if (this.slotStealsMarkHover(slot)) return { ids: [], skin: null, slot };\n return { ids: this.markAt(x, y), skin: this.hoverSkinAt(x, y), slot };\n }\n\n /**\n * 指针在两行之间的缝里。缝不按盒子碰撞,否则更高的外层会贴住缝、内层边框一灭外层就闪。\n * 用同一个横坐标问上一行的下沿和下一行的上沿。两边要亮的是同一块,缝里就继续亮这块。\n */\n private hoverInLineGap(x: number, y: number): { ids: readonly string[]; skin: string | null; slot: EmbedEntity | null } | null {\n const lines = this.layout.lines;\n let below = -1;\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].y > y) {\n below = i;\n break;\n }\n }\n if (below <= 0) return null;\n const above = lines[below - 1];\n const next = lines[below];\n if (y < above.y + above.h || y >= next.y) return null;\n const up = this.resolveHover(x, above.y + above.h - 0.5);\n const down = this.resolveHover(x, next.y + 0.5);\n if (up.skin !== down.skin || (up.slot?.id ?? null) !== (down.slot?.id ?? null)) return null;\n if (up.skin == null && up.slot == null) return null;\n return up;\n }\n\n /** 鼠标底下每一块配了悬停样式的 mark,外层和内层一起算(折行时命中任一行片段都算)。 */\n private markAt(x: number, y: number): string[] {\n const hovers = (chrome: { hoverBackground?: string; hoverPlaceholderColor?: string; hoverBorder?: { color: string } }) =>\n !!(chrome.hoverBackground || chrome.hoverPlaceholderColor || chrome.hoverBorder);\n let any = false;\n for (const b of this.doc.virtualBlocks.values()) {\n if (b.kind === 'mark' && hovers(b.chrome)) {\n any = true;\n break;\n }\n }\n if (!any) return [];\n const ids: string[] = [];\n const seen = new Set<string>();\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' || !hovers(vb.chrome) || seen.has(vb.id)) continue;\n if (x >= vb.x && x <= vb.x + vb.w && y >= vb.y && y <= vb.y + vb.h) {\n seen.add(vb.id);\n ids.push(vb.id);\n }\n }\n }\n return ids;\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 window.cancelAnimationFrame(this.markEffectRaf);\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 {\n this.markArmedId = null;\n this.sel = next;\n }\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 /** 光标停在零宽灰字上:退格和删除拆掉这块,不顺手删掉旁边的字。锁定中的不拆。 */\n private dismissEmptyPlaceholderAtCaret(): boolean {\n if (this.refEdit || !isCollapsed(this.sel)) return false;\n const i = this.sel.focus;\n const hits = this.doc\n .listVirtualBlocks()\n .filter(\n (b) =>\n b.kind === 'mark' &&\n !!b.placeholder &&\n b.start === b.end &&\n b.start === i &&\n !this.markStatus.get(b.id)?.locked\n );\n if (!hits.length) return false;\n this.runEdit('vblock.remove', (ctx) => {\n for (const b of hits) ops.removeVirtualBlock(b.id)(ctx);\n });\n return true;\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 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 && this.markEditBlocked('insert')) return;\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 this.composeAffinity = this.caretAffinity();\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 if (this.composeLen > 0) ops.deleteRange(anchor, anchor + this.composeLen)(ctx);\n const end = text ? ops.insertText(anchor, text, inherit, this.composeAffinity)(ctx) : anchor;\n ctx.select(collapsedSel(end));\n });\n this.composeLen = text.length;\n } else if (!active && this.composeAnchor !== null) {\n const anchor = this.composeAnchor;\n const len = this.composeLen;\n this.applyNow((ctx) => {\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 if (this.markEditBlocked('insert')) return;\n const affinity = this.armedEmptyMark() ? 'backward' : this.caretAffinity();\n this.runEdit('insert.text', (ctx) => {\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, affinity)(ctx);\n if (!this.refEdit && shouldTryMarkdown(text)) next = ops.applyMarkdownShortcut(next)(ctx);\n ctx.select(collapsedSel(next));\n });\n }\n\n pasteText(text: string) {\n this.pasteClipboard(text ? fakePlainClipboard(text) : null);\n }\n\n pasteClipboard(data: DataTransfer | null) {\n if (this.markEditBlocked('insert')) return;\n const slice = sliceFromClipboard(data);\n const text = data?.getData('text/plain') ?? '';\n if (!slice && !text) return;\n const affinity = this.armedEmptyMark() ? 'backward' : this.caretAffinity();\n this.runEdit('insert.paste', (ctx) => {\n this.deleteSelectionIfNeeded(ctx);\n if (slice) {\n ctx.select(collapsedSel(ops.insertSlice(ctx.selection().focus, slice, true, affinity)(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, affinity)(ctx);\n ctx.select(collapsedSel(next));\n });\n }\n\n insertParagraph(opts?: { shift?: boolean }) {\n if (this.disabled) return;\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 if (this.markEditBlocked('insert')) return;\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 this.deleteSelectionIfNeeded(ctx);\n ctx.select(collapsedSel(ops.insertParagraph(ctx.selection().focus)(ctx)));\n });\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.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 if (this.markEditBlocked('backspace')) return;\n this.markArmedId = null;\n this.markArmedSide = null;\n if (this.dismissEmptyPlaceholderAtCaret()) return;\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.deleteSelectedEmbed('forward')) return;\n if (this.markEditBlocked('delete')) return;\n this.markArmedId = null;\n this.markArmedSide = null;\n if (this.dismissEmptyPlaceholderAtCaret()) 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 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 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 lo = range.start;\n const hi = 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, 0, this.markHintMap());\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 const src = URL.createObjectURL(file);\n const commit = (nw: number, nh: number) => {\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 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, 0, this.markHintMap());\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 this.syncMarkEffects();\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 // 方向键整段选中 mark 时不画选区,只留这块自己的选中皮。拖选和 Shift 仍画选区。\n this.painter.paintSelection(embed || this.armedWholeMark() ? [] : 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 ?? this.mainCaretPos()),\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.armedEmptyMark() &&\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 this.painter.paintFocusMark(this.focusMarkPos());\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 * 文字选区焦点端的标记位置。整块选中的嵌入对象不画:那是选中一个对象,没有可挪动的一端。\n */\n private focusMarkPos(): CaretPos | null {\n if (!this.isFocused() || this.isEmbedChromeFocused() || this.ime.composing) return null;\n if (this.refEdit) return isCollapsed(this.fragSel) ? null : this.refCaretPos();\n if (isCollapsed(this.sel) || this.selectedImage() || this.armedWholeMark()) return null;\n const cache = this.focusMarkCache;\n if (cache && cache.layout === this.layout && cache.anchor === this.sel.anchor && cache.focus === this.sel.focus) {\n return cache.pos;\n }\n const sel = this.sel;\n let pos = caretFromIndex(this.layout, sel.focus);\n if (sel.focus > sel.anchor) {\n // 往下扩选时,行尾下标和下一行行首是同一个点。普通折行要把焦点留在上一行末尾。\n // 下一行是空行时留在空行上,否则焦点画在上一行末尾,空行上看起来被跳过了。\n const onEmptyLine = this.layout.lines.some(\n (l) => l.start === sel.focus && l.end > l.start && l.glyphs.length === 0 && l.images.length === 0\n );\n if (!onEmptyLine) {\n const line = this.layout.lines.find((l) => l.end === sel.focus && l.caretStops.some((s) => s.index === sel.focus));\n const stop = line?.caretStops.find((s) => s.index === sel.focus);\n if (line && stop) pos = { x: stop.x, y: line.y, h: line.h, index: sel.focus };\n }\n }\n this.focusMarkCache = { layout: this.layout, anchor: this.sel.anchor, focus: this.sel.focus, pos };\n return pos;\n }\n\n private focusMarkCache: { layout: DocLayout; anchor: number; focus: number; pos: CaretPos } | null = null;\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.syncMarkCaret();\n this.syncSelectedSkin();\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 * mark 边界上的光标亲和。块内最后一个字后面和块外第一个位置是同一个下标(左边界同理),\n * 只能靠它区分:backward 贴前一个字(右边界在块内、左边界在块外),forward 贴后一个字。\n * index 对不上或不再是边界就作废,按 backward 算。\n */\n private affinity: { index: number; dir: ops.CaretAffinity } | null = null;\n /**\n * 从外侧移入 mark 时先整段选中。关闭后方向键按字符流进出:\n * 边界上先换内外侧,再按一次才走进或走出。\n */\n private readonly wholeMarkSelect = true;\n /** 这次整段高亮是方向键撞上 mark 产生的选中态。拖选和 Shift 拉出的选区不记。 */\n private markArmedId: string | null = null;\n /** 零宽 mark 选中时,焦点算在左边还是右边。有字的 mark 用选区两端表示,不记这个。 */\n private markArmedSide: 'left' | 'right' | null = null;\n\n /** index 恰好是某个 mark 的起点或终点 */\n private isMarkBoundary(index: number): boolean {\n if (this.refEdit) return false;\n return this.doc\n .listVirtualBlocks()\n .some((b) => b.kind === 'mark' && b.start < b.end && (b.end === index || b.start === index));\n }\n\n /** 光标算在这块 mark 里面:空 mark 的落点、区间内部、以及左右内侧边界。不可选中的块永远不算在里面。 */\n private caretInsideMark(block: VirtualBlock, index: number): boolean {\n if (block.kind !== 'mark' || !isSelectable(block.chrome)) return false;\n if (block.start === block.end) {\n if (this.markArmedId === block.id) return false;\n if (!block.placeholder || block.start !== index) return false;\n // 贴在外层右缘外侧时,下标仍是空 mark 的落点,但光标已经出了块,不再算在里面。\n return !(this.caretAffinity() === 'forward' && this.nonEmptyMarkEndsAt(index));\n }\n if (index > block.start && index < block.end) return true;\n if (index === block.end) return this.caretAffinity() !== 'forward';\n if (index === block.start) return this.caretAffinity() === 'forward';\n return false;\n }\n\n /** 有文字的 mark 在这个下标结束。空 mark 和它共用下标时,用来判断光标是不是已经贴到外侧。 */\n private nonEmptyMarkEndsAt(index: number): boolean {\n return this.doc.listVirtualBlocks().some((b) => b.kind === 'mark' && b.start < b.end && b.end === index);\n }\n\n /** 零宽灰字正好落在某块有字 mark 的右缘。这个下标有内外两侧。 */\n private emptyPlaceholderAtMarkEnd(index: number): boolean {\n if (!this.nonEmptyMarkEndsAt(index)) return false;\n return this.doc\n .listVirtualBlocks()\n .some((b) => b.kind === 'mark' && !!b.placeholder && b.start === index && b.end === index);\n }\n\n private lockedMarkBlocks(): VirtualBlock[] {\n const out: VirtualBlock[] = [];\n for (const [id, status] of this.markStatus) {\n if (!status.locked) continue;\n const block = this.doc.blockById(id);\n if (block?.kind === 'mark') out.push(block);\n }\n return out;\n }\n\n /** 这个下标上的字符属于锁定中的 mark。 */\n private indexCoveredByLockedMark(index: number): boolean {\n return this.lockedMarkBlocks().some((b) => b.start <= index && index < b.end);\n }\n\n private rangeHitsLockedMark(from: number, to: number): boolean {\n return this.lockedMarkBlocks().some((b) => {\n if (b.start === b.end) return from <= b.start && b.start < to;\n return b.start < to && b.end > from;\n });\n }\n\n /**\n * 锁定中的 mark:内侧和块内不能输入、粘贴、回车;\n * 退格删到块内的字、向前删到块内的字也不行。外侧边界上的输入仍然有效。\n */\n private markEditBlocked(kind: 'insert' | 'backspace' | 'delete'): boolean {\n if (this.refEdit || !this.markStatus.size) return false;\n const sel = this.sel;\n if (!isCollapsed(sel)) return this.rangeHitsLockedMark(selStart(sel), selEnd(sel));\n const i = sel.focus;\n if (kind === 'insert') return this.lockedMarkBlocks().some((b) => this.caretInsideMark(b, i));\n if (kind === 'backspace') return i > 0 && this.indexCoveredByLockedMark(i - 1);\n return this.indexCoveredByLockedMark(i) || this.lockedMarkBlocks().some((b) => b.start === b.end && !!b.placeholder && b.start === i);\n }\n\n /** 中间态里要交给排版的部分。块已经没了就丢掉。 */\n private markHintMap() {\n for (const id of [...this.markStatus.keys()]) {\n const block = this.doc.blockById(id);\n if (!block || block.kind !== 'mark') this.markStatus.delete(id);\n }\n if (!this.markStatus.size) return undefined;\n const map = new Map<string, { label: string; rainbow?: boolean; pulse?: boolean }>();\n for (const [id, status] of this.markStatus) {\n map.set(id, {\n label: status.label ?? '',\n rainbow: status.text === 'rainbow',\n pulse: status.border === 'pulse'\n });\n }\n return map;\n }\n\n private syncMarkCaret() {\n const next: string[] = [];\n if (!this.refEdit && isCollapsed(this.sel)) {\n for (const block of this.doc.listVirtualBlocks()) {\n if (this.caretInsideMark(block, this.sel.focus)) next.push(block.id);\n }\n }\n for (const id of this.markCaretIds) {\n if (!next.includes(id)) this.emit('markleave', { id });\n }\n for (const id of next) {\n if (!this.markCaretIds.includes(id)) this.emit('markenter', { id });\n }\n this.markCaretIds = next;\n }\n\n private selectedMarkId: string | null = null;\n private selectedSlotId: string | null = null;\n private hoveredSlotId: string | null = null;\n\n private setHoverSlot(entity: EmbedEntity | null) {\n const id = entity?.id ?? null;\n if (id === this.hoveredSlotId) return;\n this.hoveredSlotId = id;\n this.paintSlotChrome();\n }\n\n /** 只有方向键整段选中的那一块换选中皮。光标停在里面不算。芯片盖住 mark。 */\n private syncSelectedSkin() {\n if (this.refEdit) {\n this.applySelectedMark(null);\n this.applySelectedSlot(null);\n return;\n }\n const slot = this.slotAtCaret();\n this.applySelectedSlot(slot);\n this.applySelectedMark(slot ? null : this.markAtCaret());\n }\n\n private applySelectedMark(id: string | null) {\n if (id === this.selectedMarkId) return;\n this.selectedMarkId = id;\n this.painter.setSelectedBlock?.(id);\n this.emit('markselect', { id });\n }\n\n private applySelectedSlot(entity: EmbedEntity | null) {\n const id = entity?.id ?? null;\n const changed = id !== this.selectedSlotId;\n this.selectedSlotId = id;\n this.paintSlotChrome();\n if (changed) this.emit('slotselect', { id });\n }\n\n /** 方向键整段选中的那一块。有字的用选区,零宽的用选中标记。光标只是停在里面不算。 */\n private markAtCaret(): string | null {\n return this.armedWholeMark()?.id ?? this.armedEmptyMark()?.id ?? null;\n }\n\n /** 选区正好是一颗芯片。 */\n private slotAtCaret(): EmbedEntity | null {\n const img = this.selectedImage();\n const kind = img?.entity.kind;\n if (kind !== 'internalSlot' && kind !== 'hostSlot') return null;\n return img!.entity;\n }\n\n private paintSlotChrome() {\n for (const el of this.pageInner.querySelectorAll<HTMLElement>('.mini-slot, .mini-host')) {\n const id = el.dataset.entity;\n const chrome = id ? this.doc.entities.get(id)?.chrome : undefined;\n const hoverOn = !!id && id === this.hoveredSlotId;\n const selectOn = !hoverOn && !!id && id === this.selectedSlotId;\n const skin = hoverOn ? 'hover' : selectOn ? 'selected' : null;\n const fill = chrome ? resolveMarkFill(chrome, skin) : undefined;\n const border = chrome ? resolveMarkBorder(chrome, skin) : null;\n if (fill) el.style.background = fill;\n else el.style.removeProperty('background');\n if (border?.color && border.width > 0) {\n el.style.outline = `${border.width}px solid ${border.color}`;\n el.style.outlineOffset = `-${border.width}px`;\n } else {\n el.style.removeProperty('outline');\n el.style.removeProperty('outline-offset');\n }\n if (chrome?.radius != null) el.style.borderRadius = `${chrome.radius}px`;\n else el.style.removeProperty('border-radius');\n el.style.color = chrome?.color ?? '';\n el.style.fontSize = chrome?.fontSize != null ? `${chrome.fontSize}px` : '';\n el.style.fontFamily = chrome?.fontFamily ?? '';\n el.style.fontWeight = chrome?.fontWeight != null ? String(chrome.fontWeight) : chrome?.bold ? '700' : '';\n el.style.fontStyle = chrome?.italic ? 'italic' : '';\n }\n }\n\n /** canvas 上的彩虹字和呼吸边要逐帧重画;HTML 走 CSS 动画。 */\n private syncMarkEffects() {\n const animated =\n this.paintMode === 'canvas' &&\n [...this.markStatus.values()].some((s) => s.border === 'pulse' || (s.text === 'rainbow' && !!s.label));\n if (!animated) {\n if (this.markEffectRaf) {\n window.cancelAnimationFrame(this.markEffectRaf);\n this.markEffectRaf = 0;\n }\n return;\n }\n if (this.markEffectRaf) return;\n const tick = () => {\n this.painter.paintMarkEffects?.();\n this.markEffectRaf = window.requestAnimationFrame(tick);\n };\n this.markEffectRaf = window.requestAnimationFrame(tick);\n }\n\n private caretAffinity(): ops.CaretAffinity {\n const i = this.sel.focus;\n const forward =\n isCollapsed(this.sel) && this.affinity?.index === i && this.affinity.dir === 'forward' && this.isMarkBoundary(i);\n return forward ? 'forward' : 'backward';\n }\n\n /** 光标所在行上该下标的停靠点 */\n private caretStopAt(index: number) {\n return this.lineAt(this.layout, index)?.caretStops.find((s) => s.index === index) ?? null;\n }\n\n /** 这个下标上外层右缘的停靠点。空 mark 折行时右缘在最后一行,不在灰字开头那一行。 */\n private markEndEdge(index: number): { line: LineBox; stop: CaretStop } | null {\n let found: { line: LineBox; stop: CaretStop } | null = null;\n for (const line of this.layout.lines) {\n for (const stop of line.caretStops) {\n if (stop.index === index && stop.boxEndX != null) found = { line, stop };\n }\n }\n return found;\n }\n\n /** 点击或上下键落到 mark 边界时按横坐标定亲和:越过两侧底色的分界算贴后一个字 */\n private setAffinityByX(index: number, x: number) {\n const stop = this.isMarkBoundary(index) ? this.caretStopAt(index) : null;\n this.affinity = stop ? { index, dir: x > (stop.midX ?? stop.x) ? 'forward' : 'backward' } : null;\n }\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 const snapped = this.placeOutsideUnselectable(focus, focus >= this.dragAnchor ? 1 : -1);\n this.markArmedId = null;\n this.sel = this.expandSel(this.dragAnchor, snapped.index);\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 const clickedMark = this.markUnderPoint(x, y);\n if (clickedMark && !this.markStatus.get(clickedMark)?.locked) this.emit('markclick', { id: clickedMark });\n this.affinity = null;\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 && this.embedSkipped(img.index)) {\n const at = x < img.x + img.w / 2 ? img.index : img.index + 1;\n this.setSel(collapsedSel(at));\n } else if (img) {\n this.setSel({ anchor: img.index, focus: img.index + 1 });\n } else if (e.shiftKey) {\n const snapped = this.placeOutsideUnselectable(index, index >= this.sel.anchor ? 1 : -1);\n this.setSel(this.expandSel(this.sel.anchor, snapped.index));\n } else {\n const snapped = this.placeOutsideUnselectable(index, 0);\n this.setSel(collapsedSel(snapped.index));\n if (snapped.affinity) this.affinity = { index: snapped.index, dir: snapped.affinity };\n }\n if (isCollapsed(this.sel) && this.sel.focus === index && !this.affinity) this.setAffinityByX(index, x);\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, 0, this.markHintMap());\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 let hover = e.buttons ? null : this.resolveHover(x, y);\n if (hover && hover.skin == null && hover.slot == null) hover = this.hoverInLineGap(x, y) ?? hover;\n this.setHoverMark(hover?.ids ?? [], hover?.skin ?? null);\n this.setHoverSlot(hover?.slot ?? null);\n return;\n }\n this.setHoverMark([], null);\n this.setHoverSlot(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 // 整段选中一块里只有芯片时,选区长度也是 1。不可选中的芯片不能因此被当成选中。\n if (this.embedSkipped(i)) 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.markEditBlocked('backspace')) {\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 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.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, 0, this.markHintMap());\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 dir: 1 | -1 = key === 'ArrowRight' ? 1 : -1;\n const armedEmpty = this.armedEmptyMark();\n if (armedEmpty) {\n this.stepArmedEmpty(armedEmpty, dir);\n return;\n }\n const insideEmpty = this.insideEmptyMarkWithSelected();\n if (insideEmpty) {\n this.armEmptyMark(insideEmpty, dir > 0 ? 'right' : 'left');\n return;\n }\n // 空灰字贴在有字 mark 的右缘、又没配选中皮时,才在这里换内外侧。\n // 同一下标上若有配了选中皮的 mark,先整段选中那块,不能直接翻进灰字。\n if (\n isCollapsed(this.sel) &&\n this.emptyPlaceholderAtMarkEnd(this.sel.focus) &&\n !this.markEntering(dir) &&\n !this.markLeaving(dir)\n ) {\n const affinity = this.caretAffinity();\n if ((key === 'ArrowRight') === (affinity === 'backward')) {\n this.affinity = { index: this.sel.focus, dir: affinity === 'backward' ? 'forward' : 'backward' };\n this.verticalGoal = null;\n this.afterCaretMove();\n return;\n }\n }\n const next = this.moveAcrossEmbed(dir);\n if (next) {\n // 从里面往外穿过贴边的不可选中芯片:先跳过芯片,再整段选中外层。和进入时相反。\n const exitMark = this.unselectableSlotExit(dir);\n if (exitMark) {\n this.selectWholeMark(exitMark, dir > 0 ? -1 : 1);\n return;\n }\n this.sel = next;\n this.afterCaretMove();\n return;\n }\n if (this.wholeMarkSelect) {\n const whole = this.wholeSelectedMark();\n if (whole && this.markArmedId === whole.id) {\n this.stepArmedMark(whole, dir);\n return;\n }\n // 用户自己拉出的选区不走这里。先看正在离开的块,再看外侧撞上的块。\n if (!whole) {\n const leaving = this.markLeaving(dir);\n if (leaving) {\n this.selectWholeMark(leaving, dir > 0 ? -1 : 1);\n return;\n }\n const entering = this.markEntering(dir);\n if (entering) {\n this.selectWholeMark(entering, dir);\n return;\n }\n }\n }\n // 边界上先换内外侧、不挪下标。贴前时按 → 改贴后,贴后时按 ← 改回贴前。\n if (isCollapsed(this.sel) && this.selectableMarkBoundary(this.sel.focus)) {\n const affinity = this.caretAffinity();\n if ((key === 'ArrowRight') === (affinity === 'backward')) {\n this.affinity = { index: this.sel.focus, dir: affinity === 'backward' ? 'forward' : 'backward' };\n this.verticalGoal = null;\n this.afterCaretMove();\n return;\n }\n }\n }\n let index = this.sel.focus;\n const vertical = key === 'ArrowUp' || key === 'ArrowDown';\n // 已有选区时左右键收到选区头/尾,不再从 focus 多跳一格(与浏览器、Word 一致)。\n const collapseRange = !extend && !isCollapsed(this.sel) && (key === 'ArrowLeft' || key === 'ArrowRight');\n if (collapseRange) {\n const lo = Math.min(this.sel.anchor, this.sel.focus);\n const hi = Math.max(this.sel.anchor, this.sel.focus);\n index = key === 'ArrowLeft' ? lo : hi;\n }\n // 上下移动要记住\"目标列\":连续按上下键时始终用第一次出发的 x,不然每行吸附一次会越跑越偏。\n // 只要焦点被别的操作挪过(左右键、点击、输入),goal 的 focus 就对不上,自动作废。\n const goalX =\n vertical && this.verticalGoal?.focus === index ? this.verticalGoal.x : this.verticalStartX(index);\n if (!collapseRange && key === 'ArrowLeft') index = this.stepIndex(index, -1);\n if (!collapseRange && key === 'ArrowRight') index = this.stepIndex(index, 1);\n if (key === 'ArrowUp' || key === 'ArrowDown') {\n index = this.verticalMove(index, key === 'ArrowDown' ? 1 : -1, goalX);\n }\n const prev = this.sel.focus;\n const horizontal = key === 'ArrowLeft' ? -1 : key === 'ArrowRight' ? 1 : 0;\n const skipped = horizontal ? this.placeOutsideUnselectable(index, horizontal) : this.placeOutsideUnselectable(index, 0);\n index = skipped.index;\n if (!extend && horizontal && index !== prev) {\n const landed = this.emptyMarkWithSelectedAt(index);\n if (landed) {\n this.armEmptyMark(landed, horizontal > 0 ? 'left' : 'right');\n return;\n }\n }\n const remember = () => {\n this.verticalGoal = vertical ? { x: goalX, focus: this.sel.focus } : null;\n };\n if (!extend && this.doc.spacers[index] === MARKERS.IMAGE && !this.embedSkipped(index)) {\n this.sel = { anchor: index, focus: index + 1 };\n } else if (extend) {\n this.sel = { ...this.sel, focus: index };\n } else {\n this.sel = collapsedSel(index);\n }\n // 向右走到 mark 边界先贴前一个字,向左走到先贴后一个字,再按一次才换侧;上下键按目标列定。\n // 跳过不可选中的块时,落点已经在外侧:往右贴后,往左贴前。\n if (extend || !isCollapsed(this.sel)) this.affinity = null;\n else if (skipped.affinity) this.affinity = { index, dir: skipped.affinity };\n else if (collapseRange) this.affinity = null;\n else if (vertical) this.setAffinityByX(index, goalX);\n else this.affinity = { index, dir: key === 'ArrowLeft' ? 'forward' : 'backward' };\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 placed = this.placeOutsideUnselectable(nearestSafeIndex(this.doc.spacers, raw), dir);\n const index = placed.index;\n this.sel = extend ? { ...this.sel, focus: index } : collapsedSel(index);\n this.affinity = !extend && placed.affinity ? { index, dir: placed.affinity } : null;\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 selectionPaintRects() {\n return selectionRects(this.layout, this.sel);\n }\n\n /**\n * 光标在 mark 内,下一步会穿过贴在出口上的不可选中芯片。\n * 先跳过芯片,整段选中这块(范围最小的一层)。芯片在中间时不算出口。\n */\n private unselectableSlotExit(dir: 1 | -1): VirtualBlock | null {\n if (!isCollapsed(this.sel)) return null;\n const index = this.sel.focus;\n const slot = dir > 0 ? index : index - 1;\n if (slot < 0 || this.doc.spacers[slot] !== MARKERS.IMAGE || !this.embedSkipped(slot)) return null;\n let best: VirtualBlock | null = null;\n for (const block of this.doc.listVirtualBlocks()) {\n if (block.kind !== 'mark' || !isSelectable(block.chrome) || block.start >= block.end) continue;\n if (!this.hasSelectedChrome(block)) continue;\n const atExit = dir > 0 ? block.end === slot + 1 : block.start === slot;\n if (!atExit || !this.caretInsideMark(block, index)) continue;\n if (!best || block.end - block.start < best.end - best.start) best = block;\n }\n return best;\n }\n\n /** 左右方向键从内侧离开 mark 时,选范围最小的那一块。零宽占位没有字,不走这条。 */\n private markLeaving(dir: 1 | -1): VirtualBlock | null {\n if (!isCollapsed(this.sel)) return null;\n const index = this.sel.focus;\n let best: VirtualBlock | null = null;\n for (const block of this.doc.listVirtualBlocks()) {\n if (block.kind !== 'mark' || block.start >= block.end || !isSelectable(block.chrome)) continue;\n if (!this.hasSelectedChrome(block)) continue;\n const atEdge = dir > 0 ? block.end === index : block.start === index;\n if (!atEdge || !this.caretInsideMark(block, index)) continue;\n if (!best || block.end - block.start < best.end - best.start) best = block;\n }\n return best;\n }\n\n /** 左右方向键从外侧撞上 mark 时,选范围最大的那一块。零宽占位没有字,不走这条。 */\n private markEntering(dir: 1 | -1): VirtualBlock | null {\n if (!isCollapsed(this.sel)) return null;\n const index = this.sel.focus;\n let best: VirtualBlock | null = null;\n for (const block of this.doc.listVirtualBlocks()) {\n if (block.kind !== 'mark' || block.start >= block.end || !isSelectable(block.chrome)) continue;\n if (!this.hasSelectedChrome(block)) continue;\n const atEdge = dir > 0 ? block.start === index : block.end === index;\n if (!atEdge || this.caretInsideMark(block, index)) continue;\n if (!best || block.end - block.start > best.end - best.start) best = block;\n }\n return best;\n }\n\n /** 配了选中皮才在方向键上停一下整段选中。没配的直接走过。 */\n private hasSelectedChrome(block: VirtualBlock): boolean {\n return !!(block.chrome.selectedBackground || block.chrome.selectedBorder);\n }\n\n /** 这个下标上配了选中皮的零宽灰字。叠在一起时取最内层。 */\n private emptyMarkWithSelectedAt(index: number): VirtualBlock | null {\n let found: VirtualBlock | null = null;\n for (const block of this.doc.listVirtualBlocks()) {\n if (block.kind !== 'mark' || block.start !== index || block.end !== index) continue;\n if (!block.placeholder || !isSelectable(block.chrome) || !this.hasSelectedChrome(block)) continue;\n found = block;\n }\n return found;\n }\n\n /** 光标正停在灰字上,并且这块配了选中皮。选中态本身不算停在里面。 */\n private insideEmptyMarkWithSelected(): VirtualBlock | null {\n if (!isCollapsed(this.sel) || this.markArmedId) return null;\n const block = this.emptyMarkWithSelectedAt(this.sel.focus);\n return block && this.caretInsideMark(block, this.sel.focus) ? block : null;\n }\n\n /** 方向键停在零宽 mark 上的选中态。选区仍是折叠的,不画选区。 */\n private armedEmptyMark(): VirtualBlock | null {\n if (!this.markArmedId || !isCollapsed(this.sel)) return null;\n const block = this.doc.virtualBlocks.get(this.markArmedId);\n if (!block || block.start !== this.sel.focus || block.end !== this.sel.focus) return null;\n if (block.kind !== 'mark' || !block.placeholder || !this.hasSelectedChrome(block)) return null;\n return block;\n }\n\n private armEmptyMark(block: VirtualBlock, side: 'left' | 'right') {\n this.sel = collapsedSel(block.start);\n this.affinity = null;\n this.verticalGoal = null;\n this.markArmedId = block.id;\n this.markArmedSide = side;\n this.afterCaretMove(true);\n }\n\n /**\n * 零宽 mark 的选中态。朝内进入灰字,朝外离开。\n * 出口贴着另一块配了选中皮的 mark 时,先改选中那一块,不直接跳出。\n */\n private stepArmedEmpty(block: VirtualBlock, dir: 1 | -1) {\n const side = this.markArmedSide ?? 'left';\n const inward = side === 'left' ? dir > 0 : dir < 0;\n if (inward) {\n this.sel = collapsedSel(block.start);\n this.affinity = null;\n this.verticalGoal = null;\n this.afterCaretMove();\n return;\n }\n const outer = this.selectedMarkAtEmptyExit(block.start, dir);\n if (outer) {\n this.selectWholeMark(outer, dir > 0 ? -1 : 1);\n return;\n }\n if (dir > 0 && this.nonEmptyMarkEndsAt(block.start)) {\n this.sel = collapsedSel(block.start);\n this.affinity = { index: block.start, dir: 'forward' };\n this.verticalGoal = null;\n this.afterCaretMove();\n return;\n }\n if (dir < 0 && this.selectableMarkStartsAt(block.start)) {\n this.sel = collapsedSel(block.start);\n this.affinity = { index: block.start, dir: 'backward' };\n this.verticalGoal = null;\n this.afterCaretMove();\n return;\n }\n const index = this.stepIndex(block.start, dir);\n this.sel = collapsedSel(index);\n this.affinity = { index, dir: dir > 0 ? 'backward' : 'forward' };\n this.verticalGoal = null;\n this.afterCaretMove();\n }\n\n /** 零宽点正好是某块有字 mark 的出口,并且那块配了选中皮。取范围最小的一层。 */\n private selectedMarkAtEmptyExit(index: number, dir: 1 | -1): VirtualBlock | null {\n let best: VirtualBlock | null = null;\n for (const block of this.doc.listVirtualBlocks()) {\n if (block.kind !== 'mark' || block.start >= block.end || !isSelectable(block.chrome)) continue;\n if (!this.hasSelectedChrome(block)) continue;\n const atExit = dir > 0 ? block.end === index : block.start === index;\n if (!atExit) continue;\n if (!best || block.end - block.start < best.end - best.start) best = block;\n }\n return best;\n }\n\n /** 方向键撞上 mark 产生的整段选中。拖选和 Shift 拉出的选区不算。 */\n private armedWholeMark(): VirtualBlock | null {\n if (!this.markArmedId) return null;\n const whole = this.wholeSelectedMark();\n return whole?.id === this.markArmedId ? whole : null;\n }\n\n /** 当前选区正好盖住某一块 mark 的全部文字。 */\n private wholeSelectedMark(): VirtualBlock | null {\n if (isCollapsed(this.sel)) return null;\n const from = Math.min(this.sel.anchor, this.sel.focus);\n const to = Math.max(this.sel.anchor, this.sel.focus);\n for (const block of this.doc.listVirtualBlocks()) {\n if (block.kind === 'mark' && block.start === from && block.end === to && block.end > block.start) return block;\n }\n return null;\n }\n\n /** 焦点留在进入的这一侧,锚点在另一端。记成选中态,和用户拉出的选区分开。 */\n private selectWholeMark(block: VirtualBlock, dir: 1 | -1) {\n this.sel = dir > 0 ? { anchor: block.end, focus: block.start } : { anchor: block.start, focus: block.end };\n this.affinity = null;\n this.verticalGoal = null;\n this.markArmedId = block.id;\n this.markArmedSide = null;\n this.afterCaretMove(true);\n }\n\n /**\n * 选中态下的左右键。朝块内进入这一侧的内侧,朝回来的方向回到这一侧的外侧。\n * 焦点在起点表示从左边进入。\n * 这一侧贴着不可选中的芯片时,进入的同一步就跳过它,落在芯片另一侧、仍在 mark 内。\n * 落点是配了选中皮的零宽 mark 时,先停在那块的选中态,再按一次才进灰字。\n */\n private stepArmedMark(block: VirtualBlock, dir: 1 | -1) {\n const fromLeft = this.sel.focus <= this.sel.anchor;\n const inward = fromLeft ? dir > 0 : dir < 0;\n if (inward) {\n const at = fromLeft ? block.start : block.end;\n const empty = this.emptyMarkWithSelectedAt(at);\n if (empty && empty.id !== block.id) {\n this.armEmptyMark(empty, fromLeft ? 'left' : 'right');\n return;\n }\n }\n if (fromLeft) {\n let index = block.start;\n let affinity: 'forward' | 'backward' = inward ? 'forward' : 'backward';\n if (inward) {\n while (index < block.end && this.embedSkipped(index)) index += 1;\n if (index === block.end) affinity = 'backward';\n }\n this.sel = collapsedSel(index);\n this.affinity = { index, dir: affinity };\n } else {\n this.sel = collapsedSel(block.end);\n this.affinity = { index: block.end, dir: inward ? 'backward' : 'forward' };\n }\n this.verticalGoal = null;\n this.afterCaretMove();\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 if (this.embedSkipped(i)) {\n // 芯片贴在 mark 边缘时仍属于这块。先整段选中或离开,下一次进入再跳过芯片。\n if (this.markEntering(dir) || this.markLeaving(dir)) return null;\n return collapsedSel(i + 1);\n }\n return { anchor: i, focus: i + 1 };\n }\n if (dir < 0 && i > 0 && this.doc.spacers[i - 1] === MARKERS.IMAGE) {\n if (this.embedSkipped(i - 1)) {\n if (this.markEntering(dir) || this.markLeaving(dir)) return null;\n return collapsedSel(i - 1);\n }\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.markArmedId = null;\n this.markArmedSide = null;\n this.sel = next;\n if (moved) this.typingStyle = null;\n }\n\n private afterCaretMove(keepArmed = false) {\n if (!keepArmed) {\n this.markArmedId = null;\n this.markArmedSide = null;\n }\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 /** 有文字、且允许光标进入的 mark 边界。不可选中的块不在这里换内外侧。 */\n private selectableMarkBoundary(index: number): boolean {\n return this.doc.listVirtualBlocks().some(\n (b) => b.kind === 'mark' && isSelectable(b.chrome) && b.start < b.end && (b.end === index || b.start === index)\n );\n }\n\n /** `chrome.selectable === false` 的芯片或其它嵌入。光标不选中它。 */\n private embedSkipped(index: number): boolean {\n const entity = this.doc.imageAt(index);\n return !!entity && !isSelectable(entity.chrome);\n }\n\n /**\n * 把落点挪出不可选中的 mark 和芯片。\n * `dir` 为 1 / -1 时沿移动方向跳到外侧;为 0 时(点击、上下)停在更近的一侧。\n */\n private placeOutsideUnselectable(\n index: number,\n dir: 1 | -1 | 0\n ): { index: number; affinity: 'forward' | 'backward' | null } {\n const blocks = this.doc.listVirtualBlocks();\n let i = index;\n if (dir === 0) {\n const right = indexOutsideUnselectableMarks(index, 1, blocks);\n const left = indexOutsideUnselectableMarks(index, -1, blocks);\n if (left !== index || right !== index) {\n i = right === index || (left !== index && index - left <= right - index) ? left : right;\n }\n } else {\n i = indexOutsideUnselectableMarks(index, dir, blocks);\n }\n let affinity: 'forward' | 'backward' | null = null;\n if (i !== index) affinity = i > index ? 'forward' : 'backward';\n // 一步正好落在不可选中 mark 的端点上时,亲和必须贴在外侧。\n // 往右默认贴前一个字,会画进这块的右缘里面。\n if (!affinity && dir > 0 && this.unselectableMarkEndsAt(i) && !this.selectableMarkEndsAt(i)) affinity = 'forward';\n if (!affinity && dir < 0 && this.unselectableMarkStartsAt(i) && !this.selectableMarkStartsAt(i)) affinity = 'backward';\n return { index: i, affinity };\n }\n\n /** 有文字的不可选中 mark 是否以这个下标收尾。 */\n private unselectableMarkEndsAt(index: number): boolean {\n return this.doc.listVirtualBlocks().some(\n (b) => b.kind === 'mark' && !isSelectable(b.chrome) && b.start < b.end && b.end === index\n );\n }\n\n private unselectableMarkStartsAt(index: number): boolean {\n return this.doc.listVirtualBlocks().some(\n (b) => b.kind === 'mark' && !isSelectable(b.chrome) && b.start < b.end && b.start === index\n );\n }\n\n private selectableMarkEndsAt(index: number): boolean {\n return this.doc.listVirtualBlocks().some(\n (b) => b.kind === 'mark' && isSelectable(b.chrome) && b.start < b.end && b.end === index\n );\n }\n\n private selectableMarkStartsAt(index: number): boolean {\n return this.doc.listVirtualBlocks().some(\n (b) => b.kind === 'mark' && isSelectable(b.chrome) && b.start < b.end && b.start === index\n );\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 index === this.sel.focus ? this.mainCaretPos().x : caretFromIndex(this.layout, index).x;\n }\n\n /** 主文档光标的绘制位置;贴后一个字时画在 mark 内边距空白的另一侧,正是下一个字落下的地方。 */\n private mainCaretPos() {\n const caret = caretFromIndex(this.layout, this.sel.focus);\n if (this.caretAffinity() !== 'forward') return caret;\n const edge = this.markEndEdge(this.sel.focus);\n if (edge?.stop.fwdX != null) return { ...caret, x: edge.stop.fwdX, y: edge.line.y, h: edge.line.h };\n const fwdX = this.caretStopAt(this.sel.focus)?.fwdX;\n return fwdX == null ? caret : { ...caret, x: fwdX };\n }\n\n private verticalMove(index: number, dir: 1 | -1, x: number): number {\n const lines = this.layout.lines;\n // 空行与上一行共享段尾下标(上一行 end == 空行 start)。findIndex 会命中上一行,\n // 再按下键等于“走到当前空行”,光标原地不动。以光标实际绘制的那一行为准。\n const curLine = this.lineAt(this.layout, index);\n let idx = curLine ? lines.indexOf(curLine) : lines.findIndex((l) => index >= l.start && index <= l.end);\n if (idx < 0) idx = 0;\n for (let next = idx + dir; next >= 0 && next < lines.length; next += 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 && this.embedSkipped(hitEmbed.index)) {\n const mid = hitEmbed.x + hitEmbed.w / 2;\n return x <= mid ? hitEmbed.index : hitEmbed.index + 1;\n }\n if (hitEmbed) return hitEmbed.index;\n const at = hitTestIndex(this.layout, x, line.y + 1);\n if (at !== index) return at;\n }\n return index;\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\n/** 选区焦点标记色:默认选区蓝去掉透明度后的实色。 */\nconst FOCUS_MARK_COLOR = '#2b6cff';\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","MARK_DEFAULT_PADDING_X","MARK_PLACEHOLDER_COLOR","paddingXOf","marginXOf","margin","paddingYOf","pad","isSelectable","chrome","indexOutsideUnselectableMarks","n","edge","next","shiftVirtualBlocksOnInsert","len","shiftVirtualBlocksOnDelete","docLength","wholeDoc","boundaryPlaceholder","depthOf","byId","d","id","parent","sortOuterToInner","map","la","lb","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","paintCtx","paintMeasureContext","canvas","measurePaintWidth","measureWidth","key","w","prepared","prepareWithSegments","measureNaturalWidth","glyphCache","GLYPH_CACHE_MAX","naturalWidth","measureGlyphWidths","widths","prevWidth","cp","width","lineHeightOf","size","lh","m","px","REF_PAD","REF_HEAD","refInnerWidth","boxW","chromeFallback","chain","t","preferChromeText","resolvedTextStyle","heading","link","href","body","_b","_c","_d","_e","HOST_FALLBACK_W","HOST_FALLBACK_H","embedLayoutSize","maxWidth","host","height","embedOccupiesLine","preparedCache","PREPARED_CACHE_MAX","preparedFor","WINDOW_SLACK","nextLineText","rest","whole","win","line","layoutNextLine","markHints","setMarkLayoutHints","markLayoutHint","markGaps","gaps","empty","add","g","markHolds","holds","shown","at","styleAt","content","slack","padEnd","list","collectRuns","runs","pushGap","endAfterHold","h","ns","leadingInset","trailingInset","length","fitMarkText","restIndex","budget","pick","fitPrefix","again","pushLeadingInset","items","hasInk","it","lo","hi","best","mid","fitPaintLine","guard","trimmed","space","withSpace","placePlaceholderHold","run","lineW","continued","remain","busy","head","more","sliceW","wrapParagraph","lineStart","flush","lineEnd","placed","isolated","widthForLine","bandSlot","contentX","contentW","bandTop","bandH","obstacles","gap","left","right","f","cursorIndex","cur","fallback","createWrapCursor","skipFloats","wrapCursorDone","wrapCursorIndex","wrapCursorPeek","wrapCursorSkip","consumeWrapLine","room","UL_MARKERS","listMarkerText","olIndex","layoutParagraph","x","y","paraProps","indent","markerText","markerW","align","floats","allObstacles","useFlow","paragraphHasFloat","lineY","peek","side","fx","slot","buildLine","last","lineGapOf","wrapped","nextOl","counter","maxW","markerX","contentH","item","emptyStyle","padY","linePaddingY","lineH","contentY","dx","glyphs","images","caretStops","cx","stop","endMargin","startMargin","endPad","startPad","endBox","afterEnd","startBox","afterAll","hasEnd","hasStart","local","marker","vblockFragments","fillRight","hold","outer","sorted","boxes","im","atEnd","nested","outerPad","top","bottom","padX","hint","emptyMark","labelText","atStyle","continues","boxLeft","boxRight","first","layoutTable","paraIndex","stored","even","hasStored","colWidths","_","sum","cy","rowCells","maxH","innerW","paras","py","ol","pp","pl","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","tables","topOl","activeFloats","dirtyTop","dirtyBottom","markDirty","styleIndex","prevByHash","entry","inPlaceAllowed","shifted","canShiftInPlace","pickCached","hash","ry","separated","cached","oldY","oldBottom","oldH","now","old","dirty","attachRefInners","model","sortedLinesCache","sortedLines","layout","caretFromIndex","near","caretFromIndexIn","allowNearest","bestLine","bestX","bestIndex","bestDist","exact","dist","earlier","later","hitTestIndex","localX","localY","closestCaretOnLines","bestScore","inY","inX","score","selectionRects","cellRects","cellGridRects","rects","stops","rightCandidates","leftEdge","x0","rightEdge","x1","hasText","x0b","x1b","y0","y1","vb","imageBoxAt","r0","r1","c0","c1","hitColBorder","fillOf","rainbowAt","sunsetAt","cssFill","runWidth","fill","canvasFill","glyphIndex","runT","paintCanvasUnderline","kind","color","amp","step","up","paintCanvasStrike","groupDecorationRuns","strike","baseline","REF_JUMP","innerUsedSize","measureRef","inner","emptyInner","used","countLabel","paintInner","renderInnerLine","hole","pic","wrap","innerCss","deco","runW","weight","italic","refPlugin","badge","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","placeEmbed","builtinEmbedPlugins","insertSpacers","insertBeforeIndex","NULL_MUTATION","deleteSpacers","startIndex","endIndex","applyStyle","styleType","addEntity","updateEntity","deleteEntity","addFragment","deleteFragment","addVirtualBlock","deleteVirtualBlock","blockId","updateVirtualBlock","scoped","multi","unwrap","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","rangeContains","range","rangeEquals","shiftIndex","shiftPosition","offset","shiftIndexExclusive","shiftRange","leadingLength","position","leadEnd","transformCoordinateAgainstDeletedRange","deleted","transformRangeAgainstDeletedRange","newStart","endpointDeleted","newEnd","insertAgainstInsert","cmd","other","aWins","insertAgainstDelete","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","second","invertEdit","Collector","selection","one","scopeContext","runOperation","op","result","resolveTextProps","resolveParagraphProps","rangeIsOnlyMarkers","contentRuns","base","runStart","textSegments","points","existing","spanCovering","expectedParagraphSpans","byStart","firstStartAtLeast","inherit","EMPTY_SLICE","emitInsert","emitDelete","emitStyle","emitTextStyle","seg","normalizeParagraphs","needed","sameSpans","needKeys","curKeys","differing","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","marksOnly","shiftStylesOnInsert","shiftStylesOnDelete","kept","snap","entities","fragmentIds","fragments","virtualBlocks","probe","normalized","documentFromSlice","sliceFromDocument","ensure","merged","collapsedSel","sliceWithoutParagraphGroup","groupId","keep","insertImage","updateImage","blockMap","validateInsert","insertVirtualBlock","spec","dismissEmptyPlaceholderMarks","removeVirtualBlock","updateVirtualBlockChrome","coverAncestorsOf","pid","coverVirtualBlocks","remapIncomingVirtualBlocks","occupied","idMap","remapped","extendMarksAt","affinity","extendMarksAtStart","extendMarksAtEnd","nonEmptyMarkEndsAt","extendEmptyPlaceholderMarks","nl","isLastParagraphWithGroupId","splitParagraphSpans","cursor","insertText","safe","replaceMarkText","placeholder","deleteRange","nextEnd","insertParagraph","oldProps","inList","paraEndContent","atStart","exitGroup","leftProps","rightProps","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","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","maxL","maxT","latency","queue","values","mini","chars","miniFps","countParagraphs","segmenter","getSegmenter","maxCaretIndex","wordSpans","wordTarget","paragraphTarget","wordRangeAt","SLICE_MIME","serializeSlice","parseSlice","data","sliceFromClipboard","markRadii","markSides","paintsHoverSkin","skinId","resolveMarkBorder","skin","resolveMarkFill","containsPoint","contentEdges","rangeInside","hoverSkinMarkId","prefer","hoverSlotInPadding","slots","frameGeometry","lineWidth","radii","sides","hw","maxR","clampR","tl","tr","br","bl","arcs","sx","ex","sy","ey","P","strokeFrame","frameCss","on","sameHoverIds","CANVAS_GUTTER","VIEWPORT_MARGIN","MAX_ZOOM_SHARPNESS","CanvasPainter","lock","dpr","zoom","band","prevSkin","targets","visible","trails","vis","mark","rect","vv","viewTop","viewH","force","wantH","changed","maxTop","legal","covers","scaleChanged","moved","fullW","resized","topCss","editorRoot","family","markerTop","cs","radius","rainbow","capH","grad","border","alpha","shift","hoverLabel","metrics","ascent","descent","solid","caretW","editorCs","glow","drawH","fontH","cssFont","cssText","HtmlPainter","child","renderTableChrome","renderLine","hover","cap","readPxVar","capBox","placeCaret","css","fade","anim","renderVBlock","hidden","borderWidthCss","hoverBorder","selectedBorder","frame","appendMarkLabel","Editor","options","indices","pos","after","ops.updateImage","refBox","interactive","clickedMark","openSafeUrl","snapped","ratio","ops.setTableColWidths","startW","startH","level","delta","hostType","opts","extend","unit","track","active","mode","prevColor","nextColor","match","cssColorsEqual","computed","selColor","FOCUS_MARK_COLOR","selRadius","cssFamily","ops.insertSlice","ops.insertVirtualBlock","origin","status","ok","ops.replaceMarkText","ops.updateVirtualBlockChrome","ops.removeVirtualBlock","markIds","ops.applyParagraphStyle","pred","ops.deleteRange","patchFor","patches","clientX","clientY","embed","canPromote","event","disabled","payload","slotId","skinned","markId","below","above","down","hovers","any","avail","selectionAfter","revert","settle","minStart","maxEnd","ops.emitDelete","ops.emitInsert","ops.normalizeParagraphs","anchor","ops.insertText","ops.applyMarkdownShortcut","fakePlainClipboard","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","hoverOn","selectOn","found","isSlot","isRef","isHost","sliceToHtml","startX","w1","armedEmpty","insideEmpty","exitMark","leaving","entering","vertical","collapseRange","goalX","skipped","landed","remember","fromLeft","inward","keepArmed","isStructural","fwdX","curLine","hitEmbed","parsed"],"mappings":"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"}