Skip to content

fix(core): restore undo of autoformat conversions - #3164

Open
nperez0111 wants to merge 2 commits into
mainfrom
premium-bumblebee
Open

nperez0111 wants to merge 2 commits into
mainfrom
premium-bumblebee

Conversation

@nperez0111

@nperez0111 nperez0111 commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fix undo of autoformat conversions in ordinary history and Yjs 13 collaboration.

Closes #3153.

Rationale

Two independent problems prevent the first undo from restoring the literal input-rule trigger:

  • Converting a non-leaf content node into a leaf with setNodeMarkup creates a ReplaceAroundStep whose inverse fails its structure check. Ordinary history can leave the divider unchanged and throw a selection-position error.
  • Yjs 13 does not honor the closeHistory boundary dispatched between insertion of the literal trigger and the input-rule conversion, so both changes can merge into one undo item.

Changes

  • Use a strict, minimal ReplaceStep for non-leaf-to-leaf conversions, preserving the enclosing block, children, and neighboring nodes.
  • Translate ProseMirror's closeHistory marker into UndoManager.stopCapturing() in the Yjs 13 undo extension.
  • Extend existing updateBlock tests with general conversion undo/redo and minimal-step inversion regressions across paragraphs, headings, code blocks, dividers, and images.
  • Add adjacent Yjs undo tests for normal capture grouping and explicit history boundaries, using mounted editors in jsdom.

Impact

No public API changes. Other block updates retain their existing minimal-step behavior. Consecutive collaborative edits still group normally when no explicit history boundary is present.

Testing

  • 207 tests passed across 10 related test files; 3 existing tests skipped.
  • Regression failures verified with the fixes disabled, including the Yjs history-boundary test in its final mounted setup.
  • Scoped type-aware lint, formatting, and git diff --check passed.
  • Commit hook passed vp check --fix.
  • The full test/browser suite was not rerun on this final main-based branch.

Screenshots/Video

Not applicable: history/transaction fixes without visual styling changes.

Checklist

  • Code follows the project's coding standards.
  • Unit tests covering the fixes have been added.
  • All existing tests pass.
  • The documentation has been updated to reflect the new feature.

Additional Notes

This PR targets main directly and does not depend on #3090. Yjs 14 undo support and its equivalent upstream history-boundary fix are outside this PR's scope. No documentation changes are needed for this bug fix.

Summary by CodeRabbit

  • Bug Fixes
    • Undo and redo now correctly restore content when blocks are converted between types, including conversions to blocks without editable content. These conversions also preserve the surrounding block and its children.
    • In collaborative editing, consecutive changes are undone and redone together, while changes separated by a history boundary remain independently undoable. This keeps the editing history consistent across collaborators.

@vercel

vercel Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
blocknote Ready Ready Preview Oct 7, 2026 4:21am UTC
blocknote-website Ready Ready Preview Oct 7, 2026 4:21am UTC

Request Review

@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 7b8888b5-9d2f-46b2-a6ca-f38fcabb0c32
📥 Commits

Reviewing files that changed from the base of the PR and between 41bd8a9 and 56b4a96.

📒 Files selected for processing (1)
  • packages/core/src/yjs/comments/RESTYjsThreadStore.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Block conversion changes now use a strict replacement step for non-leaf-to-leaf conversions. The Yjs undo extension stops capturing when a transaction marks a ProseMirror history boundary. A thread-store test now cleans up its editor and Yjs document in a finally block.

Changes

Block Conversion Undo

Layer / File(s) Summary
Leaf conversion and history tests
packages/core/src/api/blockManipulation/commands/updateBlock/updateBlock.ts, packages/core/src/api/blockManipulation/commands/updateBlock/updateBlock.test.ts
Non-leaf-to-leaf conversions replace the node with a checked leaf while preserving merged attributes and marks. Tests cover undo and redo for block conversions, plus minimal and invertible replacement steps.

Yjs History Boundaries

Layer / File(s) Summary
History boundary integration and tests
packages/core/src/yjs/extensions/YUndo.ts, packages/core/src/yjs/extensions/YUndo.test.ts
The extension registers a plugin that calls stopCapturing() when a transaction carries closeHistory metadata. Tests cover edits grouped together and edits separated by a history boundary.

