diff --git a/packages/koenig-lexical/src/plugins/KoenigBehaviourPlugin.jsx b/packages/koenig-lexical/src/plugins/KoenigBehaviourPlugin.jsx index f198a03e8f..0376a96507 100644 --- a/packages/koenig-lexical/src/plugins/KoenigBehaviourPlugin.jsx +++ b/packages/koenig-lexical/src/plugins/KoenigBehaviourPlugin.jsx @@ -1296,12 +1296,28 @@ function useKoenigBehaviour({editor, containerElem, cursorDidExitAtTop, isNested // TODO: replace with better regex to include more protocols like mailto, ftp, etc const linkMatch = text?.match(/^(https?:\/\/[^\s]+)$/); if (linkMatch) { - // avoid any conversion if we're pasting onto a card shortcut const node = $getSelection()?.anchor.getNode(); - if (node && node.getTextContent().startsWith('/')) { + + // avoid any conversion if we're pasting onto a card shortcut + const isNodeCardShortcut = node && node.getTextContent().startsWith('/'); + + if (isNodeCardShortcut) { return false; } + // avoid converting to an embed/bookmark if we're pasting onto a list item + const isNodeListItem = node && $isListItemNode(node); + + if (isNodeListItem) { + const linkNode = $createLinkNode(text); + const textNode = $createTextNode(text); + + linkNode.append(textNode); + node.append(linkNode); + + return true; + } + // we're pasting a URL, convert it to an embed/bookmark/link clipboardEvent.preventDefault(); editor.dispatchCommand(PASTE_LINK_COMMAND, {linkMatch}); diff --git a/packages/koenig-lexical/test/e2e/paste-behaviour.test.js b/packages/koenig-lexical/test/e2e/paste-behaviour.test.js index 85f09e0d93..3508ef8098 100644 --- a/packages/koenig-lexical/test/e2e/paste-behaviour.test.js +++ b/packages/koenig-lexical/test/e2e/paste-behaviour.test.js @@ -1,6 +1,6 @@ import fs from 'fs'; import path from 'path'; -import {assertHTML, ctrlOrCmd, focusEditor,html, initialize, insertCard, paste, pasteFiles, pasteFilesWithText, pasteHtml, pasteText} from '../utils/e2e'; +import {assertHTML, ctrlOrCmd, focusEditor,html, initialize, insertCard, paste, pasteFiles, pasteFilesWithText, pasteHtml, pasteLexical, pasteText} from '../utils/e2e'; import {expect, test} from '@playwright/test'; import {fileURLToPath} from 'url'; const __filename = fileURLToPath(import.meta.url); @@ -623,4 +623,50 @@ test.describe('Paste behaviour', async () => { expect(imgSrc).not.toContain('https://files.slack.com/foo-bar'); }); }); + + test.describe('Links', function () { + test('avoids converting links to embed/bookmarks when pasting it into a list item', async function () { + await focusEditor(page); + await pasteLexical(page, JSON.stringify({ + namespace: 'KoenigEditor', + nodes: [{ + children: [{ + children: [{ + detail: 0, + format: 0, + mode: 'normal', + style: '', + text: '', + type: 'text', + version: 1 + }], + format: '', + indent: 0, + type: 'listitem', + version: 1 + }], + format: '', + indent: 0, + type: 'list', + version: 1, + listType: 'bullet', + start: 1, + tag: 'ul' + }] + })); + + await paste(page, { + 'text/plain': 'https://ghost.org/', + 'text/html': '

Link

' + }); + + await assertHTML(page, html``); + }); + }); });