fix(core): don't throw when the placeholder style is already removed - #3145
Conversation
The Placeholder plugin view removed its <style> on destroy with removeChild, which throws NotFoundError if something else (e.g. Turbo merging <head> and dropping duplicate empty <style> elements) detached it first. The throw also aborts the rest of ProseMirror's view teardown. Use styleEl.remove(), which is a no-op when the element has no parent and covers both the document and shadow root cases. Closes TypeCellOS#3144
|
@adarshsm is attempting to deploy a commit to the TypeCell Team on Vercel. A member of the Team first needs to authorize it. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review. 📝 WalkthroughWalkthroughThe Placeholder view now removes its style element with ChangesPlaceholder cleanup
Priority: ➖ Normal Estimated code review effort: 1 (Trivial) | ~5 minutes Change: Bug fix · Severity of issue fixed: Medium Merge Risk: ⚪ Minimal · up to The change makes editor teardown tolerate an already-removed placeholder stylesheet, with a regression test for that case. No merge-blocking risk is evident in the supplied context. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
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. A rabbit watched the style tag go, Comment |
@blocknote/ariakit
@blocknote/code-block
@blocknote/core
@blocknote/diagram-block
@blocknote/mantine
@blocknote/math-block
@blocknote/react
@blocknote/server-util
@blocknote/shadcn
@blocknote/xl-ai
@blocknote/xl-docx-exporter
@blocknote/xl-email-exporter
@blocknote/xl-multi-column
@blocknote/xl-odt-exporter
@blocknote/xl-pdf-exporter
@blocknote/xl-typst-exporter
commit: |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Thanks! |
Summary
Closes #3144. Destroying an editor throws
NotFoundError: Failed to execute 'removeChild' on 'Node'when the Placeholder extension's<style>element was already removed from<head>(or the shadow root) by something else, e.g. Hotwire Turbo merging the next page's<head>and dropping duplicate empty<style>elements.Rationale
The Placeholder plugin view's
destroycalledview.root.removeChild(styleEl)/view.root.head.removeChild(styleEl), which throws if the element is no longer a child. Because it throws inside ProseMirror'sEditorView.destroyPluginViews, the rest of that editor's teardown (remaining plugin views, the doc view) is skipped too.Changes
packages/core/src/extensions/Placeholder/Placeholder.ts: usestyleEl.remove()indestroy. It removes the element from whatever parent it has (document head or shadow root) and is a no-op if it has none, so both branches collapse into one.Impact
No behaviour change when the style element is still attached. When it was already detached, unmounting no longer throws and the editor tears down fully.
Testing
packages/core/src/extensions/Placeholder/Placeholder.test.ts: mounts an editor, removes its placeholder<style>from<head>, and checks thateditor.unmount()doesn't throw.main(DOMException NotFoundErrorthrown) and passes with the fix.vp test --run src/extensions/Placeholder src/editor/BlockNoteEditor.test.ts src/commentsinpackages/corepasses (3 files / 18 tests).vp lintandvp fmtare clean on the changed files.Checklist
🤖 Generated with Claude Code
Summary by CodeRabbit