Skip to content

Commit 5386635

Browse files
authored
[lexical-playground] Bug fix: make clear formatting work on multiple paragraphs (facebook#8224)
1 parent 4fc1e4c commit 5386635

2 files changed

Lines changed: 48 additions & 33 deletions

File tree

packages/lexical-playground/__tests__/e2e/ClearFormatting.spec.mjs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import {
1010
centerAlign,
1111
indent,
12+
moveToPrevWord,
1213
outdent,
1314
rightAlign,
1415
selectAll,
@@ -274,4 +275,43 @@ test.describe('Clear All Formatting', () => {
274275
`,
275276
);
276277
});
278+
279+
test(`Should clear formatting of selected text which spans over 1 paragraph`, async ({
280+
page,
281+
}) => {
282+
await focusEditor(page);
283+
284+
await page.keyboard.type('Foo bar');
285+
await page.keyboard.press('Enter');
286+
await page.keyboard.type('baz qux');
287+
await selectAll(page);
288+
await toggleBold(page);
289+
await page.keyboard.press('ArrowRight');
290+
await moveToPrevWord(page);
291+
await page.keyboard.down('Shift');
292+
await page.keyboard.press('ArrowUp');
293+
await page.keyboard.up('Shift');
294+
await selectFromAdditionalStylesDropdown(page, '.clear');
295+
await assertHTML(
296+
page,
297+
html`
298+
<p class="PlaygroundEditorTheme__paragraph" dir="auto">
299+
<strong
300+
class="PlaygroundEditorTheme__textBold"
301+
data-lexical-text="true">
302+
Foo
303+
</strong>
304+
<span data-lexical-text="true">bar</span>
305+
</p>
306+
<p class="PlaygroundEditorTheme__paragraph" dir="auto">
307+
<span data-lexical-text="true">baz</span>
308+
<strong
309+
class="PlaygroundEditorTheme__textBold"
310+
data-lexical-text="true">
311+
qux
312+
</strong>
313+
</p>
314+
`,
315+
);
316+
});
277317
});

packages/lexical-playground/src/plugins/ToolbarPlugin/utils.ts

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -341,53 +341,28 @@ export const clearFormatting = (
341341
if ($isRangeSelection(selection) || $isTableSelection(selection)) {
342342
const anchor = selection.anchor;
343343
const focus = selection.focus;
344-
const nodes = selection.getNodes();
345344
const extractedNodes = selection.extract();
346345

347346
if (anchor.key === focus.key && anchor.offset === focus.offset) {
348347
return;
349348
}
350349

351-
nodes.forEach((node, idx) => {
352-
// We split the first and last node by the selection
353-
// So that we don't format unselected text inside those nodes
350+
extractedNodes.forEach((node) => {
354351
if ($isTextNode(node)) {
355-
// Use a separate variable to ensure TS does not lose the refinement
356-
let textNode = node;
357-
if (idx === 0 && anchor.offset !== 0) {
358-
textNode = textNode.splitText(anchor.offset)[1] || textNode;
352+
if (node.getStyle() !== '') {
353+
node.setStyle('');
359354
}
360-
if (idx === nodes.length - 1) {
361-
textNode = textNode.splitText(focus.offset)[0] || textNode;
362-
}
363-
/**
364-
* If the selected text has one format applied
365-
* selecting a portion of the text, could
366-
* clear the format to the wrong portion of the text.
367-
*
368-
* The cleared text is based on the length of the selected text.
369-
*/
370-
// We need this in case the selected text only has one format
371-
const extractedTextNode = extractedNodes[0];
372-
if (nodes.length === 1 && $isTextNode(extractedTextNode)) {
373-
textNode = extractedTextNode;
374-
}
375-
376-
if (textNode.__style !== '') {
377-
textNode.setStyle('');
378-
}
379-
if (textNode.__format !== 0) {
380-
textNode.setFormat(0);
355+
if (node.getFormat() !== 0) {
356+
node.setFormat(0);
381357
}
382358
const nearestBlockElement =
383-
$getNearestBlockElementAncestorOrThrow(textNode);
384-
if (nearestBlockElement.__format !== 0) {
359+
$getNearestBlockElementAncestorOrThrow(node);
360+
if (nearestBlockElement.getFormat() !== 0) {
385361
nearestBlockElement.setFormat('');
386362
}
387-
if (nearestBlockElement.__indent !== 0) {
363+
if (nearestBlockElement.getIndent() !== 0) {
388364
nearestBlockElement.setIndent(0);
389365
}
390-
node = textNode;
391366
} else if ($isHeadingNode(node) || $isQuoteNode(node)) {
392367
node.replace($createParagraphNode(), true);
393368
} else if ($isDecoratorBlockNode(node)) {

0 commit comments

Comments
 (0)