From 3fc9fb616b7ba7f355d73dd89ae6683b4507826c Mon Sep 17 00:00:00 2001 From: wnhlee <40269597+2wheeh@users.noreply.github.com> Date: Fri, 10 May 2024 11:07:09 +0900 Subject: [PATCH] [lexical-text] Bug Fix: for handling multiple matches on hashtags (#6056) --- .../__tests__/e2e/Hashtags.spec.mjs | 117 ++++++++++++++++++ .../src/registerLexicalTextEntity.ts | 8 ++ scripts/error-codes/codes.json | 3 +- 3 files changed, 127 insertions(+), 1 deletion(-) diff --git a/packages/lexical-playground/__tests__/e2e/Hashtags.spec.mjs b/packages/lexical-playground/__tests__/e2e/Hashtags.spec.mjs index e04c417cb7e..b3d190dfa19 100644 --- a/packages/lexical-playground/__tests__/e2e/Hashtags.spec.mjs +++ b/packages/lexical-playground/__tests__/e2e/Hashtags.spec.mjs @@ -14,9 +14,11 @@ import { import { assertHTML, assertSelection, + click, focusEditor, html, initialize, + pasteFromClipboard, pressToggleBold, repeat, test, @@ -383,4 +385,119 @@ test.describe('Hashtags', () => { `, ); }); + + test('Can handle hashtags following multiple invalid hashtags', async ({ + page, + }) => { + await focusEditor(page); + await page.keyboard.type('#hello'); + + await page.keyboard.press('Space'); + + await page.keyboard.type('#world'); + await page.keyboard.type('#invalid'); + await page.keyboard.type('#invalid'); + await page.keyboard.type('#invalid'); + + await page.keyboard.press('Space'); + + await page.keyboard.type('#valid'); + + await page.keyboard.press('Space'); + + await page.keyboard.type('#valid'); + await page.keyboard.type('#invalid'); + + await page.keyboard.press('Space'); + await page.keyboard.type('#valid'); + + await waitForSelector(page, '.PlaygroundEditorTheme__hashtag'); + + await assertHTML( + page, + html` +
+ + #hello + + + + #world + + #invalid#invalid#invalid + + #valid + + + + #valid + + #invalid + + #valid + +
+ `, + ); + }); + + test('Should not break when pasting multiple matches', async ({ + page, + isPlainText, + }) => { + test.skip(isPlainText); + + await focusEditor(page); + + const clipboard = {'text/html': '#hello#world'}; + await pasteFromClipboard(page, clipboard); + + await assertHTML( + page, + html` ++ + #hello + + #world +
+ `, + ); + }); + + test('Should not break while importing and exporting multiple matches', async ({ + page, + }) => { + await focusEditor(page); + await page.keyboard.type('```markdown #hello#invalid #a #b'); + + await click(page, '.action-button .markdown'); + await click(page, '.action-button .markdown'); + await click(page, '.action-button .markdown'); + + await assertHTML( + page, + html` ++ + #hello + + #invalid + + #a + + + + #b + +
+ `, + ); + }); }); diff --git a/packages/lexical-text/src/registerLexicalTextEntity.ts b/packages/lexical-text/src/registerLexicalTextEntity.ts index b29ae7d2d9f..320e3285983 100644 --- a/packages/lexical-text/src/registerLexicalTextEntity.ts +++ b/packages/lexical-text/src/registerLexicalTextEntity.ts @@ -14,6 +14,7 @@ import { LexicalNode, TextNode, } from 'lexical'; +import invariant from 'shared/invariant'; export type EntityMatch = {end: number; start: number}; @@ -151,6 +152,13 @@ export function registerLexicalTextEntity