Skip to content

fix: native text input and deletion in an empty inline math source - #3240

Open
YousefED wants to merge 1 commit into
mainfrom
fix/inline-math-empty-source
Open

YousefED wants to merge 1 commit into
mainfrom
fix/inline-math-empty-source

Conversation

@YousefED

@YousefED YousefED commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #3234

Problem

  1. In Firefox, the editor crashes when you type ^ in an inline equation that is empty or that contains only spaces. On a French (AZERTY) keyboard, ^ is a dead key. The browser inserts the dead-key character itself, not ProseMirror. An IME commit uses the same path. Thus other characters can also cause the crash.
  2. In Chromium and WebKit, the same input does not crash. But when the inline equation is empty, the text is lost. The character shows in the source popup, but the document does not get it.
  3. In all three browsers, when you delete all the source text with one word deletion (Option+Backspace on macOS), the document keeps the old text. After that, the text that you type shows in the popup, but the document and the preview do not change.

Cause

  1. SourceWithPreview added a <br> next to the source <code> while the inline source was empty. React controlled this <br>. When Firefox inserts text natively next to this <br>, Firefox removes the <br>. Then the source is not empty, so React also tries to remove the <br>. The <br> is not in the DOM, so React throws NotFoundError and the editor unmounts.

    The whitespace case has the same cause. MathInlinePreviewWithPopup gives content.trim() to SourceWithPreview. When the source is " ", the trimmed source is empty, so the <br> shows next to source DOM that is not empty.

  2. When the inline source is empty, its content element has no layout box. Chromium and WebKit then put the new text in the <pre>, before <code>, outside the content element. ProseMirror does not read text from that location.

  3. ProseMirror does not handle word deletion, so the browser deletes the word. When a deletion makes an inline element empty, the browser also removes that element and its empty inline parents, up to the nearest block element. For the inline source, the browser removes the <code> and the content element, up to the <pre>. The <pre> is outside the content element. tiptap ignores DOM changes outside the content element of a node view. Thus ProseMirror does not see the deletion and does not render the content element again.

    Block sources (block equations, diagrams) do not have this problem: their content element is a block element, so the browser stops there.

Changes

  • packages/react/src/blocks/SourceWithPreview/SourceWithPreview.tsx: Remove the conditional <br>. This change fixes the Firefox crash for a source that contains only spaces.
  • packages/core/src/editor/Block.css: Make the content element of an inline source a block (display: block) with the height of one line (min-height: 1.5em).
    • Because it is a block, a native deletion that empties it does not remove it (problem 3).
    • Because it has a line box, the browser inserts text into it when it is empty (problem 2).
    • The popup height stays the same as with one line of text. Without the <br>, the empty popup would be 24px shorter.
    • 1.5em is the same as the editor line height (.bn-block-outer { line-height: 1.5 }).
    • The rule applies only to inline sources.
  • packages/math-block/src/inlineContent/emptySourceInput.browser.test.tsx: Add a browser test.
    • The test inserts the equation through the slash menu item, which also moves the caret into the source.
    • The test inserts ^ with document.execCommand("insertText"), which uses the native insertion path.
    • The test has three cases: an empty source, a source where the user typed a space first, and a source that a native word deletion (Ctrl+Backspace on Linux) made empty.

How to test

  1. Open the "Math Block" example in Firefox.
  2. Type / and select "Inline Equation".
  3. Use a French (AZERTY) keyboard layout. Type ^, then a letter.
  4. Make sure that the editor does not crash and that the source shows the text.
  5. Delete all the text. Make sure that the popup height does not change.
  6. Type a space, then ^. Make sure that the editor does not crash.
  7. Type hello, then delete it with Option+Backspace. Type abc. Make sure that the preview shows abc.
  8. Do steps 2 to 7 again in Chrome and Safari. Close the popup and make sure that the equation shows the text.
  9. Add a block equation. Type text, then delete it. Make sure that it works as before.

Notes

These items were verified with Playwright against the playground, in Firefox, Chromium and WebKit:

  • ^ inserted with insertText and execCommand("insertText") into an empty source, and after a space. Before the fix, Firefox crashed, and Chromium and WebKit lost the text. After the fix, the source gets the text.
  • Option+Backspace on hello, then typing. Before the fix, the document kept hello in all three browsers. After the fix, the document is empty after the deletion and gets the typed text.
  • IME compositions in Chromium (CDP): a commit into an empty source, and a commit after text. Before the fix, the commit into an empty source was lost. After the fix, the source gets it.
  • Seven cycles of "delete all, then type" in one equation. The preview and the document agree after each key.
  • The source area height is 56px when empty and with text, in all three browsers. Screenshots of the popup (empty, and with a long source that wraps) are the same as on main.
  • Block equations and diagrams: Option+Backspace and typing work, before and after this change.

