@k2b/ui 0.34.0 → 0.35.0

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.
Files changed (82) hide show
  1. package/dist/browser/actions/Dropdown.js +1 -0
  2. package/dist/browser/actions/Dropdown.js.map +1 -1
  3. package/dist/browser/content/MatchText.js +61 -0
  4. package/dist/browser/content/MatchText.js.map +1 -0
  5. package/dist/browser/content/index.js +1 -0
  6. package/dist/browser/content/index.js.map +1 -1
  7. package/dist/browser/text-editor/TextEditor.js +1358 -0
  8. package/dist/browser/text-editor/TextEditor.js.map +1 -0
  9. package/dist/browser/text-editor/clipboard-html.js +152 -0
  10. package/dist/browser/text-editor/clipboard-html.js.map +1 -0
  11. package/dist/browser/text-editor/clipboard-loading.js +68 -0
  12. package/dist/browser/text-editor/clipboard-loading.js.map +1 -0
  13. package/dist/browser/text-editor/clipboard.js +51 -0
  14. package/dist/browser/text-editor/clipboard.js.map +1 -0
  15. package/dist/browser/text-editor/engine.js +125 -0
  16. package/dist/browser/text-editor/engine.js.map +1 -0
  17. package/dist/browser/text-editor/format.js +218 -0
  18. package/dist/browser/text-editor/format.js.map +1 -0
  19. package/dist/browser/text-editor/formatted.js +164 -0
  20. package/dist/browser/text-editor/formatted.js.map +1 -0
  21. package/dist/browser/text-editor/language.js +19 -0
  22. package/dist/browser/text-editor/language.js.map +1 -0
  23. package/dist/browser/text-editor/markdown-table.js +563 -0
  24. package/dist/browser/text-editor/markdown-table.js.map +1 -0
  25. package/dist/browser/text-editor/messages.js +233 -0
  26. package/dist/browser/text-editor/messages.js.map +1 -0
  27. package/dist/browser/text-editor/paste.js +115 -0
  28. package/dist/browser/text-editor/paste.js.map +1 -0
  29. package/dist/browser/text-editor/table.js +1760 -0
  30. package/dist/browser/text-editor/table.js.map +1 -0
  31. package/dist/browser/text-editor.js +5 -0
  32. package/dist/browser/text-editor.js.map +1 -0
  33. package/dist/ssr/actions/Dropdown.js +1 -0
  34. package/dist/ssr/actions/Dropdown.js.map +1 -1
  35. package/dist/ssr/content/MatchText.js +56 -0
  36. package/dist/ssr/content/MatchText.js.map +1 -0
  37. package/dist/ssr/content/index.js +1 -0
  38. package/dist/ssr/content/index.js.map +1 -1
  39. package/dist/ssr/text-editor/TextEditor.js +1155 -0
  40. package/dist/ssr/text-editor/TextEditor.js.map +1 -0
  41. package/dist/ssr/text-editor/clipboard-html.js +152 -0
  42. package/dist/ssr/text-editor/clipboard-html.js.map +1 -0
  43. package/dist/ssr/text-editor/clipboard-loading.js +68 -0
  44. package/dist/ssr/text-editor/clipboard-loading.js.map +1 -0
  45. package/dist/ssr/text-editor/clipboard.js +51 -0
  46. package/dist/ssr/text-editor/clipboard.js.map +1 -0
  47. package/dist/ssr/text-editor/engine.js +125 -0
  48. package/dist/ssr/text-editor/engine.js.map +1 -0
  49. package/dist/ssr/text-editor/format.js +218 -0
  50. package/dist/ssr/text-editor/format.js.map +1 -0
  51. package/dist/ssr/text-editor/formatted.js +164 -0
  52. package/dist/ssr/text-editor/formatted.js.map +1 -0
  53. package/dist/ssr/text-editor/language.js +19 -0
  54. package/dist/ssr/text-editor/language.js.map +1 -0
  55. package/dist/ssr/text-editor/markdown-table.js +563 -0
  56. package/dist/ssr/text-editor/markdown-table.js.map +1 -0
  57. package/dist/ssr/text-editor/messages.js +233 -0
  58. package/dist/ssr/text-editor/messages.js.map +1 -0
  59. package/dist/ssr/text-editor/paste.js +115 -0
  60. package/dist/ssr/text-editor/paste.js.map +1 -0
  61. package/dist/ssr/text-editor/table.js +1760 -0
  62. package/dist/ssr/text-editor/table.js.map +1 -0
  63. package/dist/ssr/text-editor.js +5 -0
  64. package/dist/ssr/text-editor.js.map +1 -0
  65. package/dist/styles.css +1 -1
  66. package/dist/types/actions/Dropdown.d.ts +2 -0
  67. package/dist/types/content/MatchText.d.ts +21 -0
  68. package/dist/types/content/index.d.ts +1 -0
  69. package/dist/types/text-editor/TextEditor.d.ts +69 -0
  70. package/dist/types/text-editor/clipboard-html.d.ts +9 -0
  71. package/dist/types/text-editor/clipboard-loading.d.ts +8 -0
  72. package/dist/types/text-editor/clipboard.d.ts +20 -0
  73. package/dist/types/text-editor/engine.d.ts +34 -0
  74. package/dist/types/text-editor/format.d.ts +34 -0
  75. package/dist/types/text-editor/formatted.d.ts +1 -0
  76. package/dist/types/text-editor/language.d.ts +8 -0
  77. package/dist/types/text-editor/markdown-table.d.ts +105 -0
  78. package/dist/types/text-editor/messages.d.ts +113 -0
  79. package/dist/types/text-editor/paste.d.ts +6 -0
  80. package/dist/types/text-editor/table.d.ts +81 -0
  81. package/dist/types/text-editor.d.ts +4 -0
  82. package/package.json +23 -3
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["text-editor/TextEditor.tsx"],"sourcesContent":["import { history, historyKeymap, redo, undo } from \"@codemirror/commands\";\nimport type { Extension } from \"@codemirror/state\";\nimport { EditorView, keymap } from \"@codemirror/view\";\nimport { clipboard } from \"@k2b/stdlib/solid\";\nimport { createEffect, createSignal, createUniqueId, For, type JSX, onCleanup, onMount, Show, untrack } from \"solid-js\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { Dropdown, type DropdownAction, type DropdownChoice, type DropdownItem, type DropdownPosition } from \"../actions/Dropdown\";\nimport { SegmentedControl } from \"../actions/SegmentedControl\";\nimport { Toolbar } from \"../actions/Toolbar\";\nimport { Kbd } from \"../content/Kbd\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { NumberInput } from \"../inputs/NumberInput\";\nimport { LocaleProvider, useLocale } from \"../intl/locale\";\nimport { formatShortcut, type KeyboardPlatform, keyboardPlatform } from \"../intl/shortcut\";\nimport BottomSheet, { bottomSheetAdaptiveOptions } from \"../layout/BottomSheet\";\nimport { createTextEditor, type TextEditorController, type TextEditorMode, type TextEditorOptions } from \"./engine\";\nimport { commands, formatLabels, type InlineFormat } from \"./format\";\nimport { findTables, inspectTableStructure } from \"./markdown-table\";\nimport { textEditorMessages } from \"./messages\";\nimport {\n copyTable,\n editTableSource,\n formatActiveCell,\n type MenuAction,\n runMenuAction,\n runTableAction,\n type TableHost,\n tableActionEnabled,\n} from \"./table\";\n\nexport type TextEditorProps = {\n label: string;\n initialValue?: string;\n mode?: TextEditorMode;\n onModeChange?: (mode: TextEditorMode) => void;\n readOnly?: boolean;\n loading?: boolean;\n placeholder?: string;\n extensions?: Extension;\n /** Host-owned Markdown presentation; see `createTextEditor`. The host then also styles the editor surface. */\n presentation?: TextEditorOptions[\"presentation\"];\n /** `false` when the host renders its own formatting toolbar and mode control; place `controls.TableMenu` in it. */\n toolbar?: boolean;\n /** Collaboration supplies history and server-owned structure here. */\n host?: Pick<TableHost, \"structure\" | \"renderCell\" | \"onCellSelection\" | \"tabMovesFocus\"> &\n Partial<Pick<TableHost, \"undo\" | \"redo\" | \"boundary\">>;\n maxLength: number;\n maxPasteCells?: number;\n onChange?: (text: string) => void;\n onReady?: (editor: TextEditorController, controls: TextEditorControls) => void;\n /** Return `true` when the host attached the images itself; otherwise the editor shows its attachment hint. */\n onDroppedImages?: (count: number, files: File[]) => boolean | void;\n /** Opens the host's attachment picker when clipboard images cannot be inserted. */\n onAttachImages?: () => void;\n onTableCheck?: (needsCheck: boolean) => void;\n /** Host-owned sync status; its place is reserved across transitions. */\n status?: JSX.Element;\n class?: string;\n};\n\nexport type TableSizePickerProps = {\n maxRows: number;\n maxColumns: number;\n onPick: (size: { rows: number; columns: number }) => void;\n /** Share this picker with slash commands or secondary menus. */\n onReady?: (open: () => void) => void;\n disabled?: boolean;\n class?: string;\n size?: \"xs\" | \"sm\";\n};\n\n/** Shared table-size control: pointer grid on desktop, large fields in a phone sheet. */\nexport function TableSizePicker(props: TableSizePickerProps) {\n const locale = useLocale();\n const t = () => textEditorMessages.resolve([locale()]).t;\n const [rows, setRows] = createSignal<number | null>(3);\n const [columns, setColumns] = createSignal<number | null>(3);\n const [expanded, setExpanded] = createSignal(false);\n const id = createUniqueId();\n const abort = new AbortController();\n let disposed = false;\n onCleanup(() => {\n disposed = true;\n abort.abort();\n });\n let trigger!: HTMLButtonElement;\n let popup!: HTMLDivElement;\n const reset = () => {\n setRows(Math.min(3, props.maxRows));\n setColumns(Math.min(3, props.maxColumns));\n };\n const choose = (r: number, c: number) => {\n popup.hidePopover();\n if (!disposed && !props.disabled) props.onPick({ rows: r, columns: c });\n };\n const open = async () => {\n if (disposed || props.disabled || expanded()) return;\n reset();\n if (!window.matchMedia(\"(max-width: 47.999rem)\").matches) {\n popup.showPopover();\n const anchor = trigger.getBoundingClientRect(),\n box = popup.getBoundingClientRect();\n popup.style.left = `${Math.max(8, Math.min(anchor.left, innerWidth - box.width - 8))}px`;\n popup.style.top = `${Math.max(8, anchor.top > box.height + 8 ? anchor.top - box.height - 8 : Math.min(anchor.bottom + 8, innerHeight - box.height - 8))}px`;\n popup.focus();\n return;\n }\n setExpanded(true);\n const chosen = await dialogCore.open<{ rows: number; columns: number }>(\n (close, context) => (\n <LocaleProvider locale={locale()}>\n <BottomSheet onDismiss={context.requestDismiss}>\n <BottomSheet.Header title={t().insertTable} close={context.requestDismiss} />\n <BottomSheet.Body>\n <div class=\"k2b-ste-size-picker\">\n <NumberInput label={t().rows} value={rows()} onValueChange={setRows} min={1} max={props.maxRows} step={1} />\n <NumberInput label={t().columns} value={columns()} onValueChange={setColumns} min={1} max={props.maxColumns} step={1} />\n </div>\n </BottomSheet.Body>\n <BottomSheet.Footer>\n <Button\n disabled={!rows() || !columns()}\n onClick={() => {\n const r = rows(),\n c = columns();\n if (r && c) close({ rows: r, columns: c });\n }}\n >\n {t().insertSize({ rows: rows() ?? 0, columns: columns() ?? 0 })}\n </Button>\n </BottomSheet.Footer>\n </BottomSheet>\n </LocaleProvider>\n ),\n { ...bottomSheetAdaptiveOptions, ariaLabel: t().insertTable, history: true, signal: abort.signal },\n );\n setExpanded(false);\n if (chosen && !disposed && !props.disabled) props.onPick(chosen);\n };\n onMount(() => props.onReady?.(() => void open()));\n const keyboard = (event: KeyboardEvent) => {\n const directions: Record<string, [number, number]> = { ArrowUp: [-1, 0], ArrowDown: [1, 0], ArrowLeft: [0, -1], ArrowRight: [0, 1] };\n const direction = directions[event.key];\n if (direction) {\n event.preventDefault();\n setRows(Math.max(1, Math.min(Math.min(9, props.maxRows), (rows() ?? 1) + direction[0])));\n setColumns(Math.max(1, Math.min(Math.min(10, props.maxColumns), (columns() ?? 1) + direction[1])));\n } else if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n choose(rows() ?? 1, columns() ?? 1);\n } else if (event.key === \"Escape\") trigger.focus();\n };\n return (\n <>\n <IconButton\n ref={trigger}\n variant=\"ghost\"\n class={props.class}\n size={props.size ?? \"sm\"}\n disabled={props.disabled}\n label={t().insertTable}\n aria-haspopup=\"dialog\"\n aria-controls={id}\n aria-expanded={expanded()}\n tooltip={t().insertTable}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => void open()}\n >\n <i class=\"ti ti-table\" aria-hidden=\"true\" />\n </IconButton>\n <div\n ref={popup}\n id={id}\n popover=\"auto\"\n class=\"k2b-ste-size-popover\"\n role=\"dialog\"\n aria-label={t().insertTable}\n tabIndex={-1}\n onKeyDown={keyboard}\n on:toggle={() => setExpanded(popup.matches(\":popover-open\"))}\n >\n <div class=\"k2b-ste-size-grid\" role=\"group\" aria-label={t().insertTable}>\n <For each={Array.from({ length: Math.min(9, props.maxRows) }, (_, index) => index + 1)}>\n {(r) => (\n <div class=\"k2b-ste-size-row\">\n <For each={Array.from({ length: Math.min(10, props.maxColumns) }, (_, index) => index + 1)}>\n {(c) => (\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={t().insertSize({ rows: r, columns: c })}\n data-selected={r <= (rows() ?? 0) && c <= (columns() ?? 0) ? \"true\" : undefined}\n onPointerEnter={() => {\n setRows(r);\n setColumns(c);\n }}\n onClick={() => choose(r, c)}\n />\n )}\n </For>\n </div>\n )}\n </For>\n </div>\n <div class=\"k2b-ste-size-caption\" role=\"status\">\n {t().insertSize({ rows: rows() ?? 0, columns: columns() ?? 0 })}\n </div>\n </div>\n </>\n );\n}\n\ntype TableMenuTrigger = { text?: string; class?: string; size?: \"xs\" | \"sm\"; position?: DropdownPosition };\n/** Shared table controls for a host-owned toolbar (`toolbar={false}`). */\nexport type TextEditorControls = {\n /** A table cell has focus in the formatted view. */\n tableActive: () => boolean;\n /** The shared cell menu behind a host-styled trigger; on phones it opens as a sheet. */\n TableMenu: (props: TableMenuTrigger) => JSX.Element;\n /** Formats the focused cell's selection; `false` when no cell has focus. */\n formatCell: (format: InlineFormat) => boolean;\n /** Shows a host message, such as a server's reason for a rejected table action, in the editor's notice. */\n notify: (message: string) => void;\n};\n\nconst toolbar = [\n [\"bold\", \"bold\"],\n [\"italic\", \"italic\"],\n [\"heading\", \"heading\"],\n [\"bulletList\", \"list\"],\n [\"orderedList\", \"list-numbers\"],\n [\"quote\", \"quote\"],\n [\"link\", \"link\"],\n [\"code\", \"code\"],\n [\"table\", \"table\"],\n [\"rule\", \"separator\"],\n] as const;\nconst actionIcons = {\n rowAbove: \"row-insert-top\",\n rowBelow: \"row-insert-bottom\",\n colLeft: \"column-insert-left\",\n colRight: \"column-insert-right\",\n alignLeft: \"align-left\",\n alignCenter: \"align-center\",\n alignRight: \"align-right\",\n deleteRow: \"row-remove\",\n deleteCol: \"column-remove\",\n moveRowUp: \"arrow-up\",\n moveRowDown: \"arrow-down\",\n moveColLeft: \"arrow-left\",\n moveColRight: \"arrow-right\",\n toggleHeader: \"table-row\",\n deleteTable: \"trash\",\n} as const;\nconst isInlineCommand = (command: string): command is Extract<InlineFormat, string> => inlineCommands.has(command);\nconst shortcuts: Partial<Record<keyof typeof commands, string>> = { bold: \"mod+b\", italic: \"mod+i\", link: \"mod+k\" };\nconst inlineCommands = new Set<string>([\"bold\", \"italic\", \"code\", \"link\", \"strike\"]);\n\n/** A Markdown text field with app-injected collaboration and a directly editable table view. */\nexport function TextEditor(props: TextEditorProps) {\n const locale = useLocale();\n const t = () => textEditorMessages.resolve([locale()]).t;\n const [mode, setMode] = createSignal<TextEditorMode>(props.mode ?? \"formatted\");\n const [ready, setReady] = createSignal(false);\n const [recovery, setRecovery] = createSignal<string>();\n const [notice, setNotice] = createSignal<{ message: string; images?: boolean }>();\n const [cell, setCell] = createSignal<HTMLElement>();\n const [localSource, setLocalSource] = createSignal(false);\n const [announcement, setAnnouncement] = createSignal(\"\");\n const [check, setCheck] = createSignal(false);\n const [missingSeparator, setMissingSeparator] = createSignal(false);\n const [active, setActive] = createSignal(false);\n const [documentRevision, setDocumentRevision] = createSignal(0);\n const [phoneMenu, setPhoneMenu] = createSignal(false);\n const [platform, setPlatform] = createSignal<KeyboardPlatform>(\"other\");\n createEffect(() => {\n const target = cell();\n target?.setAttribute(\"data-active\", \"\");\n onCleanup(() => target?.removeAttribute(\"data-active\"));\n });\n let disposed = false;\n onCleanup(() => {\n disposed = true;\n const text = recovery();\n if (text !== undefined) detachedRecovery(text);\n });\n // A local draft can outlive an island during navigation. Keep its recovery\n // surface in the shared dialog root so disposal never silently drops it.\n const detachedRecovery = (text: string) => {\n const language = locale();\n const labels = t();\n const beforeUnload = (event: BeforeUnloadEvent) => {\n event.preventDefault();\n event.returnValue = \"\";\n };\n window.addEventListener(\"beforeunload\", beforeUnload);\n const show = () =>\n void dialogCore\n .open<\"discard\">(\n (close, context) => {\n context.setDismissHandler(() => {});\n return (\n <LocaleProvider locale={language}>\n <BottomSheet handle={false} onDismiss={() => {}}>\n <BottomSheet.Header title={labels.recoveredInput} />\n <BottomSheet.Body>\n <label class=\"k2b-ste-recovery-label\">\n {labels.recoveredInput}\n <textarea class=\"k2b-ste-recovery\" readOnly value={text} />\n </label>\n </BottomSheet.Body>\n <BottomSheet.Footer>\n <Button variant=\"ghost\" onClick={() => close(\"discard\")}>\n {labels.discardRecovery}\n </Button>\n </BottomSheet.Footer>\n </BottomSheet>\n </LocaleProvider>\n );\n },\n { ...bottomSheetAdaptiveOptions, ariaLabel: labels.recoveredInput },\n )\n .then((result) => {\n if (result === \"discard\") window.removeEventListener(\"beforeunload\", beforeUnload);\n // The shared dialog root closes on each island disposal. Retain the\n // draft across subsequent navigation until the person explicitly discards it.\n else queueMicrotask(show);\n });\n show();\n };\n let menuOpen = false;\n let pointerAnchor: { left: string; top: string } | undefined;\n let floatingTrigger: HTMLButtonElement | undefined;\n const tableTriggers = new Set<HTMLButtonElement>();\n let frame = 0;\n const [menuPosition, setMenuPosition] = createSignal({ left: \"0px\", top: \"0px\" });\n let root!: HTMLDivElement;\n let mount!: HTMLDivElement;\n let editor: TextEditorController | undefined;\n const menuBlocked = () => !!props.loading || !ready() || recovery() !== undefined;\n const blocked = () => !!props.readOnly || menuBlocked();\n const updateCheck = () => {\n const issue =\n mode() === \"plain\"\n ? { extraCells: false, missingSeparator: false }\n : inspectTableStructure(editor?.view.state.doc.toString() ?? props.initialValue ?? \"\");\n const needsCheck = issue.extraCells || issue.missingSeparator;\n setMissingSeparator(issue.missingSeparator);\n setCheck(needsCheck);\n props.onTableCheck?.(needsCheck);\n };\n const positionMenu = () => {\n const target = cell();\n if (!target) return;\n const wrap = target.closest<HTMLElement>(\".k2b-ste-table\");\n const table = wrap?.querySelector(\"table\");\n if (!target.isConnected || !wrap || !table || mode() !== \"formatted\") {\n menuOpen = false;\n setCell(undefined);\n checkFocus();\n return;\n }\n const rect = target.getBoundingClientRect();\n const bounds = root.getBoundingClientRect();\n const right = Math.min(table.getBoundingClientRect().right, wrap.getBoundingClientRect().right);\n const position = props.readOnly\n ? {\n left: `${wrap.getBoundingClientRect().left - bounds.left}px`,\n top: `${wrap.getBoundingClientRect().bottom - bounds.top - (window.matchMedia(\"(max-width: 47.999rem)\").matches ? 44 : 0)}px`,\n }\n : { left: `${right - bounds.left - 24}px`, top: `${rect.top - bounds.top + (rect.height - 24) / 2}px` };\n setMenuPosition(pointerAnchor ?? position);\n };\n const schedulePosition = () => {\n if (!frame)\n frame = requestAnimationFrame(() => {\n frame = 0;\n positionMenu();\n });\n };\n const unavailable = () => !!props.host?.structure && !props.host.structure.available();\n const actionDisabled = (action: MenuAction) => {\n documentRevision();\n const wrap = cell()?.closest<HTMLElement>(\".k2b-ste-table\");\n return blocked() || !editor || !wrap || !tableActionEnabled(editor.view, wrap, action);\n };\n const isMove = (action: MenuAction) => action.startsWith(\"move\");\n const runAction = (action: MenuAction) => {\n const wrap = cell()?.closest<HTMLElement>(\".k2b-ste-table\");\n const focused = document.activeElement;\n const menuElement = focused instanceof HTMLElement ? focused.closest<HTMLElement>('[role=\"menu\"]') : null;\n if (editor && wrap && !actionDisabled(action)) runMenuAction(editor.view, wrap, action);\n // The phone move sheet remains usable for another move. Local structural\n // focus belongs to the cell only after the menu has closed.\n if (isMove(action) && focused instanceof HTMLElement && menuElement) {\n const restore = () => {\n if (disposed || !menuElement.isConnected) return;\n const target =\n focused.isConnected && !focused.matches(\":disabled\")\n ? focused\n : menuElement.querySelector<HTMLElement>('[role^=\"menuitem\"]:not(:disabled)');\n target?.focus({ preventScroll: true });\n };\n restore();\n queueMicrotask(restore);\n }\n };\n const moveKeys: Partial<Record<MenuAction, string>> = {\n moveRowUp: \"alt+arrowup\",\n moveRowDown: \"alt+arrowdown\",\n moveColLeft: \"alt+arrowleft\",\n moveColRight: \"alt+arrowright\",\n };\n const shortActionLabels = {\n rowAbove: \"menuAbove\",\n rowBelow: \"menuBelow\",\n moveRowUp: \"menuUp\",\n moveRowDown: \"menuDown\",\n deleteRow: \"menuDelete\",\n colLeft: \"menuInsertLeft\",\n colRight: \"menuInsertRight\",\n moveColLeft: \"menuMoveLeft\",\n moveColRight: \"menuMoveRight\",\n deleteCol: \"menuDelete\",\n } as const;\n const menuRow = () => {\n documentRevision();\n return t().menuRow(Number(cell()?.dataset.r ?? 0));\n };\n const menuColumn = () => {\n documentRevision();\n const column = Number(cell()?.dataset.c ?? 0);\n const header = cell()?.closest(\".k2b-ste-table\")?.querySelector<HTMLElement>(`.k2b-ste-cell[data-r=\"0\"][data-c=\"${column}\"]`);\n return t().menuColumn(header?.dataset.raw || t().column(column + 1));\n };\n const menuHeading = () => `${menuRow()} · ${menuColumn()}`;\n const actionItem = (action: keyof typeof actionIcons, choice?: Pick<DropdownChoice, \"choice\" | \"checked\" | \"class\" | \"ariaLabel\">) =>\n ({\n get label() {\n return phoneMenu() && action in shortActionLabels ? t()[shortActionLabels[action as keyof typeof shortActionLabels]] : t()[action];\n },\n icon: `ti ti-${actionIcons[action]}`,\n get disabled() {\n return actionDisabled(action);\n },\n immediate: true,\n trailing: moveKeys[action] ? <Kbd keys={moveKeys[action]!} /> : action === \"rowBelow\" ? <Kbd keys=\"enter\" /> : undefined,\n variant: action === \"deleteRow\" || action === \"deleteCol\" || action === \"deleteTable\" ? \"danger\" : undefined,\n closeOnSelect: !isMove(action),\n action: () => runAction(action),\n ...choice,\n }) satisfies DropdownAction;\n const [copying, setCopying] = createSignal(false);\n const tableCopy = clipboard.createWriter({\n write: ({ view, wrap, format }: { view: EditorView; wrap: HTMLElement; format: \"table\" | \"markdown\" }) => copyTable(view, wrap, format),\n });\n const copy = async (format: \"table\" | \"markdown\") => {\n const wrap = cell()?.closest<HTMLElement>(\".k2b-ste-table\");\n if (!editor || !wrap || copying()) return;\n setCopying(true);\n setNotice({ message: t().copyingTable });\n const success = await tableCopy.copy({ view: editor.view, wrap, format });\n if (disposed) return;\n setCopying(false);\n setNotice({ message: success ? (format === \"table\" ? t().copiedTable : t().copiedMarkdown) : t().copyFailed });\n };\n const copyItems = (): DropdownAction[] => [\n {\n get label() {\n return phoneMenu() && !props.readOnly ? t().menuCopy : t().copyTable;\n },\n icon: \"ti ti-copy\",\n get disabled() {\n return copying();\n },\n immediate: true,\n action: () => {\n void copy(\"table\");\n },\n },\n {\n get label() {\n return phoneMenu() && !props.readOnly ? t().menuMarkdown : t().copyMarkdown;\n },\n icon: \"ti ti-markdown\",\n get disabled() {\n return copying();\n },\n immediate: true,\n action: () => {\n void copy(\"markdown\");\n },\n },\n ];\n const items = (): DropdownItem[] => {\n if (props.readOnly) return copyItems();\n const align = () => {\n documentRevision();\n return cell()?.parentElement?.style.textAlign || \"left\";\n };\n return [\n {\n get sectionLabel() {\n return menuHeading();\n },\n items: [],\n },\n {\n get sectionLabel() {\n return menuRow();\n },\n items: ([\"rowAbove\", \"rowBelow\", \"moveRowUp\", \"moveRowDown\", \"deleteRow\"] as const).map((action) => actionItem(action)),\n },\n {\n get sectionLabel() {\n return menuColumn();\n },\n items: ([\"colLeft\", \"colRight\", \"moveColLeft\", \"moveColRight\"] as const).map((action) => actionItem(action)),\n },\n {\n sectionLabel: t().alignment,\n layout: \"row\",\n items: ([\"alignLeft\", \"alignCenter\", \"alignRight\"] as const).map((action, index) =>\n actionItem(action, {\n choice: \"radio\",\n class: \"k2b-ste-align-choice\",\n ariaLabel: t()[action],\n checked: () => align() === [\"left\", \"center\", \"right\"][index],\n }),\n ),\n },\n { items: [actionItem(\"deleteCol\")] },\n {\n sectionLabel: t().table,\n items: [\n actionItem(\"toggleHeader\", {\n choice: \"checkbox\",\n class: \"k2b-ste-header-choice\",\n checked: () => {\n documentRevision();\n return cell()?.closest<HTMLElement>(\".k2b-ste-table\")?.dataset.header === \"true\";\n },\n }),\n {\n label: t().editMarkdown,\n icon: \"ti ti-markdown\",\n action: () => {\n const wrap = cell()?.closest<HTMLElement>(\".k2b-ste-table\");\n if (editor && wrap) editTableSource(editor.view, wrap);\n },\n },\n ...copyItems(),\n actionItem(\"deleteTable\"),\n ...(unavailable() ? [{ label: t().structureUnavailable, disabled: true as const }] : []),\n ],\n },\n ];\n };\n const preserveSelection = (event: MouseEvent) => event.preventDefault();\n const menuChange = (open: boolean) => {\n menuOpen = open;\n };\n const menuClose = () => {\n menuOpen = false;\n pointerAnchor = undefined;\n schedulePosition();\n queueMicrotask(() => {\n if (disposed) return;\n const focused = document.activeElement;\n if (focused instanceof HTMLElement && focused.matches(\".k2b-ste-cell-menu, .k2b-ste-table-tool\")) cell()?.focus();\n checkFocus();\n });\n };\n const menu = (floating: boolean, trigger?: TableMenuTrigger) => (\n // A sheet owns its item inventory until it closes. Replace that owner when\n // edit access changes so an already open sheet cannot retain edit entries.\n <Show when={props.readOnly ? \"read\" : \"write\"} keyed>\n {(_access) => (\n <Dropdown\n items={items()}\n phone=\"sheet\"\n sheetTop={\n props.readOnly\n ? undefined\n : (close) => (\n <div class=\"k2b-ste-table-sheet-heading\">\n <span title={menuHeading()}>{menuHeading()}</span>\n <Button variant=\"ghost\" onClick={close}>\n {t().done}\n </Button>\n </div>\n )\n }\n menuClass=\"k2b-ste-table-menu\"\n position={floating ? \"right-start\" : (trigger?.position ?? \"bottom-right\")}\n width=\"18rem\"\n label={props.readOnly ? t().copyTable : t().tableMenu}\n disabled={menuBlocked() || localSource() || !cell()?.isConnected}\n onOpenChange={menuChange}\n onClose={menuClose}\n >\n <Dropdown.Trigger\n ref={(element) => {\n if (floating) floatingTrigger = element;\n else {\n tableTriggers.add(element);\n onCleanup(() => tableTriggers.delete(element));\n }\n }}\n class={\n floating\n ? props.readOnly\n ? \"k2b-ste-cell-menu k2b-ste-copy-menu\"\n : \"k2b-ste-cell-menu\"\n : `k2b-ste-tool k2b-ste-table-tool ${trigger?.class ?? \"\"}`\n }\n variant=\"ghost\"\n size={trigger?.size ?? \"sm\"}\n iconOnly={!trigger?.text && !props.readOnly}\n label={trigger?.text ?? (props.readOnly ? t().copyTable : t().tableMenu)}\n aria-pressed={!floating ? true : undefined}\n onMouseDown={preserveSelection}\n >\n <i class={props.readOnly ? \"ti ti-copy\" : floating ? \"ti ti-dots\" : \"ti ti-table\"} aria-hidden=\"true\" />\n {trigger?.text ?? (props.readOnly ? t().copyTable : undefined)}\n <Show when={trigger?.text}>\n <i class=\"ti ti-chevron-down\" aria-hidden=\"true\" />\n </Show>\n </Dropdown.Trigger>\n </Dropdown>\n )}\n </Show>\n );\n const runFormat = (command: keyof typeof commands) => {\n if (!editor || blocked()) return;\n if (cell()?.isConnected && isInlineCommand(command) && formatActiveCell(editor.view, command)) return;\n commands[command](editor.view);\n };\n const checkFocus = () => {\n if (disposed) return;\n // A host toolbar sits outside this root. Native popover focus moves before\n // its toggle callback, but Dropdown already exposes its synchronous state.\n if (\n menuOpen ||\n [...tableTriggers, floatingTrigger].some((trigger) => trigger?.isConnected && trigger.getAttribute(\"aria-expanded\") === \"true\")\n )\n return;\n const focused = document.activeElement;\n setLocalSource(focused instanceof HTMLElement && !!focused.closest(\".k2b-ste-table-source\"));\n const inside = focused instanceof Node && root.contains(focused);\n setActive(inside);\n if (!inside || focused === editor?.view.contentDOM) setCell(undefined);\n else if (!cell()?.isConnected) setCell(undefined);\n };\n const formatMenu = (command: \"heading\" | \"code\") => (\n <Dropdown\n phone=\"sheet\"\n label={t()[command]}\n disabled={blocked() || (command === \"heading\" && !!cell())}\n onOpenChange={menuChange}\n onClose={menuClose}\n items={\n command === \"heading\"\n ? [\n {\n items: ([\"heading1\", \"heading2\", \"heading3\"] as const).map((name, index) => ({\n label: t()[name],\n icon: `ti ti-h-${index + 1}`,\n action: () => runFormat(name),\n })),\n },\n ]\n : [\n { label: t().inlineCode, icon: \"ti ti-code\", action: () => runFormat(\"code\") },\n { label: t().codeBlock, icon: \"ti ti-source-code\", disabled: !!cell(), action: () => runFormat(\"codeBlock\") },\n { label: t().strike, icon: \"ti ti-strikethrough\", trailing: <Kbd keys=\"mod+shift+x\" />, action: () => runFormat(\"strike\") },\n ]\n }\n >\n <Dropdown.Trigger class=\"k2b-ste-tool\" variant=\"ghost\" size=\"sm\" iconOnly label={t()[command]} onMouseDown={preserveSelection}>\n <i class={`ti ti-${command}`} aria-hidden=\"true\" />\n </Dropdown.Trigger>\n </Dropdown>\n );\n const selectMode = (next: TextEditorMode) => {\n const restoreEditorFocus = !!editor?.view.contentDOM.contains(document.activeElement);\n menuOpen = false;\n setCell(undefined);\n setMode(next);\n props.onModeChange?.(next);\n if (restoreEditorFocus) queueMicrotask(() => editor?.view.focus());\n };\n onMount(() => {\n setPlatform(keyboardPlatform());\n const menuMedia = window.matchMedia(\"(max-width: 47.999rem)\");\n const menuViewport = () => setPhoneMenu(menuMedia.matches);\n menuViewport();\n menuMedia.addEventListener(\"change\", menuViewport);\n onCleanup(() => menuMedia.removeEventListener(\"change\", menuViewport));\n // A standalone editor has no binding history; collaboration supplies its own instead.\n const nativeHistory = !props.host?.undo;\n editor = createTextEditor({\n parent: mount,\n doc: props.initialValue,\n mode: mode(),\n label: props.label,\n readOnly: props.readOnly,\n placeholder: props.placeholder,\n presentation: props.presentation,\n extensions: [\n nativeHistory ? [history(), keymap.of(historyKeymap)] : [],\n formatLabels.of({\n get link() {\n return t().link;\n },\n column: (column) => t().column(column),\n }),\n EditorView.updateListener.of((update) => {\n schedulePosition();\n if (update.docChanged) queueMicrotask(() => setDocumentRevision((revision) => revision + 1));\n }),\n props.extensions ?? [],\n ],\n host: {\n ...props.host,\n undo: props.host?.undo ?? (() => editor && undo(editor.view)),\n redo: props.host?.redo ?? (() => editor && redo(editor.view)),\n boundary: props.host?.boundary ?? (() => {}),\n cellLabel: (row, column, name) => t().cellLabel({ row, column, name }),\n actionLabel: (name) => t()[name],\n sourceLabels: () => ({\n edit: t().editMarkdown,\n valid: t().markdownValid,\n invalid: t().markdownInvalid,\n changed: t().markdownChanged,\n structural: t().markdownStructural,\n applying: t().applyingTable,\n applyFailed: t().markdownApplyFailed,\n done: phoneMenu() ? t().done : t().showTable,\n discard: t().discardMarkdown,\n continue: t().continueMarkdown,\n line: t().markdownLine,\n separator: (header, separator) => t().markdownSeparator({ header, separator }),\n extra: t().markdownExtra,\n complete: t().completeColumns,\n }),\n maxLength: props.maxLength,\n maxPasteCells: props.maxPasteCells ?? 2000,\n onRecovery: (text) => {\n if (disposed) detachedRecovery(text);\n else setRecovery((previous) => (previous === undefined ? text : `${previous}\\n\\n${text}`));\n },\n onError: (code) => setNotice({ message: t()[code] }),\n },\n onChange: (text) => {\n props.onChange?.(text);\n queueMicrotask(updateCheck);\n },\n onDroppedImages: (count, files) => {\n if (props.onDroppedImages?.(count, files) !== true) setNotice({ message: t().imageHint, images: true });\n },\n });\n const focus = (event: Event) => {\n if (!(event instanceof CustomEvent) || !(event.detail.cell instanceof HTMLElement)) return;\n setActive(true);\n if (!menuOpen) pointerAnchor = undefined;\n setCell(event.detail.cell);\n positionMenu();\n };\n const structureAnnouncement = (event: Event) => {\n if (!(event instanceof CustomEvent)) return;\n const detail: unknown = event.detail;\n if (\n detail &&\n typeof detail === \"object\" &&\n \"rows\" in detail &&\n \"columns\" in detail &&\n typeof detail.rows === \"number\" &&\n typeof detail.columns === \"number\"\n )\n setAnnouncement(t().tableChanged({ rows: detail.rows, columns: detail.columns }));\n };\n const focusChange = () => queueMicrotask(checkFocus);\n let pointerCheck: ReturnType<typeof setTimeout> | undefined;\n const pointer = (event: PointerEvent) => {\n if (event.target instanceof Node && root.contains(event.target)) setActive(true);\n // After the press moved focus: a host toolbar control that keeps focus in the cell keeps it active.\n else if (!menuOpen) {\n clearTimeout(pointerCheck);\n pointerCheck = setTimeout(checkFocus);\n }\n };\n const keyboardMenu = (event: Event) => {\n if (menuBlocked()) return;\n focus(event);\n if (event instanceof CustomEvent) {\n const bounds = root.getBoundingClientRect();\n const anchor = event.detail.anchor instanceof HTMLElement ? event.detail.anchor.getBoundingClientRect() : undefined;\n if (anchor || typeof event.detail.x === \"number\") {\n pointerAnchor = {\n left: `${(anchor?.left ?? event.detail.x) - bounds.left}px`,\n top: `${(anchor?.bottom ?? event.detail.y) - bounds.top}px`,\n };\n positionMenu();\n }\n }\n queueMicrotask(() => {\n if (disposed || !cell()?.isConnected) return;\n const tableTrigger = [...tableTriggers].find((trigger) => trigger.isConnected);\n const trigger =\n (window.matchMedia(\"(max-width: 47.999rem)\").matches && tableTrigger?.isConnected ? tableTrigger : undefined) ?? floatingTrigger;\n trigger?.click();\n });\n };\n const mutations = new MutationObserver(schedulePosition);\n mutations.observe(mount, { childList: true, subtree: true, characterData: true });\n const resize = new ResizeObserver(schedulePosition);\n resize.observe(mount);\n // Safari blurs a contenteditable on mouse-down without focusing the radio.\n // Keep the caret and phone toolbar stationary until the view switch runs.\n const viewMouseDown = (event: MouseEvent) => {\n if (event.target instanceof Element && event.target.closest(\".k2b-ste-views\")) event.preventDefault();\n };\n root.addEventListener(\"mousedown\", viewMouseDown);\n document.addEventListener(\"focusin\", focusChange);\n document.addEventListener(\"pointerdown\", pointer);\n root.addEventListener(\"k2b-ste-table-structure\", structureAnnouncement);\n root.addEventListener(\"k2b-ste-cell-focus\", focus);\n root.addEventListener(\"k2b-ste-cell-blur\", focusChange);\n root.addEventListener(\"k2b-ste-cell-menu\", keyboardMenu);\n const tableScroll = (event: Event) => {\n if (\n menuOpen &&\n event.target instanceof HTMLElement &&\n event.target.classList.contains(\"k2b-ste-table\") &&\n floatingTrigger?.getAttribute(\"aria-expanded\") === \"true\"\n )\n floatingTrigger.click();\n schedulePosition();\n };\n window.addEventListener(\"scroll\", tableScroll, true);\n window.addEventListener(\"resize\", schedulePosition);\n const viewport = window.visualViewport;\n const keyboard = () =>\n root.style.setProperty(\n \"--k2b-ste-keyboard\",\n `${Math.max(0, window.innerHeight - (viewport?.height ?? window.innerHeight) - (viewport?.offsetTop ?? 0))}px`,\n );\n viewport?.addEventListener(\"resize\", keyboard);\n viewport?.addEventListener(\"scroll\", keyboard);\n keyboard();\n setReady(true);\n updateCheck();\n props.onReady?.(editor, {\n tableActive: () => mode() === \"formatted\" && !!cell()?.isConnected,\n TableMenu: (trigger) => menu(false, trigger),\n formatCell: (format) => !!editor && !blocked() && !!cell()?.isConnected && formatActiveCell(editor.view, format),\n notify: (message) => setNotice({ message }),\n });\n onCleanup(() => {\n clearTimeout(pointerCheck);\n mutations.disconnect();\n resize.disconnect();\n cancelAnimationFrame(frame);\n root.removeEventListener(\"mousedown\", viewMouseDown);\n document.removeEventListener(\"focusin\", focusChange);\n document.removeEventListener(\"pointerdown\", pointer);\n root.removeEventListener(\"k2b-ste-table-structure\", structureAnnouncement);\n root.removeEventListener(\"k2b-ste-cell-focus\", focus);\n root.removeEventListener(\"k2b-ste-cell-blur\", focusChange);\n root.removeEventListener(\"k2b-ste-cell-menu\", keyboardMenu);\n window.removeEventListener(\"scroll\", tableScroll, true);\n window.removeEventListener(\"resize\", schedulePosition);\n viewport?.removeEventListener(\"resize\", keyboard);\n viewport?.removeEventListener(\"scroll\", keyboard);\n editor?.destroy();\n });\n });\n createEffect(() => {\n if (props.mode !== undefined) setMode(props.mode);\n });\n createEffect(() => {\n if (ready()) {\n const next = mode();\n // Rendering the grid consults reactive host availability. Those reads\n // must not turn a history notification into a nested mode reconfigure.\n untrack(() => {\n menuOpen = false;\n setCell(undefined);\n editor?.setMode(next);\n updateCheck();\n });\n }\n });\n createEffect(() => {\n const label = props.label;\n if (ready()) untrack(() => editor?.setLabel(label));\n });\n createEffect(() => {\n const readOnly = !!props.readOnly || !!props.loading || recovery() !== undefined;\n if (ready()) untrack(() => editor?.setReadOnly(readOnly));\n });\n createEffect(() => {\n documentRevision();\n const disabled = blocked() || unavailable();\n if (ready())\n root.querySelectorAll<HTMLButtonElement>(\".k2b-ste-addColumn\").forEach((button) => {\n button.disabled = disabled;\n });\n });\n return (\n <div\n ref={root}\n class={`k2b-text-editor ${props.class ?? \"\"}`}\n data-mode={mode()}\n data-readonly={props.readOnly ? \"true\" : undefined}\n data-active={active() ? \"true\" : undefined}\n aria-busy={props.loading || !ready()}\n >\n <span class=\"k2b-ste-announcement\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {announcement()}\n </span>\n <Show when={!props.presentation || \"status\" in props || check()}>\n <div class=\"k2b-ste-status\" role=\"status\">\n <span>{props.status}</span>\n <Show when={check()}>\n <span class=\"k2b-ste-check\" title={missingSeparator() ? t().checkSeparatorDetail : t().checkTableDetail}>\n <i class=\"ti ti-alert-triangle\" aria-hidden=\"true\" />\n {t().checkTable}\n </span>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n disabled={blocked() || (!missingSeparator() && unavailable())}\n hidden={props.readOnly}\n tooltip={missingSeparator() ? t().checkSeparatorDetail : unavailable() ? t().structureUnavailable : t().checkTableDetail}\n onMouseDown={preserveSelection}\n onClick={() => {\n if (!editor) return;\n if (missingSeparator()) {\n selectMode(\"source\");\n queueMicrotask(() => editor?.view.focus());\n return;\n }\n const table = findTables(editor.view.state.doc.toString()).find((table) =>\n table.lines.some((row) => row.cells.length > table.columns),\n );\n if (table) runTableAction(editor.view, table.from, 0, 0, \"completeColumns\");\n }}\n >\n {missingSeparator() ? t().reviewMarkdown : t().completeColumns}\n </Button>\n </Show>\n </div>\n </Show>\n <Show when={!props.readOnly && mode() !== \"plain\" && props.toolbar !== false}>\n <div class=\"k2b-ste-toolbar-slot\">\n <Toolbar class=\"k2b-ste-toolbar\" label={t().formatting}>\n <For each={[toolbar.slice(0, 3), toolbar.slice(3, 6), toolbar.slice(6)]}>\n {(group) => (\n <Toolbar.Group class=\"k2b-ste-tool-group\">\n <For each={group}>\n {([command, icon]) =>\n command === \"heading\" || command === \"code\" ? (\n formatMenu(command)\n ) : (\n <Show\n when={command === \"table\" && mode() === \"formatted\" && cell()?.isConnected}\n fallback={\n <IconButton\n class=\"k2b-ste-tool\"\n variant=\"ghost\"\n size=\"sm\"\n label={t()[command]}\n tooltip={\n shortcuts[command]\n ? `${t()[command]} (${formatShortcut(shortcuts[command] ?? \"\", { platform: platform(), locale: locale() }).label})`\n : t()[command]\n }\n disabled={blocked() || (!!cell() && !inlineCommands.has(command) && command !== \"table\")}\n onMouseDown={preserveSelection}\n onClick={() => runFormat(command)}\n >\n <i class={`ti ti-${icon}`} aria-hidden=\"true\" />\n </IconButton>\n }\n >\n {menu(false)}\n </Show>\n )\n }\n </For>\n </Toolbar.Group>\n )}\n </For>\n <SegmentedControl\n class=\"k2b-ste-views\"\n size=\"sm\"\n ariaLabel={t().view}\n value={mode() === \"source\" ? \"source\" : \"formatted\"}\n options={[\n { value: \"formatted\", label: t().formatted, icon: \"ti ti-typography\" },\n { value: \"source\", label: t().source, icon: \"ti ti-markdown\" },\n ]}\n onValueChange={selectMode}\n />\n </Toolbar>\n </div>\n </Show>\n <Show when={props.loading || !ready()}>\n <div class=\"k2b-ste-loading\" role=\"status\" aria-label={t().loading}>\n <For each={[82, 100, 68, 0, 96, 74]}>\n {(width) => (\n <div>\n <span style={{ width: `${width}%` }} />\n </div>\n )}\n </For>\n </div>\n </Show>\n <div ref={mount} class={props.presentation ? \"k2b-ste-app-host\" : \"k2b-ste-host\"} hidden={props.loading || !ready()} />\n <Show when={cell() && mode() === \"formatted\" && !menuBlocked()}>\n <div class=\"k2b-ste-floating-menu\" data-readonly={props.readOnly ? \"true\" : undefined} style={menuPosition()}>\n {menu(true)}\n </div>\n </Show>\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n <Show when={notice() || recovery() !== undefined}>\n <div class=\"k2b-ste-notice\">\n <div class=\"k2b-ste-notice-content\">\n <Show when={notice()}>\n <Show when={notice()?.images && props.onAttachImages} fallback={<span>{notice()?.message}</span>}>\n <Button size=\"sm\" variant=\"ghost\" disabled={blocked()} onClick={() => props.onAttachImages?.()}>\n {notice()?.message}\n </Button>\n </Show>\n </Show>\n <Show when={recovery() !== undefined}>\n <label class=\"k2b-ste-recovery-label\">\n {t().recoveredInput}\n <textarea class=\"k2b-ste-recovery\" readOnly value={recovery()} />\n </label>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setRecovery(undefined);\n if (notice()?.message === t().cellRemoved) setNotice(undefined);\n }}\n >\n {t().discardRecovery}\n </Button>\n </Show>\n </div>\n <Show when={notice()}>\n <IconButton size=\"sm\" variant=\"ghost\" label={t().dismiss} onClick={() => setNotice(undefined)}>\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n </IconButton>\n </Show>\n </div>\n </Show>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,152 @@
1
+ import DOMPurify from "dompurify";
2
+ import { tableFromGrid } from "./markdown-table";
3
+
4
+ /** Parse only the HTML vocabulary that the Markdown converter consumes.
5
+ * Resource attributes and active elements never reach a clipboard consumer.
6
+ * The returned detached body is read as data and never mounted in the editor.
7
+ */
8
+ export const parseClipboardHtml = html => {
9
+ const body = DOMPurify.sanitize(html, {
10
+ ALLOWED_TAGS: ["p", "div", "span", "u", "font", "abbr", "acronym", "cite", "dfn", "mark", "q", "small", "sub", "sup", "big", "tt", "ins", "time", "var", "samp", "kbd", "ruby", "rt", "rp", "bdi", "bdo", "br", "b", "strong", "i", "em", "s", "del", "a", "code", "pre", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol", "li", "blockquote", "hr", "section", "article", "table", "thead", "tbody", "tfoot", "tr", "th", "td", "img"],
11
+ ALLOWED_ATTR: ["href", "style"],
12
+ ALLOW_DATA_ATTR: false,
13
+ ALLOW_ARIA_ATTR: false,
14
+ RETURN_DOM: true
15
+ });
16
+ if (!(body instanceof HTMLElement)) throw new TypeError("Clipboard HTML did not produce an HTML element");
17
+ return body;
18
+ };
19
+ const SAFE_URL = /^(https?:|mailto:)/i;
20
+ const preservesWhitespace = node => node.tagName === "PRE" || /^(pre|pre-wrap|break-spaces)$/.test(node.style.whiteSpace);
21
+ const isBlock = node => /^(P|DIV|H[1-6]|UL|OL|TABLE|BLOCKQUOTE|PRE|HR|SECTION|ARTICLE)$/.test(node.tagName) || preservesWhitespace(node);
22
+
23
+ // Editor clipboards use one div per source line. Read the sanitized, detached
24
+ // tree without paragraph spacing, Markdown formatting or whitespace folding.
25
+ const literalText = node => {
26
+ if (node.nodeType === Node.TEXT_NODE) return node.textContent ?? "";
27
+ if (!(node instanceof HTMLElement) || node.tagName === "IMG") return "";
28
+ if (node.tagName === "BR") return "\n";
29
+ if (/^(DIV|P)$/.test(node.tagName) && node.childNodes.length === 1 && node.firstChild?.nodeName === "BR") return "";
30
+ const lines = [];
31
+ let run = null;
32
+ for (const child of node.childNodes) {
33
+ if (child instanceof HTMLElement && isBlock(child)) {
34
+ if (run !== null) lines.push(run);
35
+ run = null;
36
+ lines.push(literalText(child));
37
+ } else run = (run ?? "") + literalText(child);
38
+ }
39
+ if (run !== null) lines.push(run);
40
+ return lines.join("\n");
41
+ };
42
+ const isBold = el => {
43
+ const weight = el.style.fontWeight;
44
+ if (weight === "normal" || weight === "400") return false; // Google Docs wraps everything in <b style="font-weight:normal">
45
+ return el.tagName === "B" || el.tagName === "STRONG" || weight === "bold" || Number(weight) >= 600;
46
+ };
47
+ const isItalic = el => el.tagName === "I" || el.tagName === "EM" || el.style.fontStyle === "italic";
48
+ const surround = (text, before, after = before) => {
49
+ const body = text.trim();
50
+ if (!body) return text;
51
+ const from = text.length - text.trimStart().length;
52
+ return text.slice(0, from) + before + body + after + text.slice(from + body.length);
53
+ };
54
+ const codeFence = (text, minimum) => {
55
+ let length = minimum;
56
+ for (const match of text.matchAll(/`+/g)) length = Math.max(length, match[0].length + 1);
57
+ return "`".repeat(length);
58
+ };
59
+ const inline = node => {
60
+ if (node.nodeType === Node.TEXT_NODE) return (node.textContent ?? "").replace(/\s+/g, " ");
61
+ if (!(node instanceof HTMLElement)) return "";
62
+ if (node.tagName === "BR") return "\n";
63
+ if (node.tagName === "IMG") return "";
64
+ if (node.tagName === "CODE") {
65
+ const text = node.textContent ?? "";
66
+ if (!text) return "";
67
+ const fence = codeFence(text, 1);
68
+ const padding = text.startsWith("`") || text.endsWith("`") ? " " : "";
69
+ return `${fence}${padding}${text}${padding}${fence}`;
70
+ }
71
+ const inner = [...node.childNodes].map(inline).join("");
72
+ if (!inner.trim()) return inner;
73
+ if (node.tagName === "A") {
74
+ const href = node.getAttribute("href") ?? "";
75
+ return SAFE_URL.test(href) ? surround(inner, "[", `](${href})`) : inner;
76
+ }
77
+ if (node.tagName === "S" || node.tagName === "DEL") return `~~${inner}~~`;
78
+ let out = inner;
79
+ if (isItalic(node)) out = surround(out, "*");
80
+ if (isBold(node)) out = surround(out, "**");
81
+ return out;
82
+ };
83
+ const blockContents = (node, out, prefix = "") => {
84
+ const hasBlocks = [...node.children].some(c => c instanceof HTMLElement && isBlock(c));
85
+ if (hasBlocks) {
86
+ let run = "";
87
+ for (const child of node.childNodes) {
88
+ if (child instanceof HTMLElement && isBlock(child)) {
89
+ if (run.trim()) out.push(prefix + run.trim());
90
+ run = "";
91
+ block(child, out, prefix);
92
+ } else run += inline(child);
93
+ }
94
+ if (run.trim()) out.push(prefix + run.trim());
95
+ return;
96
+ }
97
+ const text = inline(node).trim();
98
+ if (text) out.push(prefix + text);
99
+ };
100
+ const block = (node, out, prefix = "") => {
101
+ if (!(node instanceof HTMLElement)) {
102
+ const text = inline(node).trim();
103
+ if (text) out.push(prefix + text);
104
+ return;
105
+ }
106
+ const tag = node.tagName;
107
+ if (preservesWhitespace(node)) {
108
+ const text = literalText(node);
109
+ const fence = codeFence(text, 3);
110
+ out.push(`${fence}\n${text}${text.endsWith("\n") ? "" : "\n"}${fence}`);
111
+ return;
112
+ }
113
+ const heading = /^H([1-6])$/.exec(tag);
114
+ if (heading) return void out.push(`${"#".repeat(Math.min(3, Number(heading[1])))} ${inline(node).trim()}`);
115
+ if (tag === "TABLE") {
116
+ const grid = [...node.querySelectorAll("tr")].map(tr => [...tr.querySelectorAll("th,td")].map(c => inline(c).trim()));
117
+ if (grid.length) out.push(tableFromGrid(grid));
118
+ return;
119
+ }
120
+ if (tag === "UL" || tag === "OL") {
121
+ [...node.children].forEach((li, i) => {
122
+ if (li.tagName !== "LI") return;
123
+ const marker = tag === "OL" ? `${i + 1}. ` : "- ";
124
+ const nested = [...li.childNodes].filter(c => !(c instanceof HTMLElement && (c.tagName === "UL" || c.tagName === "OL")));
125
+ out.push(`${prefix}${marker}${nested.map(inline).join("").trim()}`);
126
+ li.querySelectorAll(":scope > ul, :scope > ol").forEach(sub => block(sub, out, `${prefix} `));
127
+ });
128
+ return;
129
+ }
130
+ if (tag === "BLOCKQUOTE") {
131
+ const inner = [];
132
+ blockContents(node, inner);
133
+ out.push(inner.join("\n\n").split("\n").map(line => `> ${line}`).join("\n"));
134
+ return;
135
+ }
136
+ if (tag === "HR") return void out.push("---");
137
+ blockContents(node, out, prefix);
138
+ };
139
+ export const convertHtml = (html, code) => {
140
+ const doc = parseClipboardHtml(html);
141
+ doc.querySelectorAll("style,script,meta,link,title,o\\:p,xml").forEach(el => el.remove());
142
+ const droppedImages = doc.querySelectorAll("img").length;
143
+ const out = [];
144
+ if (!code) block(doc, out);
145
+ // Block boundaries supply their own spacing; normalizing the result would alter literal code.
146
+ const markdown = code ? literalText(doc) : out.join("\n\n").trim();
147
+ return markdown || droppedImages ? {
148
+ markdown,
149
+ droppedImages
150
+ } : null;
151
+ };
152
+ //# sourceMappingURL=clipboard-html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["text-editor/clipboard-html.ts"],"sourcesContent":["import DOMPurify from \"dompurify\";\nimport { tableFromGrid } from \"./markdown-table\";\n\n/** Parse only the HTML vocabulary that the Markdown converter consumes.\n * Resource attributes and active elements never reach a clipboard consumer.\n * The returned detached body is read as data and never mounted in the editor.\n */\nexport const parseClipboardHtml = (html: string): HTMLElement => {\n const body = DOMPurify.sanitize(html, {\n ALLOWED_TAGS: [\n \"p\",\n \"div\",\n \"span\",\n \"u\",\n \"font\",\n \"abbr\",\n \"acronym\",\n \"cite\",\n \"dfn\",\n \"mark\",\n \"q\",\n \"small\",\n \"sub\",\n \"sup\",\n \"big\",\n \"tt\",\n \"ins\",\n \"time\",\n \"var\",\n \"samp\",\n \"kbd\",\n \"ruby\",\n \"rt\",\n \"rp\",\n \"bdi\",\n \"bdo\",\n \"br\",\n \"b\",\n \"strong\",\n \"i\",\n \"em\",\n \"s\",\n \"del\",\n \"a\",\n \"code\",\n \"pre\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"ul\",\n \"ol\",\n \"li\",\n \"blockquote\",\n \"hr\",\n \"section\",\n \"article\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tfoot\",\n \"tr\",\n \"th\",\n \"td\",\n \"img\",\n ],\n ALLOWED_ATTR: [\"href\", \"style\"],\n ALLOW_DATA_ATTR: false,\n ALLOW_ARIA_ATTR: false,\n RETURN_DOM: true,\n });\n if (!(body instanceof HTMLElement)) throw new TypeError(\"Clipboard HTML did not produce an HTML element\");\n return body;\n};\n\nconst SAFE_URL = /^(https?:|mailto:)/i;\nconst preservesWhitespace = (node: HTMLElement) => node.tagName === \"PRE\" || /^(pre|pre-wrap|break-spaces)$/.test(node.style.whiteSpace);\nconst isBlock = (node: HTMLElement) =>\n /^(P|DIV|H[1-6]|UL|OL|TABLE|BLOCKQUOTE|PRE|HR|SECTION|ARTICLE)$/.test(node.tagName) || preservesWhitespace(node);\n\n// Editor clipboards use one div per source line. Read the sanitized, detached\n// tree without paragraph spacing, Markdown formatting or whitespace folding.\nconst literalText = (node: Node): string => {\n if (node.nodeType === Node.TEXT_NODE) return node.textContent ?? \"\";\n if (!(node instanceof HTMLElement) || node.tagName === \"IMG\") return \"\";\n if (node.tagName === \"BR\") return \"\\n\";\n if (/^(DIV|P)$/.test(node.tagName) && node.childNodes.length === 1 && node.firstChild?.nodeName === \"BR\") return \"\";\n const lines: string[] = [];\n let run: string | null = null;\n for (const child of node.childNodes) {\n if (child instanceof HTMLElement && isBlock(child)) {\n if (run !== null) lines.push(run);\n run = null;\n lines.push(literalText(child));\n } else run = (run ?? \"\") + literalText(child);\n }\n if (run !== null) lines.push(run);\n return lines.join(\"\\n\");\n};\n\nconst isBold = (el: HTMLElement) => {\n const weight = el.style.fontWeight;\n if (weight === \"normal\" || weight === \"400\") return false; // Google Docs wraps everything in <b style=\"font-weight:normal\">\n return el.tagName === \"B\" || el.tagName === \"STRONG\" || weight === \"bold\" || Number(weight) >= 600;\n};\nconst isItalic = (el: HTMLElement) => el.tagName === \"I\" || el.tagName === \"EM\" || el.style.fontStyle === \"italic\";\n\nconst surround = (text: string, before: string, after = before): string => {\n const body = text.trim();\n if (!body) return text;\n const from = text.length - text.trimStart().length;\n return text.slice(0, from) + before + body + after + text.slice(from + body.length);\n};\n\nconst codeFence = (text: string, minimum: number): string => {\n let length = minimum;\n for (const match of text.matchAll(/`+/g)) length = Math.max(length, match[0].length + 1);\n return \"`\".repeat(length);\n};\n\nconst inline = (node: Node): string => {\n if (node.nodeType === Node.TEXT_NODE) return (node.textContent ?? \"\").replace(/\\s+/g, \" \");\n if (!(node instanceof HTMLElement)) return \"\";\n if (node.tagName === \"BR\") return \"\\n\";\n if (node.tagName === \"IMG\") return \"\";\n if (node.tagName === \"CODE\") {\n const text = node.textContent ?? \"\";\n if (!text) return \"\";\n const fence = codeFence(text, 1);\n const padding = text.startsWith(\"`\") || text.endsWith(\"`\") ? \" \" : \"\";\n return `${fence}${padding}${text}${padding}${fence}`;\n }\n const inner = [...node.childNodes].map(inline).join(\"\");\n if (!inner.trim()) return inner;\n if (node.tagName === \"A\") {\n const href = node.getAttribute(\"href\") ?? \"\";\n return SAFE_URL.test(href) ? surround(inner, \"[\", `](${href})`) : inner;\n }\n if (node.tagName === \"S\" || node.tagName === \"DEL\") return `~~${inner}~~`;\n let out = inner;\n if (isItalic(node)) out = surround(out, \"*\");\n if (isBold(node)) out = surround(out, \"**\");\n return out;\n};\n\nconst blockContents = (node: HTMLElement, out: string[], prefix = \"\"): void => {\n const hasBlocks = [...node.children].some((c) => c instanceof HTMLElement && isBlock(c));\n if (hasBlocks) {\n let run = \"\";\n for (const child of node.childNodes) {\n if (child instanceof HTMLElement && isBlock(child)) {\n if (run.trim()) out.push(prefix + run.trim());\n run = \"\";\n block(child, out, prefix);\n } else run += inline(child);\n }\n if (run.trim()) out.push(prefix + run.trim());\n return;\n }\n const text = inline(node).trim();\n if (text) out.push(prefix + text);\n};\n\nconst block = (node: Node, out: string[], prefix = \"\"): void => {\n if (!(node instanceof HTMLElement)) {\n const text = inline(node).trim();\n if (text) out.push(prefix + text);\n return;\n }\n const tag = node.tagName;\n if (preservesWhitespace(node)) {\n const text = literalText(node);\n const fence = codeFence(text, 3);\n out.push(`${fence}\\n${text}${text.endsWith(\"\\n\") ? \"\" : \"\\n\"}${fence}`);\n return;\n }\n const heading = /^H([1-6])$/.exec(tag);\n if (heading) return void out.push(`${\"#\".repeat(Math.min(3, Number(heading[1])))} ${inline(node).trim()}`);\n if (tag === \"TABLE\") {\n const grid = [...node.querySelectorAll(\"tr\")].map((tr) => [...tr.querySelectorAll(\"th,td\")].map((c) => inline(c).trim()));\n if (grid.length) out.push(tableFromGrid(grid));\n return;\n }\n if (tag === \"UL\" || tag === \"OL\") {\n [...node.children].forEach((li, i) => {\n if (li.tagName !== \"LI\") return;\n const marker = tag === \"OL\" ? `${i + 1}. ` : \"- \";\n const nested = [...li.childNodes].filter((c) => !(c instanceof HTMLElement && (c.tagName === \"UL\" || c.tagName === \"OL\")));\n out.push(`${prefix}${marker}${nested.map(inline).join(\"\").trim()}`);\n li.querySelectorAll(\":scope > ul, :scope > ol\").forEach((sub) => block(sub, out, `${prefix} `));\n });\n return;\n }\n if (tag === \"BLOCKQUOTE\") {\n const inner: string[] = [];\n blockContents(node, inner);\n out.push(\n inner\n .join(\"\\n\\n\")\n .split(\"\\n\")\n .map((line) => `> ${line}`)\n .join(\"\\n\"),\n );\n return;\n }\n if (tag === \"HR\") return void out.push(\"---\");\n blockContents(node, out, prefix);\n};\n\nexport const convertHtml = (html: string, code: boolean): { markdown: string; droppedImages: number } | null => {\n const doc = parseClipboardHtml(html);\n doc.querySelectorAll(\"style,script,meta,link,title,o\\\\:p,xml\").forEach((el) => el.remove());\n const droppedImages = doc.querySelectorAll(\"img\").length;\n const out: string[] = [];\n if (!code) block(doc, out);\n // Block boundaries supply their own spacing; normalizing the result would alter literal code.\n const markdown = code ? literalText(doc) : out.join(\"\\n\\n\").trim();\n return markdown || droppedImages ? { markdown, droppedImages } : null;\n};\n"],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW;AACjC,SAAS,aAAa,QAAQ,kBAAkB;;AAEhD;AACA;AACA;AACA;AACA,OAAO,MAAM,kBAAkB,GAAI,IAAY,IAAkB;EAC/D,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE;IACpC,YAAY,EAAE,CACZ,GAAG,EACH,KAAK,EACL,MAAM,EACN,GAAG,EACH,MAAM,EACN,MAAM,EACN,SAAS,EACT,MAAM,EACN,KAAK,EACL,MAAM,EACN,GAAG,EACH,OAAO,EACP,KAAK,EACL,KAAK,EACL,KAAK,EACL,IAAI,EACJ,KAAK,EACL,MAAM,EACN,KAAK,EACL,MAAM,EACN,KAAK,EACL,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,KAAK,EACL,IAAI,EACJ,GAAG,EACH,QAAQ,EACR,GAAG,EACH,IAAI,EACJ,GAAG,EACH,KAAK,EACL,GAAG,EACH,MAAM,EACN,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,YAAY,EACZ,IAAI,EACJ,SAAS,EACT,SAAS,EACT,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,KAAK,CACN;IACD,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/B,eAAe,EAAE,KAAK;IACtB,eAAe,EAAE,KAAK;IACtB,UAAU,EAAE;EACd,CAAC,CAAC;EACF,IAAI,EAAE,IAAI,YAAY,WAAW,CAAC,EAAE,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC;EACzG,OAAO,IAAI;AACb,CAAC;AAED,MAAM,QAAQ,GAAG,qBAAqB;AACtC,MAAM,mBAAmB,GAAI,IAAiB,IAAK,IAAI,CAAC,OAAO,KAAK,KAAK,IAAI,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;AACxI,MAAM,OAAO,GAAI,IAAiB,IAChC,gEAAgE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC;;AAElH;AACA;AACA,MAAM,WAAW,GAAI,IAAU,IAAa;EAC1C,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE,OAAO,IAAI,CAAC,WAAW,IAAI,EAAE;EACnE,IAAI,EAAE,IAAI,YAAY,WAAW,CAAC,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE,OAAO,EAAE;EACvE,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,OAAO,IAAI;EACtC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,QAAQ,KAAK,IAAI,EAAE,OAAO,EAAE;EACnH,MAAM,KAAe,GAAG,EAAE;EAC1B,IAAI,GAAkB,GAAG,IAAI;EAC7B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,EAAE;IACnC,IAAI,KAAK,YAAY,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE;MAClD,IAAI,GAAG,KAAK,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;MACjC,GAAG,GAAG,IAAI;MACV,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,IAAI,WAAW,CAAC,KAAK,CAAC;EAC/C;EACA,IAAI,GAAG,KAAK,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;EACjC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,MAAM,MAAM,GAAI,EAAe,IAAK;EAClC,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU;EAClC,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,KAAK,EAAE,OAAO,KAAK,CAAC,CAAC;EAC3D,OAAO,EAAE,CAAC,OAAO,KAAK,GAAG,IAAI,EAAE,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG;AACpG,CAAC;AACD,MAAM,QAAQ,GAAI,EAAe,IAAK,EAAE,CAAC,OAAO,KAAK,GAAG,IAAI,EAAE,CAAC,OAAO,KAAK,IAAI,IAAI,EAAE,CAAC,KAAK,CAAC,SAAS,KAAK,QAAQ;AAElH,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,MAAc,EAAE,KAAK,GAAG,MAAM,KAAa;EACzE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;EACxB,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI;EACtB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;EAClD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;AACrF,CAAC;AAED,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,OAAe,KAAa;EAC3D,IAAI,MAAM,GAAG,OAAO;EACpB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;EACxF,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;AAC3B,CAAC;AAED,MAAM,MAAM,GAAI,IAAU,IAAa;EACrC,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;EAC1F,IAAI,EAAE,IAAI,YAAY,WAAW,CAAC,EAAE,OAAO,EAAE;EAC7C,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,OAAO,IAAI;EACtC,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE,OAAO,EAAE;EACrC,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,EAAE;IAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,IAAI,EAAE;IACnC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE;IACpB,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,EAAE;IACrE,OAAO,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,GAAG,OAAO,GAAG,KAAK,EAAE;EACtD;EACA,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;EACvD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,KAAK;EAC/B,IAAI,IAAI,CAAC,OAAO,KAAK,GAAG,EAAE;IACxB,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE;IAC5C,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK;EACzE;EACA,IAAI,IAAI,CAAC,OAAO,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI;EACzE,IAAI,GAAG,GAAG,KAAK;EACf,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;EAC3C,OAAO,GAAG;AACZ,CAAC;AAED,MAAM,aAAa,GAAG,CAAC,IAAiB,EAAE,GAAa,EAAE,MAAM,GAAG,EAAE,KAAW;EAC7E,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAE,CAAC,IAAK,CAAC,YAAY,WAAW,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;EACxF,IAAI,SAAS,EAAE;IACb,IAAI,GAAG,GAAG,EAAE;IACZ,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,EAAE;MACnC,IAAI,KAAK,YAAY,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE;QAClD,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7C,GAAG,GAAG,EAAE;QACR,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC;MAC3B,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC;IAC7B;IACA,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7C;EACF;EACA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;EAChC,IAAI,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;AACnC,CAAC;AAED,MAAM,KAAK,GAAG,CAAC,IAAU,EAAE,GAAa,EAAE,MAAM,GAAG,EAAE,KAAW;EAC9D,IAAI,EAAE,IAAI,YAAY,WAAW,CAAC,EAAE;IAClC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACjC;EACF;EACA,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO;EACxB,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE;IAC7B,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC;IAC9B,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAChC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;IACvE;EACF;EACA,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;EACtC,IAAI,OAAO,EAAE,OAAO,KAAK,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;EAC1G,IAAI,GAAG,KAAK,OAAO,EAAE;IACnB,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAE,EAAE,IAAK,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAE,CAAC,IAAK,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzH,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC9C;EACF;EACA,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,EAAE;IAChC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK;MACpC,IAAI,EAAE,CAAC,OAAO,KAAK,IAAI,EAAE;MACzB,MAAM,MAAM,GAAG,GAAG,KAAK,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI;MACjD,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,MAAM,CAAE,CAAC,IAAK,EAAE,CAAC,YAAY,WAAW,KAAK,CAAC,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC;MAC1H,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;MACnE,EAAE,CAAC,gBAAgB,CAAC,0BAA0B,CAAC,CAAC,OAAO,CAAE,GAAG,IAAK,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC;IAClG,CAAC,CAAC;IACF;EACF;EACA,IAAI,GAAG,KAAK,YAAY,EAAE;IACxB,MAAM,KAAe,GAAG,EAAE;IAC1B,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC;IAC1B,GAAG,CAAC,IAAI,CACN,KAAK,CACF,IAAI,CAAC,MAAM,CAAC,CACZ,KAAK,CAAC,IAAI,CAAC,CACX,GAAG,CAAE,IAAI,IAAK,KAAK,IAAI,EAAE,CAAC,CAC1B,IAAI,CAAC,IAAI,CACd,CAAC;IACD;EACF;EACA,IAAI,GAAG,KAAK,IAAI,EAAE,OAAO,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;EAC7C,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC;AAClC,CAAC;AAED,OAAO,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,IAAa,KAAyD;EAC9G,MAAM,GAAG,GAAG,kBAAkB,CAAC,IAAI,CAAC;EACpC,GAAG,CAAC,gBAAgB,CAAC,wCAAwC,CAAC,CAAC,OAAO,CAAE,EAAE,IAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;EAC3F,MAAM,aAAa,GAAG,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,MAAM;EACxD,MAAM,GAAa,GAAG,EAAE;EACxB,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC;EAC1B;EACA,MAAM,QAAQ,GAAG,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;EAClE,OAAO,QAAQ,IAAI,aAAa,GAAG;IAAE,QAAQ;IAAE;EAAc,CAAC,GAAG,IAAI;AACvE,CAAC","ignoreList":[]}
@@ -0,0 +1,68 @@
1
+ import { ViewPlugin } from "@codemirror/view";
2
+ import { htmlClipboardReady, loadHtmlClipboard } from "./clipboard";
3
+ /** Load the HTML sanitizer only when needed, before either paste consumer runs.
4
+ * A delayed paste never overwrites edits made while its parser was loading.
5
+ */
6
+ export const clipboardLoading = (getHost, syncSelection) => ViewPlugin.define(view => {
7
+ let disposed = false;
8
+ let pending = false;
9
+ const paste = event => {
10
+ const host = getHost(view);
11
+ const data = event.clipboardData;
12
+ if (view.state.readOnly || htmlClipboardReady() || !data?.getData("text/html")) return;
13
+ event.preventDefault();
14
+ event.stopImmediatePropagation();
15
+ const text = data.getData("text/plain");
16
+ const html = data.getData("text/html");
17
+ if (text.length > (host?.maxLength ?? Infinity) || html.length > (host?.maxLength ?? Infinity)) {
18
+ host?.onError("textTooLarge");
19
+ return;
20
+ }
21
+ // Only one delayed paste is retained. Further attempts keep their input in
22
+ // the existing visible recovery surface instead of building an input queue.
23
+ if (pending) {
24
+ host?.onRecovery(text || html);
25
+ return;
26
+ }
27
+ // Native selectionchange may still be queued when paste arrives. Let the
28
+ // cell publish that same caret before capturing the delayed paste target.
29
+ syncSelection?.(view);
30
+ const clipboard = new DataTransfer();
31
+ clipboard.setData("text/plain", text);
32
+ clipboard.setData("text/html", html);
33
+ for (const file of data.files) clipboard.items.add(file);
34
+ const target = event.target;
35
+ const doc = view.state.doc;
36
+ const selection = view.state.selection;
37
+ const focused = view.dom.ownerDocument.activeElement;
38
+ const native = view.dom.ownerDocument.getSelection();
39
+ const range = native?.rangeCount ? native.getRangeAt(0).cloneRange() : null;
40
+ pending = true;
41
+ void loadHtmlClipboard().then(() => {
42
+ const current = view.dom.ownerDocument.getSelection();
43
+ const currentRange = current?.rangeCount ? current.getRangeAt(0) : null;
44
+ const sameRange = !range || currentRange && range.startContainer === currentRange.startContainer && range.endContainer === currentRange.endContainer && range.startOffset === currentRange.startOffset && range.endOffset === currentRange.endOffset;
45
+ if (disposed || view.state.readOnly || view.state.doc !== doc || !view.state.selection.eq(selection) || view.dom.ownerDocument.activeElement !== focused || !sameRange || !(target instanceof HTMLElement) || !target.isConnected) {
46
+ host?.onRecovery(text || html);
47
+ return;
48
+ }
49
+ // CodeMirror and the cell widget run their normal limit, conversion and
50
+ // selection logic. No untrusted HTML is mounted by this loader.
51
+ target.dispatchEvent(new ClipboardEvent("paste", {
52
+ bubbles: true,
53
+ cancelable: true,
54
+ clipboardData: clipboard
55
+ }));
56
+ }).catch(() => host?.onRecovery(text || html)).finally(() => {
57
+ pending = false;
58
+ });
59
+ };
60
+ view.dom.addEventListener("paste", paste, true);
61
+ return {
62
+ destroy() {
63
+ disposed = true;
64
+ view.dom.removeEventListener("paste", paste, true);
65
+ }
66
+ };
67
+ });
68
+ //# sourceMappingURL=clipboard-loading.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["text-editor/clipboard-loading.ts"],"sourcesContent":["import { type EditorView, ViewPlugin } from \"@codemirror/view\";\nimport { htmlClipboardReady, loadHtmlClipboard } from \"./clipboard\";\nimport type { TableHost } from \"./table\";\n\n/** Load the HTML sanitizer only when needed, before either paste consumer runs.\n * A delayed paste never overwrites edits made while its parser was loading.\n */\nexport const clipboardLoading = (getHost: (view: EditorView) => TableHost | null, syncSelection?: (view: EditorView) => void) =>\n ViewPlugin.define((view) => {\n let disposed = false;\n let pending = false;\n const paste = (event: ClipboardEvent) => {\n const host = getHost(view);\n const data = event.clipboardData;\n if (view.state.readOnly || htmlClipboardReady() || !data?.getData(\"text/html\")) return;\n event.preventDefault();\n event.stopImmediatePropagation();\n const text = data.getData(\"text/plain\");\n const html = data.getData(\"text/html\");\n if (text.length > (host?.maxLength ?? Infinity) || html.length > (host?.maxLength ?? Infinity)) {\n host?.onError(\"textTooLarge\");\n return;\n }\n // Only one delayed paste is retained. Further attempts keep their input in\n // the existing visible recovery surface instead of building an input queue.\n if (pending) {\n host?.onRecovery(text || html);\n return;\n }\n // Native selectionchange may still be queued when paste arrives. Let the\n // cell publish that same caret before capturing the delayed paste target.\n syncSelection?.(view);\n const clipboard = new DataTransfer();\n clipboard.setData(\"text/plain\", text);\n clipboard.setData(\"text/html\", html);\n for (const file of data.files) clipboard.items.add(file);\n const target = event.target;\n const doc = view.state.doc;\n const selection = view.state.selection;\n const focused = view.dom.ownerDocument.activeElement;\n const native = view.dom.ownerDocument.getSelection();\n const range = native?.rangeCount ? native.getRangeAt(0).cloneRange() : null;\n pending = true;\n void loadHtmlClipboard()\n .then(() => {\n const current = view.dom.ownerDocument.getSelection();\n const currentRange = current?.rangeCount ? current.getRangeAt(0) : null;\n const sameRange =\n !range ||\n (currentRange &&\n range.startContainer === currentRange.startContainer &&\n range.endContainer === currentRange.endContainer &&\n range.startOffset === currentRange.startOffset &&\n range.endOffset === currentRange.endOffset);\n if (\n disposed ||\n view.state.readOnly ||\n view.state.doc !== doc ||\n !view.state.selection.eq(selection) ||\n view.dom.ownerDocument.activeElement !== focused ||\n !sameRange ||\n !(target instanceof HTMLElement) ||\n !target.isConnected\n ) {\n host?.onRecovery(text || html);\n return;\n }\n // CodeMirror and the cell widget run their normal limit, conversion and\n // selection logic. No untrusted HTML is mounted by this loader.\n target.dispatchEvent(new ClipboardEvent(\"paste\", { bubbles: true, cancelable: true, clipboardData: clipboard }));\n })\n .catch(() => host?.onRecovery(text || html))\n .finally(() => {\n pending = false;\n });\n };\n view.dom.addEventListener(\"paste\", paste, true);\n return {\n destroy() {\n disposed = true;\n view.dom.removeEventListener(\"paste\", paste, true);\n },\n };\n });\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,51 @@
1
+ import { findTables, parseTsv } from "./markdown-table";
2
+ let parser;
3
+ let loading;
4
+ export const htmlClipboardReady = () => parser !== undefined;
5
+ export const loadHtmlClipboard = () => loading ??= import("./clipboard-html").then(module => {
6
+ parser = module;
7
+ }, error => {
8
+ loading = undefined;
9
+ throw error;
10
+ });
11
+ const loaded = () => {
12
+ if (!parser) throw new Error("HTML clipboard parser is not loaded");
13
+ return parser;
14
+ };
15
+ export const parseClipboardHtml = html => loaded().parseClipboardHtml(html);
16
+ export const convertClipboardHtml = (html, code) => loaded().convertHtml(html, code);
17
+
18
+ /** All clipboard entry paths share one preflight, before insertion or conversion. */
19
+ export function inspectClipboard(data, limits) {
20
+ const text = data.getData("text/plain");
21
+ const html = data.getData("text/html");
22
+ if (text.length > limits.maxLength || html.length > limits.maxLength) return {
23
+ error: "textTooLarge"
24
+ };
25
+ const tsv = parseTsv(text);
26
+ let cells = tsv ? tsv.length * tsv.reduce((width, row) => Math.max(width, row.length), 0) : 0;
27
+ for (const table of findTables(text)) cells += (table.lines.length - 1) * table.lines.reduce((width, row) => Math.max(width, row.cells.length), 0);
28
+ const files = Array.from(data.files).filter(file => file.type.startsWith("image/"));
29
+ let images = files.length;
30
+ if (html) {
31
+ const dom = parseClipboardHtml(html);
32
+ images = Math.max(images, dom.querySelectorAll("img").length);
33
+ let htmlCells = 0;
34
+ for (const table of dom.querySelectorAll("table")) {
35
+ const rows = [...table.querySelectorAll("tr")];
36
+ htmlCells += rows.length * rows.reduce((width, row) => Math.max(width, row.querySelectorAll("td,th").length), 0);
37
+ }
38
+ cells = Math.max(cells, htmlCells);
39
+ }
40
+ if (cells > limits.maxPasteCells) return {
41
+ error: "pasteTooLarge"
42
+ };
43
+ return {
44
+ text,
45
+ html,
46
+ images,
47
+ files,
48
+ tsv
49
+ };
50
+ }
51
+ //# sourceMappingURL=clipboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["text-editor/clipboard.ts"],"sourcesContent":["import { findTables, parseTsv } from \"./markdown-table\";\n\ntype HtmlClipboard = typeof import(\"./clipboard-html\");\nlet parser: HtmlClipboard | undefined;\nlet loading: Promise<void> | undefined;\nexport const htmlClipboardReady = () => parser !== undefined;\nexport const loadHtmlClipboard = (): Promise<void> =>\n (loading ??= import(\"./clipboard-html\").then(\n (module) => {\n parser = module;\n },\n (error: unknown) => {\n loading = undefined;\n throw error;\n },\n ));\nconst loaded = (): HtmlClipboard => {\n if (!parser) throw new Error(\"HTML clipboard parser is not loaded\");\n return parser;\n};\nexport const parseClipboardHtml = (html: string) => loaded().parseClipboardHtml(html);\nexport const convertClipboardHtml = (html: string, code: boolean) => loaded().convertHtml(html, code);\n\n/** All clipboard entry paths share one preflight, before insertion or conversion. */\nexport function inspectClipboard(\n data: DataTransfer,\n limits: { maxLength: number; maxPasteCells: number },\n): { error: \"textTooLarge\" | \"pasteTooLarge\" } | { text: string; html: string; images: number; files: File[]; tsv: string[][] | null } {\n const text = data.getData(\"text/plain\");\n const html = data.getData(\"text/html\");\n if (text.length > limits.maxLength || html.length > limits.maxLength) return { error: \"textTooLarge\" } as const;\n const tsv = parseTsv(text);\n let cells = tsv ? tsv.length * tsv.reduce((width, row) => Math.max(width, row.length), 0) : 0;\n for (const table of findTables(text))\n cells += (table.lines.length - 1) * table.lines.reduce((width, row) => Math.max(width, row.cells.length), 0);\n const files = Array.from(data.files).filter((file) => file.type.startsWith(\"image/\"));\n let images = files.length;\n if (html) {\n const dom = parseClipboardHtml(html);\n images = Math.max(images, dom.querySelectorAll(\"img\").length);\n let htmlCells = 0;\n for (const table of dom.querySelectorAll(\"table\")) {\n const rows = [...table.querySelectorAll(\"tr\")];\n htmlCells += rows.length * rows.reduce((width, row) => Math.max(width, row.querySelectorAll(\"td,th\").length), 0);\n }\n cells = Math.max(cells, htmlCells);\n }\n if (cells > limits.maxPasteCells) return { error: \"pasteTooLarge\" } as const;\n return { text, html, images, files, tsv };\n}\n"],"mappings":"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","ignoreList":[]}