diff --git a/services/web/frontend/js/features/source-editor/extensions/autocomplete-on-paste.ts b/services/web/frontend/js/features/source-editor/extensions/autocomplete-on-paste.ts new file mode 100644 index 0000000000..49bfdf1a62 --- /dev/null +++ b/services/web/frontend/js/features/source-editor/extensions/autocomplete-on-paste.ts @@ -0,0 +1,26 @@ +import { EditorView } from '@codemirror/view' +import { startCompletion } from '@codemirror/autocomplete' +import { ancestorNodeOfType } from '@/features/source-editor/utils/tree-operations/ancestors' +import { containsDOI } from '../utils/doi' + +// open autocomplete when a DOI is pasted into a \cite argument +export const autocompleteOnPaste = EditorView.domEventHandlers({ + paste(event, view) { + const text = event.clipboardData?.getData('text/plain') + if (text && containsDOI(text)) { + const node = ancestorNodeOfType( + view.state, + view.state.selection.main.from, + 'BibKeyArgument', + -1 + ) + + if (node) { + // allow time for the pasted content to appear in the state + window.setTimeout(() => { + startCompletion(view) + }) + } + } + }, +}) diff --git a/services/web/frontend/js/features/source-editor/extensions/index.ts b/services/web/frontend/js/features/source-editor/extensions/index.ts index d107756bd3..7da1d45e96 100644 --- a/services/web/frontend/js/features/source-editor/extensions/index.ts +++ b/services/web/frontend/js/features/source-editor/extensions/index.ts @@ -55,6 +55,7 @@ import { trackDetachedComments } from './track-detached-comments' import { reviewTooltip } from './review-tooltip' import { tooltipsReposition } from './tooltips-reposition' import { selectionListener } from '@/features/source-editor/extensions/selection-listener' +import { autocompleteOnPaste } from '@/features/source-editor/extensions/autocomplete-on-paste' const moduleExtensions: Array<(options: Record) => Extension> = importOverleafModules('sourceEditorExtensions').map( @@ -174,4 +175,5 @@ export const createExtensions = (options: Record): Extension[] => [ fileTreeItemDrop(), tooltipsReposition(), selectionListener(options.setEditorSelection), + autocompleteOnPaste, ] diff --git a/services/web/frontend/js/features/source-editor/utils/doi.ts b/services/web/frontend/js/features/source-editor/utils/doi.ts new file mode 100644 index 0000000000..c23aa29fb7 --- /dev/null +++ b/services/web/frontend/js/features/source-editor/utils/doi.ts @@ -0,0 +1,4 @@ +const doiRe = /10\.\d{4,}\/\S+/ + +export const containsDOI = (text: string) => + doiRe.test(decodeURIComponent(text))