@pod-os/elements 0.40.0 → 0.41.0-rc.27b005a.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.
Files changed (31) hide show
  1. package/dist/cjs/{index-Bc4gZgPG.js → index-BK2Q5l1p.js} +262 -83
  2. package/dist/cjs/{jsonld-V2RB47OZ-JAbnY92y.js → jsonld-V2RB47OZ-CFDz64pR.js} +1 -1
  3. package/dist/cjs/pos-add-literal-value_3.cjs.entry.js +1 -1
  4. package/dist/cjs/pos-add-new-thing_32.cjs.entry.js +1 -1
  5. package/dist/cjs/pos-add-relation.cjs.entry.js +1 -1
  6. package/dist/cjs/pos-container-contents.cjs.entry.js +1 -1
  7. package/dist/cjs/pos-markdown-document.cjs.entry.js +410 -120
  8. package/dist/cjs/pos-subjects.cjs.entry.js +1 -1
  9. package/dist/components/index2.js +1 -1
  10. package/dist/components/pos-markdown-document2.js +1 -1
  11. package/dist/elements/elements.esm.js +1 -1
  12. package/dist/elements/{p-f6da714c.entry.js → p-00f8d4ed.entry.js} +1 -1
  13. package/dist/elements/p-05d22c0b.entry.js +1 -0
  14. package/dist/elements/{p-2ee1efdb.entry.js → p-33dde993.entry.js} +1 -1
  15. package/dist/elements/{p-DuW6UWKz.js → p-C4h87eQU.js} +1 -1
  16. package/dist/elements/p-QvyFA_FG.js +67 -0
  17. package/dist/elements/{p-ed1d9d77.entry.js → p-bf331b7e.entry.js} +1 -1
  18. package/dist/elements/{p-57d32176.entry.js → p-f836f544.entry.js} +1 -1
  19. package/dist/elements/{p-a8628eb4.entry.js → p-fad783a9.entry.js} +1 -1
  20. package/dist/esm/{index-LnGgDqFG.js → index-UpPIXo80.js} +262 -83
  21. package/dist/esm/{jsonld-V2RB47OZ-DFmZ008Y.js → jsonld-V2RB47OZ-D-RJLZDt.js} +1 -1
  22. package/dist/esm/pos-add-literal-value_3.entry.js +1 -1
  23. package/dist/esm/pos-add-new-thing_32.entry.js +1 -1
  24. package/dist/esm/pos-add-relation.entry.js +1 -1
  25. package/dist/esm/pos-container-contents.entry.js +1 -1
  26. package/dist/esm/pos-markdown-document.entry.js +410 -120
  27. package/dist/esm/pos-subjects.entry.js +1 -1
  28. package/dist/jest-setup.js +20 -0
  29. package/package.json +10 -10
  30. package/dist/elements/p-BXBNVUZ5.js +0 -67
  31. package/dist/elements/p-d6e9d178.entry.js +0 -1
@@ -13878,7 +13878,6 @@ function isMarkInSet(marks, type, attributes = {}) {
13878
13878
  return !!findMarkInSet(marks, type, attributes);
13879
13879
  }
