diff --git a/packages/lexical-playground/__tests__/e2e/AutoLinks.spec.mjs b/packages/lexical-playground/__tests__/e2e/AutoLinks.spec.mjs index f5e045ae6c4..f02109bb3a9 100644 --- a/packages/lexical-playground/__tests__/e2e/AutoLinks.spec.mjs +++ b/packages/lexical-playground/__tests__/e2e/AutoLinks.spec.mjs @@ -307,100 +307,4 @@ test.describe('Auto Links', () => { {ignoreClasses: true}, ); }); - - test(`Does not convert bad URLs into links`, async ({page, isPlainText}) => { - const badUrls = [ - 'http://', - 'http://.', - 'http://..', - 'http://../', - 'http://?', - 'http://??', - 'http://??/', - 'http://#', - 'http://##', - 'http://##/', - '//', - '//a', - '///a', - '///', - 'http:///a', - 'rdar://1234', - 'h://test', - ':// should fail', - 'http://foo.bar/foo(bar)baz quux', - 'http://-error-.invalid/', - 'http://-a.b.co', - 'http://a.b-.co', - 'http://ex..ample.com', - 'http://example..com', - 'http://example-.com', - 'http://-example.com', - ]; - - test.skip(isPlainText); - await focusEditor(page); - await page.keyboard.type(badUrls.join(' ')); - - await assertHTML( - page, - html` -
- ${badUrls.join(' ')} -
- `, - undefined, - {ignoreClasses: true}, - ); - }); - - test('Does convert good complex URLs into links', async ({ - page, - isPlainText, - }) => { - const goodUrls = [ - 'http://foo.com/blah_blah', - 'http://foo.com/blah_blah/', - 'http://www.example.com/wpstyle/?p=364', - 'https://www.example.com/foo/?bar=baz&inga=42&quux', - 'http://foo.com/something?after=parens', - 'http://jlo.mp', - 'http://1337.net', - 'http://a.b-c.de', - // // Include IPs and localhost - 'http://localhost', - 'http://localhost:3000', - 'http://192.168.1.1', - 'http://192.168.1.1:3000', - 'http://example.com', - 'http://example.com/path/to/resource?query=string#fragment', - 'https://username:password@example.com', - 'http://example.com/path/to/page.html?query=string#fragment', - 'https://example.com#anchor', - 'http://abcdefghij.com', - ]; - - test.skip(isPlainText); - await focusEditor(page); - await page.keyboard.type(goodUrls.join(' ') + ' '); - - let expectedHTML = ''; - for (const url of goodUrls) { - expectedHTML += ` - - ${url.replace(/&/g, '&')} - - - `; - } - - await assertHTML( - page, - html` -${expectedHTML}
- `, - undefined, - {ignoreClasses: true}, - ); - }); }); diff --git a/packages/lexical-playground/src/plugins/AutoLinkPlugin/index.tsx b/packages/lexical-playground/src/plugins/AutoLinkPlugin/index.tsx index e822e7fa13b..509c3defd50 100644 --- a/packages/lexical-playground/src/plugins/AutoLinkPlugin/index.tsx +++ b/packages/lexical-playground/src/plugins/AutoLinkPlugin/index.tsx @@ -13,7 +13,8 @@ import { import * as React from 'react'; const URL_REGEX = - /(https?:\/\/)?((\w+:\w+@)?(([a-zA-Z\d]([a-zA-Z\d-]*[a-zA-Z\d])*)\.)+[a-zA-Z]{2,}|localhost|(\d{1,3}\.){3}\d{1,3})(:\d+)?(\/[-a-zA-Z\d%_.~+]*)*(\?[;&a-zA-Z\d%_.~+=-]*)?(#[-a-zA-Z\d_]*)?/; + /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/; + const EMAIL_REGEX = /(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/; diff --git a/packages/lexical-react/src/LexicalAutoLinkPlugin.ts b/packages/lexical-react/src/LexicalAutoLinkPlugin.ts index 4d67dc15e67..b28917ddb0c 100644 --- a/packages/lexical-react/src/LexicalAutoLinkPlugin.ts +++ b/packages/lexical-react/src/LexicalAutoLinkPlugin.ts @@ -73,7 +73,7 @@ function findFirstMatch( return null; } -const PUNCTUATION_OR_SPACE = /[,;\s]/; +const PUNCTUATION_OR_SPACE = /[.,;\s]/; function isSeparator(char: string): boolean { return PUNCTUATION_OR_SPACE.test(char);