@lexical/html 0.45.0 → 0.45.1-dev.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.
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import { $sliceSelectedTextNodeContent } from '@lexical/selection';
10
- import { $getEditor, createState, isDOMDocumentNode, isHTMLElement, $getEditorDOMRenderConfig, DEFAULT_EDITOR_DOM_CONFIG, $isLexicalNode, getStaticNodeConfig, $fullReconcile, defineExtension, shallowMergeConfig, RootNode, isDOMTextNode, isBlockDomNode, isInlineDomNode, IS_HIGHLIGHT, IS_CODE, $generateNodesFromRawText, $createTextNode, $createLineBreakNode, $createParagraphNode, $setFormatFromDOM, setNodeIndentFromDOM, $setDirectionFromDOM, $isTextNode, IS_BOLD, IS_ITALIC, IS_UNDERLINE, IS_STRIKETHROUGH, IS_SUBSCRIPT, IS_SUPERSCRIPT, $isElementNode, $isBlockElementNode, $isDecoratorNode, configExtension, $getRoot, isDocumentFragment, $isRootOrShadowRoot, ArtificialNode__DO_NOT_USE } from 'lexical';
10
+ import { $getEditor, createState, isDOMDocumentNode, isHTMLElement, $getEditorDOMRenderConfig, DEFAULT_EDITOR_DOM_CONFIG, $isLexicalNode, getStaticNodeConfig, $fullReconcile, defineExtension, shallowMergeConfig, RootNode, isDOMTextNode, isBlockDomNode, isInlineDomNode, $isElementNode, $isBlockElementNode, $isDecoratorNode, $isLineBreakNode, $createParagraphNode, IS_HIGHLIGHT, IS_CODE, $generateNodesFromRawText, $createTextNode, isOnlyChildInBlockNode, isLastChildInBlockNode, $createLineBreakNode, $setFormatFromDOM, setNodeIndentFromDOM, $setDirectionFromDOM, $isTextNode, IS_BOLD, IS_ITALIC, IS_UNDERLINE, IS_STRIKETHROUGH, IS_SUBSCRIPT, IS_SUPERSCRIPT, configExtension, $getRoot, $assumeActiveEditor, isDocumentFragment, $isRootOrShadowRoot, ArtificialNode__DO_NOT_USE } from 'lexical';
11
11
  import { objectKlassEquals } from '@lexical/utils';
12
12
  import { getPeerDependencyFromEditor, getKnownTypesAndNodes, $getExtensionOutput, HorizontalRuleExtension, $createHorizontalRuleNode } from '@lexical/extension';
13
13
 