The new browser test, in Docker:

  • With this change: 9 of 9 pass in Firefox, Chromium and WebKit, three runs in a row with --retry=0.
  • Without the CSS change: 4 of 9 fail. Chromium and WebKit fail the empty case and the native deletion case. (Ctrl+Backspace in Firefox on Linux does not remove the parent elements, so Firefox passes.)
  • The slash menu item opens the popup in an animation frame. Headless WebKit sometimes delays this frame by more than 1 second, so the test waits up to 5 seconds for the popup.

These items were not verified:

  • A real dead key on a real keyboard. insertText, execCommand("insertText") and the CDP IME composition were used instead.
  • Mobile browsers.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue that could prevent typing into an empty inline math source. Native text insertion now works when the source starts empty, contains only whitespace, or becomes empty after deletion, while the editor remains usable.

@vercel

vercel Bot commented Oct 22, 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 22, 2026 7:50pm UTC
blocknote-website Ready Ready Preview Oct 22, 2026 7:50pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 13eee6ec-018f-4d18-9f37-ea1e4b8e2889
📥 Commits

Reviewing files that changed from the base of the PR and between 45d07d3 and f6ae2ba.

📒 Files selected for processing: 3
  • packages/core/src/editor/Block.css
  • packages/math-block/src/inlineContent/emptySourceInput.browser.test.tsx
  • packages/react/src/blocks/SourceWithPreview/SourceWithPreview.tsx
💤 Files with no reviewable changes: 1
  • packages/react/src/blocks/SourceWithPreview/SourceWithPreview.tsx

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

The change updates empty inline-source rendering and adds browser tests for native caret insertion into inline math sources that are empty, whitespace-only, or emptied by native deletion.

Changes: Inline math source input

Layer / File(s) Summary
Empty inline source rendering
packages/react/src/blocks/SourceWithPreview/SourceWithPreview.tsx, packages/core/src/editor/Block.css
Removes the conditional line break for empty inline sources. Styles nested code content in an inline source popup as a block with a 1.5em minimum height.
Native input browser coverage
packages/math-block/src/inlineContent/emptySourceInput.browser.test.tsx
Adds browser tests that insert ^ natively into empty, whitespace-only, and natively emptied inline math sources, then check the source and editor view.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: matthewlipski

Merge Risk: ⚪ Minimal · up to f6ae2

The change is ready to merge after normal checks. The new test covers both empty-source input and the document state after native deletion.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
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 1 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main fix for native text input and deletion in empty inline math sources.
Description check Passed The description is detailed and covers the problem, cause, changes, testing, browser coverage, and known limitations. It does not use all template headings and omits the checklist and attached screens…
Linked Issues check Passed Issue [#3234] requires that typing ^ at the start of an inline equation does not crash the editor. SourceWithPreview no longer renders the conditional <br> beside the editable source. The added …
Out of Scope Changes check Passed The CSS layout change, removal of the conditional <br>, and the browser test address the same native-input failure mechanism described in [#3234]. The additional whitespace and native-deletion cases…
Full details: Description check

Explanation

The description is detailed and covers the problem, cause, changes, testing, browser coverage, and known limitations. It does not use all template headings and omits the checklist and attached screenshots or video, but the equivalent content is mostly complete.

Full details: Linked Issues check

Explanation

Issue [#3234] requires that typing ^ at the start of an inline equation does not crash the editor. SourceWithPreview no longer renders the conditional &lt;br&gt; beside the editable source. The added browser test covers an empty inline source and native insertion of ^, and it checks that the ProseMirror view remains connected. The PR description reports passing this case in Firefox, Chromium, and WebKit.

Full details: Out of Scope Changes check

Explanation

The CSS layout change, removal of the conditional &lt;br&gt;, and the browser test address the same native-input failure mechanism described in [#3234]. The additional whitespace and native-deletion cases cover related regressions in the same inline source component. No unrelated product behavior is shown in the supplied changes.

Full details: Docstring Coverage

Explanation

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 1 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ 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
  • Autofix · 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 taps the empty line,
Then sees the caret land just fine.
Three source states greet the test,
The editor view stays at rest.
I twitch my nose and hop away,
While math holds its place today.

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

@pkg-pr-new

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

Copy link
Copy Markdown

Open in StackBlitz

@blocknote/ariakit

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

@blocknote/code-block

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

@blocknote/core

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

@blocknote/diagram-block

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

@blocknote/mantine

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

@blocknote/math-block

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

@blocknote/react

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

@blocknote/server-util

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

@blocknote/shadcn

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

@blocknote/xl-ai

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

@blocknote/xl-docx-exporter

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

@blocknote/xl-email-exporter

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

@blocknote/xl-multi-column

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

@blocknote/xl-odt-exporter

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

@blocknote/xl-pdf-exporter

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

@blocknote/xl-typst-exporter

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

commit: f6ae2ba

@github-actions

github-actions Bot commented Oct 22, 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-3240/

Built to branch gh-pages at 2026-10-22 19:56 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

This branch was successfully deployed

2 active deployments
Preview – blocknote-website — f6ae2bac Deployed Oct 22, 2026 by vercel[bot]
Preview – blocknote — f6ae2bac Deployed Oct 22, 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.

🐛(Bug) editor crash when typing the caret character at the start of an inline equation

1 participant