Skip to content

Commit ade9dcd

Browse files
committed
Remove Paragraph Replacement in HeadingNode
I'm not really sure why this is here - it seems both semantically incorrect in all the cases I've observed and also causes bugs in other Lexical functions, as if they keep a reference to the `HeadingNode` that is replaced, subsequent usage of that `HeadingNode` will cause errors. See a common example of this in `RangeSelection#insertNodes()` in the added test.
1 parent 25d77f6 commit ade9dcd

File tree

2 files changed

+68
-51
lines changed

2 files changed

+68
-51
lines changed

packages/lexical-rich-text/src/index.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,6 @@ export class HeadingNode extends ElementNode {
376376
const direction = this.getDirection();
377377
newElement.setDirection(direction);
378378
this.insertAfter(newElement, restoreSelection);
379-
if (anchorOffet === 0 && !this.isEmpty() && selection) {
380-
const paragraph = $createParagraphNode();
381-
paragraph.select();
382-
this.replace(paragraph, true);
383-
}
384379
return newElement;
385380
}
386381

packages/lexical/src/__tests__/unit/LexicalSelection.test.ts

Lines changed: 68 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
ListItemNode,
1414
ListNode,
1515
} from '@lexical/list';
16+
import {$createHeadingNode} from '@lexical/rich-text';
1617
import {
1718
$caretRangeFromSelection,
1819
$comparePointCaretNext,
@@ -839,49 +840,6 @@ describe('LexicalSelection tests', () => {
839840
});
840841
});
841842

842-
describe('Regression tests for #6701', () => {
843-
test('insertNodes fails an invariant when there is no Block ancestor', async () => {
844-
class InlineElementNode extends ElementNode {
845-
static clone(prevNode: InlineElementNode): InlineElementNode {
846-
return new InlineElementNode(prevNode.__key);
847-
}
848-
static getType() {
849-
return 'inline-element-node';
850-
}
851-
static importJSON(serializedNode: SerializedElementNode) {
852-
return new InlineElementNode().updateFromJSON(serializedNode);
853-
}
854-
isInline() {
855-
return true;
856-
}
857-
createDOM() {
858-
return document.createElement('span');
859-
}
860-
updateDOM() {
861-
return false;
862-
}
863-
}
864-
const editor = createEditor({
865-
nodes: [InlineElementNode],
866-
onError: (err) => {
867-
throw err;
868-
},
869-
});
870-
expect(() =>
871-
editor.update(
872-
() => {
873-
const textNode = $createTextNode('test');
874-
$getRoot().clear().append(new InlineElementNode().append(textNode));
875-
textNode.select().insertNodes([$createTextNode('more text')]);
876-
},
877-
{discrete: true},
878-
),
879-
).toThrow(
880-
/Expected node TextNode of type text to have a block ElementNode ancestor/,
881-
);
882-
});
883-
});
884-
885843
describe('getNodes()', () => {
886844
initializeUnitTest((testEnv) => {
887845
let paragraphNode: ParagraphNode;
@@ -1553,7 +1511,50 @@ describe('extract()', () => {
15531511
});
15541512
});
15551513

1556-
describe('Regression #7081', () => {
1514+
describe('Regression tests for #6701', () => {
1515+
test('insertNodes fails an invariant when there is no Block ancestor', async () => {
1516+
class InlineElementNode extends ElementNode {
1517+
static clone(prevNode: InlineElementNode): InlineElementNode {
1518+
return new InlineElementNode(prevNode.__key);
1519+
}
1520+
static getType() {
1521+
return 'inline-element-node';
1522+
}
1523+
static importJSON(serializedNode: SerializedElementNode) {
1524+
return new InlineElementNode().updateFromJSON(serializedNode);
1525+
}
1526+
isInline() {
1527+
return true;
1528+
}
1529+
createDOM() {
1530+
return document.createElement('span');
1531+
}
1532+
updateDOM() {
1533+
return false;
1534+
}
1535+
}
1536+
const editor = createEditor({
1537+
nodes: [InlineElementNode],
1538+
onError: (err) => {
1539+
throw err;
1540+
},
1541+
});
1542+
expect(() =>
1543+
editor.update(
1544+
() => {
1545+
const textNode = $createTextNode('test');
1546+
$getRoot().clear().append(new InlineElementNode().append(textNode));
1547+
textNode.select().insertNodes([$createTextNode('more text')]);
1548+
},
1549+
{discrete: true},
1550+
),
1551+
).toThrow(
1552+
/Expected node TextNode of type text to have a block ElementNode ancestor/,
1553+
);
1554+
});
1555+
});
1556+
1557+
describe('Regression tests for #7081', () => {
15571558
initializeUnitTest((testEnv) => {
15581559
test('Firefox selection & paste before linebreak', () => {
15591560
testEnv.editor.update(
@@ -1587,7 +1588,7 @@ describe('Regression #7081', () => {
15871588
});
15881589
});
15891590

1590-
describe('Regression #7173', () => {
1591+
describe('Regression tests for #7173', () => {
15911592
initializeUnitTest((testEnv) => {
15921593
test('Can insertNodes of multiple blocks with a target of an initial empty block and the entire next block', () => {
15931594
testEnv.editor.update(
@@ -1613,7 +1614,28 @@ describe('Regression #7173', () => {
16131614
});
16141615
});
16151616

1616-
describe('Regression #3181', () => {
1617+
describe('Regression tests for #6701', () => {
1618+
initializeUnitTest((testEnv) => {
1619+
test('insertNodes can insert in HeadingNode', async () => {
1620+
testEnv.editor.update(
1621+
() => {
1622+
const heading = $createHeadingNode('h1');
1623+
const headingText = $createTextNode(' chyeah');
1624+
$getRoot().clear().append(heading.append(headingText));
1625+
const paragraph = $createParagraphNode();
1626+
const paragraphText = $createTextNode('finna');
1627+
const selection = headingText.selectStart();
1628+
selection.insertNodes([paragraph.append(paragraphText)]);
1629+
expect($getRoot().getChildren()).toEqual([paragraph]);
1630+
expect($getRoot().getTextContent()).toEqual('finna chyeah');
1631+
},
1632+
{discrete: true},
1633+
);
1634+
});
1635+
});
1636+
});
1637+
1638+
describe('Regression tests for #3181', () => {
16171639
initializeUnitTest((testEnv) => {
16181640
test('Point.isBefore edge case with mixed TextNode & ElementNode and matching descendants', () => {
16191641
testEnv.editor.update(

0 commit comments

Comments
 (0)