@mx-space/cli 0.13.1 → 0.13.3

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.
Files changed (63) hide show
  1. package/README.md +60 -1
  2. package/ROADMAP.md +11 -8
  3. package/dist/{Lexical.dev-By5dOKBN.mjs → Lexical.dev-DTxuYHmG.mjs} +2267 -431
  4. package/dist/{Lexical.node-fXM8Jp7p.mjs → Lexical.node-BlCLnfA6.mjs} +47 -10
  5. package/dist/Lexical.prod-CeB9UQuo.mjs +6816 -0
  6. package/dist/{LexicalClipboard.dev--HxGoSkO.mjs → LexicalClipboard.dev-CdFkLR_D.mjs} +131 -39
  7. package/dist/{LexicalClipboard.node-C3mRbrmW.mjs → LexicalClipboard.node-ktUajxsv.mjs} +2 -2
  8. package/dist/LexicalClipboard.prod-DliyLofW.mjs +429 -0
  9. package/dist/{LexicalCodeCore.dev-DjSrd4A4.mjs → LexicalCodeCore.dev-CL9tHWJX.mjs} +81 -67
  10. package/dist/LexicalCodeCore.prod-BoMSJc29.mjs +651 -0
  11. package/dist/LexicalDragon.dev-CqW7Aq5H.mjs +186 -0
  12. package/dist/{LexicalDragon.node-BVhw4C7s.mjs → LexicalDragon.node-DLXctJyy.mjs} +3 -2
  13. package/dist/LexicalDragon.prod-DHI3T6n5.mjs +121 -0
  14. package/dist/{LexicalExtension.dev-BPNyvGqe.mjs → LexicalExtension.dev-BP-18zns.mjs} +352 -38
  15. package/dist/{LexicalExtension.node-BVlcrgOx.mjs → LexicalExtension.node-BWH6xbzG.mjs} +9 -4
  16. package/dist/{LexicalExtension.prod-DFKbiNt-.mjs → LexicalExtension.prod-Cs6OgrDn.mjs} +479 -330
  17. package/dist/{LexicalHeadless.dev-B-cj7Pr5.mjs → LexicalHeadless.dev-DJp__UcP.mjs} +2 -2
  18. package/dist/{LexicalHeadless.prod-Byp1vNzT.mjs → LexicalHeadless.prod-o0v9cIu5.mjs} +2 -2
  19. package/dist/{LexicalHtml.dev-prBAwszN.mjs → LexicalHtml.dev-DoymwFpG.mjs} +327 -269
  20. package/dist/{LexicalHtml.node-BvNF96jZ.mjs → LexicalHtml.node-CVkbWtUA.mjs} +6 -4
  21. package/dist/{LexicalHtml.prod-Sz3CW1ht.mjs → LexicalHtml.prod-C2b3z99k.mjs} +355 -353
  22. package/dist/{LexicalLink.dev-NySTYhVR.mjs → LexicalLink.dev-7cgLOLIe.mjs} +70 -59
  23. package/dist/{LexicalLink.prod-BuCM8gts.mjs → LexicalLink.prod-DWFgoXHR.mjs} +211 -212
  24. package/dist/{LexicalList.dev-DIMOvSFD.mjs → LexicalList.dev-Ci2iOxFx.mjs} +246 -198
  25. package/dist/LexicalList.prod-D0xX5d3G.mjs +944 -0
  26. package/dist/{LexicalMarkdown.dev-C7aylvCG.mjs → LexicalMarkdown.dev-C0ZYCyuR.mjs} +130 -38
  27. package/dist/LexicalMarkdown.prod-0M-Nc-rh.mjs +932 -0
  28. package/dist/{LexicalRichText.dev-DfICq6lU.mjs → LexicalRichText.dev-Cnr1kDym.mjs} +151 -122
  29. package/dist/{LexicalRichText.node-Bg9jND3Q.mjs → LexicalRichText.node-BUJZAiap.mjs} +8 -11
  30. package/dist/LexicalRichText.prod-BfbMQ9uM.mjs +538 -0
  31. package/dist/{LexicalSelection.dev-DGjj12wW.mjs → LexicalSelection.dev-C4L7l8OB.mjs} +10 -9
  32. package/dist/{LexicalSelection.node-BU5L4193.mjs → LexicalSelection.node-CLKroUMQ.mjs} +4 -4
  33. package/dist/{LexicalSelection.prod-D-PwRbyK.mjs → LexicalSelection.prod-DzFqpTlw.mjs} +144 -146
  34. package/dist/{LexicalTable.dev-ChP7cugd.mjs → LexicalTable.dev-Cc9-zqKa.mjs} +186 -121
  35. package/dist/LexicalTable.prod-BgO4nCxy.mjs +2336 -0
  36. package/dist/{LexicalUtils.dev-BiFU3789.mjs → LexicalUtils.dev-BRgK0L6G.mjs} +375 -35
  37. package/dist/{LexicalUtils.node-j3Llm7Y3.mjs → LexicalUtils.node-BVAwOkL4.mjs} +24 -12
  38. package/dist/LexicalUtils.prod-C1gtvVDP.mjs +504 -0
  39. package/dist/bin/mxs.mjs +1 -1
  40. package/dist/{esm-DFrz5rIo.mjs → esm-BNu4sUWV.mjs} +220 -185
  41. package/dist/esm-jbwcVZth.mjs +2 -0
  42. package/dist/index.d.mts +46 -17
  43. package/dist/index.mjs +1 -1
  44. package/dist/{mxs-DXpzbUf4.mjs → mxs-zPvjkoNC.mjs} +8235 -6041
  45. package/dist/vendor/litexml/cli.mjs +24150 -0
  46. package/dist/vendor/litexml/litexml-html-preview-client.css +8862 -0
  47. package/dist/vendor/litexml/litexml-html-preview-client.js +163816 -0
  48. package/dist/vendor/litexml/style.css +96 -0
  49. package/package.json +21 -22
  50. package/skills/commands-ai.md +115 -0
  51. package/skills/commands-preview.md +3 -3
  52. package/skills/overview.md +1 -0
  53. package/dist/Lexical.prod-BlCvXPGa.mjs +0 -6088
  54. package/dist/LexicalClipboard.prod-DNJzFMcT.mjs +0 -371
  55. package/dist/LexicalCodeCore.prod-DTDShkR3.mjs +0 -642
  56. package/dist/LexicalDragon.dev-DwprRH0z.mjs +0 -88
  57. package/dist/LexicalDragon.prod-nh4J-8vn.mjs +0 -59
  58. package/dist/LexicalList.prod-MVqfA6Vo.mjs +0 -925
  59. package/dist/LexicalMarkdown.prod-CfQSM406.mjs +0 -868
  60. package/dist/LexicalRichText.prod-GsFzCK-o.mjs +0 -550
  61. package/dist/LexicalTable.prod-Bpr9YRXp.mjs +0 -2311
  62. package/dist/LexicalUtils.prod-DCvrA78p.mjs +0 -373
  63. package/dist/esm-DXO9Afik.mjs +0 -2
