Skip to content

Commit c6f14b0

Browse files
authored
fix(core): don't throw when the placeholder style is already removed (#3145)
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 #3144 Co-authored-by: adarshsm <24850536+adarshsm@users.noreply.github.com>
1 parent 14e14ca commit c6f14b0

2 files changed

Lines changed: 26 additions & 5 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { expect, it } from "vite-plus/test";
2+
3+
import { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
4+
5+
/**
6+
* @vitest-environment jsdom
7+
*/
8+
9+
it("does not throw on unmount when its style element was already removed", () => {
10+
const editor = BlockNoteEditor.create();
11+
editor.mount(document.createElement("div"));
12+
13+
const styleEl = [...document.head.querySelectorAll("style")].find((el) =>
14+
(
15+
el.sheet?.cssRules[0] as CSSStyleRule | undefined
16+
)?.selectorText?.startsWith(".placeholder-selector-"),
17+
);
18+
expect(styleEl).toBeDefined();
19+
// e.g. a router merging the next page's `<head>` into the current one
20+
styleEl!.remove();
21+
22+
expect(() => editor.unmount()).not.toThrow();
23+
});

‎packages/core/src/extensions/Placeholder/Placeholder.ts‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,9 @@ export const PlaceholderExtension = createExtension(
8989

9090
return {
9191
destroy: () => {
92-
if (view.root instanceof window.ShadowRoot) {
93-
view.root.removeChild(styleEl);
94-
} else {
95-
view.root.head.removeChild(styleEl);
96-
}
92+
// `remove()` is a no-op if something else (e.g. a router
93+
// merging `<head>`) already detached the element.
94+
styleEl.remove();
9795
},
9896
};
9997
},

0 commit comments

Comments
 (0)