13880
13880
  function getMarkRange($pos, type, attributes) {
13881
- var _a;
13882
13881
  if (!$pos || !type) {
13883
13882
  return;
13884
13883
  }
@@ -13889,7 +13888,12 @@ function getMarkRange($pos, type, attributes) {
13889
13888
  if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) {
13890
13889
  return;
13891
13890
  }
13892
- attributes = attributes || ((_a = start.node.marks[0]) == null ? void 0 : _a.attrs);
13891
+ if (!attributes) {
13892
+ const firstMark = start.node.marks.find((mark2) => mark2.type === type);
13893
+ if (firstMark) {
13894
+ attributes = firstMark.attrs;
13895
+ }
13896
+ }
13893
13897
  const mark = findMarkInSet([...start.node.marks], type, attributes);
13894
13898
  if (!mark) {
13895
13899
  return;
@@ -13924,7 +13928,7 @@ function getMarkType(nameOrType, schema) {
13924
13928
  }
13925
13929
 
13926
13930
  // src/commands/extendMarkRange.ts
13927
- var extendMarkRange = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
13931
+ var extendMarkRange = (typeOrName, attributes) => ({ tr, state, dispatch }) => {
13928
13932
  const type = getMarkType(typeOrName, state.schema);
13929
13933
  const { doc, selection } = tr;
13930
13934
  const { $from, from, to } = selection;
@@ -14259,7 +14263,7 @@ var insertContentAt = (position, value, options) => ({ tr, dispatch, editor }) =
14259
14263
  const fromSelectionAtStart = $from.parentOffset === 0;
14260
14264
  const isTextSelection2 = $fromNode.isText || $fromNode.isTextblock;
14261
14265
  const hasContent = $fromNode.content.size > 0;
14262
- if (fromSelectionAtStart && isTextSelection2 && hasContent) {
14266
+ if (fromSelectionAtStart && isTextSelection2 && hasContent && isOnlyBlockContent) {
14263
14267
  from = Math.max(0, from - 1);
14264
14268
  }
14265
14269
  tr.replaceWith(from, to, newContent);
@@ -14817,6 +14821,67 @@ function getAttributesFromExtensions(extensions) {
14817
14821
  }
14818
14822
 
14819
14823
  // src/utilities/mergeAttributes.ts
14824
+ function splitStyleDeclarations(styles) {
14825
+ const result = [];
14826
+ let current = "";
14827
+ let inSingleQuote = false;
14828
+ let inDoubleQuote = false;
14829
+ let parenDepth = 0;
14830
+ const length = styles.length;
14831
+ for (let i = 0; i < length; i += 1) {
14832
+ const char = styles[i];
14833
+ if (char === "'" && !inDoubleQuote) {
14834
+ inSingleQuote = !inSingleQuote;
14835
+ current += char;
14836
+ continue;
14837
+ }
14838
+ if (char === '"' && !inSingleQuote) {
14839
+ inDoubleQuote = !inDoubleQuote;
14840
+ current += char;
14841
+ continue;
14842
+ }
14843
+ if (!inSingleQuote && !inDoubleQuote) {
14844
+ if (char === "(") {
14845
+ parenDepth += 1;
14846
+ current += char;
14847
+ continue;
14848
+ }
14849
+ if (char === ")" && parenDepth > 0) {
14850
+ parenDepth -= 1;
14851
+ current += char;
14852
+ continue;
14853
+ }
14854
+ if (char === ";" && parenDepth === 0) {
14855
+ result.push(current);
14856
+ current = "";
14857
+ continue;
14858
+ }
14859
+ }
14860
+ current += char;
14861
+ }
14862
+ if (current) {
14863
+ result.push(current);
14864
+ }
14865
+ return result;
14866
+ }
14867
+ function parseStyleEntries(styles) {
14868
+ const pairs = [];
14869
+ const declarations = splitStyleDeclarations(styles || "");
14870
+ const numDeclarations = declarations.length;
14871
+ for (let i = 0; i < numDeclarations; i += 1) {
14872
+ const declaration = declarations[i];
14873
+ const firstColonIndex = declaration.indexOf(":");
14874
+ if (firstColonIndex === -1) {
14875
+ continue;
14876
+ }
14877
+ const property = declaration.slice(0, firstColonIndex).trim();
14878
+ const value = declaration.slice(firstColonIndex + 1).trim();
14879
+ if (property && value) {
14880
+ pairs.push([property, value]);
14881
+ }
14882
+ }
14883
+ return pairs;
14884
+ }
14820
14885
  function mergeAttributes(...objects) {
14821
14886
  return objects.filter((item) => !!item).reduce((items, item) => {
14822
14887
  const mergedAttributes = { ...items };
@@ -14832,17 +14897,7 @@ function mergeAttributes(...objects) {
14832
14897
  const insertClasses = valueClasses.filter((valueClass) => !existingClasses.includes(valueClass));
14833
14898
  mergedAttributes[key] = [...existingClasses, ...insertClasses].join(" ");
14834
14899
  } else if (key === "style") {
14835
- const newStyles = value ? value.split(";").map((style2) => style2.trim()).filter(Boolean) : [];
14836
- const existingStyles = mergedAttributes[key] ? mergedAttributes[key].split(";").map((style2) => style2.trim()).filter(Boolean) : [];
14837
- const styleMap = /* @__PURE__ */ new Map();
14838
- existingStyles.forEach((style2) => {
14839
- const [property, val] = style2.split(":").map((part) => part.trim());
14840
- styleMap.set(property, val);
14841
- });
14842
- newStyles.forEach((style2) => {
14843
- const [property, val] = style2.split(":").map((part) => part.trim());
14844
- styleMap.set(property, val);
14845
- });
14900
+ const styleMap = new Map([...parseStyleEntries(mergedAttributes[key]), ...parseStyleEntries(value)]);
14846
14901
  mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join("; ");
14847
14902
  } else {
14848
14903
  mergedAttributes[key] = value;
@@ -15440,7 +15495,7 @@ function isNodeEmpty(node, {
15440
15495
  return true;
15441
15496
  }
15442
15497
  if (node.isText) {
15443
- return /^\s*$/m.test((_a = node.text) != null ? _a : "");
15498
+ return !/\S/.test((_a = node.text) != null ? _a : "");
15444
15499
  }
15445
15500
  }
15446
15501
  if (node.isText) {
@@ -15836,6 +15891,16 @@ var joinListForwards = (tr, listType) => {
15836
15891
  tr.join(after);
15837
15892
  return true;
15838
15893
  };
15894
+ function createInnerSelectionForWholeDocList(tr) {
15895
+ const doc = tr.doc;
15896
+ const list = doc.firstChild;
15897
+ if (!list) {
15898
+ return null;
15899
+ }
15900
+ const $start = doc.resolve(1);
15901
+ const $end = doc.resolve(list.nodeSize - 1);
15902
+ return TextSelection.between($start, $end);
15903
+ }
15839
15904
  var toggleList = (listTypeOrName, itemTypeOrName, keepMarks, attributes = {}) => ({ editor, tr, state, dispatch, chain, commands, can }) => {
15840
15905
  const { extensions, splittableMarks } = editor.extensionManager;
15841
15906
  const listType = getNodeType(listTypeOrName, state.schema);
@@ -15848,13 +15913,35 @@ var toggleList = (listTypeOrName, itemTypeOrName, keepMarks, attributes = {}) =>
15848
15913
  return false;
15849
15914
  }
15850
15915
  const parentList = findParentNode((node) => isList(node.type.name, extensions))(selection);
15851
- if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) {
15852
- if (parentList.node.type === listType) {
15916
+ const isAllSelection = selection.from === 0 && selection.to === state.doc.content.size;
15917
+ const topLevelNodes = state.doc.content.content;
15918
+ const soleTopLevelNode = topLevelNodes.length === 1 ? topLevelNodes[0] : null;
15919
+ const allSelectionList = isAllSelection && soleTopLevelNode && isList(soleTopLevelNode.type.name, extensions) ? {
15920
+ node: soleTopLevelNode,
15921
+ pos: 0} : null;
15922
+ const currentList = parentList != null ? parentList : allSelectionList;
15923
+ const isInsideExistingList = !!parentList && range.depth >= 1 && range.depth - parentList.depth <= 1;
15924
+ const hasWholeDocSelectedList = !!allSelectionList;
15925
+ if ((isInsideExistingList || hasWholeDocSelectedList) && currentList) {
15926
+ if (currentList.node.type === listType) {
15927
+ if (isAllSelection && hasWholeDocSelectedList) {
15928
+ return chain().command(({ tr: trx, dispatch: disp }) => {
15929
+ const nextSelection = createInnerSelectionForWholeDocList(trx);
15930
+ if (!nextSelection) {
15931
+ return false;
15932
+ }
15933
+ trx.setSelection(nextSelection);
15934
+ if (disp) {
15935
+ disp(trx);
15936
+ }
15937
+ return true;
15938
+ }).liftListItem(itemType).run();
15939
+ }
15853
15940
  return commands.liftListItem(itemType);
15854
15941
  }
15855
- if (isList(parentList.node.type.name, extensions) && listType.validContent(parentList.node.content) && dispatch) {
15942
+ if (isList(currentList.node.type.name, extensions) && listType.validContent(currentList.node.content)) {
15856
15943
  return chain().command(() => {
15857
- tr.setNodeMarkup(parentList.pos, listType);
15944
+ tr.setNodeMarkup(currentList.pos, listType);
15858
15945
  return true;
15859
15946
  }).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run();
15860
15947
  }
@@ -17139,7 +17226,7 @@ var Delete = Extension.create({
17139
17226
  const newEnd = mapping.slice(index).map(step.to);
17140
17227
  const oldStart = mapping.invert().map(newStart, -1);
17141
17228
  const oldEnd = mapping.invert().map(newEnd);
17142
- const foundBeforeMark = (_a3 = nextTransaction.doc.nodeAt(newStart - 1)) == null ? void 0 : _a3.marks.some((mark) => mark.eq(step.mark));
17229
+ const foundBeforeMark = newStart > 0 ? (_a3 = nextTransaction.doc.nodeAt(newStart - 1)) == null ? void 0 : _a3.marks.some((mark) => mark.eq(step.mark)) : false;
17143
17230
  const foundAfterMark = (_b3 = nextTransaction.doc.nodeAt(newEnd)) == null ? void 0 : _b3.marks.some((mark) => mark.eq(step.mark));
17144
17231
  this.editor.emit("delete", {
17145
17232
  type: "mark",
@@ -18637,7 +18724,7 @@ var ResizableNodeView = class {
18637
18724
  const element = document.createElement("div");
18638
18725
  element.dataset.resizeContainer = "";
18639
18726
  element.dataset.node = this.node.type.name;
18640
- element.style.display = "flex";
18727
+ element.style.display = this.node.type.isInline ? "inline-flex" : "flex";
18641
18728
  if (this.classNames.container) {
18642
18729
  element.className = this.classNames.container;
18643
18730
  }
@@ -18977,6 +19064,14 @@ function canInsertNode(state, nodeType) {
18977
19064
  return false;
18978
19065
  }
18979
19066
 
19067
+ // src/utilities/htmlEntities.ts
19068
+ function decodeHtmlEntities(text) {
19069
+ return text.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
19070
+ }
19071
+ function encodeHtmlEntities(text) {
19072
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
19073
+ }
19074
+
18980
19075
  // src/utilities/markdown/index.ts
18981
19076
  var markdown_exports = {};
18982
19077
  __export$1(markdown_exports, {
@@ -19453,17 +19548,21 @@ function renderNestedMarkdownContent(node, h2, prefixOrGenerator, ctx) {
19453
19548
  const prefix = typeof prefixOrGenerator === "function" ? prefixOrGenerator(ctx) : prefixOrGenerator;
19454
19549
  const [content, ...children] = node.content;
19455
19550
  const mainContent = h2.renderChildren([content]);
19456
- const output = [`${prefix}${mainContent}`];
19551
+ let output = `${prefix}${mainContent}`;
19457
19552
  if (children && children.length > 0) {
19458
- children.forEach((child) => {
19459
- const childContent = h2.renderChildren([child]);
19460
- if (childContent) {
19461
- const indentedChild = childContent.split("\n").map((line) => line ? h2.indent(line) : "").join("\n");
19462
- output.push(indentedChild);
19553
+ children.forEach((child, index) => {
19554
+ var _a, _b;
19555
+ const childContent = (_b = (_a = h2.renderChild) == null ? void 0 : _a.call(h2, child, index + 1)) != null ? _b : h2.renderChildren([child]);
19556
+ if (childContent !== void 0 && childContent !== null) {
19557
+ const indentedChild = childContent.split("\n").map((line) => line ? h2.indent(line) : h2.indent("")).join("\n");
19558
+ output += child.type === "paragraph" ? `
19559
+
19560
+ ${indentedChild}` : `
19561
+ ${indentedChild}`;
19463
19562
  }
19464
19563
  });
19465
19564
  }
19466
- return output.join("\n");
19565
+ return output;
19467
19566
  }
19468
19567
 
19469
19568
  // src/MarkView.ts
@@ -19559,7 +19658,10 @@ function markPasteRule(config) {
19559
19658
  }
19560
19659
  markEnd = range.from + startSpaces + captureGroup.length;
19561
19660
  tr.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {}));
19562
- tr.removeStoredMark(config.type);
19661
+ const isMatchAtEndOfText = match.index !== void 0 && match.input !== void 0 && match.index + match[0].length >= match.input.length;
19662
+ if (!isMatchAtEndOfText) {
19663
+ tr.removeStoredMark(config.type);
19664
+ }
19563
19665
  }
19564
19666
  }
19565
19667
  });
@@ -19671,13 +19773,13 @@ function findMarksToCloseAtEnd(activeMarks, currentMarks, nextNode, markSetsEqua
19671
19773
  if (isLastNode || nextNodeHasNoMarks || nextNodeHasDifferentMarks) {
19672
19774
  if (nextNode && nextNode.type === "text" && nextNode.marks) {
19673
19775
  const nextMarks = new Map(nextNode.marks.map((mark) => [mark.type, mark]));
19674
- Array.from(activeMarks.keys()).forEach((markType) => {
19776
+ Array.from(activeMarks.keys()).reverse().forEach((markType) => {
19675
19777
  if (!nextMarks.has(markType)) {
19676
19778
  marksToCloseAtEnd.push(markType);
19677
19779
  }
19678
19780
  });
19679
19781
  } else if (isLastNode || nextNodeHasNoMarks) {
19680
- marksToCloseAtEnd.push(...Array.from(activeMarks.keys()));
19782
+ marksToCloseAtEnd.push(...Array.from(activeMarks.keys()).reverse());
19681
19783
  }
19682
19784
  }
19683
19785
  return marksToCloseAtEnd;
@@ -19730,12 +19832,14 @@ var MarkdownManager = class {
19730
19832
  * @param options.extensions An array of Tiptap extensions to register for markdown parsing and rendering.
19731
19833
  */
19732
19834
  constructor(options) {
19835
+ this.activeParseLexer = null;
19733
19836
  this.baseExtensions = [];
19734
19837
  this.extensions = [];
19838
+ /** Set of extension names whose `code` spec property is truthy (nodes and marks). */
19839
+ this.codeTypes = /* @__PURE__ */ new Set();
19735
19840
  this.lastParseResult = null;
19736
19841
  var _a, _b, _c, _d, _e;
19737
19842
  this.markedInstance = (_a = options == null ? void 0 : options.marked) != null ? _a : g;
19738
- this.lexer = new this.markedInstance.Lexer();
19739
19843
  this.indentStyle = (_c = (_b = options == null ? void 0 : options.indentation) == null ? void 0 : _b.style) != null ? _c : "space";
19740
19844
  this.indentSize = (_e = (_d = options == null ? void 0 : options.indentation) == null ? void 0 : _d.size) != null ? _e : 2;
19741
19845
  this.baseExtensions = (options == null ? void 0 : options.extensions) || [];
@@ -19747,9 +19851,8 @@ var MarkdownManager = class {
19747
19851
  if (options == null ? void 0 : options.extensions) {
19748
19852
  this.baseExtensions = options.extensions;
19749
19853
  const flattened = flattenExtensions(options.extensions);
19750
- flattened.forEach((ext) => this.registerExtension(ext, false));
19854
+ flattened.forEach((ext) => this.registerExtension(ext));
19751
19855
  }
19752
- this.lexer = new this.markedInstance.Lexer();
19753
19856
  }
19754
19857
  /** Returns the underlying marked instance. */
19755
19858
  get instance() {
@@ -19772,22 +19875,28 @@ var MarkdownManager = class {
19772
19875
  * `markdownName`, `parseMarkdown`, `renderMarkdown` and `priority` from the
19773
19876
  * extension config (using the same resolution used across the codebase).
19774
19877
  */
19775
- registerExtension(extension, recreateLexer = true) {
19878
+ registerExtension(extension) {
19776
19879
  var _a, _b;
19777
19880
  this.extensions.push(extension);
19881
+ const isCode = callOrReturn(getExtensionField(extension, "code"));
19778
19882
  const name = extension.name;
19883
+ if (isCode) {
19884
+ this.codeTypes.add(name);
19885
+ }
19779
19886
  const tokenName = getExtensionField(extension, "markdownTokenName") || name;
19780
19887
  const parseMarkdown = getExtensionField(extension, "parseMarkdown");
19781
19888
  const renderMarkdown = getExtensionField(extension, "renderMarkdown");
19782
19889
  const tokenizer = getExtensionField(extension, "markdownTokenizer");
19783
19890
  const markdownCfg = (_a = getExtensionField(extension, "markdownOptions")) != null ? _a : null;
19784
19891
  const isIndenting = (_b = markdownCfg == null ? void 0 : markdownCfg.indentsContent) != null ? _b : false;
19892
+ const htmlReopen = markdownCfg == null ? void 0 : markdownCfg.htmlReopen;
19785
19893
  const spec = {
19786
19894
  tokenName,
19787
19895
  nodeName: name,
19788
19896
  parseMarkdown,
19789
19897
  renderMarkdown,
19790
19898
  isIndenting,
19899
+ htmlReopen,
19791
19900
  tokenizer
19792
19901
  };
19793
19902
  if (tokenName && parseMarkdown) {
@@ -19802,11 +19911,21 @@ var MarkdownManager = class {
19802
19911
  }
19803
19912
  if (tokenizer && this.hasMarked()) {
19804
19913
  this.registerTokenizer(tokenizer);
19805
- if (recreateLexer) {
19806
- this.lexer = new this.markedInstance.Lexer();
19807
- }
19808
19914
  }
19809
19915
  }
19916
+ createLexer() {
19917
+ return new this.markedInstance.Lexer();
19918
+ }
19919
+ createTokenizerHelpers(lexer) {
19920
+ return {
19921
+ inlineTokens: (src) => lexer.inlineTokens(src),
19922
+ blockTokens: (src) => lexer.blockTokens(src)
19923
+ };
19924
+ }
19925
+ tokenizeInline(src) {
19926
+ var _a;
19927
+ return ((_a = this.activeParseLexer) != null ? _a : this.createLexer()).inlineTokens(src);
19928
+ }
19810
19929
  /**
19811
19930
  * Register a custom tokenizer with marked.js for parsing non-standard markdown syntax.
19812
19931
  */
@@ -19815,20 +19934,12 @@ var MarkdownManager = class {
19815
19934
  return;
19816
19935
  }
19817
19936
  const { name, start, level = "inline", tokenize } = tokenizer;
19818
- const tokenizeInline = (src) => {
19819
- return this.lexer.inlineTokens(src);
19820
- };
19821
- const tokenizeBlock = (src) => {
19822
- return this.lexer.blockTokens(src);
19823
- };
19824
- const helper = {
19825
- inlineTokens: tokenizeInline,
19826
- blockTokens: tokenizeBlock
19827
- };
19937
+ const createTokenizerHelpers = this.createTokenizerHelpers.bind(this);
19938
+ const createLexer = this.createLexer.bind(this);
19828
19939
  let startCb;
19829
19940
  if (!start) {
19830
19941
  startCb = (src) => {
19831
- const result = tokenize(src, [], helper);
19942
+ const result = tokenize(src, [], this.createTokenizerHelpers(this.createLexer()));
19832
19943
  if (result && result.raw) {
19833
19944
  const index = src.indexOf(result.raw);
19834
19945
  return index;
@@ -19842,7 +19953,8 @@ var MarkdownManager = class {
19842
19953
  name,
19843
19954
  level,
19844
19955
  start: startCb,
19845
- tokenizer: (src, tokens) => {
19956
+ tokenizer(src, tokens) {
19957
+ const helper = this.lexer ? createTokenizerHelpers(this.lexer) : createTokenizerHelpers(createLexer());
19846
19958
  const result = tokenize(src, tokens, helper);
19847
19959
  if (result && result.type) {
19848
19960
  return {
@@ -19915,23 +20027,65 @@ var MarkdownManager = class {
19915
20027
  if (!this.hasMarked()) {
19916
20028
  throw new Error("No marked instance available for parsing");
19917
20029
  }
19918
- const tokens = this.markedInstance.lexer(markdown);
19919
- const content = this.parseTokens(tokens);
19920
- return {
19921
- type: "doc",
19922
- content
19923
- };
20030
+ const previousParseLexer = this.activeParseLexer;
20031
+ const parseLexer = this.createLexer();
20032
+ this.activeParseLexer = parseLexer;
20033
+ try {
20034
+ const tokens = parseLexer.lex(markdown);
20035
+ const content = this.parseTokens(tokens, true);
20036
+ return {
20037
+ type: "doc",
20038
+ content
20039
+ };
20040
+ } finally {
20041
+ this.activeParseLexer = previousParseLexer;
20042
+ }
19924
20043
  }
19925
20044
  /**
19926
20045
  * Convert an array of marked tokens into Tiptap JSON nodes using registered extension handlers.
19927
20046
  */
19928
- parseTokens(tokens) {
19929
- return tokens.map((token) => this.parseToken(token)).filter((parsed) => parsed !== null).flatMap((parsed) => Array.isArray(parsed) ? parsed : [parsed]);
20047
+ parseTokens(tokens, parseImplicitEmptyParagraphs = false) {
20048
+ const nonSpaceTokenIndexes = tokens.reduce((indexes, token, index) => {
20049
+ if (token.type !== "space") {
20050
+ indexes.push(index);
20051
+ }
20052
+ return indexes;
20053
+ }, []);
20054
+ let previousNonSpaceTokenIndex = -1;
20055
+ let nextNonSpaceTokenPointer = 0;
20056
+ return tokens.flatMap((token, index) => {
20057
+ var _a;
20058
+ while (nextNonSpaceTokenPointer < nonSpaceTokenIndexes.length && nonSpaceTokenIndexes[nextNonSpaceTokenPointer] < index) {
20059
+ previousNonSpaceTokenIndex = nonSpaceTokenIndexes[nextNonSpaceTokenPointer];
20060
+ nextNonSpaceTokenPointer += 1;
20061
+ }
20062
+ if (parseImplicitEmptyParagraphs && token.type === "space") {
20063
+ const nextNonSpaceTokenIndex = (_a = nonSpaceTokenIndexes[nextNonSpaceTokenPointer]) != null ? _a : -1;
20064
+ return this.createImplicitEmptyParagraphsFromSpace(token, previousNonSpaceTokenIndex, nextNonSpaceTokenIndex);
20065
+ }
20066
+ const parsed = this.parseToken(token, parseImplicitEmptyParagraphs);
20067
+ if (parsed === null) {
20068
+ return [];
20069
+ }
20070
+ return Array.isArray(parsed) ? parsed : [parsed];
20071
+ });
20072
+ }
20073
+ createImplicitEmptyParagraphsFromSpace(token, previousNonSpaceTokenIndex, nextNonSpaceTokenIndex) {
20074
+ const separatorCount = this.countParagraphSeparators(token.raw || "");
20075
+ if (separatorCount === 0) {
20076
+ return [];
20077
+ }
20078
+ const isBoundarySpace = previousNonSpaceTokenIndex === -1 || nextNonSpaceTokenIndex === -1;
20079
+ const emptyParagraphCount = Math.max(separatorCount - (isBoundarySpace ? 0 : 1), 0);
20080
+ return Array.from({ length: emptyParagraphCount }, () => ({ type: "paragraph", content: [] }));
20081
+ }
20082
+ countParagraphSeparators(raw) {
20083
+ return (raw.replace(/\r\n/g, "\n").match(/\n\n/g) || []).length;
19930
20084
  }
19931
20085
  /**
19932
20086
  * Parse a single token into Tiptap JSON using the appropriate registered handler.
19933
20087
  */
19934
- parseToken(token) {
20088
+ parseToken(token, parseImplicitEmptyParagraphs = false) {
19935
20089
  if (!token.type) {
19936
20090
  return null;
19937
20091
  }
@@ -19957,7 +20111,7 @@ var MarkdownManager = class {
19957
20111
  this.lastParseResult = null;
19958
20112
  return toReturn;
19959
20113
  }
19960
- return this.parseFallbackToken(token);
20114
+ return this.parseFallbackToken(token, parseImplicitEmptyParagraphs);
19961
20115
  }
19962
20116
  /**
19963
20117
  * Parse a list token, handling mixed bullet and task list items by splitting them into separate lists.
@@ -20016,7 +20170,7 @@ var MarkdownManager = class {
20016
20170
  indentLevel,
20017
20171
  checked: checked != null ? checked : false,
20018
20172
  text: mainContent,
20019
- tokens: this.lexer.inlineTokens(mainContent),
20173
+ tokens: this.tokenizeInline(mainContent),
20020
20174
  nestedTokens
20021
20175
  };
20022
20176
  }
@@ -20085,6 +20239,7 @@ var MarkdownManager = class {
20085
20239
  return {
20086
20240
  parseInline: (tokens) => this.parseInlineTokens(tokens),
20087
20241
  parseChildren: (tokens) => this.parseTokens(tokens),
20242
+ parseBlockChildren: (tokens) => this.parseTokens(tokens, true),
20088
20243
  createTextNode: (text, marks) => {
20089
20244
  const node = {
20090
20245
  type: "text",
@@ -20129,7 +20284,7 @@ var MarkdownManager = class {
20129
20284
  if (token.type === "text") {
20130
20285
  result.push({
20131
20286
  type: "text",
20132
- text: token.text || ""
20287
+ text: decodeHtmlEntities(token.text || "")
20133
20288
  });
20134
20289
  } else if (token.type === "html") {
20135
20290
  const raw = ((_b = (_a = token.raw) != null ? _a : token.text) != null ? _b : "").toString();
@@ -20243,7 +20398,7 @@ var MarkdownManager = class {
20243
20398
  /**
20244
20399
  * Fallback parsing for common tokens when no specific handler is registered.
20245
20400
  */
20246
- parseFallbackToken(token) {
20401
+ parseFallbackToken(token, parseImplicitEmptyParagraphs = false) {
20247
20402
  switch (token.type) {
20248
20403
  case "paragraph":
20249
20404
  return {
@@ -20259,7 +20414,7 @@ var MarkdownManager = class {
20259
20414
  case "text":
20260
20415
  return {
20261
20416
  type: "text",
20262
- text: token.text || ""
20417
+ text: decodeHtmlEntities(token.text || "")
20263
20418
  };
20264
20419
  case "html":
20265
20420
  return this.parseHTMLToken(token);
@@ -20267,7 +20422,7 @@ var MarkdownManager = class {
20267
20422
  return null;
20268
20423
  default:
20269
20424
  if (token.tokens) {
20270
- return this.parseTokens(token.tokens);
20425
+ return this.parseTokens(token.tokens, parseImplicitEmptyParagraphs);
20271
20426
  }
20272
20427
  return null;
20273
20428
  }
@@ -20314,10 +20469,18 @@ var MarkdownManager = class {
20314
20469
  throw new Error(`Failed to parse HTML in markdown: ${error}`);
20315
20470
  }
20316
20471
  }
20317
- renderNodeToMarkdown(node, parentNode, index = 0, level = 0) {
20472
+ /**
20473
+ * Encode HTML entities in text unless the node is inside a code context
20474
+ * (code mark or code-block parent) where literal characters should be preserved.
20475
+ */
20476
+ encodeTextForMarkdown(text, node, parentNode) {
20477
+ const isInsideCode = (parentNode == null ? void 0 : parentNode.type) != null && this.codeTypes.has(parentNode.type) || (node.marks || []).some((m) => this.codeTypes.has(typeof m === "string" ? m : m.type));
20478
+ return isInsideCode ? text : encodeHtmlEntities(text);
20479
+ }
20480
+ renderNodeToMarkdown(node, parentNode, index = 0, level = 0, meta = {}) {
20318
20481
  var _a;
20319
20482
  if (node.type === "text") {
20320
- return node.text || "";
20483
+ return this.encodeTextForMarkdown(node.text || "", node, parentNode);
20321
20484
  }
20322
20485
  if (!node.type) {
20323
20486
  return "";
@@ -20326,6 +20489,7 @@ var MarkdownManager = class {
20326
20489
  if (!handler) {
20327
20490
  return "";
20328
20491
  }
20492
+ const previousNode = Array.isArray(parentNode == null ? void 0 : parentNode.content) && index > 0 ? parentNode.content[index - 1] : void 0;
20329
20493
  const helpers = {
20330
20494
  renderChildren: (nodes, separator) => {
20331
20495
  const childLevel = handler.isIndenting ? level + 1 : level;
@@ -20334,6 +20498,10 @@ var MarkdownManager = class {
20334
20498
  }
20335
20499
  return this.renderNodes(nodes, node, separator || "", index, childLevel);
20336
20500
  },
20501
+ renderChild: (childNode, childIndex) => {
20502
+ const childLevel = handler.isIndenting ? level + 1 : level;
20503
+ return this.renderNodeToMarkdown(childNode, node, childIndex, childLevel);
20504
+ },
20337
20505
  indent: (content) => {
20338
20506
  return this.indentString + content;
20339
20507
  },
@@ -20343,8 +20511,10 @@ var MarkdownManager = class {
20343
20511
  index,
20344
20512
  level,
20345
20513
  parentType: parentNode == null ? void 0 : parentNode.type,
20514
+ previousNode,
20346
20515
  meta: {
20347
- parentAttrs: parentNode == null ? void 0 : parentNode.attrs
20516
+ parentAttrs: parentNode == null ? void 0 : parentNode.attrs,
20517
+ ...meta
20348
20518
  }
20349
20519
  };
20350
20520
  const rendered = ((_a = handler.renderMarkdown) == null ? void 0 : _a.call(handler, node, helpers, context)) || "";
@@ -20370,34 +20540,44 @@ var MarkdownManager = class {
20370
20540
  renderNodesWithMarkBoundaries(nodes, parentNode, separator = "", level = 0) {
20371
20541
  const result = [];
20372
20542
  const activeMarks = /* @__PURE__ */ new Map();
20543
+ const reopenWithHtmlOnNextOpen = /* @__PURE__ */ new Set();
20544
+ const markOpeningModes = /* @__PURE__ */ new Map();
20373
20545
  nodes.forEach((node, i) => {
20374
20546
  const nextNode = i < nodes.length - 1 ? nodes[i + 1] : null;
20375
20547
  if (!node.type) {
20376
20548
  return;
20377
20549
  }
20378
20550
  if (node.type === "text") {
20379
- let textContent = node.text || "";
20551
+ let textContent = this.encodeTextForMarkdown(node.text || "", node, parentNode);
20380
20552
  const currentMarks = new Map((node.marks || []).map((mark) => [mark.type, mark]));
20381
20553
  const marksToOpen = findMarksToOpen(activeMarks, currentMarks);
20382
20554
  const marksToClose = findMarksToClose(currentMarks, nextNode);
20555
+ const activeMarksClosingHere = marksToClose.filter((markType) => activeMarks.has(markType));
20556
+ const hasCrossedBoundary = activeMarksClosingHere.length > 0 && marksToOpen.length > 0;
20383
20557
  let middleTrailingWhitespace = "";
20384
- if (marksToClose.length > 0) {
20558
+ if (marksToClose.length > 0 && !hasCrossedBoundary) {
20385
20559
  const middleTrailingMatch = textContent.match(/(\s+)$/);
20386
20560
  if (middleTrailingMatch) {
20387
20561
  middleTrailingWhitespace = middleTrailingMatch[1];
20388
20562
  textContent = textContent.slice(0, -middleTrailingWhitespace.length);
20389
20563
  }
20390
20564
  }
20391
- marksToClose.forEach((markType) => {
20392
- const mark = currentMarks.get(markType);
20393
- const closeMarkdown = this.getMarkClosing(markType, mark);
20394
- if (closeMarkdown) {
20395
- textContent += closeMarkdown;
20396
- }
20397
- if (activeMarks.has(markType)) {
20398
- activeMarks.delete(markType);
20399
- }
20400
- });
20565
+ if (!hasCrossedBoundary) {
20566
+ marksToClose.forEach((markType) => {
20567
+ if (!activeMarks.has(markType)) {
20568
+ return;
20569
+ }
20570
+ const mark = currentMarks.get(markType);
20571
+ const closeMarkdown = this.getMarkClosing(markType, mark, markOpeningModes.get(markType));
20572
+ if (closeMarkdown) {
20573
+ textContent += closeMarkdown;
20574
+ }
20575
+ if (activeMarks.has(markType)) {
20576
+ activeMarks.delete(markType);
20577
+ markOpeningModes.delete(markType);
20578
+ }
20579
+ });
20580
+ }
20401
20581
  let leadingWhitespace = "";
20402
20582
  if (marksToOpen.length > 0) {
20403
20583
  const leadingMatch = textContent.match(/^(\s+)/);
@@ -20407,21 +20587,37 @@ var MarkdownManager = class {
20407
20587
  }
20408
20588
  }
20409
20589
  marksToOpen.forEach(({ type, mark }) => {
20410
- const openMarkdown = this.getMarkOpening(type, mark);
20590
+ const openingMode = reopenWithHtmlOnNextOpen.has(type) ? "html" : "markdown";
20591
+ const openMarkdown = this.getMarkOpening(type, mark, openingMode);
20411
20592
  if (openMarkdown) {
20412
20593
  textContent = openMarkdown + textContent;
20413
20594
  }
20414
- if (!marksToClose.includes(type)) {
20415
- activeMarks.set(type, mark);
20416
- }
20595
+ markOpeningModes.set(type, openingMode);
20596
+ reopenWithHtmlOnNextOpen.delete(type);
20417
20597
  });
20598
+ if (!hasCrossedBoundary) {
20599
+ marksToOpen.slice().reverse().forEach(({ type, mark }) => {
20600
+ activeMarks.set(type, mark);
20601
+ });
20602
+ }
20418
20603
  textContent = leadingWhitespace + textContent;
20419
- const marksToCloseAtEnd = findMarksToCloseAtEnd(
20420
- activeMarks,
20421
- currentMarks,
20422
- nextNode,
20423
- this.markSetsEqual.bind(this)
20424
- );
20604
+ let marksToCloseAtEnd;
20605
+ if (hasCrossedBoundary) {
20606
+ const nextMarkTypes = new Set(((nextNode == null ? void 0 : nextNode.marks) || []).map((mark) => mark.type));
20607
+ marksToOpen.forEach(({ type }) => {
20608
+ if (nextMarkTypes.has(type) && this.getHtmlReopenTags(type)) {
20609
+ reopenWithHtmlOnNextOpen.add(type);
20610
+ }
20611
+ });
20612
+ marksToCloseAtEnd = [
20613
+ ...marksToOpen.map((m) => m.type),
20614
+ // inner (opened here) — close first
20615
+ ...activeMarksClosingHere
20616
+ // outer (were active before) — close last
20617
+ ];
20618
+ } else {
20619
+ marksToCloseAtEnd = findMarksToCloseAtEnd(activeMarks, currentMarks, nextNode, this.markSetsEqual.bind(this));
20620
+ }
20425
20621
  let trailingWhitespace = "";
20426
20622
  if (marksToCloseAtEnd.length > 0) {
20427
20623
  const trailingMatch = textContent.match(/(\s+)$/);
@@ -20431,21 +20627,32 @@ var MarkdownManager = class {
20431
20627
  }
20432
20628
  }
20433
20629
  marksToCloseAtEnd.forEach((markType) => {
20434
- const mark = activeMarks.get(markType);
20435
- const closeMarkdown = this.getMarkClosing(markType, mark);
20630
+ var _a;
20631
+ const mark = (_a = activeMarks.get(markType)) != null ? _a : currentMarks.get(markType);
20632
+ const closeMarkdown = this.getMarkClosing(markType, mark, markOpeningModes.get(markType));
20436
20633
  if (closeMarkdown) {
20437
20634
  textContent += closeMarkdown;
20438
20635
  }
20439
20636
  activeMarks.delete(markType);
20637
+ markOpeningModes.delete(markType);
20440
20638
  });
20441
20639
  textContent += trailingWhitespace;
20442
20640
  textContent += middleTrailingWhitespace;
20443
20641
  result.push(textContent);
20444
20642
  } else {
20445
20643
  const marksToReopen = new Map(activeMarks);
20446
- const beforeMarkdown = closeMarksBeforeNode(activeMarks, this.getMarkClosing.bind(this));
20644
+ const openingModesToReopen = new Map(markOpeningModes);
20645
+ const beforeMarkdown = closeMarksBeforeNode(activeMarks, (markType, mark) => {
20646
+ return this.getMarkClosing(markType, mark, markOpeningModes.get(markType));
20647
+ });
20648
+ markOpeningModes.clear();
20447
20649
  const nodeContent = this.renderNodeToMarkdown(node, parentNode, i, level);
20448
- const afterMarkdown = node.type === "hardBreak" ? "" : reopenMarksAfterNode(marksToReopen, activeMarks, this.getMarkOpening.bind(this));
20650
+ const afterMarkdown = node.type === "hardBreak" ? "" : reopenMarksAfterNode(marksToReopen, activeMarks, (markType, mark) => {
20651
+ var _a;
20652
+ const openingMode = (_a = openingModesToReopen.get(markType)) != null ? _a : "markdown";
20653
+ markOpeningModes.set(markType, openingMode);
20654
+ return this.getMarkOpening(markType, mark, openingMode);
20655
+ });
20449
20656
  result.push(beforeMarkdown + nodeContent + afterMarkdown);
20450
20657
  }
20451
20658
  });
@@ -20454,7 +20661,11 @@ var MarkdownManager = class {
20454
20661
  /**
20455
20662
  * Get the opening markdown syntax for a mark type.
20456
20663
  */
20457
- getMarkOpening(markType, mark) {
20664
+ getMarkOpening(markType, mark, openingMode = "markdown") {
20665
+ var _a;
20666
+ if (openingMode === "html") {
20667
+ return ((_a = this.getHtmlReopenTags(markType)) == null ? void 0 : _a.open) || "";
20668
+ }
20458
20669
  const handlers = this.getHandlersForNodeType(markType);
20459
20670
  const handler = handlers.length > 0 ? handlers[0] : void 0;
20460
20671
  if (!handler || !handler.renderMarkdown) {
@@ -20471,6 +20682,7 @@ var MarkdownManager = class {
20471
20682
  syntheticNode,
20472
20683
  {
20473
20684
  renderChildren: () => placeholder,
20685
+ renderChild: () => placeholder,
20474
20686
  indent: (content) => content,
20475
20687
  wrapInBlock: (prefix, content) => prefix + content
20476
20688
  },
@@ -20485,7 +20697,11 @@ var MarkdownManager = class {
20485
20697
  /**
20486
20698
  * Get the closing markdown syntax for a mark type.
20487
20699
  */
20488
- getMarkClosing(markType, mark) {
20700
+ getMarkClosing(markType, mark, openingMode = "markdown") {
20701
+ var _a;
20702
+ if (openingMode === "html") {
20703
+ return ((_a = this.getHtmlReopenTags(markType)) == null ? void 0 : _a.close) || "";
20704
+ }
20489
20705
  const handlers = this.getHandlersForNodeType(markType);
20490
20706
  const handler = handlers.length > 0 ? handlers[0] : void 0;
20491
20707
  if (!handler || !handler.renderMarkdown) {
@@ -20502,6 +20718,7 @@ var MarkdownManager = class {
20502
20718
  syntheticNode,
20503
20719
  {
20504
20720
  renderChildren: () => placeholder,
20721
+ renderChild: () => placeholder,
20505
20722
  indent: (content) => content,
20506
20723
  wrapInBlock: (prefix, content) => prefix + content
20507
20724
  },
@@ -20514,6 +20731,15 @@ var MarkdownManager = class {
20514
20731
  throw new Error(`Failed to get mark closing for ${markType}: ${err}`);
20515
20732
  }
20516
20733
  }
20734
+ /**
20735
+ * Returns the inline HTML tags an extension exposes for overlap-boundary
20736
+ * reopen handling, if that mark explicitly opted into HTML reopen mode.
20737
+ */
20738
+ getHtmlReopenTags(markType) {
20739
+ const handlers = this.getHandlersForNodeType(markType);
20740
+ const handler = handlers.length > 0 ? handlers[0] : void 0;
20741
+ return handler == null ? void 0 : handler.htmlReopen;
20742
+ }
20517
20743
  /**
20518
20744
  * Check if two mark sets are equal.
20519
20745
  */
@@ -20656,7 +20882,9 @@ var Blockquote = Node3.create({
20656
20882
  return /* @__PURE__ */ h("blockquote", { ...mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), children: /* @__PURE__ */ h("slot", {}) });
20657
20883
  },
20658
20884
  parseMarkdown: (token, helpers) => {
20659
- return helpers.createNode("blockquote", void 0, helpers.parseChildren(token.tokens || []));
20885
+ var _a;
20886
+ const parseBlockChildren = (_a = helpers.parseBlockChildren) != null ? _a : helpers.parseChildren;
20887
+ return helpers.createNode("blockquote", void 0, parseBlockChildren(token.tokens || []));
20660
20888
  },
20661
20889
  renderMarkdown: (node, h) => {
20662
20890
  if (!node.content) {
@@ -20664,8 +20892,9 @@ var Blockquote = Node3.create({
20664
20892
  }
20665
20893
  const prefix = ">";
20666
20894
  const result = [];
20667
- node.content.forEach((child) => {
20668
- const childContent = h.renderChildren([child]);
20895
+ node.content.forEach((child, index) => {
20896
+ var _a, _b;
20897
+ const childContent = (_b = (_a = h.renderChild) == null ? void 0 : _a.call(h, child, index)) != null ? _b : h.renderChildren([child]);
20669
20898
  const lines = childContent.split("\n");
20670
20899
  const linesWithPrefix = lines.map((line) => {
20671
20900
  if (line.trim() === "") {
@@ -20745,6 +20974,12 @@ var Bold = Mark.create({
20745
20974
  parseMarkdown: (token, helpers) => {
20746
20975
  return helpers.applyMark("bold", helpers.parseInline(token.tokens || []));
20747
20976
  },
20977
+ markdownOptions: {
20978
+ htmlReopen: {
20979
+ open: "<strong>",
20980
+ close: "</strong>"
20981
+ }
20982
+ },
20748
20983
  renderMarkdown: (node, h) => {
20749
20984
  return `**${h.renderChildren(node)}**`;
20750
20985
  },
@@ -20925,8 +21160,8 @@ var CodeBlock = Node3.create({
20925
21160
  },
20926
21161
  markdownTokenName: "code",
20927
21162
  parseMarkdown: (token, helpers) => {
20928
- var _a;
20929
- if (((_a = token.raw) == null ? void 0 : _a.startsWith("```")) === false && token.codeBlockStyle !== "indented") {
21163
+ var _a, _b;
21164
+ if (((_a = token.raw) == null ? void 0 : _a.startsWith("```")) === false && ((_b = token.raw) == null ? void 0 : _b.startsWith("~~~")) === false && token.codeBlockStyle !== "indented") {
20930
21165
  return [];
20931
21166
  }
20932
21167
  return helpers.createNode(
@@ -21454,6 +21689,12 @@ var Italic = Mark.create({
21454
21689
  parseMarkdown: (token, helpers) => {
21455
21690
  return helpers.applyMark("italic", helpers.parseInline(token.tokens || []));
21456
21691
  },
21692
+ markdownOptions: {
21693
+ htmlReopen: {
21694
+ open: "<em>",
21695
+ close: "</em>"
21696
+ }
21697
+ },
21457
21698
  renderMarkdown: (node, h) => {
21458
21699
  return `*${h.renderChildren(node)}*`;
21459
21700
  },
@@ -23757,14 +23998,16 @@ var ListItem = Node3.create({
23757
23998
  },
23758
23999
  markdownTokenName: "list_item",
23759
24000
  parseMarkdown: (token, helpers) => {
24001
+ var _a;
23760
24002
  if (token.type !== "list_item") {
23761
24003
  return [];
23762
24004
  }
24005
+ const parseBlockChildren = (_a = helpers.parseBlockChildren) != null ? _a : helpers.parseChildren;
23763
24006
  let content = [];
23764
24007
  if (token.tokens && token.tokens.length > 0) {
23765
24008
  const hasParagraphTokens = token.tokens.some((t) => t.type === "paragraph");
23766
24009
  if (hasParagraphTokens) {
23767
- content = helpers.parseChildren(token.tokens);
24010
+ content = parseBlockChildren(token.tokens);
23768
24011
  } else {
23769
24012
  const firstToken = token.tokens[0];
23770
24013
  if (firstToken && firstToken.type === "text" && firstToken.tokens && firstToken.tokens.length > 0) {
@@ -23777,11 +24020,11 @@ var ListItem = Node3.create({
23777
24020
  ];
23778
24021
  if (token.tokens.length > 1) {
23779
24022
  const remainingTokens = token.tokens.slice(1);
23780
- const additionalContent = helpers.parseChildren(remainingTokens);
24023
+ const additionalContent = parseBlockChildren(remainingTokens);
23781
24024
  content.push(...additionalContent);
23782
24025
  }
23783
24026
  } else {
23784
- content = helpers.parseChildren(token.tokens);
24027
+ content = parseBlockChildren(token.tokens);
23785
24028
  }
23786
24029
  }
23787
24030
  }
@@ -24086,6 +24329,36 @@ var ListKeymap = Extension.create({
24086
24329
  // src/ordered-list/utils.ts
24087
24330
  var ORDERED_LIST_ITEM_REGEX = /^(\s*)(\d+)\.\s+(.*)$/;
24088
24331
  var INDENTED_LINE_REGEX = /^\s/;
24332
+ function isBlockContentLine(line) {
24333
+ const trimmedLine = line.trimStart();
24334
+ return /^[-+*]\s+/.test(trimmedLine) || /^\d+\.\s+/.test(trimmedLine) || /^>\s?/.test(trimmedLine) || /^```/.test(trimmedLine) || /^~~~/.test(trimmedLine);
24335
+ }
24336
+ function splitItemContent(contentLines) {
24337
+ const paragraphLines = [];
24338
+ const blockLines = [];
24339
+ let reachedBlockBoundary = false;
24340
+ contentLines.forEach((line) => {
24341
+ if (reachedBlockBoundary) {
24342
+ blockLines.push(line);
24343
+ return;
24344
+ }
24345
+ if (line.trim() === "") {
24346
+ reachedBlockBoundary = true;
24347
+ blockLines.push(line);
24348
+ return;
24349
+ }
24350
+ if (paragraphLines.length > 0 && isBlockContentLine(line)) {
24351
+ reachedBlockBoundary = true;
24352
+ blockLines.push(line);
24353
+ return;
24354
+ }
24355
+ paragraphLines.push(line);
24356
+ });
24357
+ return {
24358
+ paragraphLines,
24359
+ blockLines
24360
+ };
24361
+ }
24089
24362
  function collectOrderedListItems(lines) {
24090
24363
  const listItems = [];
24091
24364
  let currentLineIndex = 0;
@@ -24098,9 +24371,10 @@ function collectOrderedListItems(lines) {
24098
24371
  }
24099
24372
  const [, indent, number, content] = match;
24100
24373
  const indentLevel = indent.length;
24101
- let itemContent = content;
24374
+ const itemContentLines = [content];
24102
24375
  let nextLineIndex = currentLineIndex + 1;
24103
24376
  const itemLines = [line];
24377
+ let sawBlankLine = false;
24104
24378
  while (nextLineIndex < lines.length) {
24105
24379
  const nextLine = lines[nextLineIndex];
24106
24380
  const nextMatch = nextLine.match(ORDERED_LIST_ITEM_REGEX);
@@ -24109,21 +24383,27 @@ function collectOrderedListItems(lines) {
24109
24383
  }
24110
24384
  if (nextLine.trim() === "") {
24111
24385
  itemLines.push(nextLine);
24112
- itemContent += "\n";
24386
+ itemContentLines.push("");
24387
+ sawBlankLine = true;
24113
24388
  nextLineIndex += 1;
24114
24389
  } else if (nextLine.match(INDENTED_LINE_REGEX)) {
24115
24390
  itemLines.push(nextLine);
24116
- itemContent += `
24117
- ${nextLine.slice(indentLevel + 2)}`;
24391
+ itemContentLines.push(nextLine.slice(indentLevel + 2));
24118
24392
  nextLineIndex += 1;
24119
24393
  } else {
24120
- break;
24394
+ if (sawBlankLine) {
24395
+ break;
24396
+ }
24397
+ itemLines.push(nextLine);
24398
+ itemContentLines.push(nextLine);
24399
+ nextLineIndex += 1;
24121
24400
  }
24122
24401
  }
24123
24402
  listItems.push({
24124
24403
  indent: indentLevel,
24125
24404
  number: parseInt(number, 10),
24126
- content: itemContent.trim(),
24405
+ content: itemContentLines.join("\n").trim(),
24406
+ contentLines: itemContentLines,
24127
24407
  raw: itemLines.join("\n")
24128
24408
  });
24129
24409
  consumed = nextLineIndex;
@@ -24132,14 +24412,13 @@ ${nextLine.slice(indentLevel + 2)}`;
24132
24412
  return [listItems, consumed];
24133
24413
  }
24134
24414
  function buildNestedStructure(items, baseIndent, lexer) {
24135
- var _a;
24136
24415
  const result = [];
24137
24416
  let currentIndex = 0;
24138
24417
  while (currentIndex < items.length) {
24139
24418
  const item = items[currentIndex];
24140
24419
  if (item.indent === baseIndent) {
24141
- const contentLines = item.content.split("\n");
24142
- const mainText = ((_a = contentLines[0]) == null ? void 0 : _a.trim()) || "";
24420
+ const { paragraphLines, blockLines } = splitItemContent(item.contentLines);
24421
+ const mainText = paragraphLines.join("\n").trim();
24143
24422
  const tokens = [];
24144
24423
  if (mainText) {
24145
24424
  tokens.push({
@@ -24148,7 +24427,7 @@ function buildNestedStructure(items, baseIndent, lexer) {
24148
24427
  tokens: lexer.inlineTokens(mainText)
24149
24428
  });
24150
24429
  }
24151
- const additionalContent = contentLines.slice(1).join("\n").trim();
24430
+ const additionalContent = blockLines.join("\n").trim();
24152
24431
  if (additionalContent) {
24153
24432
  const blockTokens = lexer.blockTokens(additionalContent);
24154
24433
  tokens.push(...blockTokens);
@@ -24725,18 +25004,22 @@ var Paragraph = Node3.create({
24725
25004
  return helpers.parseChildren([tokens[0]]);
24726
25005
  }
24727
25006
  const content = helpers.parseInline(tokens);
24728
- if (content.length === 1 && content[0].type === "text" && (content[0].text === EMPTY_PARAGRAPH_MARKDOWN || content[0].text === NBSP_CHAR)) {
25007
+ const hasExplicitEmptyParagraphMarker = tokens.length === 1 && tokens[0].type === "text" && (tokens[0].raw === EMPTY_PARAGRAPH_MARKDOWN || tokens[0].text === EMPTY_PARAGRAPH_MARKDOWN || tokens[0].raw === NBSP_CHAR || tokens[0].text === NBSP_CHAR);
25008
+ if (hasExplicitEmptyParagraphMarker && content.length === 1 && content[0].type === "text" && (content[0].text === EMPTY_PARAGRAPH_MARKDOWN || content[0].text === NBSP_CHAR)) {
24729
25009
  return helpers.createNode("paragraph", void 0, []);
24730
25010
  }
24731
25011
  return helpers.createNode("paragraph", void 0, content);
24732
25012
  },
24733
- renderMarkdown: (node, h) => {
25013
+ renderMarkdown: (node, h, ctx) => {
25014
+ var _a, _b;
24734
25015
  if (!node) {
24735
25016
  return "";
24736
25017
  }
24737
25018
  const content = Array.isArray(node.content) ? node.content : [];
24738
25019
  if (content.length === 0) {
24739
- return EMPTY_PARAGRAPH_MARKDOWN;
25020
+ const previousContent = Array.isArray((_a = ctx == null ? void 0 : ctx.previousNode) == null ? void 0 : _a.content) ? ctx.previousNode.content : [];
25021
+ const previousNodeIsEmptyParagraph = ((_b = ctx == null ? void 0 : ctx.previousNode) == null ? void 0 : _b.type) === "paragraph" && previousContent.length === 0;
25022
+ return previousNodeIsEmptyParagraph ? EMPTY_PARAGRAPH_MARKDOWN : "";
24740
25023
  }
24741
25024
  return h.renderChildren(content);
24742
25025
  },
@@ -25868,7 +26151,7 @@ function history(config = {}) {
25868
26151
  beforeinput(view, e) {
25869
26152
  let inputType = e.inputType;
25870
26153
  let command = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
25871
- if (!command)
26154
+ if (!command || !view.editable)
25872
26155
  return false;
25873
26156
  e.preventDefault();
25874
26157
  return command(view.state, view.dispatch);
@@ -26119,6 +26402,9 @@ Extension.create({
26119
26402
  doc.descendants((node, pos) => {
26120
26403
  const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
26121
26404
  const isEmpty = !node.isLeaf && isNodeEmpty(node);
26405
+ if (!node.type.isTextblock) {
26406
+ return this.options.includeChildren;
26407
+ }
26122
26408
  if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {
26123
26409
  const classes = [this.options.emptyNodeClass];
26124
26410
  if (isEmptyDoc) {
@@ -26172,6 +26458,7 @@ Extension.create({
26172
26458
  ];
26173
26459
  }
26174
26460
  });
26461
+ var skipTrailingNodeMeta = "skipTrailingNode";
26175
26462
  function nodeEqualsType({ types, node }) {
26176
26463
  return node && Array.isArray(types) && types.includes(node.type) || (node == null ? void 0 : node.type) === types;
26177
26464
  }
@@ -26191,11 +26478,14 @@ var TrailingNode = Extension.create({
26191
26478
  return [
26192
26479
  new Plugin({
26193
26480
  key: plugin,
26194
- appendTransaction: (_, __, state) => {
26481
+ appendTransaction: (transactions, __, state) => {
26195
26482
  const { doc, tr, schema } = state;
26196
26483
  const shouldInsertNodeAtEnd = plugin.getState(state);
26197
26484
  const endPosition = doc.content.size;
26198
26485
  const type = schema.nodes[defaultNode];
26486
+ if (transactions.some((transaction) => transaction.getMeta(skipTrailingNodeMeta))) {
26487
+ return;
26488
+ }
26199
26489
  if (!shouldInsertNodeAtEnd) {
26200
26490
  return;
26201
26491
  }