Yjs Thread Store Test Cleanup

Layer / File(s) Summary
Test resource cleanup
packages/core/src/yjs/comments/RESTYjsThreadStore.test.ts
The test destroys the editor and Yjs document in a finally block, including when an operation or assertion fails.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant ProseMirror
  participant YUndoExtension
  participant YjsUndoManager
  ProseMirror->>YUndoExtension: Dispatch transaction with closeHistory metadata
  YUndoExtension->>YjsUndoManager: Call stopCapturing()
  YUndoExtension-->>ProseMirror: Return no transaction
Loading

Merge Risk: ⚪ Minimal · up to 56b4a

The reviewed change ensures test resources are cleaned up even when an assertion fails. No actionable merge-blocking risk is established, so the change is mergeable under normal checks.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The incremental change wraps an existing resolvable-position test in cleanup that destroys its editor and Yjs document. That cleanup does not test or implement the conversion or history-boundary behav… Remove the unrelated cleanup change from packages/core/src/yjs/comments/RESTYjsThreadStore.test.ts.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 5 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: restoring undo for autoformat conversions.
Description check ✅ Passed The description covers the template’s required sections and explains the changes, impact, testing, and why screenshots and documentation are not applicable. It also discloses that the full test suite …
Linked Issues check ✅ Passed Issue [#3153] requires the first undo to restore the literal trigger after automatic conversion, then the next undo to remove the typed text. The non-leaf-to-leaf ReplaceStep is invertible and prese…
Full details: Out of Scope Changes check

Explanation

The incremental change wraps an existing resolvable-position test in cleanup that destroys its editor and Yjs document. That cleanup does not test or implement the conversion or history-boundary behavior for [#3153]. The new Yjs undo tests manage their own teardown, so the diff does not establish a need for this separate cleanup change.

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit typed three dashes with care,
Then watched a divider blossom there.
One undo brought the dashes back,
Yjs marked where edits would track.
The rabbit hopped through history,
And left each document tidy.

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@blocknote/ariakit

npm i https://pkg.pr.new/@blocknote/ariakit@3164

@blocknote/code-block

npm i https://pkg.pr.new/@blocknote/code-block@3164

@blocknote/core

npm i https://pkg.pr.new/@blocknote/core@3164

@blocknote/diagram-block

npm i https://pkg.pr.new/@blocknote/diagram-block@3164

@blocknote/mantine

npm i https://pkg.pr.new/@blocknote/mantine@3164

@blocknote/math-block

npm i https://pkg.pr.new/@blocknote/math-block@3164

@blocknote/react

npm i https://pkg.pr.new/@blocknote/react@3164

@blocknote/server-util

npm i https://pkg.pr.new/@blocknote/server-util@3164

@blocknote/shadcn

npm i https://pkg.pr.new/@blocknote/shadcn@3164

@blocknote/xl-ai

npm i https://pkg.pr.new/@blocknote/xl-ai@3164

@blocknote/xl-docx-exporter

npm i https://pkg.pr.new/@blocknote/xl-docx-exporter@3164

@blocknote/xl-email-exporter

npm i https://pkg.pr.new/@blocknote/xl-email-exporter@3164

@blocknote/xl-multi-column

npm i https://pkg.pr.new/@blocknote/xl-multi-column@3164

@blocknote/xl-odt-exporter

npm i https://pkg.pr.new/@blocknote/xl-odt-exporter@3164

@blocknote/xl-pdf-exporter

npm i https://pkg.pr.new/@blocknote/xl-pdf-exporter@3164

@blocknote/xl-typst-exporter

npm i https://pkg.pr.new/@blocknote/xl-typst-exporter@3164

commit: 56b4a96

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://TypeCellOS.github.io/BlockNote/pr-preview/pr-3164/

Built to branch gh-pages at 2026-10-07 04:28 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

This branch was successfully deployed

2 active deployments
Preview – blocknote-website — 56b4a967 Deployed Oct 7, 2026 by vercel[bot]
Preview – blocknote — 56b4a967 Deployed Oct 7, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Undo after typing --- should restore the dashes, not delete the divider

1 participant