Rich-text editing for Plain blocks (tight list items)#376
Merged
Conversation
Tight bullet/ordered lists store each item's content as a `Plain` block
(loose lists use `Para`; table cells are also `Plain`). The rich-text
block editor's gate `RICHTEXT_SUPPORTED_TYPES` listed only {Para, Header},
so clicking a tight-list item resolved a `Plain` sourceNode, the
availability check returned false, and the block fell back to the
monospaced textarea instead of the tiptap rich editor.
Add `Plain` to the set. Everything downstream is already Plain-aware:
`astToProseMirror` maps both Para and Plain to a paragraph node, and the
text-commit channel's `preserve_leaf_variant` (pampa `apply_node_edit.rs`)
coerces the re-parsed Paragraph back to Plain so editing a tight-list item
does not silently loosen the list (already covered by
`text_edit_preserves_{bullet,ordered}_list_tightness`).
Tests (TDD):
- richTextSupport.test.ts: the availability gate (module had no direct
test); the Plain assertions fail before this change, pass after.
- plain-list-item-richtext.integration.test.tsx: drives the real
PreviewRoot — a tight-list item opens the rich editor (toolbar present)
with the flag on, the textarea with it off. Fails when the fix is
reverted (true regression guard).
- richtext/plainSeed.test.ts: the single-Plain seed the editor uses
serializes back to the bare inline text (marks included), no dropped
nodes, no list marker.
Verified end-to-end via `q2 preview --allow-edit`: clicking a tight-list
item opens the tiptap editor (Pl breadcrumb); a text edit round-trips and
the on-disk list stays tight (all items Plain).
Note: a pre-existing rich-editor bug where a select-all + bold commit can
drop content (spurious hardBreak) is tracked separately as bd-hafs0qho;
it is not Plain-specific (shared, type-agnostic RichTextEditor path,
affects Para equally) and predates this change.
Strand: bd-7pxub583
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
In
format: q2-preview, the tiptap rich-text block editor only activated for a subset of Pandoc block types — its gateRICHTEXT_SUPPORTED_TYPESlisted{Para, Header}but notPlain. Tight bullet/ordered lists store each item's content as aPlainblock (loose lists usePara; table cells are alsoPlain), so clicking a tight-list item resolved aPlainsourceNode, the availability check returned false, and the block fell back to the monospaced textarea instead of the rich editor.This adds
Plainto the set (broad scope, per product direction: the more places the rich editor works, the better). Everything downstream was alreadyPlain-aware:astToProseMirrormaps bothParaandPlainto aparagraphnode.preserve_leaf_variant(pampaapply_node_edit.rs) coerces the re-parsedParagraphback toPlain, so editing a tight-list item does not silently loosen the list. Already covered bytext_edit_preserves_{bullet,ordered}_list_tightness.So the change is a one-line gate fix plus tests.
Tests (TDD)
richTextSupport.test.ts— the availability gate (the module had no direct test before). ThePlainassertions fail before this change, pass after.plain-list-item-richtext.integration.test.tsx— drives the realPreviewRoot: a tight-list item opens the rich editor (toolbar present) with the flag on, the textarea with it off. Confirmed to fail when the fix is reverted (true regression guard).richtext/plainSeed.test.ts— the single-Plainseed the editor uses serializes back to bare inline text (marks included), no dropped nodes, no list marker.Local: preview-renderer 484 unit + 517 integration + 15 oracle round-trip green; tsc clean.
End-to-end verification
Built the real chain (
cargo xtask build-q2-preview-spa+cargo build --bin q2) and droveq2 preview --allow-editin a browser on a tight-list fixture:<p>, formatting toolbar,Plbreadcrumb) — before this change it opened the textarea.banana→banana XX) commits and the on-disk file stays tight (pampa -t json→ all itemsPlain).Known pre-existing bug (not from this change) —
bd-hafs0qhoDuring E2E I found that a select-all + bold commit can drop the item's content (the committed ProseMirror doc becomes
paragraph[hardBreak]). The serializer and the Rust commit path are both verified correct; the fault is upstream in the editor. It is notPlain-specific — the RichTextEditor /astToProseMirror/ serializer are type-agnostic (Para and Plain share the code), aPararepro shows the same spurioushardBreak, and it predates this change. Filed as bd-hafs0qho (P1) for a clean root-cause.Strand: bd-7pxub583
🤖 Generated with Claude Code