lexical 0.34.1-nightly.20250818.0 → 0.34.1-nightly.20250820.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Lexical.dev.js CHANGED
@@ -140,13 +140,6 @@ const DOUBLE_LINE_BREAK = '\n\n';
140
140
  // For FF, we need to use a non-breaking space, or it gets composition
141
141
  // in a stuck state.
142
142
  const COMPOSITION_START_CHAR = IS_FIREFOX ? NON_BREAKING_SPACE : COMPOSITION_SUFFIX;
143
- const RTL = '\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC';
144
- const LTR = 'A-Za-z\u00C0-\u00D6\u00D8-\u00F6' + '\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF\u200E\u2C00-\uFB1C' + '\uFE00-\uFE6F\uFEFD-\uFFFF';
145
-
146
- // eslint-disable-next-line no-misleading-character-class
147
- const RTL_REGEX = new RegExp('^[^' + LTR + ']*[' + RTL + ']');
148
- // eslint-disable-next-line no-misleading-character-class
149
- const LTR_REGEX = new RegExp('^[^' + RTL + ']*[' + LTR + ']');
150
143
  const TEXT_TYPE_TO_FORMAT = {
151
144
  bold: IS_BOLD,
152
145
  capitalize: IS_CAPITALIZE,
@@ -1323,7 +1316,6 @@ function $normalizePoint(point) {
1323
1316
  }
1324
1317
 
1325
1318
  let subTreeTextContent = '';
1326
- let subTreeDirectionedTextContent = '';
1327
1319
  let subTreeTextFormat = null;
1328
1320
  let subTreeTextStyle = '';
1329
1321
  let editorTextContent = '';
@@ -1333,7 +1325,6 @@ let activeEditorNodes;
1333
1325
  let treatAllNodesAsDirty = false;
1334
1326
  let activeEditorStateReadOnly = false;
1335
1327
  let activeMutationListeners;
1336
- let activeTextDirection = null;
1337
1328
  let activeDirtyElements;
1338
1329
  let activeDirtyLeaves;
1339
1330
  let activePrevNodeMap;
@@ -1406,6 +1397,28 @@ function setElementFormat(dom, format) {
1406
1397
  setTextAlign(domStyle, 'end');
1407
1398
  }
1408
1399
  }
