Skip to content

Commit

Permalink
Combined selection format to ignore empty text nodes (#5521)
Browse files Browse the repository at this point in the history
  • Loading branch information
zurfyx committed Jan 22, 2024
1 parent 6a50a49 commit e1605a3
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 22 deletions.
28 changes: 28 additions & 0 deletions packages/lexical-playground/__tests__/e2e/TextFormatting.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1213,4 +1213,32 @@ test.describe('TextFormatting', () => {
`,
);
});

test('Multiline selection format ignores new lines', async ({
page,
isPlainText,
isCollab,
}) => {
test.skip(isPlainText);
let leftFrame = page;
if (isCollab) {
leftFrame = await page.frame('left');
}
await focusEditor(page);

await page.keyboard.type('Fist');
await page.keyboard.press('Enter');
await toggleUnderline(page);
await page.keyboard.type('Second');
await page.pause();

await moveLeft(page, 'Second'.length + 1);
await page.pause();
await selectCharacters(page, 'right', 'Second'.length + 1);
await page.pause();

await expect(
leftFrame.locator('.toolbar-item[title^="Underline"]'),
).toHaveClass(/active/);
});
});
46 changes: 24 additions & 22 deletions packages/lexical/src/LexicalEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,6 @@ function onSelectionChange(
if ($isRangeSelection(selection)) {
const anchor = selection.anchor;
const anchorNode = anchor.getNode();
const focus = selection.focus;
const focusNode = focus.getNode();

if (selection.isCollapsed()) {
// Badly interpreted range selection when collapsed - #1482
Expand Down Expand Up @@ -351,30 +349,34 @@ function onSelectionChange(
}
}
} else {
let combinedFormat = IS_ALL_FORMATTING;
let hasTextNodes = false;
const anchorKey = anchor.key;
const focus = selection.focus;
const focusKey = focus.key;
const nodes = selection.getNodes();
if (
selection.getTextContent().startsWith('\n') &&
!selection.getTextContent().endsWith('\n') &&
(anchorNode.getTextContentSize() === anchor.offset ||
focusNode.getTextContentSize() === focus.offset) &&
$isTextNode(nodes[0])
) {
nodes.shift();
} else if (
!selection.getTextContent().startsWith('\n') &&
selection.getTextContent().endsWith('\n') &&
(anchor.offset === 0 || focus.offset === 0) &&
$isTextNode(nodes[nodes.length - 1])
) {
nodes.pop();
}

const nodesLength = nodes.length;
const isBackward = selection.isBackward();
const startOffset = isBackward ? focusOffset : anchorOffset;
const endOffset = isBackward ? anchorOffset : focusOffset;
const startKey = isBackward ? focusKey : anchorKey;
const endKey = isBackward ? anchorKey : focusKey;
let combinedFormat = IS_ALL_FORMATTING;
let hasTextNodes = false;
for (let i = 0; i < nodesLength; i++) {
const node = nodes[i];
if ($isTextNode(node)) {
const textContentSize = node.getTextContentSize();
if (
$isTextNode(node) &&
textContentSize !== 0 &&
// Exclude empty text nodes at boundaries resulting from user's selection
!(
(i === 0 &&
node.__key === startKey &&
startOffset === textContentSize) ||
(i === nodesLength - 1 &&
node.__key === endKey &&
endOffset === 0)
)
) {
// TODO: what about style?
hasTextNodes = true;
combinedFormat &= node.getFormat();
Expand Down

2 comments on commit e1605a3

@vercel
Copy link

@vercel vercel bot commented on e1605a3 Jan 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

lexical – ./packages/lexical-website

lexical-git-main-fbopensource.vercel.app
lexicaljs.org
lexical-fbopensource.vercel.app
lexicaljs.com
lexical.dev
www.lexical.dev

@vercel
Copy link

@vercel vercel bot commented on e1605a3 Jan 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

lexical-playground – ./packages/lexical-playground

playground.lexical.dev
lexical-playground-git-main-fbopensource.vercel.app
lexical-playground-fbopensource.vercel.app
lexical-playground.vercel.app

Please sign in to comment.