fix(editor): guard stale suggestion query cleanup
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
diff --git a/dist/blocknote-react.js b/dist/blocknote-react.js
|
||||
index 6271d12d2cd5152e924c5bfe78f3b8904844dbfe..12bb96bb36d445a77d51a18d0de446a3f9f0ea59 100644
|
||||
index d4d36cd4dbb5370c3b7431ffeb577e4870b39825..5a6c325bf0ff9a23f2023169d7fcf6319df91544 100644
|
||||
--- a/dist/blocknote-react.js
|
||||
+++ b/dist/blocknote-react.js
|
||||
@@ -155,8 +155,26 @@ var Rt = (e) => {
|
||||
@@ -154,8 +154,26 @@ const co = (e) => {
|
||||
};
|
||||
function so(e) {
|
||||
let t = new DOMRect();
|
||||
- const n = "getBoundingClientRect" in e ? () => e.getBoundingClientRect() : () => e.element.getBoundingClientRect();
|
||||
@@ -17,7 +18,7 @@ index 6271d12d2cd5152e924c5bfe78f3b8904844dbfe..12bb96bb36d445a77d51a18d0de446a3
|
||||
+ t = n();
|
||||
+ return t;
|
||||
+ };
|
||||
}
|
||||
+}
|
||||
+function __bnSafeDomAtPos(e, t) {
|
||||
+ const n = e.prosemirrorView;
|
||||
+ if (!n || n.isDestroyed)
|
||||
@@ -27,11 +28,10 @@ index 6271d12d2cd5152e924c5bfe78f3b8904844dbfe..12bb96bb36d445a77d51a18d0de446a3
|
||||
+ } catch {
|
||||
+ return null;
|
||||
+ }
|
||||
+}
|
||||
}
|
||||
const z = (e) => {
|
||||
var h, b, p;
|
||||
const { refs: t, floatingStyles: n, context: o } = Ze({
|
||||
@@ -216,9 +234,7 @@ const Lt = (e) => {
|
||||
@@ -216,9 +234,7 @@ const z = (e) => {
|
||||
const s = Ue(t, c.doc);
|
||||
if (!s)
|
||||
return;
|
||||
@@ -42,7 +42,39 @@ index 6271d12d2cd5152e924c5bfe78f3b8904844dbfe..12bb96bb36d445a77d51a18d0de446a3
|
||||
if (a instanceof Element)
|
||||
return {
|
||||
element: a
|
||||
@@ -3306,14 +3322,15 @@ const pi = (e) => {
|
||||
@@ -2499,7 +2515,14 @@ function Kr(e) {
|
||||
columns: d
|
||||
} = e, m = H(
|
||||
(C) => {
|
||||
- a(), s(), u == null || u(C);
|
||||
+ a();
|
||||
+ try {
|
||||
+ s();
|
||||
+ } catch (x) {
|
||||
+ console.warn("Ignored stale suggestion menu query cleanup:", x);
|
||||
+ return;
|
||||
+ }
|
||||
+ u == null || u(C);
|
||||
},
|
||||
[u, a, s]
|
||||
), { items: g, usedQuery: f, loadingState: h } = Yt(
|
||||
@@ -2734,7 +2757,14 @@ function ti(e) {
|
||||
onItemClick: u
|
||||
} = e, d = H(
|
||||
(p) => {
|
||||
- a(), s(), u == null || u(p);
|
||||
+ a();
|
||||
+ try {
|
||||
+ s();
|
||||
+ } catch (C) {
|
||||
+ console.warn("Ignored stale suggestion menu query cleanup:", C);
|
||||
+ return;
|
||||
+ }
|
||||
+ u == null || u(p);
|
||||
},
|
||||
[u, a, s]
|
||||
), { items: m, usedQuery: g, loadingState: f } = Yt(
|
||||
@@ -3306,14 +3336,15 @@ const ii = (e, t = 0.3) => {
|
||||
);
|
||||
if (!m)
|
||||
return {};
|
||||
@@ -61,7 +93,7 @@ index 6271d12d2cd5152e924c5bfe78f3b8904844dbfe..12bb96bb36d445a77d51a18d0de446a3
|
||||
return p instanceof Element ? (d.cellReference = { element: p }, d.rowReference = {
|
||||
element: f,
|
||||
getBoundingClientRect: () => {
|
||||
@@ -4371,7 +4388,7 @@ const El = (e) => {
|
||||
@@ -4371,7 +4402,7 @@ const zi = (e) => {
|
||||
const a = Ue(t, c.prosemirrorState.doc);
|
||||
if (!a)
|
||||
return;
|
||||
|
||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@@ -19,7 +19,7 @@ patchedDependencies:
|
||||
hash: c93b0eab9c8a1800cc1489627146cbe9037999f409efcc8234b33f670d2ccf8d
|
||||
path: patches/@blocknote__core@0.46.2.patch
|
||||
'@blocknote/react@0.46.2':
|
||||
hash: e09f7011df33f4ff92c0d3fd8c9060e62f08997d076f3e438e1e82f8c1ab2f76
|
||||
hash: 9721936e806f31cf440cc94ead3ec03764ae968870c167d086a8e60d8f6d4a08
|
||||
path: patches/@blocknote__react@0.46.2.patch
|
||||
'@tiptap/extension-link@3.19.0':
|
||||
hash: fbe59b1b8b798ba3fefa371c0729b5aa3458e1ea70a4b86cd5267f9f62529284
|
||||
@@ -46,7 +46,7 @@ importers:
|
||||
version: 0.46.2(@floating-ui/dom@1.7.5)(@mantine/core@8.3.14(@mantine/hooks@8.3.14(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@mantine/hooks@8.3.14(react@19.2.4))(@mantine/utils@6.0.22(react@19.2.4))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
'@blocknote/react':
|
||||
specifier: ^0.46.2
|
||||
version: 0.46.2(patch_hash=e09f7011df33f4ff92c0d3fd8c9060e62f08997d076f3e438e1e82f8c1ab2f76)(@floating-ui/dom@1.7.5)(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
version: 0.46.2(patch_hash=9721936e806f31cf440cc94ead3ec03764ae968870c167d086a8e60d8f6d4a08)(@floating-ui/dom@1.7.5)(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
'@codemirror/commands':
|
||||
specifier: ^6.10.2
|
||||
version: 6.10.2
|
||||
@@ -5677,7 +5677,7 @@ snapshots:
|
||||
'@blocknote/mantine@0.46.2(@floating-ui/dom@1.7.5)(@mantine/core@8.3.14(@mantine/hooks@8.3.14(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@mantine/hooks@8.3.14(react@19.2.4))(@mantine/utils@6.0.22(react@19.2.4))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
|
||||
dependencies:
|
||||
'@blocknote/core': 0.46.2(patch_hash=c93b0eab9c8a1800cc1489627146cbe9037999f409efcc8234b33f670d2ccf8d)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)
|
||||
'@blocknote/react': 0.46.2(patch_hash=e09f7011df33f4ff92c0d3fd8c9060e62f08997d076f3e438e1e82f8c1ab2f76)(@floating-ui/dom@1.7.5)(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
'@blocknote/react': 0.46.2(patch_hash=9721936e806f31cf440cc94ead3ec03764ae968870c167d086a8e60d8f6d4a08)(@floating-ui/dom@1.7.5)(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
'@mantine/core': 8.3.14(@mantine/hooks@8.3.14(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
'@mantine/hooks': 8.3.14(react@19.2.4)
|
||||
'@mantine/utils': 6.0.22(react@19.2.4)
|
||||
@@ -5696,7 +5696,7 @@ snapshots:
|
||||
- sugar-high
|
||||
- supports-color
|
||||
|
||||
'@blocknote/react@0.46.2(patch_hash=e09f7011df33f4ff92c0d3fd8c9060e62f08997d076f3e438e1e82f8c1ab2f76)(@floating-ui/dom@1.7.5)(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
|
||||
'@blocknote/react@0.46.2(patch_hash=9721936e806f31cf440cc94ead3ec03764ae968870c167d086a8e60d8f6d4a08)(@floating-ui/dom@1.7.5)(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
|
||||
dependencies:
|
||||
'@blocknote/core': 0.46.2(patch_hash=c93b0eab9c8a1800cc1489627146cbe9037999f409efcc8234b33f670d2ccf8d)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)
|
||||
'@emoji-mart/data': 1.2.1
|
||||
|
||||
60
src/lib/blockNoteSuggestionWrapper.regression.test.tsx
Normal file
60
src/lib/blockNoteSuggestionWrapper.regression.test.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { BlockNoteContext, SuggestionMenuWrapper } from '@blocknote/react'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import type { SuggestionMenuProps } from '@blocknote/react'
|
||||
|
||||
function createEditor() {
|
||||
return {
|
||||
domElement: document.createElement('div'),
|
||||
}
|
||||
}
|
||||
|
||||
function Menu({ items, onItemClick }: SuggestionMenuProps<string>) {
|
||||
return (
|
||||
<button type="button" onClick={() => onItemClick?.(items[0])}>
|
||||
Pick suggestion
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
describe('patched BlockNote suggestion wrapper', () => {
|
||||
it('ignores stale query cleanup before running a suggestion item action', async () => {
|
||||
const closeMenu = vi.fn()
|
||||
const clearQuery = vi.fn(() => {
|
||||
throw new RangeError('Position -1322 outside of fragment')
|
||||
})
|
||||
const onItemClick = vi.fn()
|
||||
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
|
||||
|
||||
render(
|
||||
<BlockNoteContext.Provider
|
||||
value={{
|
||||
editor: createEditor() as never,
|
||||
setContentEditableProps: vi.fn(),
|
||||
}}
|
||||
>
|
||||
<SuggestionMenuWrapper
|
||||
query=""
|
||||
closeMenu={closeMenu}
|
||||
clearQuery={clearQuery}
|
||||
getItems={async () => ['paragraph']}
|
||||
suggestionMenuComponent={Menu}
|
||||
onItemClick={onItemClick}
|
||||
/>
|
||||
</BlockNoteContext.Provider>,
|
||||
)
|
||||
|
||||
fireEvent.click(await screen.findByRole('button', { name: 'Pick suggestion' }))
|
||||
|
||||
expect(closeMenu).toHaveBeenCalledOnce()
|
||||
expect(clearQuery).toHaveBeenCalledOnce()
|
||||
expect(onItemClick).not.toHaveBeenCalled()
|
||||
await waitFor(() => {
|
||||
expect(warn).toHaveBeenCalledWith(
|
||||
'Ignored stale suggestion menu query cleanup:',
|
||||
expect.any(RangeError),
|
||||
)
|
||||
})
|
||||
warn.mockRestore()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user