@aglyn/aglyn-markdown-editor 1.0.0-beta.143
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/LICENSE +201 -0
- package/README.md +34 -0
- package/package.json +40 -0
- package/src/index.d.ts +43 -0
- package/src/index.js +42 -0
- package/src/index.js.map +1 -0
- package/src/lib/link-target-autocomplete.component.d.ts +60 -0
- package/src/lib/link-target-autocomplete.component.js +235 -0
- package/src/lib/link-target-autocomplete.component.js.map +1 -0
- package/src/lib/markdown-editor-toolbar.component.d.ts +14 -0
- package/src/lib/markdown-editor-toolbar.component.js +254 -0
- package/src/lib/markdown-editor-toolbar.component.js.map +1 -0
- package/src/lib/markdown-field.component.d.ts +43 -0
- package/src/lib/markdown-field.component.js +144 -0
- package/src/lib/markdown-field.component.js.map +1 -0
- package/src/lib/markdown-html-paste.d.ts +38 -0
- package/src/lib/markdown-html-paste.js +312 -0
- package/src/lib/markdown-html-paste.js.map +1 -0
- package/src/lib/markdown-link-dialog.component.d.ts +39 -0
- package/src/lib/markdown-link-dialog.component.js +195 -0
- package/src/lib/markdown-link-dialog.component.js.map +1 -0
- package/src/lib/markdown-lite-view.component.d.ts +6 -0
- package/src/lib/markdown-lite-view.component.js +243 -0
- package/src/lib/markdown-lite-view.component.js.map +1 -0
- package/src/lib/markdown-source-command.d.ts +51 -0
- package/src/lib/markdown-source-command.js +56 -0
- package/src/lib/markdown-source-command.js.map +1 -0
- package/src/lib/markdown-visual-editor.component.d.ts +109 -0
- package/src/lib/markdown-visual-editor.component.js +2019 -0
- package/src/lib/markdown-visual-editor.component.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../libs/aglyn-markdown-editor/src/lib/markdown-visual-editor.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\n/**\n * WYSIWYG editor for markdown-lite blog bodies (AGL-582).\n *\n * Model-first, dependency-free: the parsed markdown-lite blocks are the\n * source of truth (`rowsRef`), rendered as ONE contentEditable element per\n * text row (paragraph / heading / list item) plus non-editable image rows.\n * Plain typing stays native — each `input` event reads the row's DOM back\n * into the model WITHOUT re-rendering, so the caret and IME composition are\n * never disturbed. Structural edits (Enter, Backspace-at-start, toolbar\n * marks, links, images, paste, undo) mutate the model, bump `version` to\n * re-render every row from the model, and restore the selection from model\n * offsets. Every change serializes through `serializeMarkdownLite`, so the\n * document round-trips losslessly to the exact markdown-lite string stored\n * in Firestore — no HTML is ever persisted.\n */\n\nimport type * as Aglyn from '@aglyn/aglyn'\nimport {\n isSupportedImageSrc,\n isSupportedLinkHref,\n parseMarkdownLite,\n resolveMediaSrc,\n serializeMarkdownLite,\n} from '@aglyn/aglyn'\nimport {\n Box,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Popover,\n Stack,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Typography,\n} from '@mui/material'\nimport FormatAlignCenterIcon from '@mui/icons-material/FormatAlignCenter'\nimport FormatAlignLeftIcon from '@mui/icons-material/FormatAlignLeft'\nimport FormatAlignRightIcon from '@mui/icons-material/FormatAlignRight'\nimport type { ReactNode } from 'react'\nimport {\n forwardRef,\n memo,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { htmlToRows } from './markdown-html-paste'\nimport MarkdownLinkDialog, {\n MarkdownLinkTargetName,\n type MarkdownLink,\n} from './markdown-link-dialog.component'\n\nexport type MarkdownEditorCommand =\n | 'bold'\n | 'italic'\n | 'heading'\n | 'heading3'\n | 'list'\n | 'orderedList'\n | 'link'\n | 'image'\n | 'code'\n | 'table'\n | 'quote'\n\n/**\n * What the caret is sitting in (AGL-984), so a toolbar can show its state.\n * `kind` is the caret row's kind, or null when the caret is in a block row\n * (a table cell or a snippet), where the mark commands do not apply.\n */\nexport interface MarkdownEditorContext {\n bold: boolean\n italic: boolean\n kind:\n | 'paragraph'\n | 'heading2'\n | 'heading3'\n | 'listItem'\n | 'orderedItem'\n | 'quote'\n | null\n}\n\nexport interface MarkdownVisualEditorHandle {\n /** Applies a toolbar command at the current (or last known) selection. */\n exec: (command: MarkdownEditorCommand) => void\n /** Inserts an image block after the caret row (console media picker). */\n insertImage: (alt: string, url: string) => void\n}\n\nexport interface MarkdownVisualEditorProps {\n /** Markdown-lite source. Re-parsed whenever it changes externally. */\n value: string\n /** Fires with the serialized markdown-lite string on every edit. */\n onChange: (markdown: string) => void\n /**\n * When set, the Insert image dialog offers a \"Choose from media\" button\n * that closes the dialog and invokes this callback — the host page opens\n * its media picker and inserts via the imperative handle (AGL-596).\n *\n * Receives the alt text typed in the dialog before the handoff (AGL-1645).\n * Handing the picker an image is the only chance to describe it: an image\n * row is `contentEditable={false}`, so an alt left empty here can never be\n * filled in afterwards without deleting and re-inserting the image. Callers\n * that mint their own alt from the asset are free to ignore it.\n */\n onPickImageFromMedia?: (alt: string) => void\n /** Fires when the caret's formatting context changes (AGL-984). */\n onContextChange?: (context: MarkdownEditorContext) => void\n minHeight?: number | string\n maxHeight?: number | string\n}\n\ntype TextRowKind =\n | 'paragraph'\n | 'heading2'\n | 'heading3'\n | 'listItem'\n | 'orderedItem'\n | 'quote'\n\ntype TextRow = {\n key: string\n kind: TextRowKind\n inlines: Aglyn.MarkdownInline[]\n /**\n * An ordered list's start number, carried on the row that OPENS the run\n * (AGL-1320). The row model is flat, so this is the only place a non-1\n * start can live — without it, editing a notice that resumes at `7.` would\n * silently renumber it to `1.` on the next save, the same way an\n * unrepresentable block used to be dropped. A row that does not open a run\n * ignores it; if the opener is deleted, the run restarts at 1.\n */\n start?: number\n}\ntype ImageRow = { key: string; kind: 'image'; src: string; alt: string }\ntype CodeRow = { key: string; kind: 'code'; lang: string; text: string }\ntype TableRow = {\n key: string\n kind: 'table'\n align: Aglyn.MarkdownTableAlign[]\n header: Aglyn.MarkdownTableCell[]\n rows: Aglyn.MarkdownTableCell[][]\n}\n/**\n * Rows the caret cannot enter: they render read-only with a Remove button\n * and are carried through the model untouched. Code blocks and tables join\n * images here (AGL-974) — this editor also writes marketplace READMEs, and\n * a block it could not represent was silently DELETED on the next save.\n */\ntype BlockRow = ImageRow | CodeRow | TableRow\nexport type EditorRow = TextRow | BlockRow\n\n/** A block row before it has a key — Omit must distribute over the union. */\ntype NewBlockRow =\n | Omit<ImageRow, 'key'>\n | Omit<CodeRow, 'key'>\n | Omit<TableRow, 'key'>\n\nconst isTextRow = (row: EditorRow): row is TextRow =>\n row.kind !== 'image' && row.kind !== 'code' && row.kind !== 'table'\n\nlet rowKeySeq = 0\nconst nextRowKey = () => `md-row-${++rowKeySeq}`\n\nconst emptyParagraph = (): TextRow => ({\n key: nextRowKey(),\n kind: 'paragraph',\n inlines: [],\n})\n\n/** Flattens parsed blocks to editable rows (lists become item rows). */\nexport function markdownToRows(markdown: string): EditorRow[] {\n const rows: EditorRow[] = []\n for (const block of parseMarkdownLite(markdown)) {\n if (block.type === 'heading') {\n rows.push({\n key: nextRowKey(),\n kind: block.level === 2 ? 'heading2' : 'heading3',\n inlines: block.inlines,\n })\n } else if (block.type === 'paragraph') {\n rows.push({ key: nextRowKey(), kind: 'paragraph', inlines: block.inlines })\n } else if (block.type === 'quote') {\n rows.push({ key: nextRowKey(), kind: 'quote', inlines: block.inlines })\n } else if (block.type === 'image') {\n rows.push({ key: nextRowKey(), kind: 'image', src: block.src, alt: block.alt })\n } else if (block.type === 'code') {\n rows.push({ key: nextRowKey(), kind: 'code', lang: block.lang, text: block.text })\n } else if (block.type === 'table') {\n rows.push({\n key: nextRowKey(),\n kind: 'table',\n align: block.align,\n header: block.header,\n rows: block.rows,\n })\n } else if (block.type === 'orderedList') {\n // The start rides on the first item row only (AGL-1320) — the run's\n // opener is what `rowsToMarkdown` reads it back from.\n block.items.forEach((item, index) => {\n rows.push({\n key: nextRowKey(),\n kind: 'orderedItem',\n inlines: item,\n ...(index === 0 ? { start: block.start } : {}),\n })\n })\n } else {\n for (const item of block.items) {\n rows.push({ key: nextRowKey(), kind: 'listItem', inlines: item })\n }\n }\n }\n if (rows.length === 0) rows.push(emptyParagraph())\n return rows\n}\n\n/** Regroups rows to blocks (adjacent list items rejoin) and serializes. */\nexport function rowsToMarkdown(rows: EditorRow[]): string {\n const blocks: Aglyn.MarkdownBlock[] = []\n for (const row of rows) {\n if (row.kind === 'image') {\n blocks.push({ type: 'image', src: row.src, alt: row.alt })\n } else if (row.kind === 'code') {\n blocks.push({ type: 'code', lang: row.lang, text: row.text })\n } else if (row.kind === 'table') {\n blocks.push({\n type: 'table',\n align: row.align,\n header: row.header,\n rows: row.rows,\n })\n } else if (row.kind === 'listItem') {\n const last = blocks[blocks.length - 1]\n if (last?.type === 'list') last.items.push(row.inlines)\n else blocks.push({ type: 'list', items: [row.inlines] })\n } else if (row.kind === 'orderedItem') {\n const last = blocks[blocks.length - 1]\n if (last?.type === 'orderedList') last.items.push(row.inlines)\n // Only the row that OPENS a run can set the start (AGL-1320); a row\n // that inherited one from a split keeps counting from the opener.\n else\n blocks.push({\n type: 'orderedList',\n start: row.start ?? 1,\n items: [row.inlines],\n })\n } else if (row.kind === 'paragraph') {\n blocks.push({ type: 'paragraph', inlines: row.inlines })\n } else if (row.kind === 'quote') {\n blocks.push({ type: 'quote', inlines: row.inlines })\n } else {\n blocks.push({\n type: 'heading',\n level: row.kind === 'heading2' ? 2 : 3,\n inlines: row.inlines,\n })\n }\n }\n return serializeMarkdownLite(blocks)\n}\n\nconst rowPlainText = (inlines: Aglyn.MarkdownInline[]): string =>\n inlines.map((inline) => inline.text).join('')\n\n/** Merges adjacent same-type runs (same href for links), drops empties. */\nfunction normalizeInlines(\n inlines: Aglyn.MarkdownInline[],\n): Aglyn.MarkdownInline[] {\n const out: Aglyn.MarkdownInline[] = []\n for (const inline of inlines) {\n if (!inline.text) continue\n const last = out[out.length - 1]\n if (\n last &&\n last.type === inline.type &&\n (last.type !== 'link' ||\n last.href === (inline as { href?: string }).href)\n ) {\n last.text += inline.text\n } else {\n out.push({ ...inline })\n }\n }\n return out\n}\n\n/** Extracts [from, to) in plain-text offsets, keeping marks on the cuts. */\nfunction sliceInlines(\n inlines: Aglyn.MarkdownInline[],\n from: number,\n to: number,\n): Aglyn.MarkdownInline[] {\n const out: Aglyn.MarkdownInline[] = []\n let position = 0\n for (const inline of inlines) {\n const end = position + inline.text.length\n const start = Math.max(from, position)\n const stop = Math.min(to, end)\n if (stop > start) {\n out.push({ ...inline, text: inline.text.slice(start - position, stop - position) })\n }\n position = end\n }\n return normalizeInlines(out)\n}\n\nfunction replaceInlineRange(\n inlines: Aglyn.MarkdownInline[],\n from: number,\n to: number,\n replacement: Aglyn.MarkdownInline[],\n): Aglyn.MarkdownInline[] {\n return normalizeInlines([\n ...sliceInlines(inlines, 0, from),\n ...replacement,\n ...sliceInlines(inlines, to, Infinity),\n ])\n}\n\n/**\n * Toggles bold/italic over [from, to). The dialect cannot nest marks, so\n * applying one flattens the covered range to plain text carrying the mark;\n * a range that is already entirely the mark unwraps back to text.\n */\nfunction toggleInlineMark(\n inlines: Aglyn.MarkdownInline[],\n from: number,\n to: number,\n mark: 'bold' | 'italic',\n): { inlines: Aglyn.MarkdownInline[]; length: number } {\n const middle = sliceInlines(inlines, from, to)\n const text = rowPlainText(middle)\n if (!text) return { inlines, length: 0 }\n const unwrap = middle.every((inline) => inline.type === mark)\n return {\n inlines: replaceInlineRange(inlines, from, to, [\n { type: unwrap ? 'text' : mark, text },\n ]),\n length: text.length,\n }\n}\n\n/**\n * Reads a row's live DOM back into canonical inlines. Only elements this\n * editor renders exist in a row (plus text nodes the browser adds while\n * typing); unknown wrappers are recursed through as plain text.\n */\nexport function readInlinesFromElement(\n rowEl: HTMLElement,\n): Aglyn.MarkdownInline[] {\n const inlines: Aglyn.MarkdownInline[] = []\n const visit = (node: Node): void => {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent ?? ''\n if (text) inlines.push({ type: 'text', text })\n return\n }\n if (!(node instanceof HTMLElement) || node.tagName === 'BR') return\n const text = node.textContent ?? ''\n if (!text) return\n if (node.tagName === 'STRONG' || node.tagName === 'B') {\n inlines.push({ type: 'bold', text })\n } else if (node.tagName === 'EM' || node.tagName === 'I') {\n inlines.push({ type: 'italic', text })\n } else if (node.dataset['mdLink'] != null) {\n inlines.push({ type: 'link', text, href: node.dataset['mdHref'] ?? '' })\n } else {\n node.childNodes.forEach(visit)\n }\n }\n rowEl.childNodes.forEach(visit)\n return normalizeInlines(inlines)\n}\n\n/** Plain-text offset of a DOM position inside a row element. */\nfunction textOffsetOf(rowEl: HTMLElement, node: Node, offset: number): number {\n const range = rowEl.ownerDocument.createRange()\n range.selectNodeContents(rowEl)\n try {\n range.setEnd(node, offset)\n } catch {\n return 0\n }\n return range.toString().length\n}\n\nfunction selectionOffsetsWithin(\n rowEl: HTMLElement,\n): { start: number; end: number } | null {\n const selection = rowEl.ownerDocument.defaultView?.getSelection?.()\n if (!selection || selection.rangeCount === 0) return null\n const range = selection.getRangeAt(0)\n if (\n !rowEl.contains(range.startContainer) ||\n !rowEl.contains(range.endContainer)\n ) {\n return null\n }\n const start = textOffsetOf(rowEl, range.startContainer, range.startOffset)\n const end = textOffsetOf(rowEl, range.endContainer, range.endOffset)\n return start <= end ? { start, end } : { start: end, end: start }\n}\n\nfunction resolveTextPosition(\n rowEl: HTMLElement,\n target: number,\n): { node: Node; offset: number } {\n const walker = rowEl.ownerDocument.createTreeWalker(\n rowEl,\n NodeFilter.SHOW_TEXT,\n )\n let remaining = target\n let node = walker.nextNode()\n let lastText: Text | null = null\n while (node) {\n const text = node as Text\n if (remaining <= text.length) return { node: text, offset: remaining }\n remaining -= text.length\n lastText = text\n node = walker.nextNode()\n }\n if (lastText) return { node: lastText, offset: lastText.length }\n return { node: rowEl, offset: 0 }\n}\n\nfunction setSelectionIn(rowEl: HTMLElement, start: number, end: number): void {\n const selection = rowEl.ownerDocument.defaultView?.getSelection?.()\n if (!selection) return\n const from = resolveTextPosition(rowEl, start)\n const to = end === start ? from : resolveTextPosition(rowEl, end)\n const range = rowEl.ownerDocument.createRange()\n range.setStart(from.node, from.offset)\n range.setEnd(to.node, to.offset)\n selection.removeAllRanges()\n selection.addRange(range)\n}\n\nfunction renderRowInlines(inlines: Aglyn.MarkdownInline[]): ReactNode {\n // An empty row keeps a <br> so the caret has a line box to land in.\n if (inlines.length === 0) return <br />\n return inlines.map((inline, index) =>\n inline.type === 'bold' ? (\n <strong key={index}>{inline.text}</strong>\n ) : inline.type === 'italic' ? (\n <em key={index}>{inline.text}</em>\n ) : inline.type === 'link' ? (\n <span key={index} data-md-link=\"\" data-md-href={inline.href}>\n {inline.text}\n </span>\n ) : (\n <span key={index}>{inline.text}</span>\n ),\n )\n}\n\ninterface TextRowViewProps {\n row: TextRow\n version: number\n onInput: (event: React.FormEvent<HTMLDivElement>) => void\n onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void\n onPaste: (event: React.ClipboardEvent<HTMLDivElement>) => void\n onClick: (event: React.MouseEvent<HTMLDivElement>) => void\n onSelectionPing: () => void\n}\n\n/**\n * One editable row. The rendered children are FROZEN per `version`: while\n * the user types, React re-renders (parent state changes on every emitted\n * keystroke) but receives the identical element references, so it bails\n * out and never touches the browser-managed DOM. A version bump swaps the\n * `key`, remounting the row cleanly from the model.\n */\nconst TextRowView = memo(function TextRowView(props: TextRowViewProps) {\n const { row, version, onInput, onKeyDown, onPaste, onClick, onSelectionPing } =\n props\n // The DOM is the source of truth between versions — deliberately NOT\n // keyed on row.inlines, which trail the DOM during silent typing syncs.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const children = useMemo(() => renderRowInlines(row.inlines), [version])\n return (\n <Box\n key={`${row.key}:${version}`}\n contentEditable\n suppressContentEditableWarning\n spellCheck\n data-row-key={row.key}\n data-row-kind={row.kind}\n // The opener of a numbered run seeds the counter (AGL-1320). Reset\n // runs before increment on the same element, so this row itself shows\n // `start` and the rest of the run counts up from it.\n style={\n row.kind === 'orderedItem' && row.start != null\n ? { counterReset: `md-ordered ${row.start - 1}` }\n : undefined\n }\n onInput={onInput}\n onKeyDown={onKeyDown}\n onPaste={onPaste}\n onClick={onClick}\n onKeyUp={onSelectionPing}\n onMouseUp={onSelectionPing}\n onFocus={onSelectionPing}\n >\n {children}\n </Box>\n )\n})\n\ninterface BlockRowViewProps {\n row: BlockRow\n version: number\n /** Mutates this row in the model, then re-renders it from the model. */\n onEdit: (mutate: (row: BlockRow) => BlockRow) => void\n /** Same, but silent: the DOM is already correct, the caret must not move. */\n onEditSilently: (mutate: (row: BlockRow) => BlockRow) => void\n onRemove: () => void\n}\n\n/** A cell edited to nothing parses back to nothing — keep it canonical. */\nconst cellFromElement = (el: HTMLElement): Aglyn.MarkdownInline[] =>\n readInlinesFromElement(el)\n\nconst CODE_LANGUAGES = ['', 'ts', 'tsx', 'js', 'json', 'bash', 'html', 'css', 'md']\n\n/**\n * A block row: an image, a code block or a table (AGL-983). The document\n * caret never enters one — each brings its own editing surface instead, and\n * the row travels through the model as a unit. Hover reveals its controls.\n *\n * Editing follows the same rule as text rows: while the user types, the DOM\n * is the source of truth and the model syncs SILENTLY (no re-render, no lost\n * caret). Only structural edits — adding a column, changing alignment —\n * re-render, and they bump `version`, which re-keys this row.\n */\nconst BlockRowView = memo(function BlockRowView({\n row,\n version,\n onEdit,\n onEditSilently,\n onRemove,\n}: BlockRowViewProps) {\n const table = row.kind === 'table' ? row : null\n const columns = table?.header.length ?? 0\n\n /**\n * Cell contents are rendered ONCE, exactly like a text row's (this view is\n * re-keyed on `version`, so a model change remounts it). Re-rendering them\n * would have React reconcile DOM the browser owns while the caret is in\n * it — typing into an empty cell replaces its <br>, and the next render\n * threw NotFoundError trying to remove a node that was already gone.\n */\n const frozenHeader = useMemo(\n () => (table?.header ?? []).map((cell) => renderRowInlines(cell)),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n )\n const frozenRows = useMemo(\n () =>\n (table?.rows ?? []).map((cells) =>\n cells.map((cell) => renderRowInlines(cell)),\n ),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n )\n\n /** Writes one cell back from its live DOM. Header row is index -1. */\n const syncCell = (rowIndex: number, cellIndex: number, el: HTMLElement) => {\n const inlines = cellFromElement(el)\n onEditSilently((current) => {\n if (current.kind !== 'table') return current\n if (rowIndex < 0) {\n const header = [...current.header]\n header[cellIndex] = inlines\n return { ...current, header }\n }\n const rows = current.rows.map((cells, index) =>\n index === rowIndex\n ? cells.map((cell, i) => (i === cellIndex ? inlines : cell))\n : cells,\n )\n return { ...current, rows }\n })\n }\n\n const cellProps = (rowIndex: number, cellIndex: number) => ({\n contentEditable: true,\n suppressContentEditableWarning: true,\n onInput: (event: React.FormEvent<HTMLTableCellElement>) =>\n syncCell(rowIndex, cellIndex, event.currentTarget),\n style: { textAlign: table?.align[cellIndex] ?? 'left' } as const,\n })\n\n return (\n <Box\n contentEditable={false}\n data-row-key={row.key}\n data-row-kind={row.kind}\n sx={{\n my: 1,\n position: 'relative',\n '&:hover [data-md-block-controls]': { opacity: 1 },\n }}\n >\n {row.kind === 'image' ? (\n // Resolved for DISPLAY only (AGL-1686); `row.src` keeps the stored\n // form, so serializing back writes the reference rather than the URL\n // it happens to resolve to right now. Without this the author would\n // be editing next to a broken-image icon while the published page\n // rendered correctly.\n // eslint-disable-next-line @next/next/no-img-element\n <img src={resolveMediaSrc(row.src)} alt={row.alt} />\n ) : row.kind === 'code' ? (\n <Box\n sx={{\n borderRadius: 1,\n border: '1px solid',\n borderColor: 'divider',\n bgcolor: 'action.hover',\n overflow: 'hidden',\n '&:focus-within': { borderColor: 'primary.main' },\n }}\n >\n <Box\n component=\"textarea\"\n spellCheck={false}\n defaultValue={row.text}\n placeholder=\"Your snippet…\"\n rows={Math.max(2, row.text.split('\\n').length)}\n onChange={(event: React.ChangeEvent<HTMLTextAreaElement>) => {\n const text = event.target.value\n // Grow with the snippet rather than scrolling a 2-row box.\n event.target.style.height = 'auto'\n event.target.style.height = `${event.target.scrollHeight}px`\n onEditSilently((current) =>\n current.kind === 'code' ? { ...current, text } : current,\n )\n }}\n sx={{\n display: 'block',\n width: '100%',\n border: 0,\n outline: 'none',\n resize: 'vertical',\n p: 1.5,\n bgcolor: 'transparent',\n color: 'text.primary',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.6,\n }}\n />\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n px: 1,\n py: 0.5,\n borderTop: '1px solid',\n borderColor: 'divider',\n }}\n >\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Language'}\n </Typography>\n <Box\n component=\"select\"\n defaultValue={row.lang}\n onChange={(event: React.ChangeEvent<HTMLSelectElement>) => {\n const lang = event.target.value\n onEditSilently((current) =>\n current.kind === 'code' ? { ...current, lang } : current,\n )\n }}\n sx={{\n border: 0,\n bgcolor: 'transparent',\n color: 'text.secondary',\n font: 'inherit',\n fontSize: 12,\n outline: 'none',\n }}\n >\n {CODE_LANGUAGES.map((lang) => (\n <option key={lang} value={lang}>\n {lang || 'plain'}\n </option>\n ))}\n </Box>\n </Box>\n </Box>\n ) : table ? (\n <Box sx={{ overflowX: 'auto' }}>\n <Box\n component=\"table\"\n sx={{\n borderCollapse: 'collapse',\n width: '100%',\n fontSize: 14,\n '& th, & td': {\n border: '1px solid',\n borderColor: 'divider',\n px: 1,\n py: 0.5,\n minWidth: 64,\n },\n '& th': { bgcolor: 'action.hover' },\n '& [contenteditable]': { outline: 'none' },\n '& [contenteditable]:focus': {\n boxShadow: (theme) => `inset 0 0 0 2px ${theme.palette.primary.main}`,\n },\n }}\n >\n <thead>\n <tr>\n {table.header.map((_cell, index) => (\n <th key={index} {...cellProps(-1, index)}>\n {frozenHeader[index]}\n </th>\n ))}\n {/* Column controls live in a trailing spacer column so they\n never sit inside a cell the caret can enter. */}\n <Box\n component=\"th\"\n data-md-block-controls=\"\"\n sx={{\n border: '0 !important',\n bgcolor: 'transparent !important',\n opacity: 0,\n transition: 'opacity 120ms',\n whiteSpace: 'nowrap',\n }}\n >\n <Button\n size=\"small\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() =>\n onEdit((current) =>\n current.kind === 'table'\n ? {\n ...current,\n align: [...current.align, 'left'],\n header: [...current.header, []],\n rows: current.rows.map((cells) => [...cells, []]),\n }\n : current,\n )\n }\n >\n {'+ Column'}\n </Button>\n {columns > 1 ? (\n <Button\n size=\"small\"\n color=\"error\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() =>\n onEdit((current) =>\n current.kind === 'table'\n ? {\n ...current,\n align: current.align.slice(0, -1),\n header: current.header.slice(0, -1),\n rows: current.rows.map((cells) =>\n cells.slice(0, -1),\n ),\n }\n : current,\n )\n }\n >\n {'− Column'}\n </Button>\n ) : null}\n </Box>\n </tr>\n {/* Per-column alignment, on the same axis as the column. */}\n <Box\n component=\"tr\"\n data-md-block-controls=\"\"\n sx={{ opacity: 0, transition: 'opacity 120ms' }}\n >\n {table.align.map((align, index) => (\n <Box\n component=\"td\"\n key={index}\n sx={{\n border: '0 !important',\n p: '0 !important',\n textAlign: 'center',\n }}\n >\n <ToggleButtonGroup\n exclusive\n size=\"small\"\n value={align}\n onChange={(_event, next) => {\n if (!next) return\n onEdit((current) =>\n current.kind === 'table'\n ? {\n ...current,\n align: current.align.map((entry, i) =>\n i === index\n ? (next as Aglyn.MarkdownTableAlign)\n : entry,\n ),\n }\n : current,\n )\n }}\n sx={{ '& .MuiToggleButton-root': { px: 0.75, py: 0, border: 0 } }}\n >\n <ToggleButton value=\"left\" aria-label=\"Align left\">\n <FormatAlignLeftIcon fontSize=\"inherit\" />\n </ToggleButton>\n <ToggleButton value=\"center\" aria-label=\"Align center\">\n <FormatAlignCenterIcon fontSize=\"inherit\" />\n </ToggleButton>\n <ToggleButton value=\"right\" aria-label=\"Align right\">\n <FormatAlignRightIcon fontSize=\"inherit\" />\n </ToggleButton>\n </ToggleButtonGroup>\n </Box>\n ))}\n <Box component=\"td\" sx={{ border: '0 !important' }} />\n </Box>\n </thead>\n <tbody>\n {table.rows.map((cells, rowIndex) => (\n <tr key={rowIndex}>\n {cells.map((_cell, index) => (\n <td key={index} {...cellProps(rowIndex, index)}>\n {frozenRows[rowIndex]?.[index]}\n </td>\n ))}\n <Box\n component=\"td\"\n data-md-block-controls=\"\"\n sx={{\n border: '0 !important',\n bgcolor: 'transparent !important',\n opacity: 0,\n transition: 'opacity 120ms',\n }}\n >\n <Button\n size=\"small\"\n color=\"error\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() =>\n onEdit((current) =>\n current.kind === 'table'\n ? {\n ...current,\n rows: current.rows.filter(\n (_cells, index) => index !== rowIndex,\n ),\n }\n : current,\n )\n }\n >\n {'Delete row'}\n </Button>\n </Box>\n </tr>\n ))}\n <tr>\n <Box\n component=\"td\"\n colSpan={columns + 1}\n data-md-block-controls=\"\"\n sx={{\n border: '0 !important',\n opacity: 0,\n transition: 'opacity 120ms',\n }}\n >\n <Button\n size=\"small\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() =>\n onEdit((current) =>\n current.kind === 'table'\n ? {\n ...current,\n rows: [\n ...current.rows,\n current.header.map(() => []),\n ],\n }\n : current,\n )\n }\n >\n {'+ Row'}\n </Button>\n </Box>\n </tr>\n </tbody>\n </Box>\n </Box>\n ) : null}\n <Button\n size=\"small\"\n color=\"error\"\n variant=\"contained\"\n data-md-block-controls=\"\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={onRemove}\n sx={{\n position: 'absolute',\n top: 8,\n right: 8,\n opacity: 0,\n transition: 'opacity 120ms',\n }}\n >\n {'Remove'}\n </Button>\n </Box>\n )\n})\n\ntype SelectionSnapshot = { key: string; start: number; end: number }\ntype HistoryEntry = { rows: EditorRow[]; selection: SelectionSnapshot | null }\n\nconst cloneRows = (rows: EditorRow[]): EditorRow[] =>\n rows.map((row) =>\n isTextRow(row)\n ? { ...row, inlines: row.inlines.map((inline) => ({ ...inline })) }\n : // Block rows are never edited in place, so a shallow copy is a\n // faithful history snapshot.\n { ...row },\n )\n\nconst HISTORY_LIMIT = 100\n\n/**\n * What the editor accepts is exactly what the PARSER keeps (AGL-1686).\n *\n * These were hand-rolled copies of the parser's rules, and the copy is what\n * broke: AGL-1645 widened the image rule here to accept the site-relative\n * `/api/media/cdn/{scope}/{id}` the media library hands back, while\n * `markdown-lite`'s image rule stayed absolute-`http(s)`-only. The insert\n * worked, serialized, saved — and the parser then dropped the block on the way\n * back out, so the image was gone from the document, the preview and the\n * published page with nothing logged anywhere.\n *\n * Delegating means the two can no longer disagree. Both still refuse\n * protocol-relative `//host`, which would silently leave the site; images\n * additionally accept a well-formed `media:` reference (AGL-1215), which is\n * now what the media picker inserts.\n */\nconst isValidLinkUrl = (url: string): boolean => isSupportedLinkHref(url)\nconst isValidImageUrl = (url: string): boolean => isSupportedImageSrc(url)\n\n/** The Insert image dialog. */\ninterface UrlDialogState {\n kind: 'image'\n url: string\n text: string\n}\n\n/**\n * The link dialog (AGL-3119): inserting over the selection, or editing an\n * existing link's target from the popover.\n */\ninterface LinkDialogState {\n /** The selection's text, offered as the link text when inserting. */\n text: string\n /** Set when editing: the link's current target. */\n href?: string\n editRowKey?: string\n editLinkIndex?: number\n}\n\n/** The clicked link, and what the popover over it acts on. */\ninterface LinkPopoverState {\n anchor: HTMLElement\n rowKey: string\n linkIndex: number\n href: string\n}\n\nconst MarkdownVisualEditor = forwardRef<\n MarkdownVisualEditorHandle,\n MarkdownVisualEditorProps\n>(function MarkdownVisualEditor(\n {\n value,\n onChange,\n onPickImageFromMedia,\n onContextChange,\n minHeight = 280,\n maxHeight = 480,\n },\n ref,\n) {\n const [version, setVersion] = useState(0)\n const rowsRef = useRef<EditorRow[] | null>(null)\n if (rowsRef.current == null) rowsRef.current = markdownToRows(value)\n const rootRef = useRef<HTMLDivElement | null>(null)\n const lastEmittedRef = useRef<string>(value)\n const pendingSelectionRef = useRef<SelectionSnapshot | null>(null)\n const lastSelectionRef = useRef<SelectionSnapshot | null>(null)\n const historyRef = useRef<{ past: HistoryEntry[]; future: HistoryEntry[] }>({\n past: [],\n future: [],\n })\n const typingBatchRef = useRef(false)\n const typingTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const dialogTargetRef = useRef<{\n index: number\n start: number\n end: number\n } | null>(null)\n const [urlDialog, setUrlDialog] = useState<UrlDialogState | null>(null)\n const [linkDialog, setLinkDialog] = useState<LinkDialogState | null>(null)\n const [linkPopover, setLinkPopover] = useState<LinkPopoverState | null>(null)\n const [placeholderVisible, setPlaceholderVisible] = useState(\n () => rowsToMarkdown(rowsRef.current ?? []).length === 0,\n )\n\n const rows = rowsRef.current ?? []\n\n const emitChange = useCallback(() => {\n const markdown = rowsToMarkdown(rowsRef.current ?? [])\n lastEmittedRef.current = markdown\n setPlaceholderVisible(markdown.length === 0)\n onChange(markdown)\n }, [onChange])\n\n // External updates (tab remount, AI assist rewriting the body): re-parse\n // unless the incoming value is the one this editor just emitted.\n useEffect(() => {\n if (value === lastEmittedRef.current) return\n rowsRef.current = markdownToRows(value)\n lastEmittedRef.current = value\n historyRef.current = { past: [], future: [] }\n pendingSelectionRef.current = null\n lastSelectionRef.current = null\n typingBatchRef.current = false\n setPlaceholderVisible(rowsToMarkdown(rowsRef.current).length === 0)\n setVersion((current) => current + 1)\n }, [value])\n\n const pushHistory = useCallback(() => {\n const { past } = historyRef.current\n past.push({\n rows: cloneRows(rowsRef.current ?? []),\n selection: lastSelectionRef.current,\n })\n if (past.length > HISTORY_LIMIT) past.shift()\n historyRef.current.future = []\n }, [])\n\n /** Re-renders every row from the model and restores the selection. */\n const commit = useCallback(\n (selection: SelectionSnapshot | null) => {\n pendingSelectionRef.current = selection\n if (selection) lastSelectionRef.current = selection\n typingBatchRef.current = false\n setVersion((current) => current + 1)\n emitChange()\n },\n [emitChange],\n )\n\n useLayoutEffect(() => {\n const pending = pendingSelectionRef.current\n if (!pending) return\n pendingSelectionRef.current = null\n const rowEl = rootRef.current?.querySelector<HTMLElement>(\n `[data-row-key=\"${pending.key}\"]`,\n )\n // Block rows (image / code / table) have no caret to restore. The\n // attribute, not `isContentEditable` — jsdom does not compute the latter.\n if (!rowEl || rowEl.getAttribute('contenteditable') !== 'true') return\n rowEl.focus()\n setSelectionIn(rowEl, pending.start, pending.end)\n }, [version])\n\n const findRowIndex = useCallback(\n (key: string): number =>\n (rowsRef.current ?? []).findIndex((row) => row.key === key),\n [],\n )\n\n /** Records the current DOM selection in model coordinates. */\n const captureSelection = useCallback((): SelectionSnapshot | null => {\n const root = rootRef.current\n const selection =\n root?.ownerDocument.defaultView?.getSelection?.() ?? null\n if (!root || !selection || selection.rangeCount === 0) {\n return lastSelectionRef.current\n }\n const range = selection.getRangeAt(0)\n const rowOf = (node: Node): HTMLElement | null => {\n const el =\n node instanceof HTMLElement ? node : node.parentElement ?? null\n const rowEl = el?.closest<HTMLElement>('[data-row-key]') ?? null\n return rowEl && root.contains(rowEl) ? rowEl : null\n }\n const startRow = rowOf(range.startContainer)\n const endRow = rowOf(range.endContainer)\n // Cross-row selections are out of scope for phase 1 — keep last known.\n if (!startRow || startRow !== endRow) return lastSelectionRef.current\n const key = startRow.dataset['rowKey']\n if (!key) return lastSelectionRef.current\n const offsets = selectionOffsetsWithin(startRow)\n if (!offsets) return lastSelectionRef.current\n const snapshot = { key, ...offsets }\n lastSelectionRef.current = snapshot\n return snapshot\n }, [])\n\n /**\n * Publishes the caret's formatting context (AGL-984). A collapsed caret\n * reports the mark of the character BEHIND it — the same character the\n * next keystroke would extend. Deduped, so a toolbar re-renders only when\n * something it draws actually changed.\n */\n const contextKeyRef = useRef('')\n const onContextChangeRef = useRef(onContextChange)\n onContextChangeRef.current = onContextChange\n const reportContext = useCallback(() => {\n const notify = onContextChangeRef.current\n if (!notify) return\n const selection = lastSelectionRef.current\n const rows = rowsRef.current ?? []\n const row = selection\n ? rows.find((entry) => entry.key === selection.key)\n : undefined\n let context: MarkdownEditorContext = {\n bold: false,\n italic: false,\n kind: null,\n }\n if (selection && row && isTextRow(row)) {\n const from =\n selection.start === selection.end\n ? Math.max(0, selection.start - 1)\n : selection.start\n const covered = sliceInlines(row.inlines, from, selection.end)\n context = {\n bold:\n covered.length > 0 &&\n covered.every((inline) => inline.type === 'bold'),\n italic:\n covered.length > 0 &&\n covered.every((inline) => inline.type === 'italic'),\n kind: row.kind,\n }\n }\n const key = `${context.bold}:${context.italic}:${context.kind}`\n if (key === contextKeyRef.current) return\n contextKeyRef.current = key\n notify(context)\n }, [])\n\n const handleSelectionPing = useCallback(() => {\n captureSelection()\n reportContext()\n }, [captureSelection, reportContext])\n\n // A structural edit moves the caret without a ping of its own.\n useEffect(() => {\n reportContext()\n }, [version, reportContext])\n\n const undo = useCallback(() => {\n const { past, future } = historyRef.current\n const entry = past.pop()\n if (!entry) return\n future.push({\n rows: cloneRows(rowsRef.current ?? []),\n selection: lastSelectionRef.current,\n })\n rowsRef.current = cloneRows(entry.rows)\n typingBatchRef.current = false\n pendingSelectionRef.current = entry.selection\n setVersion((current) => current + 1)\n emitChange()\n }, [emitChange])\n\n const redo = useCallback(() => {\n const { past, future } = historyRef.current\n const entry = future.pop()\n if (!entry) return\n past.push({\n rows: cloneRows(rowsRef.current ?? []),\n selection: lastSelectionRef.current,\n })\n rowsRef.current = cloneRows(entry.rows)\n typingBatchRef.current = false\n pendingSelectionRef.current = entry.selection\n setVersion((current) => current + 1)\n emitChange()\n }, [emitChange])\n\n /** Resolves where a toolbar command applies: selection or document end. */\n const resolveTarget = useCallback((): {\n index: number\n start: number\n end: number\n } | null => {\n const current = rowsRef.current ?? []\n const selection = captureSelection()\n if (selection) {\n const index = current.findIndex((row) => row.key === selection.key)\n const row = current[index]\n if (index >= 0 && row && isTextRow(row)) {\n return { index, start: selection.start, end: selection.end }\n }\n }\n for (let index = current.length - 1; index >= 0; index--) {\n const row = current[index]\n if (row && isTextRow(row)) {\n const length = rowPlainText(row.inlines).length\n return { index, start: length, end: length }\n }\n }\n return null\n }, [captureSelection])\n\n /** Splices a block row in after `afterIndex` (end of document if null). */\n const insertBlockRow = useCallback(\n (block: NewBlockRow, afterIndex: number | null) => {\n const current = rowsRef.current ?? []\n pushHistory()\n const index = afterIndex == null ? current.length : afterIndex + 1\n current.splice(index, 0, { key: nextRowKey(), ...block } as BlockRow)\n // Keep a caret landing spot after a trailing block.\n if (index === current.length - 1) current.push(emptyParagraph())\n const next = current[index + 1]\n commit(next && isTextRow(next) ? { key: next.key, start: 0, end: 0 } : null)\n },\n [commit, pushHistory],\n )\n\n const insertImageRow = useCallback(\n (alt: string, url: string, afterIndex: number | null) => {\n if (!isValidImageUrl(url)) return\n insertBlockRow({ kind: 'image', src: url, alt }, afterIndex)\n },\n [insertBlockRow],\n )\n\n /** Edits one block row in place; `silent` skips the re-render (AGL-983). */\n const editBlockRow = useCallback(\n (key: string, mutate: (row: BlockRow) => BlockRow, silent: boolean) => {\n const current = rowsRef.current ?? []\n const index = findRowIndex(key)\n const row = current[index]\n if (!row || isTextRow(row)) return\n // Typing in a cell or a snippet batches its history the same way\n // typing in a paragraph does: one undo step per burst, not per key.\n if (silent) {\n if (!typingBatchRef.current) {\n pushHistory()\n typingBatchRef.current = true\n }\n if (typingTimerRef.current) clearTimeout(typingTimerRef.current)\n typingTimerRef.current = setTimeout(() => {\n typingBatchRef.current = false\n }, 800)\n } else {\n pushHistory()\n }\n current[index] = mutate(row)\n if (silent) emitChange()\n else commit(null)\n },\n [commit, emitChange, findRowIndex, pushHistory],\n )\n\n const execCommand = useCallback(\n (command: MarkdownEditorCommand) => {\n const current = rowsRef.current ?? []\n const target = resolveTarget()\n if (command === 'image') {\n // URL prompt dialog; when the host page wires\n // `onPickImageFromMedia` it also offers the media picker (AGL-596).\n dialogTargetRef.current = target\n setUrlDialog({ kind: 'image', url: '', text: '' })\n return\n }\n // Block inserts (AGL-983) land after the caret row, like an image.\n if (command === 'code') {\n insertBlockRow({ kind: 'code', lang: '', text: '' }, target?.index ?? null)\n return\n }\n if (command === 'table') {\n const empty = (): Aglyn.MarkdownTableCell[] => [[], []]\n insertBlockRow(\n {\n kind: 'table',\n align: ['left', 'left'],\n header: empty(),\n rows: [empty(), empty()],\n },\n target?.index ?? null,\n )\n return\n }\n if (!target) return\n const row = current[target.index] as TextRow\n // Block-kind toggles: pressing the row's own kind returns it to prose.\n const toggleKind = (kind: TextRowKind) => {\n pushHistory()\n current[target.index] = {\n ...row,\n kind: row.kind === kind ? 'paragraph' : kind,\n }\n commit({ key: row.key, start: target.start, end: target.end })\n }\n if (command === 'heading') return toggleKind('heading2')\n if (command === 'heading3') return toggleKind('heading3')\n if (command === 'list') return toggleKind('listItem')\n if (command === 'orderedList') return toggleKind('orderedItem')\n if (command === 'quote') return toggleKind('quote')\n if (command === 'link') {\n dialogTargetRef.current = target\n setLinkDialog({\n text: rowPlainText(\n sliceInlines(row.inlines, target.start, target.end),\n ),\n })\n return\n }\n pushHistory()\n if (target.start === target.end) {\n const placeholder = command === 'bold' ? 'bold text' : 'italic text'\n current[target.index] = {\n ...row,\n inlines: replaceInlineRange(row.inlines, target.start, target.end, [\n { type: command, text: placeholder },\n ]),\n }\n commit({\n key: row.key,\n start: target.start,\n end: target.start + placeholder.length,\n })\n return\n }\n const toggled = toggleInlineMark(\n row.inlines,\n target.start,\n target.end,\n command,\n )\n current[target.index] = { ...row, inlines: toggled.inlines }\n commit({\n key: row.key,\n start: target.start,\n end: target.start + toggled.length,\n })\n },\n [commit, insertBlockRow, pushHistory, resolveTarget],\n )\n\n useImperativeHandle(\n ref,\n () => ({\n exec: execCommand,\n insertImage: (alt: string, url: string) => {\n const selection = lastSelectionRef.current\n const index = selection ? findRowIndex(selection.key) : -1\n insertImageRow(alt, url, index >= 0 ? index : null)\n },\n }),\n [execCommand, findRowIndex, insertImageRow],\n )\n\n const handleRowInput = useCallback(\n (key: string) => (event: React.FormEvent<HTMLDivElement>) => {\n const current = rowsRef.current ?? []\n const index = findRowIndex(key)\n const row = current[index]\n if (!row || !isTextRow(row)) return\n const rowEl = event.currentTarget\n // Snapshot the pre-typing model once per typing burst so undo jumps\n // back over the whole burst, not one character at a time.\n if (!typingBatchRef.current) {\n pushHistory()\n typingBatchRef.current = true\n }\n if (typingTimerRef.current) clearTimeout(typingTimerRef.current)\n typingTimerRef.current = setTimeout(() => {\n typingBatchRef.current = false\n }, 800)\n const inlines = readInlinesFromElement(rowEl)\n const text = rowPlainText(inlines)\n // Markdown shortcuts (AGL-582): \"## \" / \"### \" / \"- \" at the start\n // of a paragraph convert it to a heading or list item. \"# \" joins them\n // (AGL-1082) so typing a heading agrees with pasting one — the parser\n // clamps a single `#` to the top rendered level too. \"1. \" / \"1) \"\n // opens a numbered list at the number that was typed (AGL-1320).\n if (row.kind === 'paragraph') {\n const numbered = /^(\\d{1,9})[.)] /.exec(text)\n const shortcut = text.startsWith('### ')\n ? { kind: 'heading3' as const, trim: 4 }\n : text.startsWith('## ')\n ? { kind: 'heading2' as const, trim: 3 }\n : text.startsWith('# ')\n ? { kind: 'heading2' as const, trim: 2 }\n : text.startsWith('- ')\n ? { kind: 'listItem' as const, trim: 2 }\n : text.startsWith('> ')\n ? { kind: 'quote' as const, trim: 2 }\n : numbered\n ? {\n kind: 'orderedItem' as const,\n trim: numbered[0].length,\n start: Number(numbered[1]),\n }\n : null\n if (shortcut) {\n const caret =\n selectionOffsetsWithin(rowEl)?.start ?? text.length\n const offset = Math.max(0, caret - shortcut.trim)\n current[index] = {\n key: row.key,\n kind: shortcut.kind,\n inlines: sliceInlines(inlines, shortcut.trim, Infinity),\n ...('start' in shortcut ? { start: shortcut.start } : {}),\n }\n commit({ key: row.key, start: offset, end: offset })\n return\n }\n }\n // Plain typing: sync the model silently — no re-render, the DOM is\n // already correct and the caret must not move.\n current[index] = { ...row, inlines }\n emitChange()\n },\n [commit, emitChange, findRowIndex, pushHistory],\n )\n\n const focusAdjacentRow = useCallback(\n (fromIndex: number, direction: 1 | -1, preferredOffset: number) => {\n const current = rowsRef.current ?? []\n for (\n let index = fromIndex + direction;\n index >= 0 && index < current.length;\n index += direction\n ) {\n const row = current[index]\n if (!row || !isTextRow(row)) continue\n const rowEl = rootRef.current?.querySelector<HTMLElement>(\n `[data-row-key=\"${row.key}\"]`,\n )\n if (!rowEl) return\n const length = rowPlainText(row.inlines).length\n const offset = Math.min(Math.max(preferredOffset, 0), length)\n rowEl.focus()\n setSelectionIn(rowEl, offset, offset)\n captureSelection()\n return\n }\n },\n [captureSelection],\n )\n\n const handleRowKeyDown = useCallback(\n (key: string) => (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.nativeEvent.isComposing) return\n const current = rowsRef.current ?? []\n const index = findRowIndex(key)\n const row = current[index]\n if (!row || !isTextRow(row)) return\n const rowEl = event.currentTarget\n\n if (event.key === 'Enter') {\n event.preventDefault()\n const inlines = readInlinesFromElement(rowEl)\n const length = rowPlainText(inlines).length\n const offsets = selectionOffsetsWithin(rowEl) ?? {\n start: length,\n end: length,\n }\n current[index] = { ...row, inlines } as EditorRow\n pushHistory()\n // Enter on an empty list item exits the list into a paragraph.\n if (\n (row.kind === 'listItem' || row.kind === 'orderedItem') &&\n length === 0\n ) {\n current[index] = { key: row.key, kind: 'paragraph', inlines: [] }\n commit({ key: row.key, start: 0, end: 0 })\n return\n }\n const before = sliceInlines(inlines, 0, offsets.start)\n const after = sliceInlines(inlines, offsets.end, Infinity)\n // Splitting a heading leaves prose behind; lists continue as items.\n // The continuation deliberately carries NO `start` (AGL-1320) — only\n // the row that opens a run numbers it.\n const nextKind: TextRowKind =\n row.kind === 'listItem' || row.kind === 'orderedItem'\n ? row.kind\n : 'paragraph'\n const newRow: TextRow = {\n key: nextRowKey(),\n kind: nextKind,\n inlines: after,\n }\n current[index] = { ...row, inlines: before } as EditorRow\n current.splice(index + 1, 0, newRow)\n commit({ key: newRow.key, start: 0, end: 0 })\n return\n }\n\n if (event.key === 'Backspace') {\n const offsets = selectionOffsetsWithin(rowEl)\n if (!offsets || offsets.start !== 0 || offsets.end !== 0) return\n event.preventDefault()\n const inlines = readInlinesFromElement(rowEl)\n current[index] = { ...row, inlines } as EditorRow\n // Backspace at the start of a heading/list item demotes it first.\n if (row.kind !== 'paragraph') {\n pushHistory()\n current[index] = { key: row.key, kind: 'paragraph', inlines }\n commit({ key: row.key, start: 0, end: 0 })\n return\n }\n if (index === 0) return\n const previous = current[index - 1]\n if (!previous) return\n pushHistory()\n if (!isTextRow(previous)) {\n current.splice(index - 1, 1)\n commit({ key: row.key, start: 0, end: 0 })\n return\n }\n const junction = rowPlainText(previous.inlines).length\n current[index - 1] = {\n ...previous,\n inlines: normalizeInlines([...previous.inlines, ...inlines]),\n } as EditorRow\n current.splice(index, 1)\n commit({ key: previous.key, start: junction, end: junction })\n return\n }\n\n // Caret hops across row boundaries (separate contentEditables).\n if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey) {\n return\n }\n if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {\n const offsets = selectionOffsetsWithin(rowEl)\n if (!offsets || offsets.start !== offsets.end) return\n const length = rowPlainText(readInlinesFromElement(rowEl)).length\n if (event.key === 'ArrowLeft' && offsets.start === 0) {\n event.preventDefault()\n focusAdjacentRow(index, -1, Infinity)\n } else if (event.key === 'ArrowRight' && offsets.start >= length) {\n event.preventDefault()\n focusAdjacentRow(index, 1, 0)\n }\n return\n }\n if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {\n const before = selectionOffsetsWithin(rowEl)\n if (!before) return\n const direction = event.key === 'ArrowDown' ? 1 : -1\n // If the browser can't move within the row (first/last line), the\n // selection stays put — hop to the adjacent row instead.\n setTimeout(() => {\n const after = selectionOffsetsWithin(rowEl)\n if (!after) return\n if (after.start !== before.start || after.end !== before.end) return\n focusAdjacentRow(index, direction as 1 | -1, before.start)\n }, 0)\n }\n },\n [commit, findRowIndex, focusAdjacentRow, pushHistory],\n )\n\n const handleRowPaste = useCallback(\n (key: string) => (event: React.ClipboardEvent<HTMLDivElement>) => {\n event.preventDefault()\n const current = rowsRef.current ?? []\n const index = findRowIndex(key)\n const row = current[index]\n if (!row || !isTextRow(row)) return\n const rowEl = event.currentTarget\n const inlines = readInlinesFromElement(rowEl)\n const length = rowPlainText(inlines).length\n const offsets = selectionOffsetsWithin(rowEl) ?? {\n start: length,\n end: length,\n }\n // Rich clipboard first (AGL-596): text/html converts to rows so\n // bold/italic/links, headings, lists and images survive the paste.\n const html = event.clipboardData?.getData('text/html') ?? ''\n if (html) {\n // Re-key onto this editor's sequence — converted keys are\n // module-local placeholders and must not collide across pastes.\n const converted = htmlToRows(html).map(\n (pasted) => ({ ...pasted, key: nextRowKey() }) as EditorRow,\n )\n const only = converted.length === 1 ? converted[0] : undefined\n if (only && isTextRow(only)) {\n // One text row: merge its inlines into this row at the caret,\n // exactly like a plain-text paste but keeping the marks.\n current[index] = { ...row, inlines } as EditorRow\n pushHistory()\n current[index] = {\n ...row,\n inlines: replaceInlineRange(\n inlines,\n offsets.start,\n offsets.end,\n only.inlines,\n ),\n } as EditorRow\n const caret = offsets.start + rowPlainText(only.inlines).length\n commit({ key: row.key, start: caret, end: caret })\n return\n }\n if (converted.length > 0) {\n // Multi-row (or image) paste: splice whole rows in after this\n // one — no splitting of the current row.\n current[index] = { ...row, inlines } as EditorRow\n pushHistory()\n const tail = converted[converted.length - 1]\n if (tail && !isTextRow(tail)) converted.push(emptyParagraph())\n current.splice(index + 1, 0, ...converted)\n const focus = converted[converted.length - 1]\n if (focus && isTextRow(focus)) {\n const end = rowPlainText(focus.inlines).length\n commit({ key: focus.key, start: end, end })\n } else {\n commit(null)\n }\n return\n }\n // Nothing usable in the HTML — fall through to text/plain.\n }\n const text = event.clipboardData?.getData('text/plain') ?? ''\n if (!text) return\n const flattened = text.replace(/\\s*\\n+\\s*/g, ' ')\n current[index] = { ...row, inlines } as EditorRow\n pushHistory()\n current[index] = {\n ...row,\n inlines: replaceInlineRange(inlines, offsets.start, offsets.end, [\n { type: 'text', text: flattened },\n ]),\n } as EditorRow\n const caret = offsets.start + flattened.length\n commit({ key: row.key, start: caret, end: caret })\n },\n [commit, findRowIndex, pushHistory],\n )\n\n const handleRowClick = useCallback(\n (key: string) => (event: React.MouseEvent<HTMLDivElement>) => {\n const target = (event.target as HTMLElement).closest?.(\n '[data-md-link]',\n ) as HTMLElement | null\n if (target && event.currentTarget.contains(target)) {\n const links = Array.from(\n event.currentTarget.querySelectorAll('[data-md-link]'),\n )\n setLinkPopover({\n anchor: target,\n rowKey: key,\n linkIndex: links.indexOf(target),\n href: target.getAttribute('data-md-href') ?? '',\n })\n }\n captureSelection()\n },\n [captureSelection],\n )\n\n /** Nth link inline of a row (document order matches inline order). */\n const findLinkInline = useCallback(\n (rowKey: string, linkIndex: number) => {\n const index = findRowIndex(rowKey)\n const row = (rowsRef.current ?? [])[index]\n if (!row || !isTextRow(row)) return null\n let seen = -1\n for (let i = 0; i < row.inlines.length; i++) {\n const inline = row.inlines[i]\n if (inline?.type === 'link' && ++seen === linkIndex) {\n return { rowIndex: index, row, inlineIndex: i, inline }\n }\n }\n return null\n },\n [findRowIndex],\n )\n\n const handleLinkRemove = useCallback(() => {\n if (!linkPopover) return\n const found = findLinkInline(linkPopover.rowKey, linkPopover.linkIndex)\n setLinkPopover(null)\n if (!found) return\n pushHistory()\n const inlines = [...found.row.inlines]\n inlines[found.inlineIndex] = { type: 'text', text: found.inline.text }\n const current = rowsRef.current ?? []\n current[found.rowIndex] = {\n ...found.row,\n inlines: normalizeInlines(inlines),\n } as EditorRow\n commit(null)\n }, [commit, findLinkInline, linkPopover, pushHistory])\n\n const handleLinkEdit = useCallback(() => {\n if (!linkPopover) return\n setLinkDialog({\n href: linkPopover.href,\n text: '',\n editRowKey: linkPopover.rowKey,\n editLinkIndex: linkPopover.linkIndex,\n })\n setLinkPopover(null)\n }, [linkPopover])\n\n const handleUrlDialogConfirm = useCallback(() => {\n if (!urlDialog) return\n const url = urlDialog.url.trim()\n if (!isValidImageUrl(url)) return\n const target = dialogTargetRef.current\n setUrlDialog(null)\n insertImageRow(urlDialog.text.trim(), url, target ? target.index : null)\n }, [insertImageRow, urlDialog])\n\n /**\n * The link dialog's answer: a URL as typed, or a reference the dialog's\n * lookup produced (AGL-3119). Both are `href` on the same inline — the\n * dialect keeps either, and the renderer resolves the reference.\n */\n const handleLinkConfirm = useCallback(\n (link: MarkdownLink) => {\n if (!linkDialog) return\n const href = link.href.trim()\n if (!isValidLinkUrl(href)) return\n const current = rowsRef.current ?? []\n if (linkDialog.editRowKey != null && linkDialog.editLinkIndex != null) {\n const found = findLinkInline(\n linkDialog.editRowKey,\n linkDialog.editLinkIndex,\n )\n setLinkDialog(null)\n if (!found) return\n pushHistory()\n const inlines = [...found.row.inlines]\n inlines[found.inlineIndex] = {\n type: 'link',\n text: found.inline.text,\n href,\n }\n current[found.rowIndex] = { ...found.row, inlines } as EditorRow\n commit(null)\n return\n }\n const target = dialogTargetRef.current\n setLinkDialog(null)\n if (!target) return\n const row = current[target.index]\n if (!row || !isTextRow(row)) return\n pushHistory()\n const text = link.text.trim() || href\n current[target.index] = {\n ...row,\n inlines: replaceInlineRange(row.inlines, target.start, target.end, [\n { type: 'link', text, href },\n ]),\n } as EditorRow\n commit({\n key: row.key,\n start: target.start,\n end: target.start + text.length,\n })\n },\n [commit, findLinkInline, linkDialog, pushHistory],\n )\n\n const handleBlockRemove = useCallback(\n (key: string) => () => {\n const current = rowsRef.current ?? []\n const index = findRowIndex(key)\n if (index < 0) return\n pushHistory()\n current.splice(index, 1)\n if (current.length === 0) current.push(emptyParagraph())\n commit(null)\n },\n [commit, findRowIndex, pushHistory],\n )\n\n const handleRootKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.defaultPrevented) return\n const key = event.key.toLowerCase()\n if ((event.metaKey || event.ctrlKey) && !event.altKey) {\n if (key === 'z') {\n // Model-driven rendering breaks native contentEditable undo, so\n // the editor keeps its own snapshot stack (AGL-582).\n event.preventDefault()\n if (event.shiftKey) redo()\n else undo()\n return\n }\n if (key === 'y' && event.ctrlKey && !event.shiftKey) {\n event.preventDefault()\n redo()\n return\n }\n if (event.shiftKey) return\n if (key === 'b') {\n event.preventDefault()\n execCommand('bold')\n return\n }\n if (key === 'i') {\n event.preventDefault()\n execCommand('italic')\n }\n }\n },\n [execCommand, redo, undo],\n )\n\n /** Clicking the padding below the last row puts the caret at the end. */\n const handleRootMouseDown = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n if (event.target !== rootRef.current) return\n event.preventDefault()\n const current = rowsRef.current ?? []\n for (let index = current.length - 1; index >= 0; index--) {\n const row = current[index]\n if (!row || !isTextRow(row)) continue\n const rowEl = rootRef.current?.querySelector<HTMLElement>(\n `[data-row-key=\"${row.key}\"]`,\n )\n if (!rowEl) return\n const length = rowPlainText(row.inlines).length\n rowEl.focus()\n setSelectionIn(rowEl, length, length)\n captureSelection()\n return\n }\n },\n [captureSelection],\n )\n\n const urlDialogValid =\n urlDialog != null && isValidImageUrl(urlDialog.url.trim())\n\n return (\n <>\n <Box\n ref={rootRef}\n data-testid=\"markdown-visual-editor\"\n onKeyDown={handleRootKeyDown}\n onMouseDown={handleRootMouseDown}\n // Clicking into a table cell or a snippet is a selection change the\n // text rows never see; the toolbar still has to hear about it.\n onMouseUp={handleSelectionPing}\n onKeyUp={handleSelectionPing}\n sx={{\n position: 'relative',\n border: '1px solid',\n borderColor: 'divider',\n borderRadius: 1,\n px: 2,\n py: 1.5,\n minHeight,\n maxHeight,\n overflow: 'auto',\n cursor: 'text',\n // Seeds the numbered-row counter (AGL-1320) so a document that\n // OPENS with `1. ` has one to increment.\n counterReset: 'md-ordered 0',\n '&:focus-within': { borderColor: 'primary.main' },\n // Typography mirrors the tenant's Entry Body rendering (AGL-551)\n // so the editing surface reads like the published article.\n '& [data-row-kind]': {\n outline: 'none',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n },\n '& [data-row-kind=\"paragraph\"]': {\n typography: 'body1',\n lineHeight: 1.7,\n my: 0.75,\n },\n '& [data-row-kind=\"heading2\"]': { typography: 'h5', mt: 2, mb: 1 },\n '& [data-row-kind=\"heading3\"]': {\n typography: 'h6',\n mt: 1.5,\n mb: 0.75,\n },\n '& [data-row-kind=\"listItem\"]': {\n typography: 'body1',\n lineHeight: 1.7,\n display: 'list-item',\n listStyleType: 'disc',\n ml: 3,\n my: 0.25,\n },\n // Numbered rows (AGL-1320). Rows are siblings, not children of an\n // `<ol>`, so the markers come from an explicit counter rather than\n // `list-style-type: decimal` — the implicit list-item counter is\n // shared with the bullet rows above and would keep counting through\n // them. Every non-ordered row RESETS it, which is what ends a run:\n // a counter-reset scopes to the element and its following siblings.\n // The run's opener additionally seeds it from `start` inline.\n '& [data-row-kind]:not([data-row-kind=\"orderedItem\"])': {\n counterReset: 'md-ordered 0',\n },\n '& [data-row-kind=\"orderedItem\"]': {\n typography: 'body1',\n lineHeight: 1.7,\n counterIncrement: 'md-ordered',\n position: 'relative',\n ml: 3,\n my: 0.25,\n '&::before': {\n content: 'counter(md-ordered) \". \"',\n position: 'absolute',\n right: '100%',\n pr: 0.5,\n color: 'text.secondary',\n },\n },\n // The tenant's pull-quote treatment (AGL-1315), at editor scale.\n '& [data-row-kind=\"quote\"]': {\n typography: 'body1',\n lineHeight: 1.6,\n fontStyle: 'italic',\n borderLeft: '3px solid',\n borderColor: 'primary.main',\n pl: 2,\n my: 1,\n },\n '& [data-md-link]': {\n color: 'primary.main',\n textDecoration: 'underline',\n cursor: 'pointer',\n },\n '& img': { maxWidth: '100%', borderRadius: 1 },\n }}\n >\n {placeholderVisible ? (\n <Typography\n variant=\"body1\"\n color=\"text.disabled\"\n sx={{\n position: 'absolute',\n top: 12,\n left: 16,\n pointerEvents: 'none',\n }}\n >\n {'Start writing…'}\n </Typography>\n ) : null}\n {rows.map((row) =>\n !isTextRow(row) ? (\n <BlockRowView\n // Re-keyed on version so a re-parse (or an undo) rebuilds the\n // block's own editing surfaces from the model.\n key={`${row.key}:${version}`}\n row={row}\n version={version}\n onEdit={(mutate) => editBlockRow(row.key, mutate, false)}\n onEditSilently={(mutate) => editBlockRow(row.key, mutate, true)}\n onRemove={handleBlockRemove(row.key)}\n />\n ) : (\n <TextRowView\n key={row.key}\n row={row}\n version={version}\n onInput={handleRowInput(row.key)}\n onKeyDown={handleRowKeyDown(row.key)}\n onPaste={handleRowPaste(row.key)}\n onClick={handleRowClick(row.key)}\n onSelectionPing={handleSelectionPing}\n />\n ),\n )}\n </Box>\n\n <Popover\n open={Boolean(linkPopover)}\n anchorEl={linkPopover?.anchor ?? null}\n onClose={() => setLinkPopover(null)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n >\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ px: 1.5, py: 1, alignItems: 'center', maxWidth: 420 }}\n >\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n noWrap\n sx={{ maxWidth: 240 }}\n >\n {linkPopover ? (\n <MarkdownLinkTargetName href={linkPopover.href} />\n ) : null}\n </Typography>\n <Button size=\"small\" onClick={handleLinkEdit}>\n {'Edit'}\n </Button>\n <Button size=\"small\" color=\"error\" onClick={handleLinkRemove}>\n {'Remove'}\n </Button>\n </Stack>\n </Popover>\n\n <Dialog\n open={Boolean(urlDialog)}\n onClose={() => setUrlDialog(null)}\n maxWidth=\"xs\"\n fullWidth\n >\n <DialogTitle>{'Insert image'}</DialogTitle>\n <DialogContent\n sx={{ display: 'flex', flexDirection: 'column', gap: 2, pt: 1 }}\n >\n <TextField\n label=\"URL\"\n value={urlDialog?.url ?? ''}\n onChange={(event) =>\n setUrlDialog((prev) =>\n prev ? { ...prev, url: event.target.value } : prev,\n )\n }\n onKeyDown={(event) => {\n if (event.key === 'Enter' && urlDialogValid) {\n event.preventDefault()\n handleUrlDialogConfirm()\n }\n }}\n size=\"small\"\n autoFocus\n sx={{ mt: 1 }}\n helperText=\"https:// or a site path like /images/hero.png\"\n />\n {urlDialog ? (\n <TextField\n label=\"Alt text\"\n value={urlDialog.text}\n onChange={(event) =>\n setUrlDialog((prev) =>\n prev ? { ...prev, text: event.target.value } : prev,\n )\n }\n size=\"small\"\n />\n ) : null}\n </DialogContent>\n <DialogActions>\n {urlDialog && onPickImageFromMedia ? (\n <Button\n color=\"primary\"\n sx={{ mr: 'auto' }}\n onClick={() => {\n // Read the alt BEFORE clearing the dialog (AGL-1645) — the\n // author has already typed it, and the picked image has no\n // other way to acquire one.\n const alt = urlDialog.text.trim()\n setUrlDialog(null)\n onPickImageFromMedia(alt)\n }}\n >\n {'Choose from media'}\n </Button>\n ) : null}\n <Button onClick={() => setUrlDialog(null)}>{'Cancel'}</Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={!urlDialogValid}\n onClick={handleUrlDialogConfirm}\n >\n {'Insert'}\n </Button>\n </DialogActions>\n </Dialog>\n\n {/* Where a link goes (AGL-3119): a page, a listing, a feed or an entry\n picked by name, or an address typed as before. */}\n <MarkdownLinkDialog\n open={Boolean(linkDialog)}\n href={linkDialog?.href}\n text={linkDialog?.text}\n withText={linkDialog?.editRowKey == null}\n onClose={() => setLinkDialog(null)}\n onConfirm={handleLinkConfirm}\n />\n </>\n )\n})\nMarkdownVisualEditor.displayName = 'MarkdownVisualEditor'\n\nexport default MarkdownVisualEditor\n"],"names":["isSupportedImageSrc","isSupportedLinkHref","parseMarkdownLite","resolveMediaSrc","serializeMarkdownLite","Box","Button","Dialog","DialogActions","DialogContent","DialogTitle","Popover","Stack","TextField","ToggleButton","ToggleButtonGroup","Typography","FormatAlignCenterIcon","FormatAlignLeftIcon","FormatAlignRightIcon","forwardRef","memo","useCallback","useEffect","useImperativeHandle","useLayoutEffect","useMemo","useRef","useState","htmlToRows","MarkdownLinkDialog","MarkdownLinkTargetName","isTextRow","row","kind","rowKeySeq","nextRowKey","emptyParagraph","key","inlines","markdownToRows","markdown","rows","block","type","push","level","src","alt","lang","text","align","header","items","forEach","item","index","start","length","rowsToMarkdown","blocks","last","rowPlainText","map","inline","join","normalizeInlines","out","href","sliceInlines","from","to","position","end","Math","max","stop","min","slice","replaceInlineRange","replacement","Infinity","toggleInlineMark","mark","middle","unwrap","every","readInlinesFromElement","rowEl","visit","node","nodeType","Node","TEXT_NODE","textContent","HTMLElement","tagName","dataset","childNodes","textOffsetOf","offset","range","ownerDocument","createRange","selectNodeContents","setEnd","toString","selectionOffsetsWithin","selection","defaultView","getSelection","rangeCount","getRangeAt","contains","startContainer","endContainer","startOffset","endOffset","resolveTextPosition","target","walker","createTreeWalker","NodeFilter","SHOW_TEXT","remaining","nextNode","lastText","setSelectionIn","setStart","removeAllRanges","addRange","renderRowInlines","br","strong","em","span","data-md-link","data-md-href","TextRowView","props","version","onInput","onKeyDown","onPaste","onClick","onSelectionPing","children","contentEditable","suppressContentEditableWarning","spellCheck","data-row-key","data-row-kind","style","counterReset","undefined","onKeyUp","onMouseUp","onFocus","cellFromElement","el","CODE_LANGUAGES","BlockRowView","onEdit","onEditSilently","onRemove","table","columns","frozenHeader","cell","frozenRows","cells","syncCell","rowIndex","cellIndex","current","i","cellProps","event","currentTarget","textAlign","sx","my","opacity","img","borderRadius","border","borderColor","bgcolor","overflow","component","defaultValue","placeholder","split","onChange","value","height","scrollHeight","display","width","outline","resize","p","color","fontFamily","fontSize","lineHeight","alignItems","gap","px","py","borderTop","variant","font","option","overflowX","borderCollapse","minWidth","boxShadow","theme","palette","primary","main","thead","tr","_cell","th","data-md-block-controls","transition","whiteSpace","size","onMouseDown","preventDefault","exclusive","_event","next","entry","aria-label","tbody","td","filter","_cells","colSpan","top","right","cloneRows","HISTORY_LIMIT","isValidLinkUrl","url","isValidImageUrl","MarkdownVisualEditor","onPickImageFromMedia","onContextChange","minHeight","maxHeight","ref","rowsRef","setVersion","rootRef","lastEmittedRef","pendingSelectionRef","lastSelectionRef","historyRef","past","future","typingBatchRef","typingTimerRef","dialogTargetRef","urlDialog","setUrlDialog","linkDialog","setLinkDialog","linkPopover","setLinkPopover","placeholderVisible","setPlaceholderVisible","emitChange","pushHistory","shift","commit","pending","querySelector","getAttribute","focus","findRowIndex","findIndex","captureSelection","root","rowOf","parentElement","closest","startRow","endRow","offsets","snapshot","contextKeyRef","onContextChangeRef","reportContext","notify","find","context","bold","italic","covered","handleSelectionPing","undo","pop","redo","resolveTarget","insertBlockRow","afterIndex","splice","insertImageRow","editBlockRow","mutate","silent","clearTimeout","setTimeout","execCommand","command","empty","toggleKind","toggled","exec","insertImage","handleRowInput","numbered","shortcut","startsWith","trim","Number","caret","focusAdjacentRow","fromIndex","direction","preferredOffset","handleRowKeyDown","nativeEvent","isComposing","before","after","nextKind","newRow","previous","junction","shiftKey","metaKey","ctrlKey","altKey","handleRowPaste","html","clipboardData","getData","converted","pasted","only","tail","flattened","replace","handleRowClick","links","Array","querySelectorAll","anchor","rowKey","linkIndex","indexOf","findLinkInline","seen","inlineIndex","handleLinkRemove","found","handleLinkEdit","editRowKey","editLinkIndex","handleUrlDialogConfirm","handleLinkConfirm","link","handleBlockRemove","handleRootKeyDown","defaultPrevented","toLowerCase","handleRootMouseDown","urlDialogValid","data-testid","cursor","wordBreak","typography","mt","mb","listStyleType","ml","counterIncrement","content","pr","fontStyle","borderLeft","pl","textDecoration","maxWidth","left","pointerEvents","open","Boolean","anchorEl","onClose","anchorOrigin","vertical","horizontal","spacing","noWrap","fullWidth","flexDirection","pt","label","prev","autoFocus","helperText","mr","disabled","withText","onConfirm","displayName"],"mappings":"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"}
|