1400
+ function $getReconciledDirection(node) {
1401
+ const direction = node.__dir;
1402
+ if (direction !== null) {
1403
+ return direction;
1404
+ }
1405
+ if ($isRootNode(node)) {
1406
+ return null;
1407
+ }
1408
+ const parent = node.getParentOrThrow();
1409
+ if (!$isRootNode(parent) || parent.__dir !== null) {
1410
+ return null;
1411
+ }
1412
+ return 'auto';
1413
+ }
1414
+ function $setElementDirection(dom, node) {
1415
+ const direction = $getReconciledDirection(node);
1416
+ if (direction !== null) {
1417
+ dom.dir = direction;
1418
+ } else {
1419
+ dom.removeAttribute('dir');
1420
+ }
1421
+ }
1409
1422
  function $createNode(key, slot) {
1410
1423
  const node = activeNextNodeMap.get(key);
1411
1424
  if (node === undefined) {
@@ -1427,13 +1440,14 @@ function $createNode(key, slot) {
1427
1440
  if ($isElementNode(node)) {
1428
1441
  const indent = node.__indent;
1429
1442
  const childrenSize = node.__size;
1443
+ $setElementDirection(dom, node);
1430
1444
  if (indent !== 0) {
1431
1445
  setElementIndent(dom, indent);
1432
1446
  }
1433
1447
  if (childrenSize !== 0) {
1434
1448
  const endIndex = childrenSize - 1;
1435
1449
  const children = createChildrenArray(node, activeNextNodeMap);
1436
- $createChildrenWithDirection(children, endIndex, node, dom);
1450
+ $createChildren(children, node, 0, endIndex, node.getDOMSlot(dom));
1437
1451
  }
1438
1452
  const format = node.__format;
1439
1453
  if (format !== 0) {
@@ -1455,10 +1469,6 @@ function $createNode(key, slot) {
1455
1469
  }
1456
1470
  // Decorators are always non editable
1457
1471
  dom.contentEditable = 'false';
1458
- } else if ($isTextNode(node)) {
1459
- if (!node.isDirectionless()) {
1460
- subTreeDirectionedTextContent += text;
1461
- }
1462
1472
  }
1463
1473
  subTreeTextContent += text;
1464
1474
  editorTextContent += text;
@@ -1473,13 +1483,6 @@ function $createNode(key, slot) {
1473
1483
  setMutatedNode(mutatedNodes, activeEditorNodes, activeMutationListeners, node, 'created');
1474
1484
  return dom;
1475
1485
  }
1476
- function $createChildrenWithDirection(children, endIndex, element, dom) {
1477
- const previousSubTreeDirectionedTextContent = subTreeDirectionedTextContent;
1478
- subTreeDirectionedTextContent = '';
1479
- $createChildren(children, element, 0, endIndex, element.getDOMSlot(dom));
1480
- reconcileBlockDirection(element, dom);
1481
- subTreeDirectionedTextContent = previousSubTreeDirectionedTextContent;
1482
- }
1483
1486
  function $createChildren(children, element, _startIndex, endIndex, slot) {
1484
1487
  const previousSubTreeTextContent = subTreeTextContent;
1485
1488
  subTreeTextContent = '';
@@ -1535,67 +1538,12 @@ function reconcileTextStyle(element) {
1535
1538
  element.setTextStyle(subTreeTextStyle);
1536
1539
  }
1537
1540
  }
1538
- function reconcileBlockDirection(element, dom) {
1539
- const previousSubTreeDirectionTextContent = dom.__lexicalDirTextContent || '';
1540
- const previousDirection = dom.__lexicalDir || '';
1541
- if (previousSubTreeDirectionTextContent !== subTreeDirectionedTextContent || previousDirection !== activeTextDirection) {
1542
- const hasEmptyDirectionedTextContent = subTreeDirectionedTextContent === '';
1543
- const direction = hasEmptyDirectionedTextContent ? activeTextDirection : getTextDirection(subTreeDirectionedTextContent);
1544
- if (direction !== previousDirection) {
1545
- const classList = dom.classList;
1546
- const theme = activeEditorConfig.theme;
1547
- let previousDirectionTheme = previousDirection !== null ? theme[previousDirection] : undefined;
1548
- let nextDirectionTheme = direction !== null ? theme[direction] : undefined;
1549
-
1550
- // Remove the old theme classes if they exist
1551
- if (previousDirectionTheme !== undefined) {
1552
- if (typeof previousDirectionTheme === 'string') {
1553
- const classNamesArr = normalizeClassNames(previousDirectionTheme);
1554
- previousDirectionTheme = theme[previousDirection] = classNamesArr;
1555
- }
1556
-
1557
- // @ts-ignore: intentional
1558
- classList.remove(...previousDirectionTheme);
1559
- }
1560
- if (direction === null || hasEmptyDirectionedTextContent && direction === 'ltr') {
1561
- // Remove direction
1562
- dom.removeAttribute('dir');
1563
- } else {
1564
- // Apply the new theme classes if they exist
1565
- if (nextDirectionTheme !== undefined) {
1566
- if (typeof nextDirectionTheme === 'string') {
1567
- const classNamesArr = normalizeClassNames(nextDirectionTheme);
1568
- // @ts-expect-error: intentional
1569
- nextDirectionTheme = theme[direction] = classNamesArr;
1570
- }
1571
- if (nextDirectionTheme !== undefined) {
1572
- classList.add(...nextDirectionTheme);
1573
- }
1574
- }
1575
-
1576
- // Update direction
1577
- dom.dir = direction;
1578
- }
1579
- if (!activeEditorStateReadOnly) {
1580
- const writableNode = element.getWritable();
1581
- writableNode.__dir = direction;
1582
- }
1583
- }
1584
- activeTextDirection = direction;
1585
- dom.__lexicalDirTextContent = subTreeDirectionedTextContent;
1586
- dom.__lexicalDir = direction;
1587
- }
1588
- }
1589
1541
  function $reconcileChildrenWithDirection(prevElement, nextElement, dom) {
1590
- const previousSubTreeDirectionTextContent = subTreeDirectionedTextContent;
1591
- subTreeDirectionedTextContent = '';
1592
1542
  subTreeTextFormat = null;
1593
1543
  subTreeTextStyle = '';
1594
1544
  $reconcileChildren(prevElement, nextElement, nextElement.getDOMSlot(dom));
1595
- reconcileBlockDirection(nextElement, dom);
1596
1545
  reconcileTextFormat(nextElement);
1597
1546
  reconcileTextStyle(nextElement);
1598
- subTreeDirectionedTextContent = previousSubTreeDirectionTextContent;
1599
1547
  }
1600
1548
  function createChildrenArray(element, nodeMap) {
1601
1549
  const children = [];
@@ -1700,15 +1648,8 @@ function $reconcileNode(key, parentDOM) {
1700
1648
  subTreeTextContent += previousSubTreeTextContent;
1701
1649
  editorTextContent += previousSubTreeTextContent;
1702
1650
  }
1703
- const previousSubTreeDirectionTextContent = dom.__lexicalDirTextContent;
1704
- if (previousSubTreeDirectionTextContent !== undefined) {
1705
- subTreeDirectionedTextContent += previousSubTreeDirectionTextContent;
1706
- }
1707
1651
  } else {
1708
1652
  const text = prevNode.getTextContent();
1709
- if ($isTextNode(prevNode) && !prevNode.isDirectionless()) {
1710
- subTreeDirectionedTextContent += text;
1711
- }
1712
1653
  editorTextContent += text;
1713
1654
  subTreeTextContent += text;
1714
1655
  }
@@ -1733,13 +1674,12 @@ function $reconcileNode(key, parentDOM) {
1733
1674
  return replacementDOM;
1734
1675
  }
1735
1676
  if ($isElementNode(prevNode) && $isElementNode(nextNode)) {
1736
- // Reconcile element children
1737
1677
  const nextIndent = nextNode.__indent;
1738
- if (nextIndent !== prevNode.__indent) {
1678
+ if (treatAllNodesAsDirty || nextIndent !== prevNode.__indent) {
1739
1679
  setElementIndent(dom, nextIndent);
1740
1680
  }
1741
1681
  const nextFormat = nextNode.__format;
1742
- if (nextFormat !== prevNode.__format) {
1682
+ if (treatAllNodesAsDirty || nextFormat !== prevNode.__format) {
1743
1683
  setElementFormat(dom, nextFormat);
1744
1684
  }
1745
1685
  if (isDirty) {
@@ -1752,6 +1692,22 @@ function $reconcileNode(key, parentDOM) {
1752
1692
  subTreeTextContent += DOUBLE_LINE_BREAK;
1753
1693
  editorTextContent += DOUBLE_LINE_BREAK;
1754
1694
  }
1695
+ if (treatAllNodesAsDirty || nextNode.__dir !== prevNode.__dir) {
1696
+ $setElementDirection(dom, nextNode);
1697
+ if (
1698
+ // Root node direction changing from set to unset (or vice versa)
1699
+ // changes how children's direction is calculated.
1700
+ $isRootNode(nextNode) &&
1701
+ // Can skip if all children already reconciled.
1702
+ !treatAllNodesAsDirty) {
1703
+ for (const child of nextNode.getChildren()) {
1704
+ if ($isElementNode(child)) {
1705
+ const childDom = getElementByKeyOrThrow(activeEditor$1, child.getKey());
1706
+ $setElementDirection(childDom, child);
1707
+ }
1708
+ }
1709
+ }
1710
+ }
1755
1711
  } else {
1756
1712
  const text = nextNode.getTextContent();
1757
1713
  if ($isDecoratorNode(nextNode)) {
@@ -1759,9 +1715,6 @@ function $reconcileNode(key, parentDOM) {
1759
1715
  if (decorator !== null) {
1760
1716
  reconcileDecorator(key, decorator);
1761
1717
  }
1762
- } else if ($isTextNode(nextNode) && !nextNode.isDirectionless()) {
1763
- // Handle text content, for LTR, LTR cases.
1764
- subTreeDirectionedTextContent += text;
1765
1718
  }
1766
1719
  subTreeTextContent += text;
1767
1720
  editorTextContent += text;
@@ -1867,11 +1820,9 @@ function $reconcileRoot(prevEditorState, nextEditorState, editor, dirtyType, dir
1867
1820
  // The cache must be rebuilt during reconciliation to account for any changes.
1868
1821
  subTreeTextContent = '';
1869
1822
  editorTextContent = '';
1870
- subTreeDirectionedTextContent = '';
1871
1823
  // Rather than pass around a load of arguments through the stack recursively
1872
1824
  // we instead set them as bindings within the scope of the module.
1873
1825
  treatAllNodesAsDirty = dirtyType === FULL_RECONCILE;
1874
- activeTextDirection = null;
1875
1826
  activeEditor$1 = editor;
1876
1827
  activeEditorConfig = editor._config;
1877
1828
  activeEditorNodes = editor._nodes;
@@ -10771,7 +10722,7 @@ class LexicalEditor {
10771
10722
  };
10772
10723
  }
10773
10724
  }
10774
- LexicalEditor.version = "0.34.1-nightly.20250818.0+dev.cjs";
10725
+ LexicalEditor.version = "0.34.1-nightly.20250820.0+dev.cjs";
10775
10726
 
10776
10727
  let pendingNodeToClone = null;
10777
10728
  function setPendingNodeToClone(pendingNode) {
@@ -10859,15 +10810,6 @@ function getEditorPropertyFromDOMNode(node) {
10859
10810
  // @ts-expect-error: internal field
10860
10811
  return node ? node.__lexicalEditor : null;
10861
10812
  }
10862
- function getTextDirection(text) {
10863
- if (RTL_REGEX.test(text)) {
10864
- return 'rtl';
10865
- }
10866
- if (LTR_REGEX.test(text)) {
10867
- return 'ltr';
10868
- }
10869
- return null;
10870
- }
10871
10813
 
10872
10814
  /**
10873
10815
  * Return true if the TextNode is a TabNode or is in token mode.
package/Lexical.dev.mjs CHANGED
@@ -138,13 +138,6 @@ const DOUBLE_LINE_BREAK = '\n\n';
138
138
  // For FF, we need to use a non-breaking space, or it gets composition
139
139
  // in a stuck state.
140
140
  const COMPOSITION_START_CHAR = IS_FIREFOX ? NON_BREAKING_SPACE : COMPOSITION_SUFFIX;
141
- const RTL = '\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC';
142
- const LTR = 'A-Za-z\u00C0-\u00D6\u00D8-\u00F6' + '\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF\u200E\u2C00-\uFB1C' + '\uFE00-\uFE6F\uFEFD-\uFFFF';
143
-
144
- // eslint-disable-next-line no-misleading-character-class
145
- const RTL_REGEX = new RegExp('^[^' + LTR + ']*[' + RTL + ']');
146
- // eslint-disable-next-line no-misleading-character-class
147
- const LTR_REGEX = new RegExp('^[^' + RTL + ']*[' + LTR + ']');
148
141
  const TEXT_TYPE_TO_FORMAT = {
149
142
  bold: IS_BOLD,
150
143
  capitalize: IS_CAPITALIZE,
@@ -1321,7 +1314,6 @@ function $normalizePoint(point) {
1321
1314
  }
1322
1315
 
1323
1316
  let subTreeTextContent = '';
1324
- let subTreeDirectionedTextContent = '';
1325
1317
  let subTreeTextFormat = null;
1326
1318
  let subTreeTextStyle = '';
1327
1319
  let editorTextContent = '';
@@ -1331,7 +1323,6 @@ let activeEditorNodes;
1331
1323
  let treatAllNodesAsDirty = false;
1332
1324
  let activeEditorStateReadOnly = false;
1333
1325
  let activeMutationListeners;
1334
- let activeTextDirection = null;
1335
1326
  let activeDirtyElements;
1336
1327
  let activeDirtyLeaves;
1337
1328
  let activePrevNodeMap;
@@ -1404,6 +1395,28 @@ function setElementFormat(dom, format) {
1404
1395
  setTextAlign(domStyle, 'end');
1405
1396
  }
1406
1397
  }
1398
+ function $getReconciledDirection(node) {
1399
+ const direction = node.__dir;
1400
+ if (direction !== null) {
1401
+ return direction;
1402
+ }
1403
+ if ($isRootNode(node)) {
1404
+ return null;
1405
+ }
1406
+ const parent = node.getParentOrThrow();
1407
+ if (!$isRootNode(parent) || parent.__dir !== null) {
1408
+ return null;
1409
+ }
1410
+ return 'auto';
1411
+ }
1412
+ function $setElementDirection(dom, node) {
1413
+ const direction = $getReconciledDirection(node);
1414
+ if (direction !== null) {
1415
+ dom.dir = direction;
1416
+ } else {
1417
+ dom.removeAttribute('dir');
1418
+ }
1419
+ }
1407
1420
  function $createNode(key, slot) {
1408
1421
  const node = activeNextNodeMap.get(key);
1409
1422
  if (node === undefined) {
@@ -1425,13 +1438,14 @@ function $createNode(key, slot) {
1425
1438
  if ($isElementNode(node)) {
1426
1439
  const indent = node.__indent;
1427
1440
  const childrenSize = node.__size;
1441
+ $setElementDirection(dom, node);
1428
1442
  if (indent !== 0) {
1429
1443
  setElementIndent(dom, indent);
1430
1444
  }
1431
1445
  if (childrenSize !== 0) {
1432
1446
  const endIndex = childrenSize - 1;
1433
1447
  const children = createChildrenArray(node, activeNextNodeMap);
1434
- $createChildrenWithDirection(children, endIndex, node, dom);
1448
+ $createChildren(children, node, 0, endIndex, node.getDOMSlot(dom));
1435
1449
  }
1436
1450
  const format = node.__format;
1437
1451
  if (format !== 0) {
@@ -1453,10 +1467,6 @@ function $createNode(key, slot) {
1453
1467
  }
1454
1468
  // Decorators are always non editable
1455
1469
  dom.contentEditable = 'false';
1456
- } else if ($isTextNode(node)) {
1457
- if (!node.isDirectionless()) {
1458
- subTreeDirectionedTextContent += text;
1459
- }
1460
1470
  }
1461
1471
  subTreeTextContent += text;
1462
1472
  editorTextContent += text;
@@ -1471,13 +1481,6 @@ function $createNode(key, slot) {
1471
1481
  setMutatedNode(mutatedNodes, activeEditorNodes, activeMutationListeners, node, 'created');
1472
1482
  return dom;
1473
1483
  }
1474
- function $createChildrenWithDirection(children, endIndex, element, dom) {
1475
- const previousSubTreeDirectionedTextContent = subTreeDirectionedTextContent;
1476
- subTreeDirectionedTextContent = '';
1477
- $createChildren(children, element, 0, endIndex, element.getDOMSlot(dom));
1478
- reconcileBlockDirection(element, dom);
1479
- subTreeDirectionedTextContent = previousSubTreeDirectionedTextContent;
1480
- }
1481
1484
  function $createChildren(children, element, _startIndex, endIndex, slot) {
1482
1485
  const previousSubTreeTextContent = subTreeTextContent;
1483
1486
  subTreeTextContent = '';
@@ -1533,67 +1536,12 @@ function reconcileTextStyle(element) {
1533
1536
  element.setTextStyle(subTreeTextStyle);
1534
1537
  }
1535
1538
  }
1536
- function reconcileBlockDirection(element, dom) {
1537
- const previousSubTreeDirectionTextContent = dom.__lexicalDirTextContent || '';
1538
- const previousDirection = dom.__lexicalDir || '';
1539
- if (previousSubTreeDirectionTextContent !== subTreeDirectionedTextContent || previousDirection !== activeTextDirection) {
1540
- const hasEmptyDirectionedTextContent = subTreeDirectionedTextContent === '';
1541
- const direction = hasEmptyDirectionedTextContent ? activeTextDirection : getTextDirection(subTreeDirectionedTextContent);
1542
- if (direction !== previousDirection) {
1543
- const classList = dom.classList;
1544
- const theme = activeEditorConfig.theme;
1545
- let previousDirectionTheme = previousDirection !== null ? theme[previousDirection] : undefined;
1546
- let nextDirectionTheme = direction !== null ? theme[direction] : undefined;
1547
-
1548
- // Remove the old theme classes if they exist
1549
- if (previousDirectionTheme !== undefined) {
1550
- if (typeof previousDirectionTheme === 'string') {
1551
- const classNamesArr = normalizeClassNames(previousDirectionTheme);
1552
- previousDirectionTheme = theme[previousDirection] = classNamesArr;
1553
- }
1554
-
1555
- // @ts-ignore: intentional
1556
- classList.remove(...previousDirectionTheme);
1557
- }
1558
- if (direction === null || hasEmptyDirectionedTextContent && direction === 'ltr') {
1559
- // Remove direction
1560
- dom.removeAttribute('dir');
1561
- } else {
1562
- // Apply the new theme classes if they exist
1563
- if (nextDirectionTheme !== undefined) {
1564
- if (typeof nextDirectionTheme === 'string') {
1565
- const classNamesArr = normalizeClassNames(nextDirectionTheme);
1566
- // @ts-expect-error: intentional
1567
- nextDirectionTheme = theme[direction] = classNamesArr;
1568
- }
1569
- if (nextDirectionTheme !== undefined) {
1570
- classList.add(...nextDirectionTheme);
1571
- }
1572
- }
1573
-
1574
- // Update direction
1575
- dom.dir = direction;
1576
- }
1577
- if (!activeEditorStateReadOnly) {
1578
- const writableNode = element.getWritable();
1579
- writableNode.__dir = direction;
1580
- }
1581
- }
1582
- activeTextDirection = direction;
1583
- dom.__lexicalDirTextContent = subTreeDirectionedTextContent;
1584
- dom.__lexicalDir = direction;
1585
- }
1586
- }
1587
1539
  function $reconcileChildrenWithDirection(prevElement, nextElement, dom) {
1588
- const previousSubTreeDirectionTextContent = subTreeDirectionedTextContent;
1589
- subTreeDirectionedTextContent = '';
1590
1540
  subTreeTextFormat = null;
1591
1541
  subTreeTextStyle = '';
1592
1542
  $reconcileChildren(prevElement, nextElement, nextElement.getDOMSlot(dom));
1593
- reconcileBlockDirection(nextElement, dom);
1594
1543
  reconcileTextFormat(nextElement);
1595
1544
  reconcileTextStyle(nextElement);
1596
- subTreeDirectionedTextContent = previousSubTreeDirectionTextContent;
1597
1545
  }
1598
1546
  function createChildrenArray(element, nodeMap) {
1599
1547
  const children = [];
@@ -1698,15 +1646,8 @@ function $reconcileNode(key, parentDOM) {
1698
1646
  subTreeTextContent += previousSubTreeTextContent;
1699
1647
  editorTextContent += previousSubTreeTextContent;
1700
1648
  }
1701
- const previousSubTreeDirectionTextContent = dom.__lexicalDirTextContent;
1702
- if (previousSubTreeDirectionTextContent !== undefined) {
1703
- subTreeDirectionedTextContent += previousSubTreeDirectionTextContent;
1704
- }
1705
1649
  } else {
1706
1650
  const text = prevNode.getTextContent();
1707
- if ($isTextNode(prevNode) && !prevNode.isDirectionless()) {
1708
- subTreeDirectionedTextContent += text;
1709
- }
1710
1651
  editorTextContent += text;
1711
1652
  subTreeTextContent += text;
1712
1653
  }
@@ -1731,13 +1672,12 @@ function $reconcileNode(key, parentDOM) {
1731
1672
  return replacementDOM;
1732
1673
  }
1733
1674
  if ($isElementNode(prevNode) && $isElementNode(nextNode)) {
1734
- // Reconcile element children
1735
1675
  const nextIndent = nextNode.__indent;
1736
- if (nextIndent !== prevNode.__indent) {
1676
+ if (treatAllNodesAsDirty || nextIndent !== prevNode.__indent) {
1737
1677
  setElementIndent(dom, nextIndent);
1738
1678
  }
1739
1679
  const nextFormat = nextNode.__format;
1740
- if (nextFormat !== prevNode.__format) {
1680
+ if (treatAllNodesAsDirty || nextFormat !== prevNode.__format) {
1741
1681
  setElementFormat(dom, nextFormat);
1742
1682
  }
1743
1683
  if (isDirty) {
@@ -1750,6 +1690,22 @@ function $reconcileNode(key, parentDOM) {
1750
1690
  subTreeTextContent += DOUBLE_LINE_BREAK;
1751
1691
  editorTextContent += DOUBLE_LINE_BREAK;
1752
1692
  }
1693
+ if (treatAllNodesAsDirty || nextNode.__dir !== prevNode.__dir) {
1694
+ $setElementDirection(dom, nextNode);
1695
+ if (
1696
+ // Root node direction changing from set to unset (or vice versa)
1697
+ // changes how children's direction is calculated.
1698
+ $isRootNode(nextNode) &&
1699
+ // Can skip if all children already reconciled.
1700
+ !treatAllNodesAsDirty) {
1701
+ for (const child of nextNode.getChildren()) {
1702
+ if ($isElementNode(child)) {
1703
+ const childDom = getElementByKeyOrThrow(activeEditor$1, child.getKey());
1704
+ $setElementDirection(childDom, child);
1705
+ }
1706
+ }
1707
+ }
1708
+ }
1753
1709
  } else {
1754
1710
  const text = nextNode.getTextContent();
1755
1711
  if ($isDecoratorNode(nextNode)) {
@@ -1757,9 +1713,6 @@ function $reconcileNode(key, parentDOM) {
1757
1713
  if (decorator !== null) {
1758
1714
  reconcileDecorator(key, decorator);
1759
1715
  }
1760
- } else if ($isTextNode(nextNode) && !nextNode.isDirectionless()) {
1761
- // Handle text content, for LTR, LTR cases.
1762
- subTreeDirectionedTextContent += text;
1763
1716
  }
1764
1717
  subTreeTextContent += text;
1765
1718
  editorTextContent += text;
@@ -1865,11 +1818,9 @@ function $reconcileRoot(prevEditorState, nextEditorState, editor, dirtyType, dir
1865
1818
  // The cache must be rebuilt during reconciliation to account for any changes.
1866
1819
  subTreeTextContent = '';
1867
1820
  editorTextContent = '';
1868
- subTreeDirectionedTextContent = '';
1869
1821
  // Rather than pass around a load of arguments through the stack recursively
1870
1822
  // we instead set them as bindings within the scope of the module.
1871
1823
  treatAllNodesAsDirty = dirtyType === FULL_RECONCILE;
1872
- activeTextDirection = null;
1873
1824
  activeEditor$1 = editor;
1874
1825
  activeEditorConfig = editor._config;
1875
1826
  activeEditorNodes = editor._nodes;
@@ -10769,7 +10720,7 @@ class LexicalEditor {
10769
10720
  };
10770
10721
  }
10771
10722
  }
10772
- LexicalEditor.version = "0.34.1-nightly.20250818.0+dev.esm";
10723
+ LexicalEditor.version = "0.34.1-nightly.20250820.0+dev.esm";
10773
10724
 
10774
10725
  let pendingNodeToClone = null;
10775
10726
  function setPendingNodeToClone(pendingNode) {
@@ -10857,15 +10808,6 @@ function getEditorPropertyFromDOMNode(node) {
10857
10808
  // @ts-expect-error: internal field
10858
10809
  return node ? node.__lexicalEditor : null;
10859
10810
  }
10860
- function getTextDirection(text) {
10861
- if (RTL_REGEX.test(text)) {
10862
- return 'rtl';
10863
- }
10864
- if (LTR_REGEX.test(text)) {
10865
- return 'ltr';
10866
- }
10867
- return null;
10868
- }
10869
10811
 
10870
10812
  /**
10871
10813
  * Return true if the TextNode is a TabNode or is in token mode.