import '@prosekit/pm/view/style/prosemirror.css' import { defineBaseCommands, defineBaseKeymap, defineHistory, union, type Extension, type ExtractMarkActions, type ExtractNodeActions, type NodeChild, } from '@prosekit/core' import { createTestEditor, readClipboardHTML, readClipboardText, type TestEditor } from '@prosekit/core/test' import { formatHTML } from 'diffable-html-snapshot' import { keyboard } from 'vitest-browser-commands/playwright' import { defineBackgroundColor } from '../background-color/index.ts' import { defineBlockquote } from '../blockquote/index.ts' import { defineBold } from '../bold/index.ts' import { defineCodeBlock } from '../code-block/index.ts' import { defineCode } from '../code/index.ts' import { defineDoc } from '../doc/index.ts' import { defineFontFamily } from '../font-family/index.ts' import { defineHardBreak } from '../hard-break/index.ts' import { defineHeading } from '../heading/index.ts' import { defineHighlight } from '../highlight/index.ts' import { defineHorizontalRule } from '../horizontal-rule/index.ts' import { defineImage } from '../image/index.ts' import { defineItalic } from '../italic/index.ts' import { defineLink } from '../link/index.ts' import { defineList, type ListAttrs } from '../list/index.ts' import { defineMath } from '../math/index.ts' import { defineParagraph } from '../paragraph/index.ts' import { defineStrike } from '../strike/index.ts' import { defineSubscript } from '../subscript/index.ts' import { defineSuperscript } from '../superscript/index.ts' import { defineTable } from '../table/index.ts' import type { CellAttrs } from '../table/table-spec.ts' import { defineTextColor } from '../text-color/index.ts' import { defineText } from '../text/index.ts' import { defineUnderline } from '../underline/index.ts' import { renderMathBlock, renderMathInline } from './katex.ts' /** * @internal */ export function defineTestExtension() { return union( defineDoc(), defineText(), defineHeading(), defineHighlight(), defineHistory(), defineList(), defineBlockquote(), defineBaseKeymap(), defineBaseCommands(), defineItalic(), defineBold(), defineUnderline(), defineStrike(), defineSubscript(), defineSuperscript(), defineCode(), defineFontFamily(), defineTextColor(), defineBackgroundColor(), defineLink(), defineImage(), defineParagraph(), defineTable(), defineHorizontalRule(), defineHardBreak(), defineCodeBlock(), defineMath({ renderMathBlock, renderMathInline }), ) } /** * @internal */ export function setupTestFromExtension( extension: E, ): { editor: TestEditor n: ExtractNodeActions m: ExtractMarkActions } { const editor = createTestEditor({ extension }) const div = document.body.appendChild(document.createElement('div')) div.style.minWidth = '200px' div.style.minHeight = '200px' editor.mount(div) editor.view.dom.focus() const n = editor.nodes const m = editor.marks return { editor, n, m } } /** * @internal */ export function setupTest() { const { editor, m, n } = setupTestFromExtension(defineTestExtension()) const listWithAttrs = (attrs: ListAttrs) => { return (...children: NodeChild[]) => { return n.list(attrs, ...children) } } const headingWithAttrs = (attrs: { level: number }) => { return (...children: NodeChild[]) => { return n.heading(attrs, ...children) } } const p = n.paragraph const td = (text?: string, attrs?: CellAttrs) => { return n.tableCell({ ...attrs }, text ? p(text) : p()) } const th = (text?: string, attrs?: CellAttrs) => { return n.tableHeaderCell({ ...attrs }, text ? p(text) : p()) } const copy = async () => { editor.view.dom.focus() await keyboard.press('ControlOrMeta+C') const html = formatHTML((await readClipboardHTML()) ?? '') const plain = (await readClipboardText()) ?? '' return { html, plain } } return { editor, m, n: { ...n, p, td, th, tr: n.tableRow, h1: headingWithAttrs({ level: 1 }), h2: headingWithAttrs({ level: 2 }), h3: headingWithAttrs({ level: 3 }), h4: headingWithAttrs({ level: 4 }), h5: headingWithAttrs({ level: 5 }), h6: headingWithAttrs({ level: 6 }), bullet: listWithAttrs({ kind: 'bullet' }), ordered: listWithAttrs({ kind: 'ordered' }), checked: listWithAttrs({ kind: 'task', checked: true }), unchecked: listWithAttrs({ kind: 'task', checked: false }), collapsed: listWithAttrs({ kind: 'toggle', collapsed: true }), expanded: listWithAttrs({ kind: 'toggle', collapsed: false }), }, copy, } }