import { EditorView } from '@codemirror/view' import { Transaction, EditorSelection } from '@codemirror/state' import type { Extension } from '@codemirror/state' import { INLINE_SEMANTIC_CHANGE_ANNOTATION, INLINE_SEMANTIC_TEXT_CHANGE_ANNOTATION, } from '../inline-semantic-ops' export function markdownPasteHandler(): Extension { return EditorView.domEventHandlers({ paste: markdownDomPasteHandler, }) } export function markdownDomPasteHandler(event: Event, view: EditorView): boolean { if (event.defaultPrevented) return false if (view.state.readOnly) return false const dt = (event as ClipboardEvent).clipboardData if (!dt) return false const sel = view.state.selection if (sel.ranges.length !== 1) return false // Delegate to image handler when files are present if (dt.files && dt.files.length > 0) return false // Delegate when clipboard has no text const text = dt.getData('text/plain') if (!text) return false const range = sel.main const from = range.from const to = range.to const pastedEnd = from + text.length view.dispatch({ changes: { from, to, insert: text }, selection: EditorSelection.single(pastedEnd), scrollIntoView: true, annotations: [ Transaction.userEvent.of('input.paste'), INLINE_SEMANTIC_CHANGE_ANNOTATION.of({ ops: [{ kind: 'synthesize-paste', range: { start: from, end: pastedEnd } }], }), INLINE_SEMANTIC_TEXT_CHANGE_ANNOTATION.of({ from, to, insert: text, }), ], }) event.preventDefault() return true }