0003. Edit with ProseMirror's headless core, without prosemirror-view
- Status: Accepted
- Date: 2026-10-01 (recorded with
@nextgensoftwares/folio-editor, commit65bcd0b)
Context
A paginated editor needs a document model with transactions, a selection model, undo history, structural commands, tables and collaboration. ProseMirror provides all of these as small, MIT-licensed, headless packages. Its view (prosemirror-view), however, is built on contenteditable: the browser lays out the text, and the DOM it renders would compete with Folio's own page layout.
Decision
@nextgensoftwares/folio-editor uses ProseMirror's headless packages (model, state, transform, commands, history, schema-list, keymap, tables, gapcursor, collab) for the document, selection, undo and collaboration, and does not use prosemirror-view or contenteditable. Folio lays out the document; a PositionIndex maps ProseMirror positions to positioned fragments (fragment paths mirror the ProseMirror tree; line offsets are ProseMirror inline offsets); the host draws pages, caret and selection and forwards input (a hidden textarea captures keys, IME and clipboard). The ProseMirror schema is generated from the Folio schema (toProseMirrorSchema), and DocBridge converts back to Folio JSON memoized per ProseMirror node.
Consequences
- We reuse a mature, well-tested editing core and its ecosystem (prosemirror-tables, prosemirror-collab) without its rendering model.
- What the user edits is exactly what layout produced: caret placement, hit-testing, vertical movement with a goal column, selection rects across pages and bidi-aware arrow keys all come from Folio's own geometry.
- Things the browser did for free with
contenteditablemust be implemented explicitly: grapheme-aware deletion, word deletion, IME positioning, the gap cursor beside figures, clipboard serialization. - ProseMirror drops undeclared attributes, so every attribute a host or plugin stores must be declared in the Folio schema.
- ProseMirror's flat top-level child array is O(blocks) per edit; at book scale this needs care (a verified fast content matcher; future section nodes).