diff --git a/src/components/InlineWikilinkInput.tsx b/src/components/InlineWikilinkInput.tsx index d533ea98..3e356dcb 100644 --- a/src/components/InlineWikilinkInput.tsx +++ b/src/components/InlineWikilinkInput.tsx @@ -31,6 +31,7 @@ import { handleInlineWikilinkKeyDown } from './inlineWikilinkKeydown' import { useInlineWikilinkSelection } from './useInlineWikilinkSelection' import { useInlineWikilinkSuggestionsState } from './useInlineWikilinkSuggestionsState' import { normalizeInlineWikilinkValue } from './inlineWikilinkTokens' +import { isInsertBeforeInput } from './inlineWikilinkBeforeInput' interface InlineWikilinkInputProps { entries: VaultEntry[] @@ -208,7 +209,7 @@ export function InlineWikilinkInput({ if (disabled) return const nativeEvent = event.nativeEvent as InputEvent - if (!nativeEvent.inputType.startsWith('insert')) return + if (!isInsertBeforeInput(nativeEvent)) return const dataTransfer = nativeEvent.dataTransfer if (!dataTransfer || !hasUnsupportedClipboardPayload(dataTransfer)) return diff --git a/src/components/WikilinkChatInput.test.tsx b/src/components/WikilinkChatInput.test.tsx index 895d98af..bb47f71d 100644 --- a/src/components/WikilinkChatInput.test.tsx +++ b/src/components/WikilinkChatInput.test.tsx @@ -8,7 +8,10 @@ import { waitFor, } from '@testing-library/react' import { WikilinkChatInput } from './WikilinkChatInput' -import { UNSUPPORTED_INLINE_PASTE_MESSAGE } from './InlineWikilinkInput' +import { + UNSUPPORTED_INLINE_PASTE_MESSAGE, +} from './InlineWikilinkInput' +import { isInsertBeforeInput } from './inlineWikilinkBeforeInput' import type { VaultEntry } from '../types' const makeEntry = (overrides: Partial = {}): VaultEntry => ({ @@ -271,6 +274,27 @@ describe('WikilinkChatInput', () => { expect(editor.textContent).toContain('still works') }) + it('treats missing inputType as a non-insert beforeinput event', () => { + expect(() => isInsertBeforeInput({} as InputEvent)).not.toThrow() + expect(isInsertBeforeInput({} as InputEvent)).toBe(false) + expect(isInsertBeforeInput({ inputType: 'insertFromPaste' } as InputEvent)).toBe(true) + }) + + it('ignores beforeinput events without inputType instead of crashing', () => { + render() + + const editor = screen.getByTestId('agent-input') + const beforeInputEvent = new Event('beforeinput', { + bubbles: true, + cancelable: true, + }) + + expect(() => fireEvent(editor, beforeInputEvent)).not.toThrow() + + updateEditorText('still works') + expect(editor.textContent).toContain('still works') + }) + it('recovers if unsupported media lands in the editor DOM', async () => { const onUnsupportedPaste = vi.fn() render() diff --git a/src/components/inlineWikilinkBeforeInput.ts b/src/components/inlineWikilinkBeforeInput.ts new file mode 100644 index 00000000..b820e51e --- /dev/null +++ b/src/components/inlineWikilinkBeforeInput.ts @@ -0,0 +1,4 @@ +export function isInsertBeforeInput(nativeEvent: Pick) { + return typeof nativeEvent.inputType === 'string' + && nativeEvent.inputType.startsWith('insert') +}