@@ -1669,6 +1669,249 @@ function $getImportContextValue(cfg, editor = $getEditor()) {
1669
1669
  */
1670
1670
  const $withImportContext = $withContext(DOMImportContextSymbol, getDefaultImportContext);
1671
1671
 
1672
+ /**
1673
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
1674
+ *
1675
+ * This source code is licensed under the MIT license found in the
1676
+ * LICENSE file in the root directory of this source tree.
1677
+ *
1678
+ */
1679
+
1680
+
1681
+ /**
1682
+ * True if the node fills a block slot at the root or inside another
1683
+ * block — covers both ElementNode-style blocks (paragraph, heading,
1684
+ * quote) and block-level DecoratorNodes (HorizontalRuleNode,
1685
+ * ImageNode-as-block, etc.). Used by {@link BlockSchema},
1686
+ * {@link RootSchema}, and {@link NestedBlockSchema}.
1687
+ *
1688
+ * @experimental
1689
+ */
1690
+ function $isBlockLevel(node) {
1691
+ return $isBlockElementNode(node) || $isDecoratorNode(node) && !node.isInline();
1692
+ }
1693
+
1694
+ /**
1695
+ * Distribute an inline wrapper (`LinkNode`, `MarkNode`, …) across a
1696
+ * heterogeneous run of children produced by `$importChildren`, lifting
1697
+ * any block children to the top level while keeping the wrapper around
1698
+ * the leaf inline content.
1699
+ *
1700
+ * Use from a rule whose DOM source is an inline element that the
1701
+ * browser permitted to enclose block elements — the canonical case is
1702
+ * `<a href="…"><h1>title</h1><div>body</div></a>`, which a link rule
1703
+ * wants to surface as two block siblings (heading + paragraph), each
1704
+ * with its own link wrapping the original inline content. Schemas
1705
+ * can't express this because they reason about a parent's children
1706
+ * only — they cannot lift the parent out of itself.
1707
+ *
1708
+ * For each top-level child:
1709
+ * - **Inline children** are collected into runs; each run is wrapped
1710
+ * in a single fresh wrapper (from `$makeWrapper()`).
1711
+ * - **Block children** are descended into: their own children are
1712
+ * recursively distributed with `$makeWrapper`, then re-attached so
1713
+ * the block keeps its position at the top level.
1714
+ *
1715
+ * The returned list will contain a mix of blocks and wrapped inline
1716
+ * runs. The enclosing schema (typically {@link BlockSchema}) will
1717
+ * then package those inline wrappers into paragraphs as usual.
1718
+ *
1719
+ * @experimental
1720
+ */
1721
+ function $distributeInlineWrapper(children, $makeWrapper) {
1722
+ const out = [];
1723
+ let inlineRun = [];
1724
+ const flushInline = () => {
1725
+ if (inlineRun.length === 0) {
1726
+ return;
1727
+ }
1728
+ out.push($makeWrapper().splice(0, 0, inlineRun));
1729
+ inlineRun = [];
1730
+ };
1731
+ for (const child of children) {
1732
+ if ($isBlockLevel(child)) {
1733
+ flushInline();
1734
+ // Recursively distribute the wrapper into the block's own
1735
+ // children. A block DecoratorNode (no children) is left alone.
1736
+ if ($isElementNode(child)) {
1737
+ const wrapped = $distributeInlineWrapper(child.getChildren(), $makeWrapper);
1738
+ child.splice(0, child.getChildrenSize(), wrapped);
1739
+ }
1740
+ out.push(child);
1741
+ } else {
1742
+ inlineRun.push(child);
1743
+ }
1744
+ }
1745
+ flushInline();
1746
+ return out;
1747
+ }
1748
+
1749
+ /**
1750
+ * Apply a {@link ChildSchema} to a flat list of children produced by
1751
+ * `$importChildren`. Walks the list once, partitions into accepted vs.
1752
+ * rejected runs, packages or drops rejected runs, then runs `$finalize`.
1753
+ *
1754
+ * @internal
1755
+ */
1756
+ function $applySchema(schema, children, parent, domParent) {
1757
+ const out = [];
1758
+ let run = null;
1759
+ const flushRun = () => {
1760
+ if (run === null) {
1761
+ return;
1762
+ }
1763
+ const rejected = run;
1764
+ run = null;
1765
+ if (schema.$packageRun) {
1766
+ const packaged = schema.$packageRun(rejected, parent, domParent);
1767
+ if (packaged.length > 0) {
1768
+ for (const n of packaged) {
1769
+ out.push(n);
1770
+ }
1771
+ return;
1772
+ }
1773
+ }
1774
+ // No $packageRun (or it returned []) — apply onReject. 'drop' (default)
1775
+ // discards the run. 'hoist' lets it through unchanged at this level.
1776
+ if (schema.onReject === 'hoist') {
1777
+ for (const n of rejected) {
1778
+ out.push(n);
1779
+ }
1780
+ }
1781
+ };
1782
+ for (const child of children) {
1783
+ if (schema.$accepts(child, parent)) {
1784
+ flushRun();
1785
+ out.push(child);
1786
+ } else {
1787
+ if (run === null) {
1788
+ run = [];
1789
+ }
1790
+ run.push(child);
1791
+ }
1792
+ }
1793
+ flushRun();
1794
+ return schema.$finalize ? schema.$finalize(out, parent) : out;
1795
+ }
1796
+
1797
+ /**
1798
+ * Apply a parent DOM element's `text-align` (when set to one of the
1799
+ * supported {@link ElementFormatType} values) to each block-level child
1800
+ * Lexical node that does not yet have its own format.
1801
+ *
1802
+ * Mirrors the part of the legacy `wrapContinuousInlines` that wrote
1803
+ * `node.setFormat(textAlign)` onto pre-existing block children when the
1804
+ * DOM parent carried `style.textAlign`. Pair with
1805
+ * {@link $paragraphPackageRun} (which carries the same propagation onto
1806
+ * paragraphs synthesized around inline runs) to fully replicate the
1807
+ * legacy behavior on a run of mixed children.
1808
+ *
1809
+ * @experimental
1810
+ */
1811
+ function $propagateTextAlignToBlockChildren(children, domParent) {
1812
+ if (!isHTMLElement(domParent)) {
1813
+ return children;
1814
+ }
1815
+ const textAlign = domParent.style.textAlign;
1816
+ if (!isAlignmentValue(textAlign)) {
1817
+ return children;
1818
+ }
1819
+ for (const child of children) {
1820
+ if ($isBlockElementNode(child) && child.getFormatType() === '') {
1821
+ child.setFormat(textAlign);
1822
+ }
1823
+ }
1824
+ return children;
1825
+ }
1826
+
1827
+ /**
1828
+ * Wrap a run of inline lexical nodes in a fresh paragraph, propagating the
1829
+ * `text-align` of `domParent` as the paragraph's format type (matching the
1830
+ * legacy `wrapContinuousInlines` behavior).
1831
+ */
1832
+ function $paragraphPackageRun(run, _parent, domParent) {
1833
+ // Mirror the legacy `$wrapInlineNodes` (driven by
1834
+ // `selection.insertNodes`) shortcut where a lone `<br>` at this
1835
+ // level (a `LineBreakNode` is the only thing in the rejected run)
1836
+ // becomes an *empty* paragraph rather than a paragraph wrapping a
1837
+ // visible line break — that's the form clipboard pastes ending in a
1838
+ // trailing `<br>` (Google Docs, Gmail, …) rely on for the editor's
1839
+ // "extra trailing empty line" expectation.
1840
+ if (run.length === 1 && $isLineBreakNode(run[0])) {
1841
+ run = [];
1842
+ }
1843
+ const paragraph = $createParagraphNode();
1844
+ if (isHTMLElement(domParent)) {
1845
+ const textAlign = domParent.style.textAlign;
1846
+ if (isAlignmentValue(textAlign)) {
1847
+ paragraph.setFormat(textAlign);
1848
+ }
1849
+ }
1850
+ return [paragraph.splice(0, 0, run)];
1851
+ }
1852
+
1853
+ /**
1854
+ * Default schema for block-level positions (root of the document, the body
1855
+ * of a block element node). Accepts block lexical nodes; packages runs of
1856
+ * inline children into fresh paragraph nodes.
1857
+ *
1858
+ * @experimental
1859
+ */
1860
+ const BlockSchema = {
1861
+ $accepts: $isBlockLevel,
1862
+ $packageRun: $paragraphPackageRun,
1863
+ name: 'BlockSchema'
1864
+ };
1865
+
1866
+ /**
1867
+ * Schema for inline-only positions (the body of an inline lexical node such
1868
+ * as a link). Accepts non-block lexical nodes; runs of block children are
1869
+ * dropped (`onReject: 'drop'` is the default).
1870
+ *
1871
+ * @experimental
1872
+ */
1873
+ const InlineSchema = {
1874
+ $accepts: child => !$isBlockLevel(child),
1875
+ name: 'InlineSchema'
1876
+ };
1877
+
1878
+ /**
1879
+ * Schema for nested block positions — the equivalent of the legacy
1880
+ * `ArtificialNode__DO_NOT_USE` flow used when a block DOM element appears
1881
+ * inside another block lexical ancestor. Accepts block nodes; runs of inline
1882
+ * children are emitted with a line break between consecutive runs (instead
1883
+ * of being wrapped in a paragraph, which would introduce an extra level of
1884
+ * nesting).
1885
+ *
1886
+ * @experimental
1887
+ */
1888
+ const NestedBlockSchema = {
1889
+ $accepts: $isBlockLevel,
1890
+ /**
1891
+ * Pass an inline run through unchanged. Because the schema iterator only
1892
+ * groups *maximal* rejected runs (each separated from the next by an
1893
+ * accepted block child), the legacy "linebreak between adjacent inline
1894
+ * groups" case never arises — adjacent inline siblings are already
1895
+ * coalesced into one run.
1896
+ */
1897
+ $packageRun: run => run,
1898
+ name: 'NestedBlockSchema'
1899
+ };
1900
+
1901
+ /**
1902
+ * Schema for the topmost level of `$generateNodesFromDOM`. Identical to
1903
+ * {@link BlockSchema}; aliased for clarity at the entry point and so it can
1904
+ * be overridden separately in the future (e.g. to synthesize a `ListNode`
1905
+ * around runs of orphan `ListItemNode`s).
1906
+ *
1907
+ * @experimental
1908
+ */
1909
+ const RootSchema = {
1910
+ $accepts: $isBlockLevel,
1911
+ $packageRun: $paragraphPackageRun,
1912
+ name: 'RootSchema'
1913
+ };
1914
+
1672
1915
  /**
1673
1916
  * Copyright (c) Meta Platforms, Inc. and affiliates.
1674
1917
  *
@@ -2022,7 +2265,13 @@ const IgnoreScriptStyleRule = defineImportRule({
2022
2265
  name: '@lexical/html/script-style-ignore'
2023
2266
  });
2024
2267
  const LineBreakRule = defineImportRule({
2025
- $import: () => [$createLineBreakNode()],
2268
+ // Mirror the legacy LineBreakNode.importDOM filter: stray `<br>` that
2269
+ // are the sole or trailing child of a block parent (e.g. Apple's
2270
+ // `<br class="Apple-interchange-newline">` clipboard sentinel, or the
2271
+ // trailing `<br>` browsers insert after the last text in a `<div>`)
2272
+ // would otherwise survive as a LineBreakNode and tack an extra blank
2273
+ // line onto the imported content.
2274
+ $import: (_ctx, el) => isOnlyChildInBlockNode(el) || isLastChildInBlockNode(el) ? [] : [$createLineBreakNode()],
2026
2275
  match: sel$1.tag('br'),
2027
2276
  name: '@lexical/html/br'
2028
2277
  });
@@ -2052,6 +2301,51 @@ const ParagraphRule = defineImportRule({
2052
2301
  name: '@lexical/html/p'
2053
2302
  });
2054
2303
 
2304
+ /**
2305
+ * Transparent block-container rule for any unconverted block-level DOM
2306
+ * element — `<div>`, but also `<section>`, `<article>`, `<header>`,
2307
+ * `<figure>`, … (everything {@link isBlockDomNode} recognizes via the
2308
+ * legacy `BLOCK_TAG_RE`). Without it these would fall through to the
2309
+ * dispatcher's `$hoistChildrenOf` / `DefaultHoistRule` fallback, which
2310
+ * transparently lifts children up to the enclosing context. That works
2311
+ * structurally, but (a) two sibling `<section>`s collapse into a single
2312
+ * paragraph instead of two, and (b) any `text-align` set on the element
2313
+ * is lost because the synthesized paragraph (built by the enclosing
2314
+ * schema) sees the *grandparent* as `domParent`.
2315
+ *
2316
+ * The rule is registered as a `sel.any()` wildcard and defers (via
2317
+ * `$next()`) for non-block elements so inline tags still reach the inline
2318
+ * rules. Higher-priority tag rules (`<p>`, `<li>`, `<td>`, headings, …)
2319
+ * are dispatched first and never reach here.
2320
+ *
2321
+ * The element's children run through {@link BlockSchema} so each inline
2322
+ * run becomes its own `ParagraphNode` (with the element's `text-align`
2323
+ * picked up via {@link $paragraphPackageRun}'s `domParent`), and any
2324
+ * pre-existing block children get the same alignment applied via
2325
+ * {@link $propagateTextAlignToBlockChildren}. The resulting block-level
2326
+ * nodes are what the enclosing context sees — at the root a sibling
2327
+ * paragraph is the natural shape; inside a block lexical container the
2328
+ * container rule (e.g. {@link ListItemRule}) collapses paragraph
2329
+ * children back into inline-with-line-break form. That way both `<p>`
2330
+ * and transparent blocks (`<div>`, `<section>`, …) project to the same
2331
+ * `ParagraphNode` intermediate, and there is no need for a marker node
2332
+ * to distinguish them.
2333
+ */
2334
+ const TransparentBlockRule = defineImportRule({
2335
+ $import: (ctx, el, $next) => {
2336
+ if (!isBlockDomNode(el)) {
2337
+ // Inline element with no dedicated rule — let the inline rules (or
2338
+ // the default hoist) handle it.
2339
+ return $next();
2340
+ }
2341
+ return $propagateTextAlignToBlockChildren(ctx.$importChildren(el, {
2342
+ schema: BlockSchema
2343
+ }), el);
2344
+ },
2345
+ match: sel$1.any(),
2346
+ name: '@lexical/html/transparent-block'
2347
+ });
2348
+
2055
2349
  /**
2056
2350
  * Rules covering the {@link ParagraphNode}, {@link TextNode},
2057
2351
  * {@link LineBreakNode}, and {@link TabNode} cases that the legacy
@@ -2061,7 +2355,7 @@ const ParagraphRule = defineImportRule({
2061
2355
  *
2062
2356
  * @experimental
2063
2357
  */
2064
- const CoreImportRules = [IgnoreScriptStyleRule, ParagraphRule, TextRule, LineBreakRule, InlineFormatRule];
2358
+ const CoreImportRules = [IgnoreScriptStyleRule, ParagraphRule, TransparentBlockRule, TextRule, LineBreakRule, InlineFormatRule];
2065
2359
 
2066
2360
  /**
2067
2361
  * Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -2280,209 +2574,6 @@ function defineOverlayRules(entries) {
2280
2574
  };
2281
2575
  }
2282
2576
 
2283
- /**
2284
- * Copyright (c) Meta Platforms, Inc. and affiliates.
2285
- *
2286
- * This source code is licensed under the MIT license found in the
2287
- * LICENSE file in the root directory of this source tree.
2288
- *
2289
- */
2290
-
2291
-
2292
- /**
2293
- * True if the node fills a block slot at the root or inside another
2294
- * block — covers both ElementNode-style blocks (paragraph, heading,
2295
- * quote) and block-level DecoratorNodes (HorizontalRuleNode,
2296
- * ImageNode-as-block, etc.). Used by {@link BlockSchema},
2297
- * {@link RootSchema}, and {@link NestedBlockSchema}.
2298
- *
2299
- * @experimental
2300
- */
2301
- function $isBlockLevel(node) {
2302
- return $isBlockElementNode(node) || $isDecoratorNode(node) && !node.isInline();
2303
- }
2304
-
2305
- /**
2306
- * Distribute an inline wrapper (`LinkNode`, `MarkNode`, …) across a
2307
- * heterogeneous run of children produced by `$importChildren`, lifting
2308
- * any block children to the top level while keeping the wrapper around
2309
- * the leaf inline content.
2310
- *
2311
- * Use from a rule whose DOM source is an inline element that the
2312
- * browser permitted to enclose block elements — the canonical case is
2313
- * `<a href="…"><h1>title</h1><div>body</div></a>`, which a link rule
2314
- * wants to surface as two block siblings (heading + paragraph), each
2315
- * with its own link wrapping the original inline content. Schemas
2316
- * can't express this because they reason about a parent's children
2317
- * only — they cannot lift the parent out of itself.
2318
- *
2319
- * For each top-level child:
2320
- * - **Inline children** are collected into runs; each run is wrapped
2321
- * in a single fresh wrapper (from `$makeWrapper()`).
2322
- * - **Block children** are descended into: their own children are
2323
- * recursively distributed with `$makeWrapper`, then re-attached so
2324
- * the block keeps its position at the top level.
2325
- *
2326
- * The returned list will contain a mix of blocks and wrapped inline
2327
- * runs. The enclosing schema (typically {@link BlockSchema}) will
2328
- * then package those inline wrappers into paragraphs as usual.
2329
- *
2330
- * @experimental
2331
- */
2332
- function $distributeInlineWrapper(children, $makeWrapper) {
2333
- const out = [];
2334
- let inlineRun = [];
2335
- const flushInline = () => {
2336
- if (inlineRun.length === 0) {
2337
- return;
2338
- }
2339
- out.push($makeWrapper().splice(0, 0, inlineRun));
2340
- inlineRun = [];
2341
- };
2342
- for (const child of children) {
2343
- if ($isBlockLevel(child)) {
2344
- flushInline();
2345
- // Recursively distribute the wrapper into the block's own
2346
- // children. A block DecoratorNode (no children) is left alone.
2347
- if ($isElementNode(child)) {
2348
- const wrapped = $distributeInlineWrapper(child.getChildren(), $makeWrapper);
2349
- child.splice(0, child.getChildrenSize(), wrapped);
2350
- }
2351
- out.push(child);
2352
- } else {
2353
- inlineRun.push(child);
2354
- }
2355
- }
2356
- flushInline();
2357
- return out;
2358
- }
2359
-
2360
- /**
2361
- * Apply a {@link ChildSchema} to a flat list of children produced by
2362
- * `$importChildren`. Walks the list once, partitions into accepted vs.
2363
- * rejected runs, packages or drops rejected runs, then runs `$finalize`.
2364
- *
2365
- * @internal
2366
- */
2367
- function $applySchema(schema, children, parent, domParent) {
2368
- const out = [];
2369
- let run = null;
2370
- const flushRun = () => {
2371
- if (run === null) {
2372
- return;
2373
- }
2374
- const rejected = run;
2375
- run = null;
2376
- if (schema.$packageRun) {
2377
- const packaged = schema.$packageRun(rejected, parent, domParent);
2378
- if (packaged.length > 0) {
2379
- for (const n of packaged) {
2380
- out.push(n);
2381
- }
2382
- return;
2383
- }
2384
- }
2385
- // No $packageRun (or it returned []) — apply onReject. 'drop' (default)
2386
- // discards the run. 'hoist' lets it through unchanged at this level.
2387
- if (schema.onReject === 'hoist') {
2388
- for (const n of rejected) {
2389
- out.push(n);
2390
- }
2391
- }
2392
- };
2393
- for (const child of children) {
2394
- if (schema.$accepts(child, parent)) {
2395
- flushRun();
2396
- out.push(child);
2397
- } else {
2398
- if (run === null) {
2399
- run = [];
2400
- }
2401
- run.push(child);
2402
- }
2403
- }
2404
- flushRun();
2405
- return schema.$finalize ? schema.$finalize(out, parent) : out;
2406
- }
2407
-
2408
- /**
2409
- * Wrap a run of inline lexical nodes in a fresh paragraph, propagating the
2410
- * `text-align` of `domParent` as the paragraph's format type (matching the
2411
- * legacy `wrapContinuousInlines` behavior).
2412
- */
2413
- function $paragraphPackageRun(run, _parent, domParent) {
2414
- const paragraph = $createParagraphNode();
2415
- if (isHTMLElement(domParent)) {
2416
- const textAlign = domParent.style.textAlign;
2417
- if (isAlignmentValue(textAlign)) {
2418
- paragraph.setFormat(textAlign);
2419
- }
2420
- }
2421
- return [paragraph.splice(0, 0, run)];
2422
- }
2423
-
2424
- /**
2425
- * Default schema for block-level positions (root of the document, the body
2426
- * of a block element node). Accepts block lexical nodes; packages runs of
2427
- * inline children into fresh paragraph nodes.
2428
- *
2429
- * @experimental
2430
- */
2431
- const BlockSchema = {
2432
- $accepts: $isBlockLevel,
2433
- $packageRun: $paragraphPackageRun,
2434
- name: 'BlockSchema'
2435
- };
2436
-
2437
- /**
2438
- * Schema for inline-only positions (the body of an inline lexical node such
2439
- * as a link). Accepts non-block lexical nodes; runs of block children are
2440
- * dropped (`onReject: 'drop'` is the default).
2441
- *
2442
- * @experimental
2443
- */
2444
- const InlineSchema = {
2445
- $accepts: child => !$isBlockLevel(child),
2446
- name: 'InlineSchema'
2447
- };
2448
-
2449
- /**
2450
- * Schema for nested block positions — the equivalent of the legacy
2451
- * `ArtificialNode__DO_NOT_USE` flow used when a block DOM element appears
2452
- * inside another block lexical ancestor. Accepts block nodes; runs of inline
2453
- * children are emitted with a line break between consecutive runs (instead
2454
- * of being wrapped in a paragraph, which would introduce an extra level of
2455
- * nesting).
2456
- *
2457
- * @experimental
2458
- */
2459
- const NestedBlockSchema = {
2460
- $accepts: $isBlockLevel,
2461
- /**
2462
- * Pass an inline run through unchanged. Because the schema iterator only
2463
- * groups *maximal* rejected runs (each separated from the next by an
2464
- * accepted block child), the legacy "linebreak between adjacent inline
2465
- * groups" case never arises — adjacent inline siblings are already
2466
- * coalesced into one run.
2467
- */
2468
- $packageRun: run => run,
2469
- name: 'NestedBlockSchema'
2470
- };
2471
-
2472
- /**
2473
- * Schema for the topmost level of `$generateNodesFromDOM`. Identical to
2474
- * {@link BlockSchema}; aliased for clarity at the entry point and so it can
2475
- * be overridden separately in the future (e.g. to synthesize a `ListNode`
2476
- * around runs of orphan `ListItemNode`s).
2477
- *
2478
- * @experimental
2479
- */
2480
- const RootSchema = {
2481
- $accepts: $isBlockLevel,
2482
- $packageRun: $paragraphPackageRun,
2483
- name: 'RootSchema'
2484
- };
2485
-
2486
2577
  /**
2487
2578
  * Copyright (c) Meta Platforms, Inc. and affiliates.
2488
2579
  *
@@ -2831,20 +2922,21 @@ const HorizontalRuleRule = defineImportRule({
2831
2922
  const HorizontalRuleImportRules = [HorizontalRuleRule];
2832
2923
 
2833
2924
  /**
2834
- * Bundles {@link HorizontalRuleImportRules} (plus
2835
- * {@link CoreImportExtension}) into a single dependency. The legacy
2836
- * {@link HorizontalRuleExtension.importDOM} continues to work in parallel;
2837
- * depend on this extension to opt into the new pipeline.
2925
+ * Bundles {@link HorizontalRuleImportRules} together with the runtime
2926
+ * {@link HorizontalRuleExtension}. The application is expected to
2927
+ * already have `CoreImportExtension` (or some equivalent) in its
2928
+ * dependency graph the core/text/paragraph/inline-format rules are a
2929
+ * shared baseline, not something this leaf importer should re-declare.
2838
2930
  *
2839
2931
  * Lives in `@lexical/html` (not `@lexical/extension`) because
2840
2932
  * {@link DOMImportExtension} itself is in `@lexical/html`, and
2841
2933
  * `@lexical/extension` is upstream of `@lexical/html` in the dependency
2842
- * graph — same arrangement as {@link CoreImportExtension}.
2934
+ * graph.
2843
2935
  *
2844
2936
  * @experimental
2845
2937
  */
2846
2938
  const HorizontalRuleImportExtension = defineExtension({
2847
- dependencies: [CoreImportExtension, HorizontalRuleExtension, configExtension(DOMImportExtension, {
2939
+ dependencies: [HorizontalRuleExtension, configExtension(DOMImportExtension, {
2848
2940
  rules: HorizontalRuleImportRules
2849
2941
  })],
2850
2942
  name: '@lexical/html/HorizontalRuleImport'
@@ -2952,6 +3044,10 @@ function $generateHtmlFromNodes(editor, selection = null) {
2952
3044
  formatDevErrorMessage(`To use $generateHtmlFromNodes in headless mode please initialize a headless browser implementation such as JSDom or use withDOM from @lexical/headless/dom before calling this function.`);
2953
3045
  }
2954
3046
  }
3047
+ // BC: $setTextContent now requires an active-editor scope (added in #8519).
3048
+ // If the caller is in a legacy `editorState.read(cb)` scope (no active editor),
3049
+ // establish one via internal API.
3050
+ $assumeActiveEditor(editor);
2955
3051
  return $generateDOMFromNodes(document.createElement('div'), selection, editor).innerHTML;
2956
3052
  }
2957
3053
  function $appendNodesToHTML(editor, currentNode, parentElementAppend, selection = null, domConfig = $getEditorDOMRenderConfig(editor)) {
@@ -3143,4 +3239,4 @@ function isDomNodeBetweenTwoInlineNodes(node) {
3143
3239
  return isInlineDomNode(node.nextSibling) && isInlineDomNode(node.previousSibling);
3144
3240
  }
3145
3241
 
3146
- export { $distributeInlineWrapper, $generateDOMFromNodes, $generateDOMFromRoot, $generateHtmlFromNodes, $generateNodesFromDOM, $generateNodesFromDOMViaExtension, $getImportContextValue, $getRenderContextValue, $getSessionDOMRenderConfig, $inlineStylesFromStyleSheets, $isBlockLevel, $setRenderContextValue, $updateRenderContextValue, $withImportContext, $withRenderContext, BlockSchema, CoreImportExtension, CoreImportRules, DOMImportExtension, DOMRenderExtension, HorizontalRuleImportExtension, HorizontalRuleImportRules, ImportOverlays, ImportSource, ImportSourceDataTransfer, ImportTextFormat, ImportTextStyle, ImportWhitespaceConfig, InlineSchema, NestedBlockSchema, RenderContextExport, RenderContextRoot, RootSchema, contextUpdater, contextValue, createImportState, createRenderState, defaultIsInline, defaultPreservesWhitespace, defineImportRule, defineOverlayRules, domOverride, isElementOfTag, parseSelector, sel };
3242
+ export { $distributeInlineWrapper, $generateDOMFromNodes, $generateDOMFromRoot, $generateHtmlFromNodes, $generateNodesFromDOM, $generateNodesFromDOMViaExtension, $getImportContextValue, $getRenderContextValue, $getSessionDOMRenderConfig, $inlineStylesFromStyleSheets, $isBlockLevel, $propagateTextAlignToBlockChildren, $setRenderContextValue, $updateRenderContextValue, $withImportContext, $withRenderContext, BlockSchema, CoreImportExtension, CoreImportRules, DOMImportExtension, DOMRenderExtension, HorizontalRuleImportExtension, HorizontalRuleImportRules, ImportOverlays, ImportSource, ImportSourceDataTransfer, ImportTextFormat, ImportTextStyle, ImportWhitespaceConfig, InlineSchema, NestedBlockSchema, RenderContextExport, RenderContextRoot, RootSchema, contextUpdater, contextValue, createImportState, createRenderState, defaultIsInline, defaultPreservesWhitespace, defineImportRule, defineOverlayRules, domOverride, isElementOfTag, parseSelector, sel };
@@ -20,6 +20,7 @@ export const $getRenderContextValue = mod.$getRenderContextValue;
20
20
  export const $getSessionDOMRenderConfig = mod.$getSessionDOMRenderConfig;
21
21
  export const $inlineStylesFromStyleSheets = mod.$inlineStylesFromStyleSheets;
22
22
  export const $isBlockLevel = mod.$isBlockLevel;
23
+ export const $propagateTextAlignToBlockChildren = mod.$propagateTextAlignToBlockChildren;
23
24
  export const $setRenderContextValue = mod.$setRenderContextValue;
24
25
  export const $updateRenderContextValue = mod.$updateRenderContextValue;
25
26
  export const $withImportContext = mod.$withImportContext;
@@ -18,6 +18,7 @@ export const $getRenderContextValue = mod.$getRenderContextValue;
18
18
  export const $getSessionDOMRenderConfig = mod.$getSessionDOMRenderConfig;
19
19
  export const $inlineStylesFromStyleSheets = mod.$inlineStylesFromStyleSheets;
20
20
  export const $isBlockLevel = mod.$isBlockLevel;
21
+ export const $propagateTextAlignToBlockChildren = mod.$propagateTextAlignToBlockChildren;
21
22
  export const $setRenderContextValue = mod.$setRenderContextValue;
22
23
  export const $updateRenderContextValue = mod.$updateRenderContextValue;
23
24
  export const $withImportContext = mod.$withImportContext;