@@ -1,8 +1,8 @@
1
- import { d as getPeerDependencyFromEditor, i as HorizontalRuleExtension, n as $getExtensionOutput, t as $createHorizontalRuleNode, u as getKnownTypesAndNodes } from "./LexicalExtension.node-BVlcrgOx.mjs";
2
- import { $ as $isElementNode, At as ArtificialNode__DO_NOT_USE, Cn as IS_STRIKETHROUGH, En as IS_UNDERLINE, F as $getEditor, Fr as shallowMergeConfig, Gn as RootNode, Gt as DEFAULT_EDITOR_DOM_CONFIG, H as $getRoot, I as $getEditorDOMRenderConfig, Pr as setNodeIndentFromDOM, Sr as isHTMLElement, St as $setFormatFromDOM, Tn as IS_SUPERSCRIPT, Y as $isBlockElementNode, Z as $isDecoratorNode, _ as $createTextNode, _n as IS_CODE, _r as isDOMDocumentNode, b as $fullReconcile, br as isDocumentFragment, cr as defineExtension, f as $createParagraphNode, fr as getStaticNodeConfig, ft as $isTextNode, hn as IS_BOLD, hr as isBlockDomNode, lt as $isRootOrShadowRoot, or as createState, rr as configExtension, rt as $isLexicalNode, u as $createLineBreakNode, wn as IS_SUBSCRIPT, wr as isInlineDomNode, x as $generateNodesFromRawText, xn as IS_ITALIC, xt as $setDirectionFromDOM, yn as IS_HIGHLIGHT, yr as isDOMTextNode } from "./Lexical.node-fXM8Jp7p.mjs";
3
- import { i as $sliceSelectedTextNodeContent } from "./LexicalSelection.node-BU5L4193.mjs";
4
- import { g as objectKlassEquals } from "./LexicalUtils.node-j3Llm7Y3.mjs";
5
- //#region ../../node_modules/.pnpm/@lexical+html@0.45.0/node_modules/@lexical/html/dist/LexicalHtml.dev.mjs
1
+ import { a as HorizontalRuleNode, d as getPeerDependencyFromEditor, i as HorizontalRuleExtension, n as $getExtensionOutput, t as $createHorizontalRuleNode, u as getKnownTypesAndNodes } from "./LexicalExtension.node-BWH6xbzG.mjs";
2
+ import { At as $setFormatFromDOM, Br as isDOMDocumentNode, Dn as IS_BOLD, Fn as IS_STRIKETHROUGH, I as $getEditor, In as IS_SUBSCRIPT, L as $getEditorDOMRenderConfig, Ln as IS_SUPERSCRIPT, Nn as IS_ITALIC, Nr as getRegisteredSubtypeMap, Qr as isOnlyChildInBlockNode, Rn as IS_UNDERLINE, Rr as isBlockDomNode, Rt as ArtificialNode__DO_NOT_USE, S as $generateNodesFromRawText, U as $getRoot, Ur as isDOMTextNode, Wr as isDocumentFragment, Xr as isLastChildInBlockNode, Yr as isInlineDomNode, at as $isElementNode, br as defineExtension, bt as $isTextNode, ci as setNodeIndentFromDOM, d as $createLineBreakNode, dt as $isNodeSelection, ei as iterStaticNodeConfigChain, hr as configExtension, ht as $isRootOrShadowRoot, jn as IS_HIGHLIGHT, kn as IS_CODE, kt as $setDirectionFromDOM, li as shallowMergeConfig, lt as $isLexicalNode, p as $createParagraphNode, pt as $isRangeSelection, q as $getSlotFrame, qr as isHTMLElement, r as $assumeActiveEditor, rn as DEFAULT_EDITOR_DOM_CONFIG, rr as RootNode, rt as $isDecoratorNode, tt as $isBlockElementNode, ut as $isLineBreakNode, v as $createTextNode, vr as createState, x as $fullReconcile } from "./Lexical.node-BlCLnfA6.mjs";
3
+ import { a as $sliceSelectedTextNodeContent } from "./LexicalSelection.node-CLKroUMQ.mjs";
4
+ import { h as objectKlassEquals } from "./LexicalUtils.node-BVAwOkL4.mjs";
5
+ //#region ../../node_modules/.pnpm/@lexical+html@0.46.0_typescript@6.0.3/node_modules/@lexical/html/dist/LexicalHtml.dev.mjs
6
6
  /**
7
7
  * Copyright (c) Meta Platforms, Inc. and affiliates.
8
8
  *
@@ -256,12 +256,12 @@ function createRenderState(name, getDefaultValue, isEqual) {
256
256
  * Render context state that is true if the export was initiated from the root of the document.
257
257
  * @experimental
258
258
  */
259
- const RenderContextRoot = createRenderState("root", Boolean);
259
+ const RenderContextRoot = /* @__PURE__ */ createRenderState("root", Boolean);
260
260
  /**
261
261
  * Render context state that is true if this is an export operation ($generateHtmlFromNodes).
262
262
  * @experimental
263
263
  */
264
- const RenderContextExport = createRenderState("isExport", Boolean);
264
+ const RenderContextExport = /* @__PURE__ */ createRenderState("isExport", Boolean);
265
265
  function getDefaultRenderContext(editor) {
266
266
  const dep = getPeerDependencyFromEditor(editor, DOMRenderExtensionName);
267
267
  return dep ? dep.output.defaults : void 0;
@@ -348,39 +348,19 @@ function domOverride(nodes, config, options) {
348
348
  nodes
349
349
  };
350
350
  }
351
- function buildTypeTree(editorConfig) {
352
- const t = {};
353
- const { nodes } = getKnownTypesAndNodes(editorConfig);
354
- for (const klass of nodes) {
355
- const type = klass.getType();
356
- t[type] = {
357
- klass,
358
- types: {}
359
- };
360
- }
361
- for (const baseRec of Object.values(t)) if (baseRec) {
362
- const baseType = baseRec.klass.getType();
363
- for (let { klass } = baseRec; $isLexicalNode(klass.prototype); klass = Object.getPrototypeOf(klass)) {
364
- const { ownNodeType } = getStaticNodeConfig(klass);
365
- const superRec = ownNodeType && t[ownNodeType];
366
- if (superRec) superRec.types[baseType] = true;
367
- }
368
- }
369
- return t;
370
- }
371
351
  function buildNodePredicate(klass) {
372
352
  return (node) => node instanceof klass;
373
353
  }
