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