diff --git a/packages/extension-link/src/helpers/pasteHandler.ts b/packages/extension-link/src/helpers/pasteHandler.ts new file mode 100644 index 00000000000..dfca342b3f3 --- /dev/null +++ b/packages/extension-link/src/helpers/pasteHandler.ts @@ -0,0 +1,52 @@ +import { Editor } from '@tiptap/core' +import { MarkType } from '@tiptap/pm/model' +import { Plugin, PluginKey } from '@tiptap/pm/state' +import { find } from 'linkifyjs' + +type PasteHandlerOptions = { + editor: Editor + type: MarkType +} + +export function pasteHandler(options: PasteHandlerOptions): Plugin { + return new Plugin({ + key: new PluginKey('handlePasteLink'), + props: { + handlePaste: (view, event, slice) => { + const { state } = view + const { selection } = state + const { empty } = selection + + if (empty) { + return false + } + + let textContent = '' + + slice.content.forEach(node => { + textContent += node.textContent + }) + + const link = find(textContent).find(item => item.isLink && item.value === textContent) + + if (!textContent || !link) { + return false + } + + const html = event.clipboardData.getData('text/html') + + const hrefRegex = /href="([^"]*)"/ + + const existingLink = html?.match(hrefRegex) + + const url = existingLink ? existingLink[1] : link.href + + options.editor.commands.setMark(options.type, { + href: url, + }) + + return true + }, + }, + }) +} diff --git a/packages/extension-link/src/link.ts b/packages/extension-link/src/link.ts index 9c9c89b2ba1..41d6ac1365d 100644 --- a/packages/extension-link/src/link.ts +++ b/packages/extension-link/src/link.ts @@ -4,6 +4,7 @@ import { find, registerCustomProtocol, reset } from 'linkifyjs' import { autolink } from './helpers/autolink.js' import { clickHandler } from './helpers/clickHandler.js' +import { pasteHandler } from './helpers/pasteHandler.js' export interface LinkProtocolOptions { scheme: string; @@ -167,7 +168,7 @@ export const Link = Mark.create({ })), type: this.type, getAttributes: (match, pasteEvent) => { - const html = pasteEvent.clipboardData?.getData('text/html') + const html = pasteEvent?.clipboardData?.getData('text/html') const hrefRegex = /href="([^"]*)"/ const existingLink = html?.match(hrefRegex) @@ -206,6 +207,15 @@ export const Link = Mark.create({ ) } + if (this.options.linkOnPaste) { + plugins.push( + pasteHandler({ + editor: this.editor, + type: this.type, + }), + ) + } + return plugins }, })