mirror of
https://github.com/facebook/lexical.git
synced 2025-08-06 16:39:33 +08:00
[lexical-text] Bug Fix: for handling multiple matches on hashtags (#6056)
This commit is contained in:
@ -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`
|
||||
<p
|
||||
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
|
||||
dir="ltr">
|
||||
<span class="PlaygroundEditorTheme__hashtag" data-lexical-text="true">
|
||||
#hello
|
||||
</span>
|
||||
<span data-lexical-text="true"></span>
|
||||
<span class="PlaygroundEditorTheme__hashtag" data-lexical-text="true">
|
||||
#world
|
||||
</span>
|
||||
<span data-lexical-text="true">#invalid#invalid#invalid</span>
|
||||
<span class="PlaygroundEditorTheme__hashtag" data-lexical-text="true">
|
||||
#valid
|
||||
</span>
|
||||
<span data-lexical-text="true"></span>
|
||||
<span class="PlaygroundEditorTheme__hashtag" data-lexical-text="true">
|
||||
#valid
|
||||
</span>
|
||||
<span data-lexical-text="true">#invalid</span>
|
||||
<span class="PlaygroundEditorTheme__hashtag" data-lexical-text="true">
|
||||
#valid
|
||||
</span>
|
||||
</p>
|
||||
`,
|
||||
);
|
||||
});
|
||||
|
||||
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`
|
||||
<p
|
||||
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
|
||||
dir="ltr">
|
||||
<span class="PlaygroundEditorTheme__hashtag" data-lexical-text="true">
|
||||
#hello
|
||||
</span>
|
||||
<span data-lexical-text="true">#world</span>
|
||||
</p>
|
||||
`,
|
||||
);
|
||||
});
|
||||
|
||||
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`
|
||||
<p
|
||||
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
|
||||
dir="ltr">
|
||||
<span class="PlaygroundEditorTheme__hashtag" data-lexical-text="true">
|
||||
#hello
|
||||
</span>
|
||||
<span data-lexical-text="true">#invalid</span>
|
||||
<span class="PlaygroundEditorTheme__hashtag" data-lexical-text="true">
|
||||
#a
|
||||
</span>
|
||||
<span data-lexical-text="true"></span>
|
||||
<span class="PlaygroundEditorTheme__hashtag" data-lexical-text="true">
|
||||
#b
|
||||
</span>
|
||||
</p>
|
||||
`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -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<T extends TextNode>(
|
||||
match.end + prevMatchLengthToSkip,
|
||||
);
|
||||
}
|
||||
|
||||
invariant(
|
||||
nodeToReplace !== undefined,
|
||||
'%s should not be undefined. You may want to check splitOffsets passed to the splitText.',
|
||||
'nodeToReplace',
|
||||
);
|
||||
|
||||
const replacementNode = createNode(nodeToReplace);
|
||||
replacementNode.setFormat(nodeToReplace.getFormat());
|
||||
nodeToReplace.replace(replacementNode);
|
||||
|
@ -163,5 +163,6 @@
|
||||
"161": "Unexpected dirty selection to be null",
|
||||
"162": "Root element not registered",
|
||||
"163": "node is not a ListNode",
|
||||
"164": "Root element count less than 0"
|
||||
"164": "Root element count less than 0",
|
||||
"165": "%s should not be undefined. You may want to check splitOffsets passed to the splitText."
|
||||
}
|
||||
|
Reference in New Issue
Block a user