374
- function getPredicate(typeTree, { nodes }) {
354
+ function getPredicate(subtypeMap, { nodes }) {
375
355
  if (nodes === "*") return ALWAYS_TRUE;
376
356
  let types = {};
377
357
  const predicates = [];
378
358
  for (const klassOrPredicate of nodes) if ("getType" in klassOrPredicate) {
379
359
  const type = klassOrPredicate.getType();
380
360
  if (types) {
381
- const tree = typeTree[type];
382
- if (!(tree !== void 0)) formatDevErrorMessage(`Node class ${klassOrPredicate.name} with type ${type} not registered in editor`);
383
- types = Object.assign(types, tree.types);
361
+ const subtypes = subtypeMap.get(type);
362
+ if (!(subtypes !== void 0)) formatDevErrorMessage(`Node class ${klassOrPredicate.name} with type ${type} not registered in editor`);
363
+ for (const subtype of subtypes) types[subtype] = true;
384
364
  }
385
365
  predicates.push(buildNodePredicate(klassOrPredicate));
386
366
  } else {
@@ -401,6 +381,7 @@ function makePrerender() {
401
381
  $exportDOM: [],
402
382
  $extractWithChild: [],
403
383
  $getDOMSlot: [],
384
+ $getSlotTargetElement: [],
404
385
  $shouldExclude: [],
405
386
  $shouldInclude: [],
406
387
  $updateDOM: []
@@ -513,8 +494,8 @@ function sortedOverrides(overrides) {
513
494
  const depthOf = (klass) => {
514
495
  let depth = depths.get(klass);
515
496
  if (depth === void 0) {
516
- depth = 0;
517
- for (let k = klass; $isLexicalNode(k.prototype); k = Object.getPrototypeOf(k)) depth++;
497
+ depth = -1;
498
+ for (const _ of iterStaticNodeConfigChain(klass)) depth++;
518
499
  depths.set(klass, depth);
519
500
  }
520
501
  return depth;
@@ -527,10 +508,10 @@ function sortedOverrides(overrides) {
527
508
  ];
528
509
  }
529
510
  function precompileDOMRenderConfigOverrides(editorConfig, overrides) {
530
- const typeTree = buildTypeTree(editorConfig);
511
+ const subtypeMap = getRegisteredSubtypeMap(getKnownTypesAndNodes(editorConfig).nodes);
531
512
  const prerender = makePrerender();
532
513
  for (const override of sortedOverrides(overrides)) {
533
- const predicateOrTypes = getPredicate(typeTree, override);
514
+ const predicateOrTypes = getPredicate(subtypeMap, override);
534
515
  for (const k_ in prerender) {
535
516
  const k = k_;
536
517
  addOverride(prerender, k, predicateOrTypes, override[k]);
@@ -553,6 +534,7 @@ function compileDOMRenderConfigOverrides(editorConfig, { overrides }) {
553
534
  compilePrerenderKey(prerender, "$getDOMSlot", dom, merge3GetDOMSlot, ignoreNext3GetDOMSlot);
554
535
  compilePrerenderKey(prerender, "$shouldExclude", dom, merge3, ignoreNext3);
555
536
  compilePrerenderKey(prerender, "$shouldInclude", dom, merge3, ignoreNext3);
537
+ compilePrerenderKey(prerender, "$getSlotTargetElement", dom, merge4, ignoreNext4);
556
538
  compilePrerenderKey(prerender, "$updateDOM", dom, merge4, ignoreNext4);
557
539
  compilePrerenderKey(prerender, "$decorateDOM", dom, sequence4, identity);
558
540
  return dom;
@@ -712,7 +694,7 @@ var DOMRenderRuntimeImpl = class {
712
694
  * editor. This is highly experimental and subject to change from one version
713
695
  * to the next.
714
696
  **/
715
- const DOMRenderExtension = defineExtension({
697
+ const DOMRenderExtension = /* @__PURE__ */ defineExtension({
716
698
  build(editor, config, state) {
717
699
  const { initialEditorConfig } = state.getInitResult();
718
700
  const editorContext = createEditorContextRecord(config.contextDefaults);
@@ -725,7 +707,7 @@ const DOMRenderExtension = defineExtension({
725
707
  contextDefaults: [],
726
708
  overrides: []
727
709
  },
728
- html: { export: new Map([[RootNode, () => {
710
+ html: { export: /* @__PURE__ */ new Map([[RootNode, () => {
729
711
  const element = document.createElement("div");
730
712
  element.role = "textbox";
731
713
  return { element };
@@ -1119,7 +1101,7 @@ function createImportState(name, getDefaultValue, isEqual) {
1119
1101
  *
1120
1102
  * @experimental
1121
1103
  */
1122
- const ImportSource = createImportState("importSource", () => "unknown");
1104
+ const ImportSource = /* @__PURE__ */ createImportState("importSource", () => "unknown");
1123
1105
  /**
1124
1106
  * Built-in import-context state holding the {@link DataTransfer} the
1125
1107
  * import was sourced from, if any. `null` outside paste/drop flows.
@@ -1143,7 +1125,7 @@ const ImportSource = createImportState("importSource", () => "unknown");
1143
1125
  *
1144
1126
  * @experimental
1145
1127
  */
1146
- const ImportSourceDataTransfer = createImportState("importSourceDataTransfer", () => null);
1128
+ const ImportSourceDataTransfer = /* @__PURE__ */ createImportState("importSourceDataTransfer", () => null);
1147
1129
  /**
1148
1130
  * Built-in import-context state holding the bit-packed
1149
1131
  * {@link TextFormatType} formats that should apply to {@link TextNode}s
@@ -1153,7 +1135,7 @@ const ImportSourceDataTransfer = createImportState("importSourceDataTransfer", (
1153
1135
  *
1154
1136
  * @experimental
1155
1137
  */
1156
- const ImportTextFormat = createImportState("textFormat", () => 0);
1138
+ const ImportTextFormat = /* @__PURE__ */ createImportState("textFormat", () => 0);
1157
1139
  /**
1158
1140
  * Built-in import-context state holding a parsed CSS-style record
1159
1141
  * (the {@link getStyleObjectFromCSS} shape) that should apply to
@@ -1170,7 +1152,7 @@ const ImportTextFormat = createImportState("textFormat", () => 0);
1170
1152
  *
1171
1153
  * @experimental
1172
1154
  */
1173
- const ImportTextStyle = createImportState("textStyle", () => ({}));
1155
+ const ImportTextStyle = /* @__PURE__ */ createImportState("textStyle", () => ({}));
1174
1156
  /**
1175
1157
  * Determines whether a given DOM element should be treated as preserving
1176
1158
  * whitespace (i.e. text content under it is not collapsed and is split on
@@ -1234,7 +1216,7 @@ function defaultIsInline(node) {
1234
1216
  *
1235
1217
  * @experimental
1236
1218
  */
1237
- const ImportWhitespaceConfig = createImportState("whitespaceConfig", () => ({
1219
+ const ImportWhitespaceConfig = /* @__PURE__ */ createImportState("whitespaceConfig", () => ({
1238
1220
  isInline: defaultIsInline,
1239
1221
  preservesWhitespace: defaultPreservesWhitespace
1240
1222
  }));
@@ -1256,7 +1238,7 @@ const ImportWhitespaceConfig = createImportState("whitespaceConfig", () => ({
1256
1238
  *
1257
1239
  * @experimental
1258
1240
  */
1259
- const ImportOverlays = createImportState("importOverlays", () => []);
1241
+ const ImportOverlays = /* @__PURE__ */ createImportState("importOverlays", () => []);
1260
1242
  /**
1261
1243
  * The session IS the root-layer {@link ContextRecord} of the walk. Reads
1262
1244
  * fall through the prototype chain to the editor's `contextDefaults`,
@@ -1311,8 +1293,199 @@ const $withImportContext = $withContext(DOMImportContextSymbol, getDefaultImport
1311
1293
  * LICENSE file in the root directory of this source tree.
1312
1294
  *
1313
1295
  */
1296
+ /**
1297
+ * True if the node fills a block slot at the root or inside another
1298
+ * block — covers both ElementNode-style blocks (paragraph, heading,
1299
+ * quote) and block-level DecoratorNodes (HorizontalRuleNode,
1300
+ * ImageNode-as-block, etc.). Used by {@link BlockSchema},
1301
+ * {@link RootSchema}, and {@link NestedBlockSchema}.
1302
+ *
1303
+ * @experimental
1304
+ */
1305
+ function $isBlockLevel(node) {
1306
+ return $isBlockElementNode(node) || $isDecoratorNode(node) && !node.isInline();
1307
+ }
1308
+ /**
1309
+ * Distribute an inline wrapper (`LinkNode`, `MarkNode`, …) across a
1310
+ * heterogeneous run of children produced by `$importChildren`, lifting
1311
+ * any block children to the top level while keeping the wrapper around
1312
+ * the leaf inline content.
1313
+ *
1314
+ * Use from a rule whose DOM source is an inline element that the
1315
+ * browser permitted to enclose block elements — the canonical case is
1316
+ * `<a href="…"><h1>title</h1><div>body</div></a>`, which a link rule
1317
+ * wants to surface as two block siblings (heading + paragraph), each
1318
+ * with its own link wrapping the original inline content. Schemas
1319
+ * can't express this because they reason about a parent's children
1320
+ * only — they cannot lift the parent out of itself.
1321
+ *
1322
+ * For each top-level child:
1323
+ * - **Inline children** are collected into runs; each run is wrapped
1324
+ * in a single fresh wrapper (from `$makeWrapper()`).
1325
+ * - **Block children** are descended into: their own children are
1326
+ * recursively distributed with `$makeWrapper`, then re-attached so
1327
+ * the block keeps its position at the top level.
1328
+ *
1329
+ * The returned list will contain a mix of blocks and wrapped inline
1330
+ * runs. The enclosing schema (typically {@link BlockSchema}) will
1331
+ * then package those inline wrappers into paragraphs as usual.
1332
+ *
1333
+ * @experimental
1334
+ */
1335
+ function $distributeInlineWrapper(children, $makeWrapper) {
1336
+ const out = [];
1337
+ let inlineRun = [];
1338
+ const flushInline = () => {
1339
+ if (inlineRun.length === 0) return;
1340
+ out.push($makeWrapper().splice(0, 0, inlineRun));
1341
+ inlineRun = [];
1342
+ };
1343
+ for (const child of children) if ($isBlockLevel(child)) {
1344
+ flushInline();
1345
+ if ($isElementNode(child)) {
1346
+ const wrapped = $distributeInlineWrapper(child.getChildren(), $makeWrapper);
1347
+ child.splice(0, child.getChildrenSize(), wrapped);
1348
+ }
1349
+ out.push(child);
1350
+ } else inlineRun.push(child);
1351
+ flushInline();
1352
+ return out;
1353
+ }
1354
+ /**
1355
+ * Apply a {@link ChildSchema} to a flat list of children produced by
1356
+ * `$importChildren`. Walks the list once, partitions into accepted vs.
1357
+ * rejected runs, packages or drops rejected runs, then runs `$finalize`.
1358
+ *
1359
+ * @internal
1360
+ */
1361
+ function $applySchema(schema, children, parent, domParent) {
1362
+ const out = [];
1363
+ let run = null;
1364
+ const flushRun = () => {
1365
+ if (run === null) return;
1366
+ const rejected = run;
1367
+ run = null;
1368
+ if (schema.$packageRun) {
1369
+ const packaged = schema.$packageRun(rejected, parent, domParent);
1370
+ if (packaged.length > 0) {
1371
+ for (const n of packaged) out.push(n);
1372
+ return;
1373
+ }
1374
+ }
1375
+ if (schema.onReject === "hoist") for (const n of rejected) out.push(n);
1376
+ };
1377
+ for (const child of children) if (schema.$accepts(child, parent)) {
1378
+ flushRun();
1379
+ out.push(child);
1380
+ } else {
1381
+ if (run === null) run = [];
1382
+ run.push(child);
1383
+ }
1384
+ flushRun();
1385
+ return schema.$finalize ? schema.$finalize(out, parent) : out;
1386
+ }
1387
+ /**
1388
+ * Apply a parent DOM element's `text-align` (when set to one of the
1389
+ * supported {@link ElementFormatType} values) to each block-level child
1390
+ * Lexical node that does not yet have its own format.
1391
+ *
1392
+ * Mirrors the part of the legacy `wrapContinuousInlines` that wrote
1393
+ * `node.setFormat(textAlign)` onto pre-existing block children when the
1394
+ * DOM parent carried `style.textAlign`. Pair with
1395
+ * {@link $paragraphPackageRun} (which carries the same propagation onto
1396
+ * paragraphs synthesized around inline runs) to fully replicate the
1397
+ * legacy behavior on a run of mixed children.
1398
+ *
1399
+ * @experimental
1400
+ */
1401
+ function $propagateTextAlignToBlockChildren(children, domParent) {
1402
+ if (!isHTMLElement(domParent)) return children;
1403
+ const textAlign = domParent.style.textAlign;
1404
+ if (!isAlignmentValue(textAlign)) return children;
1405
+ for (const child of children) if ($isBlockElementNode(child) && child.getFormatType() === "") child.setFormat(textAlign);
1406
+ return children;
1407
+ }
1408
+ /**
1409
+ * Wrap a run of inline lexical nodes in a fresh paragraph, propagating the
1410
+ * `text-align` of `domParent` as the paragraph's format type (matching the
1411
+ * legacy `wrapContinuousInlines` behavior).
1412
+ */
1413
+ function $paragraphPackageRun(run, _parent, domParent) {
1414
+ if (run.length === 1 && $isLineBreakNode(run[0])) run = [];
1415
+ const paragraph = $createParagraphNode();
1416
+ if (isHTMLElement(domParent)) {
1417
+ const textAlign = domParent.style.textAlign;
1418
+ if (isAlignmentValue(textAlign)) paragraph.setFormat(textAlign);
1419
+ }
1420
+ return [paragraph.splice(0, 0, run)];
1421
+ }
1422
+ /**
1423
+ * Default schema for block-level positions (root of the document, the body
1424
+ * of a block element node). Accepts block lexical nodes; packages runs of
1425
+ * inline children into fresh paragraph nodes.
1426
+ *
1427
+ * @experimental
1428
+ */
1429
+ const BlockSchema = {
1430
+ $accepts: $isBlockLevel,
1431
+ $packageRun: $paragraphPackageRun,
1432
+ name: "BlockSchema"
1433
+ };
1434
+ /**
1435
+ * Schema for inline-only positions (the body of an inline lexical node such
1436
+ * as a link). Accepts non-block lexical nodes; runs of block children are
1437
+ * dropped (`onReject: 'drop'` is the default).
1438
+ *
1439
+ * @experimental
1440
+ */
1441
+ const InlineSchema = {
1442
+ $accepts: (child) => !$isBlockLevel(child),
1443
+ name: "InlineSchema"
1444
+ };
1445
+ /**
1446
+ * Schema for nested block positions — the equivalent of the legacy
1447
+ * `ArtificialNode__DO_NOT_USE` flow used when a block DOM element appears
1448
+ * inside another block lexical ancestor. Accepts block nodes; runs of inline
1449
+ * children are emitted with a line break between consecutive runs (instead
1450
+ * of being wrapped in a paragraph, which would introduce an extra level of
1451
+ * nesting).
1452
+ *
1453
+ * @experimental
1454
+ */
1455
+ const NestedBlockSchema = {
1456
+ $accepts: $isBlockLevel,
1457
+ /**
1458
+ * Pass an inline run through unchanged. Because the schema iterator only
1459
+ * groups *maximal* rejected runs (each separated from the next by an
1460
+ * accepted block child), the legacy "linebreak between adjacent inline
1461
+ * groups" case never arises — adjacent inline siblings are already
1462
+ * coalesced into one run.
1463
+ */
1464
+ $packageRun: (run) => run,
1465
+ name: "NestedBlockSchema"
1466
+ };
1467
+ /**
1468
+ * Schema for the topmost level of `$generateNodesFromDOM`. Identical to
1469
+ * {@link BlockSchema}; aliased for clarity at the entry point and so it can
1470
+ * be overridden separately in the future (e.g. to synthesize a `ListNode`
1471
+ * around runs of orphan `ListItemNode`s).
1472
+ *
1473
+ * @experimental
1474
+ */
1475
+ const RootSchema = {
1476
+ $accepts: $isBlockLevel,
1477
+ $packageRun: $paragraphPackageRun,
1478
+ name: "RootSchema"
1479
+ };
1480
+ /**
1481
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
1482
+ *
1483
+ * This source code is licensed under the MIT license found in the
1484
+ * LICENSE file in the root directory of this source tree.
1485
+ *
1486
+ */
1314
1487
  const sel$1 = selBase;
1315
- const ALIGNMENT_VALUES = new Set([
1488
+ const ALIGNMENT_VALUES = /* @__PURE__ */ new Set([
1316
1489
  "center",
1317
1490
  "end",
1318
1491
  "justify",
@@ -1392,7 +1565,7 @@ function mergeStyles(defaults, override) {
1392
1565
  * doesn't end up in both places (where the inline-style version would
1393
1566
  * shadow the format's themed CSS).
1394
1567
  */
1395
- const FORMAT_BIT_STYLE_PROPS = new Set([
1568
+ const FORMAT_BIT_STYLE_PROPS = /* @__PURE__ */ new Set([
1396
1569
  "font-weight",
1397
1570
  "font-style",
1398
1571
  "text-decoration",
@@ -1448,7 +1621,7 @@ function applyFormatOverride(format, ov) {
1448
1621
  * - `<span style="text-decoration: none">` strip inherited underline /
1449
1622
  * line-through.
1450
1623
  */
1451
- const InlineFormatRule = defineImportRule({
1624
+ const InlineFormatRule = /* @__PURE__ */ defineImportRule({
1452
1625
  $import: (ctx, el) => {
1453
1626
  const inherited = ctx.get(ImportTextFormat);
1454
1627
  const tagDefault = TAG_DEFAULT_STYLE[el.nodeName];
@@ -1549,7 +1722,7 @@ function $applyTextStyle(node, style) {
1549
1722
  * collapse whitespace using the same neighbor-aware rules as the legacy
1550
1723
  * `$convertTextDOMNode`.
1551
1724
  */
1552
- const TextRule = defineImportRule({
1725
+ const TextRule = /* @__PURE__ */ defineImportRule({
1553
1726
  $import: (ctx, el) => {
1554
1727
  const format = ctx.get(ImportTextFormat);
1555
1728
  const style = ctx.get(ImportTextStyle);
@@ -1578,41 +1751,77 @@ const TextRule = defineImportRule({
1578
1751
  * a higher-priority `<style>` rule to capture stylesheet text into the
1579
1752
  * import session for later use.
1580
1753
  */
1581
- const IgnoreScriptStyleRule = defineImportRule({
1754
+ const IgnoreScriptStyleRule = /* @__PURE__ */ defineImportRule({
1582
1755
  $import: () => [],
1583
1756
  match: sel$1.tag("script", "style"),
1584
1757
  name: "@lexical/html/script-style-ignore"
1585
1758
  });
1586
- const LineBreakRule = defineImportRule({
1587
- $import: () => [$createLineBreakNode()],
1759
+ const LineBreakRule = /* @__PURE__ */ defineImportRule({
1760
+ $import: (_ctx, el) => isOnlyChildInBlockNode(el) || isLastChildInBlockNode(el) ? [] : [$createLineBreakNode()],
1588
1761
  match: sel$1.tag("br"),
1589
1762
  name: "@lexical/html/br"
1590
1763
  });
1591
1764
  /**
1765
+ * `<p>` rule. Re-applies format, indent, direction, and the legacy
1766
+ * `align` attribute fallback.
1767
+ */
1768
+ const ParagraphRule = /* @__PURE__ */ defineImportRule({
1769
+ $import: (ctx, el) => {
1770
+ const p = $createParagraphNode();
1771
+ $setFormatFromDOM(p, el);
1772
+ setNodeIndentFromDOM(el, p);
1773
+ if (p.getFormatType() === "") {
1774
+ const align = el.getAttribute("align");
1775
+ if (align && isAlignmentValue(align)) p.setFormat(align);
1776
+ }
1777
+ $setDirectionFromDOM(p, el);
1778
+ return [p.splice(0, 0, ctx.$importChildren(el))];
1779
+ },
1780
+ match: sel$1.tag("p"),
1781
+ name: "@lexical/html/p"
1782
+ });
1783
+ /**
1784
+ * `<hr>` rule, gated on {@link HorizontalRuleNode} registration so it
1785
+ * mirrors the legacy `importDOM` contract (a node's conversions are only
1786
+ * active when the node itself is registered). It lives here rather than
1787
+ * next to `HorizontalRuleExtension` because `@lexical/extension`
1788
+ * is upstream of `@lexical/html` in the package graph and cannot define
1789
+ * import rules — this is the one node-providing extension whose import
1790
+ * support cannot be implied by depending on it.
1791
+ *
1792
+ * Registered ahead of {@link TransparentBlockRule}: `<hr>` matches
1793
+ * `isBlockDomNode`, so the wildcard block rule would otherwise consume
1794
+ * it. When `HorizontalRuleNode` is not registered, `$next()` restores
1795
+ * the old behavior (the childless element vanishes).
1796
+ *
1797
+ * @internal
1798
+ */
1799
+ const HorizontalRuleRule = /* @__PURE__ */ defineImportRule({
1800
+ $import: (_ctx, _el, $next) => $getEditor().hasNode(HorizontalRuleNode) ? [$createHorizontalRuleNode()] : $next(),
1801
+ match: sel$1.tag("hr"),
1802
+ name: "@lexical/html/hr"
1803
+ });
1804
+ /**
1592
1805
  * Rules covering the {@link ParagraphNode}, {@link TextNode},
1593
1806
  * {@link LineBreakNode}, and {@link TabNode} cases that the legacy
1594
- * `importDOM` machinery in `@lexical/lexical` handled. Intended to be
1595
- * registered as a dependency of every editor that uses
1596
- * {@link DOMImportExtension}.
1807
+ * `importDOM` machinery in `@lexical/lexical` handled, plus the
1808
+ * registration-gated `<hr>` rule for {@link HorizontalRuleNode} (see
1809
+ * {@link HorizontalRuleRule}). Intended to be registered as a dependency
1810
+ * of every editor that uses {@link DOMImportExtension}.
1597
1811
  *
1598
1812
  * @experimental
1599
1813
  */
1600
1814
  const CoreImportRules = [
1601
1815
  IgnoreScriptStyleRule,
1602
- defineImportRule({
1603
- $import: (ctx, el) => {
1604
- const p = $createParagraphNode();
1605
- $setFormatFromDOM(p, el);
1606
- setNodeIndentFromDOM(el, p);
1607
- if (p.getFormatType() === "") {
1608
- const align = el.getAttribute("align");
1609
- if (align && isAlignmentValue(align)) p.setFormat(align);
1610
- }
1611
- $setDirectionFromDOM(p, el);
1612
- return [p.splice(0, 0, ctx.$importChildren(el))];
1816
+ ParagraphRule,
1817
+ HorizontalRuleRule,
1818
+ /* @__PURE__ */ defineImportRule({
1819
+ $import: (ctx, el, $next) => {
1820
+ if (!isBlockDomNode(el)) return $next();
1821
+ return $propagateTextAlignToBlockChildren(ctx.$importChildren(el, { schema: BlockSchema }), el);
1613
1822
  },
1614
- match: sel$1.tag("p"),
1615
- name: "@lexical/html/p"
1823
+ match: sel$1.any(),
1824
+ name: "@lexical/html/transparent-block"
1616
1825
  }),
1617
1826
  TextRule,
1618
1827
  LineBreakRule,
@@ -1780,175 +1989,6 @@ function defineOverlayRules(entries) {
1780
1989
  * LICENSE file in the root directory of this source tree.
1781
1990
  *
1782
1991
  */
1783
- /**
1784
- * True if the node fills a block slot at the root or inside another
1785
- * block — covers both ElementNode-style blocks (paragraph, heading,
1786
- * quote) and block-level DecoratorNodes (HorizontalRuleNode,
1787
- * ImageNode-as-block, etc.). Used by {@link BlockSchema},
1788
- * {@link RootSchema}, and {@link NestedBlockSchema}.
1789
- *
1790
- * @experimental
1791
- */
1792
- function $isBlockLevel(node) {
1793
- return $isBlockElementNode(node) || $isDecoratorNode(node) && !node.isInline();
1794
- }
1795
- /**
1796
- * Distribute an inline wrapper (`LinkNode`, `MarkNode`, …) across a
1797
- * heterogeneous run of children produced by `$importChildren`, lifting
1798
- * any block children to the top level while keeping the wrapper around
1799
- * the leaf inline content.
1800
- *
1801
- * Use from a rule whose DOM source is an inline element that the
1802
- * browser permitted to enclose block elements — the canonical case is
1803
- * `<a href="…"><h1>title</h1><div>body</div></a>`, which a link rule
1804
- * wants to surface as two block siblings (heading + paragraph), each
1805
- * with its own link wrapping the original inline content. Schemas
1806
- * can't express this because they reason about a parent's children
1807
- * only — they cannot lift the parent out of itself.
1808
- *
1809
- * For each top-level child:
1810
- * - **Inline children** are collected into runs; each run is wrapped
1811
- * in a single fresh wrapper (from `$makeWrapper()`).
1812
- * - **Block children** are descended into: their own children are
1813
- * recursively distributed with `$makeWrapper`, then re-attached so
1814
- * the block keeps its position at the top level.
1815
- *
1816
- * The returned list will contain a mix of blocks and wrapped inline
1817
- * runs. The enclosing schema (typically {@link BlockSchema}) will
1818
- * then package those inline wrappers into paragraphs as usual.
1819
- *
1820
- * @experimental
1821
- */
1822
- function $distributeInlineWrapper(children, $makeWrapper) {
1823
- const out = [];
1824
- let inlineRun = [];
1825
- const flushInline = () => {
1826
- if (inlineRun.length === 0) return;
1827
- out.push($makeWrapper().splice(0, 0, inlineRun));
1828
- inlineRun = [];
1829
- };
1830
- for (const child of children) if ($isBlockLevel(child)) {
1831
- flushInline();
1832
- if ($isElementNode(child)) {
1833
- const wrapped = $distributeInlineWrapper(child.getChildren(), $makeWrapper);
1834
- child.splice(0, child.getChildrenSize(), wrapped);
1835
- }
1836
- out.push(child);
1837
- } else inlineRun.push(child);
1838
- flushInline();
1839
- return out;
1840
- }
1841
- /**
1842
- * Apply a {@link ChildSchema} to a flat list of children produced by
1843
- * `$importChildren`. Walks the list once, partitions into accepted vs.
1844
- * rejected runs, packages or drops rejected runs, then runs `$finalize`.
1845
- *
1846
- * @internal
1847
- */
1848
- function $applySchema(schema, children, parent, domParent) {
1849
- const out = [];
1850
- let run = null;
1851
- const flushRun = () => {
1852
- if (run === null) return;
1853
- const rejected = run;
1854
- run = null;
1855
- if (schema.$packageRun) {
1856
- const packaged = schema.$packageRun(rejected, parent, domParent);
1857
- if (packaged.length > 0) {
1858
- for (const n of packaged) out.push(n);
1859
- return;
1860
- }
1861
- }
1862
- if (schema.onReject === "hoist") for (const n of rejected) out.push(n);
1863
- };
1864
- for (const child of children) if (schema.$accepts(child, parent)) {
1865
- flushRun();
1866
- out.push(child);
1867
- } else {
1868
- if (run === null) run = [];
1869
- run.push(child);
1870
- }
1871
- flushRun();
1872
- return schema.$finalize ? schema.$finalize(out, parent) : out;
1873
- }
1874
- /**
1875
- * Wrap a run of inline lexical nodes in a fresh paragraph, propagating the
1876
- * `text-align` of `domParent` as the paragraph's format type (matching the
1877
- * legacy `wrapContinuousInlines` behavior).
1878
- */
1879
- function $paragraphPackageRun(run, _parent, domParent) {
1880
- const paragraph = $createParagraphNode();
1881
- if (isHTMLElement(domParent)) {
1882
- const textAlign = domParent.style.textAlign;
1883
- if (isAlignmentValue(textAlign)) paragraph.setFormat(textAlign);
1884
- }
1885
- return [paragraph.splice(0, 0, run)];
1886
- }
1887
- /**
1888
- * Default schema for block-level positions (root of the document, the body
1889
- * of a block element node). Accepts block lexical nodes; packages runs of
1890
- * inline children into fresh paragraph nodes.
1891
- *
1892
- * @experimental
1893
- */
1894
- const BlockSchema = {
1895
- $accepts: $isBlockLevel,
1896
- $packageRun: $paragraphPackageRun,
1897
- name: "BlockSchema"
1898
- };
1899
- /**
1900
- * Schema for inline-only positions (the body of an inline lexical node such
1901
- * as a link). Accepts non-block lexical nodes; runs of block children are
1902
- * dropped (`onReject: 'drop'` is the default).
1903
- *
1904
- * @experimental
1905
- */
1906
- const InlineSchema = {
1907
- $accepts: (child) => !$isBlockLevel(child),
1908
- name: "InlineSchema"
1909
- };
1910
- /**
1911
- * Schema for nested block positions — the equivalent of the legacy
1912
- * `ArtificialNode__DO_NOT_USE` flow used when a block DOM element appears
1913
- * inside another block lexical ancestor. Accepts block nodes; runs of inline
1914
- * children are emitted with a line break between consecutive runs (instead
1915
- * of being wrapped in a paragraph, which would introduce an extra level of
1916
- * nesting).
1917
- *
1918
- * @experimental
1919
- */
1920
- const NestedBlockSchema = {
1921
- $accepts: $isBlockLevel,
1922
- /**
1923
- * Pass an inline run through unchanged. Because the schema iterator only
1924
- * groups *maximal* rejected runs (each separated from the next by an
1925
- * accepted block child), the legacy "linebreak between adjacent inline
1926
- * groups" case never arises — adjacent inline siblings are already
1927
- * coalesced into one run.
1928
- */
1929
- $packageRun: (run) => run,
1930
- name: "NestedBlockSchema"
1931
- };
1932
- /**
1933
- * Schema for the topmost level of `$generateNodesFromDOM`. Identical to
1934
- * {@link BlockSchema}; aliased for clarity at the entry point and so it can
1935
- * be overridden separately in the future (e.g. to synthesize a `ListNode`
1936
- * around runs of orphan `ListItemNode`s).
1937
- *
1938
- * @experimental
1939
- */
1940
- const RootSchema = {
1941
- $accepts: $isBlockLevel,
1942
- $packageRun: $paragraphPackageRun,
1943
- name: "RootSchema"
1944
- };
1945
- /**
1946
- * Copyright (c) Meta Platforms, Inc. and affiliates.
1947
- *
1948
- * This source code is licensed under the MIT license found in the
1949
- * LICENSE file in the root directory of this source tree.
1950
- *
1951
- */
1952
1992
  const NO_CAPTURES = Object.freeze({});
1953
1993
  function makeContext(runtime, captures) {
1954
1994
  return {
@@ -2113,7 +2153,7 @@ function $runPreprocessStack(stack, dom, ctx) {
2113
2153
  *
2114
2154
  * @experimental
2115
2155
  */
2116
- const DefaultHoistRule = defineImportRule({
2156
+ const DefaultHoistRule = /* @__PURE__ */ defineImportRule({
2117
2157
  $import: (ctx, el) => ctx.$importChildren(el),
2118
2158
  match: selBase.any(),
2119
2159
  name: "@lexical/html/default-hoist"
@@ -2130,7 +2170,7 @@ const DefaultHoistRule = defineImportRule({
2130
2170
  * The legacy `$generateNodesFromDOM` continues to work in parallel; the
2131
2171
  * intent is to migrate node packages over to this extension incrementally.
2132
2172
  */
2133
- const DOMImportExtension = defineExtension({
2173
+ const DOMImportExtension = /* @__PURE__ */ defineExtension({
2134
2174
  build(editor, config) {
2135
2175
  const dispatch = compileImportRules(flattenRuleEntries(config.rules));
2136
2176
  const defaults = contextFromPairs(config.contextDefaults, void 0);
@@ -2186,47 +2226,49 @@ function $generateNodesFromDOMViaExtension(dom, options) {
2186
2226
  */
2187
2227
  /**
2188
2228
  * Bundles {@link CoreImportRules} into a {@link DOMImportExtension}-aware
2189
- * extension. Depend on this from your editor (directly or via richer
2190
- * extensions like `RichTextImportExtension`) to get the equivalent of the
2191
- * legacy core `importDOM` behavior for `<p>`, `<span>`, `<b>`,
2192
- * `<strong>`, `<em>`, `<i>`, `<code>`, `<mark>`, `<s>`, `<sub>`, `<sup>`,
2193
- * `<u>`, `<br>`, and `#text`.
2229
+ * extension. Node-providing extensions that contribute import rules
2230
+ * (`RichTextExtension`, `ListExtension`, `LinkExtension`,
2231
+ * `TableExtension`, `CodeExtension`, …) depend on this themselves, so
2232
+ * most editors get it implicitly; depend on it directly to get the
2233
+ * equivalent of the legacy core `importDOM` behavior for `<p>`,
2234
+ * `<span>`, `<b>`, `<strong>`, `<em>`, `<i>`, `<code>`, `<mark>`,
2235
+ * `<s>`, `<sub>`, `<sup>`, `<u>`, `<br>`, and `#text` (plus `<hr>`
2236
+ * when `HorizontalRuleNode` is registered).
2194
2237
  *
2195
2238
  * @experimental
2196
2239
  */
2197
- const CoreImportExtension = defineExtension({
2198
- dependencies: [configExtension(DOMImportExtension, { rules: CoreImportRules })],
2240
+ const CoreImportExtension = /* @__PURE__ */ defineExtension({
2241
+ dependencies: [/* @__PURE__ */ configExtension(DOMImportExtension, { rules: CoreImportRules })],
2199
2242
  name: "@lexical/html/CoreImport"
2200
2243
  });
2201
2244
  /**
2202
- * Import rules for {@link HorizontalRuleNode}.
2245
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
2246
+ *
2247
+ * This source code is licensed under the MIT license found in the
2248
+ * LICENSE file in the root directory of this source tree.
2203
2249
  *
2204
- * @experimental
2205
2250
  */
2206
- const HorizontalRuleImportRules = [defineImportRule({
2207
- $import: () => [$createHorizontalRuleNode()],
2208
- match: selBase.tag("hr"),
2209
- name: "@lexical/html/hr"
2210
- })];
2211
2251
  /**
2212
- * Bundles {@link HorizontalRuleImportRules} (plus
2213
- * {@link CoreImportExtension}) into a single dependency. The legacy
2214
- * {@link HorizontalRuleExtension.importDOM} continues to work in parallel;
2215
- * depend on this extension to opt into the new pipeline.
2252
+ * Import rules for {@link HorizontalRuleNode}. The `<hr>` rule is part of
2253
+ * {@link CoreImportRules} (gated on `HorizontalRuleNode` registration), so
2254
+ * this array exists only for backwards compatibility and introspection.
2216
2255
  *
2217
- * Lives in `@lexical/html` (not `@lexical/extension`) because
2218
- * {@link DOMImportExtension} itself is in `@lexical/html`, and
2219
- * `@lexical/extension` is upstream of `@lexical/html` in the dependency
2220
- * graph — same arrangement as {@link CoreImportExtension}.
2256
+ * @experimental
2257
+ */
2258
+ const HorizontalRuleImportRules = [HorizontalRuleRule];
2259
+ /**
2260
+ * Bundles the runtime {@link HorizontalRuleExtension} together with
2261
+ * {@link CoreImportExtension}, whose {@link CoreImportRules} include the
2262
+ * registration-gated `<hr>` rule.
2221
2263
  *
2222
2264
  * @experimental
2265
+ * @deprecated The `<hr>` import rule now ships with
2266
+ * {@link CoreImportRules} and activates whenever `HorizontalRuleNode` is
2267
+ * registered — depend on `HorizontalRuleExtension` (plus any extension
2268
+ * that brings in `CoreImportExtension`) directly instead.
2223
2269
  */
2224
- const HorizontalRuleImportExtension = defineExtension({
2225
- dependencies: [
2226
- CoreImportExtension,
2227
- HorizontalRuleExtension,
2228
- configExtension(DOMImportExtension, { rules: HorizontalRuleImportRules })
2229
- ],
2270
+ const HorizontalRuleImportExtension = /* @__PURE__ */ defineExtension({
2271
+ dependencies: [HorizontalRuleExtension, CoreImportExtension],
2230
2272
  name: "@lexical/html/HorizontalRuleImport"
2231
2273
  });
2232
2274
  /**
@@ -2254,7 +2296,7 @@ const sel = {
2254
2296
  tag: selBase.tag,
2255
2297
  text: selBase.text
2256
2298
  };
2257
- const IGNORE_TAGS = new Set(["STYLE", "SCRIPT"]);
2299
+ const IGNORE_TAGS = /* @__PURE__ */ new Set(["STYLE", "SCRIPT"]);
2258
2300
  /**
2259
2301
  * How you parse your html string to get a document is left up to you. In the browser you can use the native
2260
2302
  * DOMParser API to generate a document (see clipboard.ts), but to use in a headless environment you can use JSDom
@@ -2281,8 +2323,9 @@ function $generateDOMFromNodes(container, selection = null, editor = $getEditor(
2281
2323
  return $withRenderContext([contextValue(RenderContextExport, true)], editor)(() => {
2282
2324
  const root = $getRoot();
2283
2325
  const domConfig = $getSessionDOMRenderConfig(editor);
2326
+ const slotFrame = $isRangeSelection(selection) ? $getSlotFrame(selection.anchor.getNode()) : null;
2284
2327
  const parentElementAppend = container.append.bind(container);
2285
- for (const topLevelNode of root.getChildren()) $appendNodesToHTML(editor, topLevelNode, parentElementAppend, selection, domConfig);
2328
+ for (const topLevelNode of ($isElementNode(slotFrame) ? slotFrame : root).getChildren()) $appendNodesToHTML(editor, topLevelNode, parentElementAppend, selection, domConfig);
2286
2329
  return container;
2287
2330
  });
2288
2331
  }
@@ -2312,6 +2355,7 @@ function $generateDOMFromRoot(container, root = $getRoot()) {
2312
2355
  */
2313
2356
  function $generateHtmlFromNodes(editor, selection = null) {
2314
2357
  if (typeof document === "undefined" || typeof window === "undefined" && typeof global.window === "undefined") 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.`);
2358
+ $assumeActiveEditor(editor);
2315
2359
  return $generateDOMFromNodes(document.createElement("div"), selection, editor).innerHTML;
2316
2360
  }
2317
2361
  function $appendNodesToHTML(editor, currentNode, parentElementAppend, selection = null, domConfig = $getEditorDOMRenderConfig(editor)) {
@@ -2323,9 +2367,10 @@ function $appendNodesToHTML(editor, currentNode, parentElementAppend, selection
2323
2367
  if (!element) return false;
2324
2368
  const fragment = document.createDocumentFragment();
2325
2369
  const children = $getChildNodes ? $getChildNodes() : $isElementNode(target) ? target.getChildren() : [];
2370
+ const childSelection = shouldInclude && $isNodeSelection(selection) && $isElementNode(currentNode) ? null : selection;
2326
2371
  const fragmentAppend = fragment.append.bind(fragment);
2327
2372
  for (const childNode of children) {
2328
- const shouldIncludeChild = $appendNodesToHTML(editor, childNode, fragmentAppend, selection, domConfig);
2373
+ const shouldIncludeChild = $appendNodesToHTML(editor, childNode, fragmentAppend, childSelection, domConfig);
2329
2374
  if (!shouldInclude && shouldIncludeChild && domConfig.$extractWithChild(currentNode, childNode, selection, "html", editor)) shouldInclude = true;
2330
2375
  }
2331
2376
  if (shouldInclude && !shouldExclude) {
@@ -2340,6 +2385,19 @@ function $appendNodesToHTML(editor, currentNode, parentElementAppend, selection
2340
2385
  } else parentElementAppend(fragment);
2341
2386
  return shouldInclude;
2342
2387
  }
2388
+ /**
2389
+ * Serialize a single node (and its subtree) into `parentElement`, the same way
2390
+ * the top-level HTML exporter serializes the nodes it walks. Slots are not part
2391
+ * of any node's child list and — like {@link LexicalNode.exportJSON} vs
2392
+ * `exportDOM` for NodeState — are intentionally NOT auto-serialized to HTML;
2393
+ * a host node opts in by calling this from its own `exportDOM`, e.g. to render
2394
+ * each slot value into a `data-lexical-slot` wrapper.
2395
+ *
2396
+ * @experimental
2397
+ */
2398
+ function $appendNodeToHTML(editor, node, parentElement, selection = null) {
2399
+ return $appendNodesToHTML(editor, node, parentElement.append.bind(parentElement), selection, $getSessionDOMRenderConfig(editor));
2400
+ }
2343
2401
  function getConversionFunction(domNode, editor) {
2344
2402
  const { nodeName } = domNode;
2345
2403
  const cachedConversions = editor._htmlConversions.get(nodeName.toLowerCase());
@@ -2421,4 +2479,4 @@ function isDomNodeBetweenTwoInlineNodes(node) {
2421
2479
  return isInlineDomNode(node.nextSibling) && isInlineDomNode(node.previousSibling);
2422
2480
  }
2423
2481
  //#endregion
2424
- 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 };
2482
+ export { $appendNodeToHTML, $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 };