@payloadcms/richtext-lexical 3.29.0-internal.e4e913b → 3.29.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.
@@ -110,6 +110,10 @@ unclosedTags, unclosableTags) {
110
110
  // bring the whitespace back. So our returned string looks like this: " **foo** "
111
111
  const frozenString = textContent.trim();
112
112
  let output = frozenString;
113
+ if (!node.hasFormat('code')) {
114
+ // Escape any markdown characters in the text content
115
+ output = output.replace(/([*_`~\\])/g, '\\$1');
116
+ }
113
117
  // the opening tags to be added to the result
114
118
  let openingTags = '';
115
119
  // the closing tags to be added to the result
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownExport.js","names":["$getRoot","$isDecoratorNode","$isElementNode","$isLineBreakNode","$isTextNode","isEmptyParagraph","transformersByType","createMarkdownExport","transformers","shouldPreserveNewLines","byType","elementTransformers","multilineElement","element","isNewlineDelimited","textFormatTransformers","textFormat","filter","transformer","format","length","sort","a","b","includes","node","output","children","getChildren","forEach","child","i","result","exportTopLevelElements","textMatch","push","concat","join","textTransformersIndex","textMatchTransformers","export","_node","exportChildren","getTextContent","unclosedTags","unclosableTags","mainLoop","parentNode","textNode","textContent","exportTextFormat","textTransformers","frozenString","trim","openingTags","closingTagsBefore","closingTagsAfter","prevNode","getTextSibling","nextNode","applied","Set","tag","hasFormat","has","add","find","unclosedTag","nodeHasFormat","nextNodeHasFormat","unhandledUnclosedTags","pop","replace","backward","sibling","getPreviousSibling","getNextSibling","parent","getParentOrThrow","isInline","descendant","getLastDescendant","getFirstDescendant"],"sources":["../../../../src/packages/@lexical/markdown/MarkdownExport.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport type { ElementNode, LexicalNode, TextFormatType, TextNode } from 'lexical'\n\nimport { $getRoot, $isDecoratorNode, $isElementNode, $isLineBreakNode, $isTextNode } from 'lexical'\n\nimport type {\n ElementTransformer,\n MultilineElementTransformer,\n TextFormatTransformer,\n TextMatchTransformer,\n Transformer,\n} from './MarkdownTransformers.js'\n\nimport { isEmptyParagraph, transformersByType } from './utils.js'\n\n/**\n * Renders string from markdown. The selection is moved to the start after the operation.\n */\nexport function createMarkdownExport(\n transformers: Array<Transformer>,\n shouldPreserveNewLines: boolean = false,\n): (node?: ElementNode) => string {\n const byType = transformersByType(transformers)\n const elementTransformers = [...byType.multilineElement, ...byType.element]\n const isNewlineDelimited = !shouldPreserveNewLines\n\n // Export only uses text formats that are responsible for single format\n // e.g. it will filter out *** (bold, italic) and instead use separate ** and *\n const textFormatTransformers = byType.textFormat\n .filter((transformer) => transformer.format.length === 1)\n // Make sure all text transformers that contain 'code' in their format are at the end of the array. Otherwise, formatted code like\n // <strong><code>code</code></strong> will be exported as `**Bold Code**`, as the code format will be applied first, and the bold format\n // will be applied second and thus skipped entirely, as the code format will prevent any further formatting.\n .sort((a, b) => {\n if (a.format.includes('code') && !b.format.includes('code')) {\n return 1\n } else if (!a.format.includes('code') && b.format.includes('code')) {\n return -1\n } else {\n return 0\n }\n })\n\n return (node) => {\n const output: string[] = []\n const children = (node || $getRoot()).getChildren()\n\n children.forEach((child, i) => {\n const result = exportTopLevelElements(\n child,\n elementTransformers,\n textFormatTransformers,\n byType.textMatch,\n )\n\n if (result != null) {\n output.push(\n // separate consecutive group of texts with a line break: eg. [\"hello\", \"world\"] -> [\"hello\", \"/nworld\"]\n isNewlineDelimited &&\n i > 0 &&\n !isEmptyParagraph(child) &&\n !isEmptyParagraph(children[i - 1]!)\n ? '\\n'.concat(result)\n : result,\n )\n }\n })\n // Ensure consecutive groups of texts are at least \\n\\n apart while each empty paragraph render as a newline.\n // Eg. [\"hello\", \"\", \"\", \"hi\", \"\\nworld\"] -> \"hello\\n\\n\\nhi\\n\\nworld\"\n return output.join('\\n')\n }\n}\n\nfunction exportTopLevelElements(\n node: LexicalNode,\n elementTransformers: Array<ElementTransformer | MultilineElementTransformer>,\n textTransformersIndex: Array<TextFormatTransformer>,\n textMatchTransformers: Array<TextMatchTransformer>,\n): null | string {\n for (const transformer of elementTransformers) {\n if (!transformer.export) {\n continue\n }\n const result = transformer.export(node, (_node) =>\n exportChildren(_node, textTransformersIndex, textMatchTransformers),\n )\n\n if (result != null) {\n return result\n }\n }\n\n if ($isElementNode(node)) {\n return exportChildren(node, textTransformersIndex, textMatchTransformers)\n } else if ($isDecoratorNode(node)) {\n return node.getTextContent()\n } else {\n return null\n }\n}\n\nfunction exportChildren(\n node: ElementNode,\n textTransformersIndex: Array<TextFormatTransformer>,\n textMatchTransformers: Array<TextMatchTransformer>,\n unclosedTags?: Array<{ format: TextFormatType; tag: string }>,\n unclosableTags?: Array<{ format: TextFormatType; tag: string }>,\n): string {\n const output = []\n const children = node.getChildren()\n // keep track of unclosed tags from the very beginning\n if (!unclosedTags) {\n unclosedTags = []\n }\n if (!unclosableTags) {\n unclosableTags = []\n }\n\n mainLoop: for (const child of children) {\n for (const transformer of textMatchTransformers) {\n if (!transformer.export) {\n continue\n }\n\n const result = transformer.export(\n child,\n (parentNode) =>\n exportChildren(\n parentNode,\n textTransformersIndex,\n textMatchTransformers,\n unclosedTags,\n // Add current unclosed tags to the list of unclosable tags - we don't want nested tags from\n // textmatch transformers to close the outer ones, as that may result in invalid markdown.\n // E.g. **text [text**](https://lexical.io)\n // is invalid markdown, as the closing ** is inside the link.\n //\n [...unclosableTags, ...unclosedTags],\n ),\n (textNode, textContent) =>\n exportTextFormat(\n textNode,\n textContent,\n textTransformersIndex,\n unclosedTags,\n unclosableTags,\n ),\n )\n\n if (result != null) {\n output.push(result)\n continue mainLoop\n }\n }\n\n if ($isLineBreakNode(child)) {\n output.push('\\n')\n } else if ($isTextNode(child)) {\n output.push(\n exportTextFormat(\n child,\n child.getTextContent(),\n textTransformersIndex,\n unclosedTags,\n unclosableTags,\n ),\n )\n } else if ($isElementNode(child)) {\n // empty paragraph returns \"\"\n output.push(\n exportChildren(\n child,\n textTransformersIndex,\n textMatchTransformers,\n unclosedTags,\n unclosableTags,\n ),\n )\n } else if ($isDecoratorNode(child)) {\n output.push(child.getTextContent())\n }\n }\n\n return output.join('')\n}\n\nfunction exportTextFormat(\n node: TextNode,\n textContent: string,\n textTransformers: Array<TextFormatTransformer>,\n // unclosed tags include the markdown tags that haven't been closed yet, and their associated formats\n unclosedTags: Array<{ format: TextFormatType; tag: string }>,\n unclosableTags?: Array<{ format: TextFormatType; tag: string }>,\n): string {\n // This function handles the case of a string looking like this: \" foo \"\n // Where it would be invalid markdown to generate: \"** foo **\"\n // We instead want to trim the whitespace out, apply formatting, and then\n // bring the whitespace back. So our returned string looks like this: \" **foo** \"\n const frozenString = textContent.trim()\n let output = frozenString\n // the opening tags to be added to the result\n let openingTags = ''\n // the closing tags to be added to the result\n let closingTagsBefore = ''\n let closingTagsAfter = ''\n\n const prevNode = getTextSibling(node, true)\n const nextNode = getTextSibling(node, false)\n\n const applied = new Set()\n\n for (const transformer of textTransformers) {\n const format = transformer.format[0]!\n const tag = transformer.tag\n\n // dedup applied formats\n if (hasFormat(node, format) && !applied.has(format)) {\n // Multiple tags might be used for the same format (*, _)\n applied.add(format)\n\n // append the tag to openningTags, if it's not applied to the previous nodes,\n // or the nodes before that (which would result in an unclosed tag)\n if (!hasFormat(prevNode, format) || !unclosedTags.find((element) => element.tag === tag)) {\n unclosedTags.push({ format, tag })\n openingTags += tag\n }\n }\n }\n\n // close any tags in the same order they were applied, if necessary\n for (let i = 0; i < unclosedTags.length; i++) {\n const unclosedTag = unclosedTags[i]!\n const nodeHasFormat = hasFormat(node, unclosedTag.format)\n const nextNodeHasFormat = hasFormat(nextNode, unclosedTag.format)\n\n // prevent adding closing tag if next sibling will do it\n if (nodeHasFormat && nextNodeHasFormat) {\n continue\n }\n\n const unhandledUnclosedTags = [...unclosedTags] // Shallow copy to avoid modifying the original array\n\n while (unhandledUnclosedTags.length > i) {\n const unclosedTag = unhandledUnclosedTags.pop()\n\n // If tag is unclosable, don't close it and leave it in the original array,\n // So that it can be closed when it's no longer unclosable\n if (\n unclosableTags &&\n unclosedTag &&\n unclosableTags.find((element) => element.tag === unclosedTag.tag)\n ) {\n continue\n }\n\n if (unclosedTag && typeof unclosedTag.tag === 'string') {\n if (!nodeHasFormat) {\n // Handles cases where the tag has not been closed before, e.g. if the previous node\n // was a text match transformer that did not account for closing tags of the next node (e.g. a link)\n closingTagsBefore += unclosedTag.tag\n } else if (!nextNodeHasFormat) {\n closingTagsAfter += unclosedTag.tag\n }\n }\n // Mutate the original array to remove the closed tag\n unclosedTags.pop()\n }\n break\n }\n\n output = openingTags + output + closingTagsAfter\n // Replace trimmed version of textContent ensuring surrounding whitespace is not modified\n return closingTagsBefore + textContent.replace(frozenString, () => output)\n}\n\n// Get next or previous text sibling a text node, including cases\n// when it's a child of inline element (e.g. link)\nfunction getTextSibling(node: TextNode, backward: boolean): null | TextNode {\n let sibling = backward ? node.getPreviousSibling() : node.getNextSibling()\n\n if (!sibling) {\n const parent = node.getParentOrThrow()\n\n if (parent.isInline()) {\n sibling = backward ? parent.getPreviousSibling() : parent.getNextSibling()\n }\n }\n\n while (sibling) {\n if ($isElementNode(sibling)) {\n if (!sibling.isInline()) {\n break\n }\n\n const descendant = backward ? sibling.getLastDescendant() : sibling.getFirstDescendant()\n\n if ($isTextNode(descendant)) {\n return descendant\n } else {\n sibling = backward ? sibling.getPreviousSibling() : sibling.getNextSibling()\n }\n }\n\n if ($isTextNode(sibling)) {\n return sibling\n }\n\n if (!$isElementNode(sibling)) {\n return null\n }\n }\n\n return null\n}\n\nfunction hasFormat(node: LexicalNode | null | undefined, format: TextFormatType): boolean {\n return $isTextNode(node) && node.hasFormat(format)\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"MarkdownExport.js","names":["$getRoot","$isDecoratorNode","$isElementNode","$isLineBreakNode","$isTextNode","isEmptyParagraph","transformersByType","createMarkdownExport","transformers","shouldPreserveNewLines","byType","elementTransformers","multilineElement","element","isNewlineDelimited","textFormatTransformers","textFormat","filter","transformer","format","length","sort","a","b","includes","node","output","children","getChildren","forEach","child","i","result","exportTopLevelElements","textMatch","push","concat","join","textTransformersIndex","textMatchTransformers","export","_node","exportChildren","getTextContent","unclosedTags","unclosableTags","mainLoop","parentNode","textNode","textContent","exportTextFormat","textTransformers","frozenString","trim","hasFormat","replace","openingTags","closingTagsBefore","closingTagsAfter","prevNode","getTextSibling","nextNode","applied","Set","tag","has","add","find","unclosedTag","nodeHasFormat","nextNodeHasFormat","unhandledUnclosedTags","pop","backward","sibling","getPreviousSibling","getNextSibling","parent","getParentOrThrow","isInline","descendant","getLastDescendant","getFirstDescendant"],"sources":["../../../../src/packages/@lexical/markdown/MarkdownExport.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport type { ElementNode, LexicalNode, TextFormatType, TextNode } from 'lexical'\n\nimport { $getRoot, $isDecoratorNode, $isElementNode, $isLineBreakNode, $isTextNode } from 'lexical'\n\nimport type {\n ElementTransformer,\n MultilineElementTransformer,\n TextFormatTransformer,\n TextMatchTransformer,\n Transformer,\n} from './MarkdownTransformers.js'\n\nimport { isEmptyParagraph, transformersByType } from './utils.js'\n\n/**\n * Renders string from markdown. The selection is moved to the start after the operation.\n */\nexport function createMarkdownExport(\n transformers: Array<Transformer>,\n shouldPreserveNewLines: boolean = false,\n): (node?: ElementNode) => string {\n const byType = transformersByType(transformers)\n const elementTransformers = [...byType.multilineElement, ...byType.element]\n const isNewlineDelimited = !shouldPreserveNewLines\n\n // Export only uses text formats that are responsible for single format\n // e.g. it will filter out *** (bold, italic) and instead use separate ** and *\n const textFormatTransformers = byType.textFormat\n .filter((transformer) => transformer.format.length === 1)\n // Make sure all text transformers that contain 'code' in their format are at the end of the array. Otherwise, formatted code like\n // <strong><code>code</code></strong> will be exported as `**Bold Code**`, as the code format will be applied first, and the bold format\n // will be applied second and thus skipped entirely, as the code format will prevent any further formatting.\n .sort((a, b) => {\n if (a.format.includes('code') && !b.format.includes('code')) {\n return 1\n } else if (!a.format.includes('code') && b.format.includes('code')) {\n return -1\n } else {\n return 0\n }\n })\n\n return (node) => {\n const output: string[] = []\n const children = (node || $getRoot()).getChildren()\n\n children.forEach((child, i) => {\n const result = exportTopLevelElements(\n child,\n elementTransformers,\n textFormatTransformers,\n byType.textMatch,\n )\n\n if (result != null) {\n output.push(\n // separate consecutive group of texts with a line break: eg. [\"hello\", \"world\"] -> [\"hello\", \"/nworld\"]\n isNewlineDelimited &&\n i > 0 &&\n !isEmptyParagraph(child) &&\n !isEmptyParagraph(children[i - 1]!)\n ? '\\n'.concat(result)\n : result,\n )\n }\n })\n // Ensure consecutive groups of texts are at least \\n\\n apart while each empty paragraph render as a newline.\n // Eg. [\"hello\", \"\", \"\", \"hi\", \"\\nworld\"] -> \"hello\\n\\n\\nhi\\n\\nworld\"\n return output.join('\\n')\n }\n}\n\nfunction exportTopLevelElements(\n node: LexicalNode,\n elementTransformers: Array<ElementTransformer | MultilineElementTransformer>,\n textTransformersIndex: Array<TextFormatTransformer>,\n textMatchTransformers: Array<TextMatchTransformer>,\n): null | string {\n for (const transformer of elementTransformers) {\n if (!transformer.export) {\n continue\n }\n const result = transformer.export(node, (_node) =>\n exportChildren(_node, textTransformersIndex, textMatchTransformers),\n )\n\n if (result != null) {\n return result\n }\n }\n\n if ($isElementNode(node)) {\n return exportChildren(node, textTransformersIndex, textMatchTransformers)\n } else if ($isDecoratorNode(node)) {\n return node.getTextContent()\n } else {\n return null\n }\n}\n\nfunction exportChildren(\n node: ElementNode,\n textTransformersIndex: Array<TextFormatTransformer>,\n textMatchTransformers: Array<TextMatchTransformer>,\n unclosedTags?: Array<{ format: TextFormatType; tag: string }>,\n unclosableTags?: Array<{ format: TextFormatType; tag: string }>,\n): string {\n const output = []\n const children = node.getChildren()\n // keep track of unclosed tags from the very beginning\n if (!unclosedTags) {\n unclosedTags = []\n }\n if (!unclosableTags) {\n unclosableTags = []\n }\n\n mainLoop: for (const child of children) {\n for (const transformer of textMatchTransformers) {\n if (!transformer.export) {\n continue\n }\n\n const result = transformer.export(\n child,\n (parentNode) =>\n exportChildren(\n parentNode,\n textTransformersIndex,\n textMatchTransformers,\n unclosedTags,\n // Add current unclosed tags to the list of unclosable tags - we don't want nested tags from\n // textmatch transformers to close the outer ones, as that may result in invalid markdown.\n // E.g. **text [text**](https://lexical.io)\n // is invalid markdown, as the closing ** is inside the link.\n //\n [...unclosableTags, ...unclosedTags],\n ),\n (textNode, textContent) =>\n exportTextFormat(\n textNode,\n textContent,\n textTransformersIndex,\n unclosedTags,\n unclosableTags,\n ),\n )\n\n if (result != null) {\n output.push(result)\n continue mainLoop\n }\n }\n\n if ($isLineBreakNode(child)) {\n output.push('\\n')\n } else if ($isTextNode(child)) {\n output.push(\n exportTextFormat(\n child,\n child.getTextContent(),\n textTransformersIndex,\n unclosedTags,\n unclosableTags,\n ),\n )\n } else if ($isElementNode(child)) {\n // empty paragraph returns \"\"\n output.push(\n exportChildren(\n child,\n textTransformersIndex,\n textMatchTransformers,\n unclosedTags,\n unclosableTags,\n ),\n )\n } else if ($isDecoratorNode(child)) {\n output.push(child.getTextContent())\n }\n }\n\n return output.join('')\n}\n\nfunction exportTextFormat(\n node: TextNode,\n textContent: string,\n textTransformers: Array<TextFormatTransformer>,\n // unclosed tags include the markdown tags that haven't been closed yet, and their associated formats\n unclosedTags: Array<{ format: TextFormatType; tag: string }>,\n unclosableTags?: Array<{ format: TextFormatType; tag: string }>,\n): string {\n // This function handles the case of a string looking like this: \" foo \"\n // Where it would be invalid markdown to generate: \"** foo **\"\n // We instead want to trim the whitespace out, apply formatting, and then\n // bring the whitespace back. So our returned string looks like this: \" **foo** \"\n const frozenString = textContent.trim()\n let output = frozenString\n\n if (!node.hasFormat('code')) {\n // Escape any markdown characters in the text content\n output = output.replace(/([*_`~\\\\])/g, '\\\\$1')\n }\n\n // the opening tags to be added to the result\n let openingTags = ''\n // the closing tags to be added to the result\n let closingTagsBefore = ''\n let closingTagsAfter = ''\n\n const prevNode = getTextSibling(node, true)\n const nextNode = getTextSibling(node, false)\n\n const applied = new Set()\n\n for (const transformer of textTransformers) {\n const format = transformer.format[0]!\n const tag = transformer.tag\n\n // dedup applied formats\n if (hasFormat(node, format) && !applied.has(format)) {\n // Multiple tags might be used for the same format (*, _)\n applied.add(format)\n\n // append the tag to openningTags, if it's not applied to the previous nodes,\n // or the nodes before that (which would result in an unclosed tag)\n if (!hasFormat(prevNode, format) || !unclosedTags.find((element) => element.tag === tag)) {\n unclosedTags.push({ format, tag })\n openingTags += tag\n }\n }\n }\n\n // close any tags in the same order they were applied, if necessary\n for (let i = 0; i < unclosedTags.length; i++) {\n const unclosedTag = unclosedTags[i]!\n const nodeHasFormat = hasFormat(node, unclosedTag.format)\n const nextNodeHasFormat = hasFormat(nextNode, unclosedTag.format)\n\n // prevent adding closing tag if next sibling will do it\n if (nodeHasFormat && nextNodeHasFormat) {\n continue\n }\n\n const unhandledUnclosedTags = [...unclosedTags] // Shallow copy to avoid modifying the original array\n\n while (unhandledUnclosedTags.length > i) {\n const unclosedTag = unhandledUnclosedTags.pop()\n\n // If tag is unclosable, don't close it and leave it in the original array,\n // So that it can be closed when it's no longer unclosable\n if (\n unclosableTags &&\n unclosedTag &&\n unclosableTags.find((element) => element.tag === unclosedTag.tag)\n ) {\n continue\n }\n\n if (unclosedTag && typeof unclosedTag.tag === 'string') {\n if (!nodeHasFormat) {\n // Handles cases where the tag has not been closed before, e.g. if the previous node\n // was a text match transformer that did not account for closing tags of the next node (e.g. a link)\n closingTagsBefore += unclosedTag.tag\n } else if (!nextNodeHasFormat) {\n closingTagsAfter += unclosedTag.tag\n }\n }\n // Mutate the original array to remove the closed tag\n unclosedTags.pop()\n }\n break\n }\n\n output = openingTags + output + closingTagsAfter\n // Replace trimmed version of textContent ensuring surrounding whitespace is not modified\n return closingTagsBefore + textContent.replace(frozenString, () => output)\n}\n\n// Get next or previous text sibling a text node, including cases\n// when it's a child of inline element (e.g. link)\nfunction getTextSibling(node: TextNode, backward: boolean): null | TextNode {\n let sibling = backward ? node.getPreviousSibling() : node.getNextSibling()\n\n if (!sibling) {\n const parent = node.getParentOrThrow()\n\n if (parent.isInline()) {\n sibling = backward ? parent.getPreviousSibling() : parent.getNextSibling()\n }\n }\n\n while (sibling) {\n if ($isElementNode(sibling)) {\n if (!sibling.isInline()) {\n break\n }\n\n const descendant = backward ? sibling.getLastDescendant() : sibling.getFirstDescendant()\n\n if ($isTextNode(descendant)) {\n return descendant\n } else {\n sibling = backward ? sibling.getPreviousSibling() : sibling.getNextSibling()\n }\n }\n\n if ($isTextNode(sibling)) {\n return sibling\n }\n\n if (!$isElementNode(sibling)) {\n return null\n }\n }\n\n return null\n}\n\nfunction hasFormat(node: LexicalNode | null | undefined, format: TextFormatType): boolean {\n return $isTextNode(node) && node.hasFormat(format)\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownImport.d.ts","sourceRoot":"","sources":["../../../../src/packages/@lexical/markdown/MarkdownImport.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAc1C,OAAO,KAAK,EAGV,qBAAqB,EAErB,WAAW,EACZ,MAAM,2BAA2B,CAAA;AAMlC,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IACjD,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACtD,cAAc,EAAE,MAAM,CAAA;IACtB,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAA;CACnE,CAAC,CAAA;AAEF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,EAChC,sBAAsB,UAAQ,GAC7B,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,IAAI,CAyCtD"}
1
+ {"version":3,"file":"MarkdownImport.d.ts","sourceRoot":"","sources":["../../../../src/packages/@lexical/markdown/MarkdownImport.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAc1C,OAAO,KAAK,EAGV,qBAAqB,EAErB,WAAW,EACZ,MAAM,2BAA2B,CAAA;AAKlC,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IACjD,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACtD,cAAc,EAAE,MAAM,CAAA;IACtB,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAA;CACnE,CAAC,CAAA;AAEF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,EAChC,sBAAsB,UAAQ,GAC7B,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,IAAI,CAyCtD"}
@@ -8,7 +8,6 @@
8
8
  import { $isQuoteNode } from '@lexical/rich-text';
9
9
  import { $findMatchingParent } from '@lexical/utils';
10
10
  import { $createLineBreakNode, $createParagraphNode, $createTextNode, $getRoot, $getSelection, $isParagraphNode } from 'lexical';
11
- import { IS_APPLE_WEBKIT, IS_IOS, IS_SAFARI } from '../../../lexical/utils/environment.js';
12
11
  import { importTextTransformers } from './importTextTransformers.js';
13
12
  import { isEmptyParagraph, transformersByType } from './utils.js';
14
13
  /**
@@ -183,17 +182,20 @@ function createTextFormatTransformersIndex(textTransformers) {
183
182
  transformersByTag[tag] = transformer;
184
183
  const tagRegExp = tag.replace(/([*^+])/g, '\\$1');
185
184
  openTagsRegExp.push(tagRegExp);
186
- if (IS_SAFARI || IS_IOS || IS_APPLE_WEBKIT) {
187
- fullMatchRegExpByTag[tag] = new RegExp(`(${tagRegExp})(?![${tagRegExp}\\s])(.*?[^${tagRegExp}\\s])${tagRegExp}(?!${tagRegExp})`);
188
- } else {
185
+ // Single-char tag (e.g. "*"),
186
+ if (tag.length === 1) {
189
187
  fullMatchRegExpByTag[tag] = new RegExp(`(?<![\\\\${tagRegExp}])(${tagRegExp})((\\\\${tagRegExp})?.*?[^${tagRegExp}\\s](\\\\${tagRegExp})?)((?<!\\\\)|(?<=\\\\\\\\))(${tagRegExp})(?![\\\\${tagRegExp}])`);
188
+ } else {
189
+ // Multi‐char tags (e.g. "**")
190
+ fullMatchRegExpByTag[tag] = new RegExp(`(?<!\\\\)(${tagRegExp})((\\\\${tagRegExp})?.*?[^\\s](\\\\${tagRegExp})?)((?<!\\\\)|(?<=\\\\\\\\))(${tagRegExp})(?!\\\\)`);
190
191
  }
191
192
  }
192
193
  return {
193
194
  // Reg exp to find open tag + content + close tag
194
195
  fullMatchRegExpByTag,
195
- // Reg exp to find opening tags
196
- openTagsRegExp: new RegExp((IS_SAFARI || IS_IOS || IS_APPLE_WEBKIT ? '' : `${escapeRegExp}`) + '(' + openTagsRegExp.join('|') + ')', 'g'),
196
+ // Regexp to locate *any* potential opening tag (longest first).
197
+ // eslint-disable-next-line regexp/no-useless-character-class, regexp/no-empty-capturing-group, regexp/no-empty-group
198
+ openTagsRegExp: new RegExp(`${escapeRegExp}(${openTagsRegExp.join('|')})`, 'g'),
197
199
  transformersByTag
198
200
  };
199
201
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownImport.js","names":["$isListItemNode","$isListNode","$isQuoteNode","$findMatchingParent","$createLineBreakNode","$createParagraphNode","$createTextNode","$getRoot","$getSelection","$isParagraphNode","IS_APPLE_WEBKIT","IS_IOS","IS_SAFARI","importTextTransformers","isEmptyParagraph","transformersByType","createMarkdownImport","transformers","shouldPreserveNewLines","byType","textFormatTransformersIndex","createTextFormatTransformersIndex","textFormat","markdownString","node","lines","split","linesLength","length","root","clear","i","lineText","imported","shiftedIndex","$importMultiline","multilineElement","$importBlocks","element","textMatch","children","getChildren","child","getChildrenSize","remove","selectStart","startLineIndex","multilineElementTransformers","rootNode","transformer","handleImportAfterStartMatch","regExpEnd","regExpStart","replace","startMatch","match","result","regexpEndRegex","regExp","isEndOptional","optional","endLineIndex","endMatch","index","linesInBetween","push","slice","line","text","elementTransformers","textMatchTransformers","textNode","elementNode","append","setTextContent","isAttached","previousNode","getPreviousSibling","targetNode","lastDescendant","getLastDescendant","getTextContentSize","splice","textTransformers","transformersByTag","fullMatchRegExpByTag","openTagsRegExp","escapeRegExp","tag","tagRegExp","RegExp","join"],"sources":["../../../../src/packages/@lexical/markdown/MarkdownImport.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport type { ListItemNode } from '@lexical/list'\nimport type { ElementNode } from 'lexical'\n\nimport { $isListItemNode, $isListNode } from '@lexical/list'\nimport { $isQuoteNode } from '@lexical/rich-text'\nimport { $findMatchingParent } from '@lexical/utils'\nimport {\n $createLineBreakNode,\n $createParagraphNode,\n $createTextNode,\n $getRoot,\n $getSelection,\n $isParagraphNode,\n} from 'lexical'\n\nimport type {\n ElementTransformer,\n MultilineElementTransformer,\n TextFormatTransformer,\n TextMatchTransformer,\n Transformer,\n} from './MarkdownTransformers.js'\n\nimport { IS_APPLE_WEBKIT, IS_IOS, IS_SAFARI } from '../../../lexical/utils/environment.js'\nimport { importTextTransformers } from './importTextTransformers.js'\nimport { isEmptyParagraph, transformersByType } from './utils.js'\n\nexport type TextFormatTransformersIndex = Readonly<{\n fullMatchRegExpByTag: Readonly<Record<string, RegExp>>\n openTagsRegExp: RegExp\n transformersByTag: Readonly<Record<string, TextFormatTransformer>>\n}>\n\n/**\n * Renders markdown from a string. The selection is moved to the start after the operation.\n */\nexport function createMarkdownImport(\n transformers: Array<Transformer>,\n shouldPreserveNewLines = false,\n): (markdownString: string, node?: ElementNode) => void {\n const byType = transformersByType(transformers)\n const textFormatTransformersIndex = createTextFormatTransformersIndex(byType.textFormat)\n\n return (markdownString, node) => {\n const lines = markdownString.split('\\n')\n const linesLength = lines.length\n const root = node || $getRoot()\n root.clear()\n\n for (let i = 0; i < linesLength; i++) {\n const lineText = lines[i]!\n\n const [imported, shiftedIndex] = $importMultiline(lines, i, byType.multilineElement, root)\n\n if (imported) {\n // If a multiline markdown element was imported, we don't want to process the lines that were part of it anymore.\n // There could be other sub-markdown elements (both multiline and normal ones) matching within this matched multiline element's children.\n // However, it would be the responsibility of the matched multiline transformer to decide how it wants to handle them.\n // We cannot handle those, as there is no way for us to know how to maintain the correct order of generated lexical nodes for possible children.\n i = shiftedIndex // Next loop will start from the line after the last line of the multiline element\n continue\n }\n\n $importBlocks(lineText, root, byType.element, textFormatTransformersIndex, byType.textMatch)\n }\n\n // By default, removing empty paragraphs as md does not really\n // allow empty lines and uses them as delimiter.\n // If you need empty lines set shouldPreserveNewLines = true.\n const children = root.getChildren()\n for (const child of children) {\n if (!shouldPreserveNewLines && isEmptyParagraph(child) && root.getChildrenSize() > 1) {\n child.remove()\n }\n }\n\n if ($getSelection() !== null) {\n root.selectStart()\n }\n }\n}\n\n/**\n *\n * @returns first element of the returned tuple is a boolean indicating if a multiline element was imported. The second element is the index of the last line that was processed.\n */\nfunction $importMultiline(\n lines: Array<string>,\n startLineIndex: number,\n multilineElementTransformers: Array<MultilineElementTransformer>,\n rootNode: ElementNode,\n): [boolean, number] {\n for (const transformer of multilineElementTransformers) {\n const { handleImportAfterStartMatch, regExpEnd, regExpStart, replace } = transformer\n\n const startMatch = lines[startLineIndex]?.match(regExpStart)\n if (!startMatch) {\n continue // Try next transformer\n }\n\n if (handleImportAfterStartMatch) {\n const result = handleImportAfterStartMatch({\n lines,\n rootNode,\n startLineIndex,\n startMatch,\n transformer,\n })\n if (result === null) {\n continue\n } else if (result) {\n return result\n }\n }\n\n const regexpEndRegex: RegExp | undefined =\n typeof regExpEnd === 'object' && 'regExp' in regExpEnd ? regExpEnd.regExp : regExpEnd\n\n const isEndOptional =\n regExpEnd && typeof regExpEnd === 'object' && 'optional' in regExpEnd\n ? regExpEnd.optional\n : !regExpEnd\n\n let endLineIndex = startLineIndex\n const linesLength = lines.length\n\n // check every single line for the closing match. It could also be on the same line as the opening match.\n while (endLineIndex < linesLength) {\n const endMatch = regexpEndRegex ? lines[endLineIndex]?.match(regexpEndRegex) : null\n if (!endMatch) {\n if (\n !isEndOptional ||\n (isEndOptional && endLineIndex < linesLength - 1) // Optional end, but didn't reach the end of the document yet => continue searching for potential closing match\n ) {\n endLineIndex++\n continue // Search next line for closing match\n }\n }\n\n // Now, check if the closing match matched is the same as the opening match.\n // If it is, we need to continue searching for the actual closing match.\n if (endMatch && startLineIndex === endLineIndex && endMatch.index === startMatch.index) {\n endLineIndex++\n continue // Search next line for closing match\n }\n\n // At this point, we have found the closing match. Next: calculate the lines in between open and closing match\n // This should not include the matches themselves, and be split up by lines\n const linesInBetween: string[] = []\n\n if (endMatch && startLineIndex === endLineIndex) {\n linesInBetween.push(lines[startLineIndex]!.slice(startMatch[0].length, -endMatch[0].length))\n } else {\n for (let i = startLineIndex; i <= endLineIndex; i++) {\n const line = lines[i]!\n if (i === startLineIndex) {\n const text = line.slice(startMatch[0].length)\n linesInBetween.push(text) // Also include empty text\n } else if (i === endLineIndex && endMatch) {\n const text = line.slice(0, -endMatch[0].length)\n linesInBetween.push(text) // Also include empty text\n } else {\n linesInBetween.push(line)\n }\n }\n }\n\n if (replace(rootNode, null, startMatch, endMatch!, linesInBetween, true) !== false) {\n // Return here. This $importMultiline function is run line by line and should only process a single multiline element at a time.\n return [true, endLineIndex]\n }\n\n // The replace function returned false, despite finding the matching open and close tags => this transformer does not want to handle it.\n // Thus, we continue letting the remaining transformers handle the passed lines of text from the beginning\n break\n }\n }\n\n // No multiline transformer handled this line successfully\n return [false, startLineIndex]\n}\n\nfunction $importBlocks(\n lineText: string,\n rootNode: ElementNode,\n elementTransformers: Array<ElementTransformer>,\n textFormatTransformersIndex: TextFormatTransformersIndex,\n textMatchTransformers: Array<TextMatchTransformer>,\n) {\n const textNode = $createTextNode(lineText)\n const elementNode = $createParagraphNode()\n elementNode.append(textNode)\n rootNode.append(elementNode)\n\n for (const { regExp, replace } of elementTransformers) {\n const match = lineText.match(regExp)\n\n if (match) {\n textNode.setTextContent(lineText.slice(match[0].length))\n if (replace(elementNode, [textNode], match, true) !== false) {\n break\n }\n }\n }\n\n importTextTransformers(textNode, textFormatTransformersIndex, textMatchTransformers)\n\n // If no transformer found and we left with original paragraph node\n // can check if its content can be appended to the previous node\n // if it's a paragraph, quote or list\n if (elementNode.isAttached() && lineText.length > 0) {\n const previousNode = elementNode.getPreviousSibling()\n if ($isParagraphNode(previousNode) || $isQuoteNode(previousNode) || $isListNode(previousNode)) {\n let targetNode: ListItemNode | null | typeof previousNode = previousNode\n\n if ($isListNode(previousNode)) {\n const lastDescendant = previousNode.getLastDescendant()\n if (lastDescendant == null) {\n targetNode = null\n } else {\n targetNode = $findMatchingParent(lastDescendant, $isListItemNode)\n }\n }\n\n if (targetNode != null && targetNode.getTextContentSize() > 0) {\n targetNode.splice(targetNode.getChildrenSize(), 0, [\n $createLineBreakNode(),\n ...elementNode.getChildren(),\n ])\n elementNode.remove()\n }\n }\n }\n}\n\nfunction createTextFormatTransformersIndex(\n textTransformers: Array<TextFormatTransformer>,\n): TextFormatTransformersIndex {\n const transformersByTag: Record<string, TextFormatTransformer> = {}\n const fullMatchRegExpByTag: Record<string, RegExp> = {}\n const openTagsRegExp: string[] = []\n const escapeRegExp = `(?<![\\\\\\\\])`\n\n for (const transformer of textTransformers) {\n const { tag } = transformer\n transformersByTag[tag] = transformer\n const tagRegExp = tag.replace(/([*^+])/g, '\\\\$1')\n openTagsRegExp.push(tagRegExp)\n\n if (IS_SAFARI || IS_IOS || IS_APPLE_WEBKIT) {\n fullMatchRegExpByTag[tag] = new RegExp(\n `(${tagRegExp})(?![${tagRegExp}\\\\s])(.*?[^${tagRegExp}\\\\s])${tagRegExp}(?!${tagRegExp})`,\n )\n } else {\n fullMatchRegExpByTag[tag] = new RegExp(\n `(?<![\\\\\\\\${tagRegExp}])(${tagRegExp})((\\\\\\\\${tagRegExp})?.*?[^${tagRegExp}\\\\s](\\\\\\\\${tagRegExp})?)((?<!\\\\\\\\)|(?<=\\\\\\\\\\\\\\\\))(${tagRegExp})(?![\\\\\\\\${tagRegExp}])`,\n )\n }\n }\n\n return {\n // Reg exp to find open tag + content + close tag\n fullMatchRegExpByTag,\n // Reg exp to find opening tags\n openTagsRegExp: new RegExp(\n (IS_SAFARI || IS_IOS || IS_APPLE_WEBKIT ? '' : `${escapeRegExp}`) +\n '(' +\n openTagsRegExp.join('|') +\n ')',\n 'g',\n ),\n transformersByTag,\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"MarkdownImport.js","names":["$isListItemNode","$isListNode","$isQuoteNode","$findMatchingParent","$createLineBreakNode","$createParagraphNode","$createTextNode","$getRoot","$getSelection","$isParagraphNode","importTextTransformers","isEmptyParagraph","transformersByType","createMarkdownImport","transformers","shouldPreserveNewLines","byType","textFormatTransformersIndex","createTextFormatTransformersIndex","textFormat","markdownString","node","lines","split","linesLength","length","root","clear","i","lineText","imported","shiftedIndex","$importMultiline","multilineElement","$importBlocks","element","textMatch","children","getChildren","child","getChildrenSize","remove","selectStart","startLineIndex","multilineElementTransformers","rootNode","transformer","handleImportAfterStartMatch","regExpEnd","regExpStart","replace","startMatch","match","result","regexpEndRegex","regExp","isEndOptional","optional","endLineIndex","endMatch","index","linesInBetween","push","slice","line","text","elementTransformers","textMatchTransformers","textNode","elementNode","append","setTextContent","isAttached","previousNode","getPreviousSibling","targetNode","lastDescendant","getLastDescendant","getTextContentSize","splice","textTransformers","transformersByTag","fullMatchRegExpByTag","openTagsRegExp","escapeRegExp","tag","tagRegExp","RegExp","join"],"sources":["../../../../src/packages/@lexical/markdown/MarkdownImport.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport type { ListItemNode } from '@lexical/list'\nimport type { ElementNode } from 'lexical'\n\nimport { $isListItemNode, $isListNode } from '@lexical/list'\nimport { $isQuoteNode } from '@lexical/rich-text'\nimport { $findMatchingParent } from '@lexical/utils'\nimport {\n $createLineBreakNode,\n $createParagraphNode,\n $createTextNode,\n $getRoot,\n $getSelection,\n $isParagraphNode,\n} from 'lexical'\n\nimport type {\n ElementTransformer,\n MultilineElementTransformer,\n TextFormatTransformer,\n TextMatchTransformer,\n Transformer,\n} from './MarkdownTransformers.js'\n\nimport { importTextTransformers } from './importTextTransformers.js'\nimport { isEmptyParagraph, transformersByType } from './utils.js'\n\nexport type TextFormatTransformersIndex = Readonly<{\n fullMatchRegExpByTag: Readonly<Record<string, RegExp>>\n openTagsRegExp: RegExp\n transformersByTag: Readonly<Record<string, TextFormatTransformer>>\n}>\n\n/**\n * Renders markdown from a string. The selection is moved to the start after the operation.\n */\nexport function createMarkdownImport(\n transformers: Array<Transformer>,\n shouldPreserveNewLines = false,\n): (markdownString: string, node?: ElementNode) => void {\n const byType = transformersByType(transformers)\n const textFormatTransformersIndex = createTextFormatTransformersIndex(byType.textFormat)\n\n return (markdownString, node) => {\n const lines = markdownString.split('\\n')\n const linesLength = lines.length\n const root = node || $getRoot()\n root.clear()\n\n for (let i = 0; i < linesLength; i++) {\n const lineText = lines[i]!\n\n const [imported, shiftedIndex] = $importMultiline(lines, i, byType.multilineElement, root)\n\n if (imported) {\n // If a multiline markdown element was imported, we don't want to process the lines that were part of it anymore.\n // There could be other sub-markdown elements (both multiline and normal ones) matching within this matched multiline element's children.\n // However, it would be the responsibility of the matched multiline transformer to decide how it wants to handle them.\n // We cannot handle those, as there is no way for us to know how to maintain the correct order of generated lexical nodes for possible children.\n i = shiftedIndex // Next loop will start from the line after the last line of the multiline element\n continue\n }\n\n $importBlocks(lineText, root, byType.element, textFormatTransformersIndex, byType.textMatch)\n }\n\n // By default, removing empty paragraphs as md does not really\n // allow empty lines and uses them as delimiter.\n // If you need empty lines set shouldPreserveNewLines = true.\n const children = root.getChildren()\n for (const child of children) {\n if (!shouldPreserveNewLines && isEmptyParagraph(child) && root.getChildrenSize() > 1) {\n child.remove()\n }\n }\n\n if ($getSelection() !== null) {\n root.selectStart()\n }\n }\n}\n\n/**\n *\n * @returns first element of the returned tuple is a boolean indicating if a multiline element was imported. The second element is the index of the last line that was processed.\n */\nfunction $importMultiline(\n lines: Array<string>,\n startLineIndex: number,\n multilineElementTransformers: Array<MultilineElementTransformer>,\n rootNode: ElementNode,\n): [boolean, number] {\n for (const transformer of multilineElementTransformers) {\n const { handleImportAfterStartMatch, regExpEnd, regExpStart, replace } = transformer\n\n const startMatch = lines[startLineIndex]?.match(regExpStart)\n if (!startMatch) {\n continue // Try next transformer\n }\n\n if (handleImportAfterStartMatch) {\n const result = handleImportAfterStartMatch({\n lines,\n rootNode,\n startLineIndex,\n startMatch,\n transformer,\n })\n if (result === null) {\n continue\n } else if (result) {\n return result\n }\n }\n\n const regexpEndRegex: RegExp | undefined =\n typeof regExpEnd === 'object' && 'regExp' in regExpEnd ? regExpEnd.regExp : regExpEnd\n\n const isEndOptional =\n regExpEnd && typeof regExpEnd === 'object' && 'optional' in regExpEnd\n ? regExpEnd.optional\n : !regExpEnd\n\n let endLineIndex = startLineIndex\n const linesLength = lines.length\n\n // check every single line for the closing match. It could also be on the same line as the opening match.\n while (endLineIndex < linesLength) {\n const endMatch = regexpEndRegex ? lines[endLineIndex]?.match(regexpEndRegex) : null\n if (!endMatch) {\n if (\n !isEndOptional ||\n (isEndOptional && endLineIndex < linesLength - 1) // Optional end, but didn't reach the end of the document yet => continue searching for potential closing match\n ) {\n endLineIndex++\n continue // Search next line for closing match\n }\n }\n\n // Now, check if the closing match matched is the same as the opening match.\n // If it is, we need to continue searching for the actual closing match.\n if (endMatch && startLineIndex === endLineIndex && endMatch.index === startMatch.index) {\n endLineIndex++\n continue // Search next line for closing match\n }\n\n // At this point, we have found the closing match. Next: calculate the lines in between open and closing match\n // This should not include the matches themselves, and be split up by lines\n const linesInBetween: string[] = []\n\n if (endMatch && startLineIndex === endLineIndex) {\n linesInBetween.push(lines[startLineIndex]!.slice(startMatch[0].length, -endMatch[0].length))\n } else {\n for (let i = startLineIndex; i <= endLineIndex; i++) {\n const line = lines[i]!\n if (i === startLineIndex) {\n const text = line.slice(startMatch[0].length)\n linesInBetween.push(text) // Also include empty text\n } else if (i === endLineIndex && endMatch) {\n const text = line.slice(0, -endMatch[0].length)\n linesInBetween.push(text) // Also include empty text\n } else {\n linesInBetween.push(line)\n }\n }\n }\n\n if (replace(rootNode, null, startMatch, endMatch!, linesInBetween, true) !== false) {\n // Return here. This $importMultiline function is run line by line and should only process a single multiline element at a time.\n return [true, endLineIndex]\n }\n\n // The replace function returned false, despite finding the matching open and close tags => this transformer does not want to handle it.\n // Thus, we continue letting the remaining transformers handle the passed lines of text from the beginning\n break\n }\n }\n\n // No multiline transformer handled this line successfully\n return [false, startLineIndex]\n}\n\nfunction $importBlocks(\n lineText: string,\n rootNode: ElementNode,\n elementTransformers: Array<ElementTransformer>,\n textFormatTransformersIndex: TextFormatTransformersIndex,\n textMatchTransformers: Array<TextMatchTransformer>,\n) {\n const textNode = $createTextNode(lineText)\n const elementNode = $createParagraphNode()\n elementNode.append(textNode)\n rootNode.append(elementNode)\n\n for (const { regExp, replace } of elementTransformers) {\n const match = lineText.match(regExp)\n\n if (match) {\n textNode.setTextContent(lineText.slice(match[0].length))\n if (replace(elementNode, [textNode], match, true) !== false) {\n break\n }\n }\n }\n\n importTextTransformers(textNode, textFormatTransformersIndex, textMatchTransformers)\n\n // If no transformer found and we left with original paragraph node\n // can check if its content can be appended to the previous node\n // if it's a paragraph, quote or list\n if (elementNode.isAttached() && lineText.length > 0) {\n const previousNode = elementNode.getPreviousSibling()\n if ($isParagraphNode(previousNode) || $isQuoteNode(previousNode) || $isListNode(previousNode)) {\n let targetNode: ListItemNode | null | typeof previousNode = previousNode\n\n if ($isListNode(previousNode)) {\n const lastDescendant = previousNode.getLastDescendant()\n if (lastDescendant == null) {\n targetNode = null\n } else {\n targetNode = $findMatchingParent(lastDescendant, $isListItemNode)\n }\n }\n\n if (targetNode != null && targetNode.getTextContentSize() > 0) {\n targetNode.splice(targetNode.getChildrenSize(), 0, [\n $createLineBreakNode(),\n ...elementNode.getChildren(),\n ])\n elementNode.remove()\n }\n }\n }\n}\n\nfunction createTextFormatTransformersIndex(\n textTransformers: Array<TextFormatTransformer>,\n): TextFormatTransformersIndex {\n const transformersByTag: Record<string, TextFormatTransformer> = {}\n const fullMatchRegExpByTag: Record<string, RegExp> = {}\n const openTagsRegExp: string[] = []\n const escapeRegExp = `(?<![\\\\\\\\])`\n\n for (const transformer of textTransformers) {\n const { tag } = transformer\n transformersByTag[tag] = transformer\n const tagRegExp = tag.replace(/([*^+])/g, '\\\\$1')\n openTagsRegExp.push(tagRegExp)\n\n // Single-char tag (e.g. \"*\"),\n if (tag.length === 1) {\n fullMatchRegExpByTag[tag] = new RegExp(\n `(?<![\\\\\\\\${tagRegExp}])(${tagRegExp})((\\\\\\\\${tagRegExp})?.*?[^${tagRegExp}\\\\s](\\\\\\\\${tagRegExp})?)((?<!\\\\\\\\)|(?<=\\\\\\\\\\\\\\\\))(${tagRegExp})(?![\\\\\\\\${tagRegExp}])`,\n )\n } else {\n // Multi‐char tags (e.g. \"**\")\n fullMatchRegExpByTag[tag] = new RegExp(\n `(?<!\\\\\\\\)(${tagRegExp})((\\\\\\\\${tagRegExp})?.*?[^\\\\s](\\\\\\\\${tagRegExp})?)((?<!\\\\\\\\)|(?<=\\\\\\\\\\\\\\\\))(${tagRegExp})(?!\\\\\\\\)`,\n )\n }\n }\n\n return {\n // Reg exp to find open tag + content + close tag\n fullMatchRegExpByTag,\n\n // Regexp to locate *any* potential opening tag (longest first).\n // eslint-disable-next-line regexp/no-useless-character-class, regexp/no-empty-capturing-group, regexp/no-empty-group\n openTagsRegExp: new RegExp(`${escapeRegExp}(${openTagsRegExp.join('|')})`, 'g'),\n transformersByTag,\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"importTextTransformers.d.ts","sourceRoot":"","sources":["../../../../src/packages/@lexical/markdown/importTextTransformers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEpD;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAA;AACtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAWrE;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,EAClB,2BAA2B,EAAE,2BAA2B,EACxD,qBAAqB,EAAE,KAAK,CAAC,oBAAoB,CAAC,QAyFnD"}
1
+ {"version":3,"file":"importTextTransformers.d.ts","sourceRoot":"","sources":["../../../../src/packages/@lexical/markdown/importTextTransformers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEpD;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAA;AACtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAWrE;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,EAClB,2BAA2B,EAAE,2BAA2B,EACxD,qBAAqB,EAAE,KAAK,CAAC,oBAAoB,CAAC,QAwFnD"}
@@ -31,7 +31,6 @@ export function importTextTransformers(textNode, textFormatTransformersIndex, te
31
31
  if (result.transformedNode && $isTextNode(result.transformedNode) && !result.transformedNode.hasFormat('code')) {
32
32
  importTextTransformers(result.transformedNode, textFormatTransformersIndex, textMatchTransformers);
33
33
  }
34
- return;
35
34
  } else if (foundTextMatch) {
36
35
  const result = importFoundTextMatchTransformer(textNode, foundTextMatch.startIndex, foundTextMatch.endIndex, foundTextMatch.transformer, foundTextMatch.match);
37
36
  if (!result) {
@@ -46,10 +45,10 @@ export function importTextTransformers(textNode, textFormatTransformersIndex, te
46
45
  if (result.transformedNode && $isTextNode(result.transformedNode) && !result.transformedNode.hasFormat('code')) {
47
46
  importTextTransformers(result.transformedNode, textFormatTransformersIndex, textMatchTransformers);
48
47
  }
49
- return;
50
- } else {
51
- // Done!
52
- return;
53
48
  }
49
+ // Handle escape characters
50
+ const textContent = textNode.getTextContent();
51
+ const escapedText = textContent.replace(/\\([*_`~])/g, '$1');
52
+ textNode.setTextContent(escapedText);
54
53
  }
55
54
  //# sourceMappingURL=importTextTransformers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"importTextTransformers.js","names":["$isTextNode","findOutermostTextFormatTransformer","importTextFormatTransformer","findOutermostTextMatchTransformer","importFoundTextMatchTransformer","importTextTransformers","textNode","textFormatTransformersIndex","textMatchTransformers","foundTextFormat","foundTextMatch","startIndex","endIndex","result","transformer","match","nodeAfter","hasFormat","nodeBefore","transformedNode"],"sources":["../../../../src/packages/@lexical/markdown/importTextTransformers.ts"],"sourcesContent":["import { $isTextNode, type TextNode } from 'lexical'\n\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\nimport type { TextFormatTransformersIndex } from './MarkdownImport.js'\nimport type { TextMatchTransformer } from './MarkdownTransformers.js'\n\nimport {\n findOutermostTextFormatTransformer,\n importTextFormatTransformer,\n} from './importTextFormatTransformer.js'\nimport {\n findOutermostTextMatchTransformer,\n importFoundTextMatchTransformer,\n} from './importTextMatchTransformer.js'\n\n/**\n * Handles applying both text format and text match transformers.\n * It finds the outermost text format or text match and applies it,\n * then recursively calls itself to apply the next outermost transformer,\n * until there are no more transformers to apply.\n */\nexport function importTextTransformers(\n textNode: TextNode,\n textFormatTransformersIndex: TextFormatTransformersIndex,\n textMatchTransformers: Array<TextMatchTransformer>,\n) {\n let foundTextFormat = findOutermostTextFormatTransformer(textNode, textFormatTransformersIndex)\n\n let foundTextMatch = findOutermostTextMatchTransformer(textNode, textMatchTransformers)\n\n if (foundTextFormat && foundTextMatch) {\n // Find the outermost transformer\n if (\n foundTextFormat.startIndex <= foundTextMatch.startIndex &&\n foundTextFormat.endIndex >= foundTextMatch.endIndex\n ) {\n // foundTextFormat wraps foundTextMatch - apply foundTextFormat by setting foundTextMatch to null\n foundTextMatch = null\n } else {\n // foundTextMatch wraps foundTextFormat - apply foundTextMatch by setting foundTextFormat to null\n foundTextFormat = null\n }\n }\n\n if (foundTextFormat) {\n const result = importTextFormatTransformer(\n textNode,\n foundTextFormat.startIndex,\n foundTextFormat.endIndex,\n foundTextFormat.transformer,\n foundTextFormat.match,\n )\n\n if (result.nodeAfter && $isTextNode(result.nodeAfter) && !result.nodeAfter.hasFormat('code')) {\n importTextTransformers(result.nodeAfter, textFormatTransformersIndex, textMatchTransformers)\n }\n if (\n result.nodeBefore &&\n $isTextNode(result.nodeBefore) &&\n !result.nodeBefore.hasFormat('code')\n ) {\n importTextTransformers(result.nodeBefore, textFormatTransformersIndex, textMatchTransformers)\n }\n if (\n result.transformedNode &&\n $isTextNode(result.transformedNode) &&\n !result.transformedNode.hasFormat('code')\n ) {\n importTextTransformers(\n result.transformedNode,\n textFormatTransformersIndex,\n textMatchTransformers,\n )\n }\n return\n } else if (foundTextMatch) {\n const result = importFoundTextMatchTransformer(\n textNode,\n foundTextMatch.startIndex,\n foundTextMatch.endIndex,\n foundTextMatch.transformer,\n foundTextMatch.match,\n )\n if (!result) {\n return\n }\n\n if (result.nodeAfter && $isTextNode(result.nodeAfter) && !result.nodeAfter.hasFormat('code')) {\n importTextTransformers(result.nodeAfter, textFormatTransformersIndex, textMatchTransformers)\n }\n if (\n result.nodeBefore &&\n $isTextNode(result.nodeBefore) &&\n !result.nodeBefore.hasFormat('code')\n ) {\n importTextTransformers(result.nodeBefore, textFormatTransformersIndex, textMatchTransformers)\n }\n if (\n result.transformedNode &&\n $isTextNode(result.transformedNode) &&\n !result.transformedNode.hasFormat('code')\n ) {\n importTextTransformers(\n result.transformedNode,\n textFormatTransformersIndex,\n textMatchTransformers,\n )\n }\n return\n } else {\n // Done!\n return\n }\n}\n"],"mappings":"AAAA,SAASA,WAAW,QAAuB;AAY3C,SACEC,kCAAkC,EAClCC,2BAA2B,QACtB;AACP,SACEC,iCAAiC,EACjCC,+BAA+B,QAC1B;AAEP;;;;;;AAMA,OAAO,SAASC,uBACdC,QAAkB,EAClBC,2BAAwD,EACxDC,qBAAkD;EAElD,IAAIC,eAAA,GAAkBR,kCAAA,CAAmCK,QAAA,EAAUC,2BAAA;EAEnE,IAAIG,cAAA,GAAiBP,iCAAA,CAAkCG,QAAA,EAAUE,qBAAA;EAEjE,IAAIC,eAAA,IAAmBC,cAAA,EAAgB;IACrC;IACA,IACED,eAAA,CAAgBE,UAAU,IAAID,cAAA,CAAeC,UAAU,IACvDF,eAAA,CAAgBG,QAAQ,IAAIF,cAAA,CAAeE,QAAQ,EACnD;MACA;MACAF,cAAA,GAAiB;IACnB,OAAO;MACL;MACAD,eAAA,GAAkB;IACpB;EACF;EAEA,IAAIA,eAAA,EAAiB;IACnB,MAAMI,MAAA,GAASX,2BAAA,CACbI,QAAA,EACAG,eAAA,CAAgBE,UAAU,EAC1BF,eAAA,CAAgBG,QAAQ,EACxBH,eAAA,CAAgBK,WAAW,EAC3BL,eAAA,CAAgBM,KAAK;IAGvB,IAAIF,MAAA,CAAOG,SAAS,IAAIhB,WAAA,CAAYa,MAAA,CAAOG,SAAS,KAAK,CAACH,MAAA,CAAOG,SAAS,CAACC,SAAS,CAAC,SAAS;MAC5FZ,sBAAA,CAAuBQ,MAAA,CAAOG,SAAS,EAAET,2BAAA,EAA6BC,qBAAA;IACxE;IACA,IACEK,MAAA,CAAOK,UAAU,IACjBlB,WAAA,CAAYa,MAAA,CAAOK,UAAU,KAC7B,CAACL,MAAA,CAAOK,UAAU,CAACD,SAAS,CAAC,SAC7B;MACAZ,sBAAA,CAAuBQ,MAAA,CAAOK,UAAU,EAAEX,2BAAA,EAA6BC,qBAAA;IACzE;IACA,IACEK,MAAA,CAAOM,eAAe,IACtBnB,WAAA,CAAYa,MAAA,CAAOM,eAAe,KAClC,CAACN,MAAA,CAAOM,eAAe,CAACF,SAAS,CAAC,SAClC;MACAZ,sBAAA,CACEQ,MAAA,CAAOM,eAAe,EACtBZ,2BAAA,EACAC,qBAAA;IAEJ;IACA;EACF,OAAO,IAAIE,cAAA,EAAgB;IACzB,MAAMG,MAAA,GAAST,+BAAA,CACbE,QAAA,EACAI,cAAA,CAAeC,UAAU,EACzBD,cAAA,CAAeE,QAAQ,EACvBF,cAAA,CAAeI,WAAW,EAC1BJ,cAAA,CAAeK,KAAK;IAEtB,IAAI,CAACF,MAAA,EAAQ;MACX;IACF;IAEA,IAAIA,MAAA,CAAOG,SAAS,IAAIhB,WAAA,CAAYa,MAAA,CAAOG,SAAS,KAAK,CAACH,MAAA,CAAOG,SAAS,CAACC,SAAS,CAAC,SAAS;MAC5FZ,sBAAA,CAAuBQ,MAAA,CAAOG,SAAS,EAAET,2BAAA,EAA6BC,qBAAA;IACxE;IACA,IACEK,MAAA,CAAOK,UAAU,IACjBlB,WAAA,CAAYa,MAAA,CAAOK,UAAU,KAC7B,CAACL,MAAA,CAAOK,UAAU,CAACD,SAAS,CAAC,SAC7B;MACAZ,sBAAA,CAAuBQ,MAAA,CAAOK,UAAU,EAAEX,2BAAA,EAA6BC,qBAAA;IACzE;IACA,IACEK,MAAA,CAAOM,eAAe,IACtBnB,WAAA,CAAYa,MAAA,CAAOM,eAAe,KAClC,CAACN,MAAA,CAAOM,eAAe,CAACF,SAAS,CAAC,SAClC;MACAZ,sBAAA,CACEQ,MAAA,CAAOM,eAAe,EACtBZ,2BAAA,EACAC,qBAAA;IAEJ;IACA;EACF,OAAO;IACL;IACA;EACF;AACF","ignoreList":[]}
1
+ {"version":3,"file":"importTextTransformers.js","names":["$isTextNode","findOutermostTextFormatTransformer","importTextFormatTransformer","findOutermostTextMatchTransformer","importFoundTextMatchTransformer","importTextTransformers","textNode","textFormatTransformersIndex","textMatchTransformers","foundTextFormat","foundTextMatch","startIndex","endIndex","result","transformer","match","nodeAfter","hasFormat","nodeBefore","transformedNode","textContent","getTextContent","escapedText","replace","setTextContent"],"sources":["../../../../src/packages/@lexical/markdown/importTextTransformers.ts"],"sourcesContent":["import { $isTextNode, type TextNode } from 'lexical'\n\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\nimport type { TextFormatTransformersIndex } from './MarkdownImport.js'\nimport type { TextMatchTransformer } from './MarkdownTransformers.js'\n\nimport {\n findOutermostTextFormatTransformer,\n importTextFormatTransformer,\n} from './importTextFormatTransformer.js'\nimport {\n findOutermostTextMatchTransformer,\n importFoundTextMatchTransformer,\n} from './importTextMatchTransformer.js'\n\n/**\n * Handles applying both text format and text match transformers.\n * It finds the outermost text format or text match and applies it,\n * then recursively calls itself to apply the next outermost transformer,\n * until there are no more transformers to apply.\n */\nexport function importTextTransformers(\n textNode: TextNode,\n textFormatTransformersIndex: TextFormatTransformersIndex,\n textMatchTransformers: Array<TextMatchTransformer>,\n) {\n let foundTextFormat = findOutermostTextFormatTransformer(textNode, textFormatTransformersIndex)\n\n let foundTextMatch = findOutermostTextMatchTransformer(textNode, textMatchTransformers)\n\n if (foundTextFormat && foundTextMatch) {\n // Find the outermost transformer\n if (\n foundTextFormat.startIndex <= foundTextMatch.startIndex &&\n foundTextFormat.endIndex >= foundTextMatch.endIndex\n ) {\n // foundTextFormat wraps foundTextMatch - apply foundTextFormat by setting foundTextMatch to null\n foundTextMatch = null\n } else {\n // foundTextMatch wraps foundTextFormat - apply foundTextMatch by setting foundTextFormat to null\n foundTextFormat = null\n }\n }\n\n if (foundTextFormat) {\n const result = importTextFormatTransformer(\n textNode,\n foundTextFormat.startIndex,\n foundTextFormat.endIndex,\n foundTextFormat.transformer,\n foundTextFormat.match,\n )\n\n if (result.nodeAfter && $isTextNode(result.nodeAfter) && !result.nodeAfter.hasFormat('code')) {\n importTextTransformers(result.nodeAfter, textFormatTransformersIndex, textMatchTransformers)\n }\n if (\n result.nodeBefore &&\n $isTextNode(result.nodeBefore) &&\n !result.nodeBefore.hasFormat('code')\n ) {\n importTextTransformers(result.nodeBefore, textFormatTransformersIndex, textMatchTransformers)\n }\n if (\n result.transformedNode &&\n $isTextNode(result.transformedNode) &&\n !result.transformedNode.hasFormat('code')\n ) {\n importTextTransformers(\n result.transformedNode,\n textFormatTransformersIndex,\n textMatchTransformers,\n )\n }\n } else if (foundTextMatch) {\n const result = importFoundTextMatchTransformer(\n textNode,\n foundTextMatch.startIndex,\n foundTextMatch.endIndex,\n foundTextMatch.transformer,\n foundTextMatch.match,\n )\n if (!result) {\n return\n }\n\n if (result.nodeAfter && $isTextNode(result.nodeAfter) && !result.nodeAfter.hasFormat('code')) {\n importTextTransformers(result.nodeAfter, textFormatTransformersIndex, textMatchTransformers)\n }\n if (\n result.nodeBefore &&\n $isTextNode(result.nodeBefore) &&\n !result.nodeBefore.hasFormat('code')\n ) {\n importTextTransformers(result.nodeBefore, textFormatTransformersIndex, textMatchTransformers)\n }\n if (\n result.transformedNode &&\n $isTextNode(result.transformedNode) &&\n !result.transformedNode.hasFormat('code')\n ) {\n importTextTransformers(\n result.transformedNode,\n textFormatTransformersIndex,\n textMatchTransformers,\n )\n }\n }\n // Handle escape characters\n const textContent = textNode.getTextContent()\n const escapedText = textContent.replace(/\\\\([*_`~])/g, '$1')\n textNode.setTextContent(escapedText)\n}\n"],"mappings":"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","ignoreList":[]}
@@ -45,7 +45,7 @@ export async function buildInitialState({
45
45
  if (node.type === 'block') {
46
46
  const currentFieldPreferences = context.preferences?.fields?.[context.field.name];
47
47
  const collapsedArray = currentFieldPreferences?.collapsed;
48
- if (collapsedArray && collapsedArray.includes(id)) {
48
+ if (Array.isArray(collapsedArray) && collapsedArray.includes(id)) {
49
49
  initialState[id].collapsed = true;
50
50
  }
51
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"buildInitialState.js","names":["fieldSchemasToFormState","buildInitialState","context","initialState","initialStateFromArgs","nodeData","node","children","type","blockNode","id","fields","schemaFieldsPath","lexicalFieldSchemaPath","blockType","formStateResult","clientFieldSchemaMap","collectionSlug","data","documentData","fieldSchemaMap","get","initialBlockData","operation","permissions","preferences","renderAllFields","renderFieldFn","req","schemaPath","formState","currentFieldPreferences","field","name","collapsedArray","collapsed","includes"],"sources":["../../src/utilities/buildInitialState.ts"],"sourcesContent":["import type { SerializedLexicalNode } from 'lexical'\nimport type {\n ClientFieldSchemaMap,\n DocumentPreferences,\n FieldSchemaMap,\n FormState,\n Operation,\n PayloadRequest,\n RichTextField,\n SanitizedFieldPermissions,\n} from 'payload'\n\nimport { fieldSchemasToFormState } from '@payloadcms/ui/forms/fieldSchemasToFormState'\n\nimport type { SerializedBlockNode } from '../nodeTypes.js'\n\nexport type InitialLexicalFormState = {\n [nodeID: string]: {\n [key: string]: any\n formState?: FormState\n }\n}\n\ntype Props = {\n context: {\n clientFieldSchemaMap: ClientFieldSchemaMap\n collectionSlug: string\n documentData?: any\n field: RichTextField\n fieldSchemaMap: FieldSchemaMap\n id?: number | string\n lexicalFieldSchemaPath: string\n operation: Operation\n permissions?: SanitizedFieldPermissions\n preferences: DocumentPreferences\n renderFieldFn: any\n req: PayloadRequest\n }\n initialState?: InitialLexicalFormState\n nodeData: SerializedLexicalNode[]\n}\n\nexport async function buildInitialState({\n context,\n initialState: initialStateFromArgs,\n nodeData,\n}: Props): Promise<InitialLexicalFormState> {\n let initialState: InitialLexicalFormState = initialStateFromArgs ?? {}\n for (const node of nodeData) {\n if ('children' in node) {\n initialState = await buildInitialState({\n context,\n initialState,\n nodeData: node.children as SerializedLexicalNode[],\n })\n }\n\n if (node.type === 'block' || node.type === 'inlineBlock') {\n const blockNode = node as SerializedBlockNode\n const id = blockNode?.fields?.id\n if (!id) {\n continue\n }\n\n const schemaFieldsPath =\n node.type === 'block'\n ? `${context.lexicalFieldSchemaPath}.lexical_internal_feature.blocks.lexical_blocks.${blockNode.fields.blockType}.fields`\n : `${context.lexicalFieldSchemaPath}.lexical_internal_feature.blocks.lexical_inline_blocks.${blockNode.fields.blockType}.fields`\n\n // Build form state for the block\n\n const formStateResult = await fieldSchemasToFormState({\n id: context.id,\n clientFieldSchemaMap: context.clientFieldSchemaMap,\n collectionSlug: context.collectionSlug,\n data: blockNode.fields,\n documentData: context.documentData,\n fields: (context.fieldSchemaMap.get(schemaFieldsPath) as any)?.fields,\n fieldSchemaMap: context.fieldSchemaMap,\n initialBlockData: blockNode.fields,\n operation: context.operation as any, // TODO: Type\n permissions: true,\n preferences: context.preferences,\n renderAllFields: true, // If this function runs, the parent lexical field is being re-rendered => thus we can assume all its sub-fields need to be re-rendered\n renderFieldFn: context.renderFieldFn,\n req: context.req,\n schemaPath: schemaFieldsPath,\n })\n\n if (!initialState[id]) {\n initialState[id] = {}\n }\n\n initialState[id].formState = formStateResult\n\n if (node.type === 'block') {\n const currentFieldPreferences = context.preferences?.fields?.[context.field.name]\n const collapsedArray = currentFieldPreferences?.collapsed\n if (collapsedArray && collapsedArray.includes(id)) {\n initialState[id].collapsed = true\n }\n }\n }\n }\n return initialState\n}\n"],"mappings":"AAYA,SAASA,uBAAuB,QAAQ;AA8BxC,OAAO,eAAeC,kBAAkB;EACtCC,OAAO;EACPC,YAAA,EAAcC,oBAAoB;EAClCC;AAAQ,CACF;EACN,IAAIF,YAAA,GAAwCC,oBAAA,IAAwB,CAAC;EACrE,KAAK,MAAME,IAAA,IAAQD,QAAA,EAAU;IAC3B,IAAI,cAAcC,IAAA,EAAM;MACtBH,YAAA,GAAe,MAAMF,iBAAA,CAAkB;QACrCC,OAAA;QACAC,YAAA;QACAE,QAAA,EAAUC,IAAA,CAAKC;MACjB;IACF;IAEA,IAAID,IAAA,CAAKE,IAAI,KAAK,WAAWF,IAAA,CAAKE,IAAI,KAAK,eAAe;MACxD,MAAMC,SAAA,GAAYH,IAAA;MAClB,MAAMI,EAAA,GAAKD,SAAA,EAAWE,MAAA,EAAQD,EAAA;MAC9B,IAAI,CAACA,EAAA,EAAI;QACP;MACF;MAEA,MAAME,gBAAA,GACJN,IAAA,CAAKE,IAAI,KAAK,UACV,GAAGN,OAAA,CAAQW,sBAAsB,mDAAmDJ,SAAA,CAAUE,MAAM,CAACG,SAAS,SAAS,GACvH,GAAGZ,OAAA,CAAQW,sBAAsB,0DAA0DJ,SAAA,CAAUE,MAAM,CAACG,SAAS,SAAS;MAEpI;MAEA,MAAMC,eAAA,GAAkB,MAAMf,uBAAA,CAAwB;QACpDU,EAAA,EAAIR,OAAA,CAAQQ,EAAE;QACdM,oBAAA,EAAsBd,OAAA,CAAQc,oBAAoB;QAClDC,cAAA,EAAgBf,OAAA,CAAQe,cAAc;QACtCC,IAAA,EAAMT,SAAA,CAAUE,MAAM;QACtBQ,YAAA,EAAcjB,OAAA,CAAQiB,YAAY;QAClCR,MAAA,EAAST,OAAA,CAAQkB,cAAc,CAACC,GAAG,CAACT,gBAAA,GAA2BD,MAAA;QAC/DS,cAAA,EAAgBlB,OAAA,CAAQkB,cAAc;QACtCE,gBAAA,EAAkBb,SAAA,CAAUE,MAAM;QAClCY,SAAA,EAAWrB,OAAA,CAAQqB,SAAS;QAC5BC,WAAA,EAAa;QACbC,WAAA,EAAavB,OAAA,CAAQuB,WAAW;QAChCC,eAAA,EAAiB;QACjBC,aAAA,EAAezB,OAAA,CAAQyB,aAAa;QACpCC,GAAA,EAAK1B,OAAA,CAAQ0B,GAAG;QAChBC,UAAA,EAAYjB;MACd;MAEA,IAAI,CAACT,YAAY,CAACO,EAAA,CAAG,EAAE;QACrBP,YAAY,CAACO,EAAA,CAAG,GAAG,CAAC;MACtB;MAEAP,YAAY,CAACO,EAAA,CAAG,CAACoB,SAAS,GAAGf,eAAA;MAE7B,IAAIT,IAAA,CAAKE,IAAI,KAAK,SAAS;QACzB,MAAMuB,uBAAA,GAA0B7B,OAAA,CAAQuB,WAAW,EAAEd,MAAA,GAAST,OAAA,CAAQ8B,KAAK,CAACC,IAAI,CAAC;QACjF,MAAMC,cAAA,GAAiBH,uBAAA,EAAyBI,SAAA;QAChD,IAAID,cAAA,IAAkBA,cAAA,CAAeE,QAAQ,CAAC1B,EAAA,GAAK;UACjDP,YAAY,CAACO,EAAA,CAAG,CAACyB,SAAS,GAAG;QAC/B;MACF;IACF;EACF;EACA,OAAOhC,YAAA;AACT","ignoreList":[]}
1
+ {"version":3,"file":"buildInitialState.js","names":["fieldSchemasToFormState","buildInitialState","context","initialState","initialStateFromArgs","nodeData","node","children","type","blockNode","id","fields","schemaFieldsPath","lexicalFieldSchemaPath","blockType","formStateResult","clientFieldSchemaMap","collectionSlug","data","documentData","fieldSchemaMap","get","initialBlockData","operation","permissions","preferences","renderAllFields","renderFieldFn","req","schemaPath","formState","currentFieldPreferences","field","name","collapsedArray","collapsed","Array","isArray","includes"],"sources":["../../src/utilities/buildInitialState.ts"],"sourcesContent":["import type { SerializedLexicalNode } from 'lexical'\nimport type {\n ClientFieldSchemaMap,\n DocumentPreferences,\n FieldSchemaMap,\n FormState,\n Operation,\n PayloadRequest,\n RichTextField,\n SanitizedFieldPermissions,\n} from 'payload'\n\nimport { fieldSchemasToFormState } from '@payloadcms/ui/forms/fieldSchemasToFormState'\n\nimport type { SerializedBlockNode } from '../nodeTypes.js'\n\nexport type InitialLexicalFormState = {\n [nodeID: string]: {\n [key: string]: any\n formState?: FormState\n }\n}\n\ntype Props = {\n context: {\n clientFieldSchemaMap: ClientFieldSchemaMap\n collectionSlug: string\n documentData?: any\n field: RichTextField\n fieldSchemaMap: FieldSchemaMap\n id?: number | string\n lexicalFieldSchemaPath: string\n operation: Operation\n permissions?: SanitizedFieldPermissions\n preferences: DocumentPreferences\n renderFieldFn: any\n req: PayloadRequest\n }\n initialState?: InitialLexicalFormState\n nodeData: SerializedLexicalNode[]\n}\n\nexport async function buildInitialState({\n context,\n initialState: initialStateFromArgs,\n nodeData,\n}: Props): Promise<InitialLexicalFormState> {\n let initialState: InitialLexicalFormState = initialStateFromArgs ?? {}\n for (const node of nodeData) {\n if ('children' in node) {\n initialState = await buildInitialState({\n context,\n initialState,\n nodeData: node.children as SerializedLexicalNode[],\n })\n }\n\n if (node.type === 'block' || node.type === 'inlineBlock') {\n const blockNode = node as SerializedBlockNode\n const id = blockNode?.fields?.id\n if (!id) {\n continue\n }\n\n const schemaFieldsPath =\n node.type === 'block'\n ? `${context.lexicalFieldSchemaPath}.lexical_internal_feature.blocks.lexical_blocks.${blockNode.fields.blockType}.fields`\n : `${context.lexicalFieldSchemaPath}.lexical_internal_feature.blocks.lexical_inline_blocks.${blockNode.fields.blockType}.fields`\n\n // Build form state for the block\n\n const formStateResult = await fieldSchemasToFormState({\n id: context.id,\n clientFieldSchemaMap: context.clientFieldSchemaMap,\n collectionSlug: context.collectionSlug,\n data: blockNode.fields,\n documentData: context.documentData,\n fields: (context.fieldSchemaMap.get(schemaFieldsPath) as any)?.fields,\n fieldSchemaMap: context.fieldSchemaMap,\n initialBlockData: blockNode.fields,\n operation: context.operation as any, // TODO: Type\n permissions: true,\n preferences: context.preferences,\n renderAllFields: true, // If this function runs, the parent lexical field is being re-rendered => thus we can assume all its sub-fields need to be re-rendered\n renderFieldFn: context.renderFieldFn,\n req: context.req,\n schemaPath: schemaFieldsPath,\n })\n\n if (!initialState[id]) {\n initialState[id] = {}\n }\n\n initialState[id].formState = formStateResult\n\n if (node.type === 'block') {\n const currentFieldPreferences = context.preferences?.fields?.[context.field.name]\n const collapsedArray = currentFieldPreferences?.collapsed\n if (Array.isArray(collapsedArray) && collapsedArray.includes(id)) {\n initialState[id].collapsed = true\n }\n }\n }\n }\n return initialState\n}\n"],"mappings":"AAYA,SAASA,uBAAuB,QAAQ;AA8BxC,OAAO,eAAeC,kBAAkB;EACtCC,OAAO;EACPC,YAAA,EAAcC,oBAAoB;EAClCC;AAAQ,CACF;EACN,IAAIF,YAAA,GAAwCC,oBAAA,IAAwB,CAAC;EACrE,KAAK,MAAME,IAAA,IAAQD,QAAA,EAAU;IAC3B,IAAI,cAAcC,IAAA,EAAM;MACtBH,YAAA,GAAe,MAAMF,iBAAA,CAAkB;QACrCC,OAAA;QACAC,YAAA;QACAE,QAAA,EAAUC,IAAA,CAAKC;MACjB;IACF;IAEA,IAAID,IAAA,CAAKE,IAAI,KAAK,WAAWF,IAAA,CAAKE,IAAI,KAAK,eAAe;MACxD,MAAMC,SAAA,GAAYH,IAAA;MAClB,MAAMI,EAAA,GAAKD,SAAA,EAAWE,MAAA,EAAQD,EAAA;MAC9B,IAAI,CAACA,EAAA,EAAI;QACP;MACF;MAEA,MAAME,gBAAA,GACJN,IAAA,CAAKE,IAAI,KAAK,UACV,GAAGN,OAAA,CAAQW,sBAAsB,mDAAmDJ,SAAA,CAAUE,MAAM,CAACG,SAAS,SAAS,GACvH,GAAGZ,OAAA,CAAQW,sBAAsB,0DAA0DJ,SAAA,CAAUE,MAAM,CAACG,SAAS,SAAS;MAEpI;MAEA,MAAMC,eAAA,GAAkB,MAAMf,uBAAA,CAAwB;QACpDU,EAAA,EAAIR,OAAA,CAAQQ,EAAE;QACdM,oBAAA,EAAsBd,OAAA,CAAQc,oBAAoB;QAClDC,cAAA,EAAgBf,OAAA,CAAQe,cAAc;QACtCC,IAAA,EAAMT,SAAA,CAAUE,MAAM;QACtBQ,YAAA,EAAcjB,OAAA,CAAQiB,YAAY;QAClCR,MAAA,EAAST,OAAA,CAAQkB,cAAc,CAACC,GAAG,CAACT,gBAAA,GAA2BD,MAAA;QAC/DS,cAAA,EAAgBlB,OAAA,CAAQkB,cAAc;QACtCE,gBAAA,EAAkBb,SAAA,CAAUE,MAAM;QAClCY,SAAA,EAAWrB,OAAA,CAAQqB,SAAS;QAC5BC,WAAA,EAAa;QACbC,WAAA,EAAavB,OAAA,CAAQuB,WAAW;QAChCC,eAAA,EAAiB;QACjBC,aAAA,EAAezB,OAAA,CAAQyB,aAAa;QACpCC,GAAA,EAAK1B,OAAA,CAAQ0B,GAAG;QAChBC,UAAA,EAAYjB;MACd;MAEA,IAAI,CAACT,YAAY,CAACO,EAAA,CAAG,EAAE;QACrBP,YAAY,CAACO,EAAA,CAAG,GAAG,CAAC;MACtB;MAEAP,YAAY,CAACO,EAAA,CAAG,CAACoB,SAAS,GAAGf,eAAA;MAE7B,IAAIT,IAAA,CAAKE,IAAI,KAAK,SAAS;QACzB,MAAMuB,uBAAA,GAA0B7B,OAAA,CAAQuB,WAAW,EAAEd,MAAA,GAAST,OAAA,CAAQ8B,KAAK,CAACC,IAAI,CAAC;QACjF,MAAMC,cAAA,GAAiBH,uBAAA,EAAyBI,SAAA;QAChD,IAAIC,KAAA,CAAMC,OAAO,CAACH,cAAA,KAAmBA,cAAA,CAAeI,QAAQ,CAAC5B,EAAA,GAAK;UAChEP,YAAY,CAACO,EAAA,CAAG,CAACyB,SAAS,GAAG;QAC/B;MACF;IACF;EACF;EACA,OAAOhC,YAAA;AACT","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/richtext-lexical",
3
- "version": "3.29.0-internal.e4e913b",
3
+ "version": "3.29.0",
4
4
  "description": "The officially supported Lexical richtext adapter for Payload",
5
5
  "homepage": "https://payloadcms.com",
6
6
  "repository": {
@@ -364,8 +364,8 @@
364
364
  "react-error-boundary": "4.1.2",
365
365
  "ts-essentials": "10.0.3",
366
366
  "uuid": "10.0.0",
367
- "@payloadcms/translations": "3.29.0-internal.e4e913b",
368
- "@payloadcms/ui": "3.29.0-internal.e4e913b"
367
+ "@payloadcms/translations": "3.29.0",
368
+ "@payloadcms/ui": "3.29.0"
369
369
  },
370
370
  "devDependencies": {
371
371
  "@babel/cli": "7.26.4",
@@ -385,16 +385,16 @@
385
385
  "esbuild-sass-plugin": "3.3.1",
386
386
  "eslint-plugin-react-compiler": "19.0.0-beta-714736e-20250131",
387
387
  "swc-plugin-transform-remove-imports": "3.1.0",
388
- "@payloadcms/eslint-config": "3.28.0",
389
- "payload": "3.29.0-internal.e4e913b"
388
+ "payload": "3.29.0",
389
+ "@payloadcms/eslint-config": "3.28.0"
390
390
  },
391
391
  "peerDependencies": {
392
392
  "@faceless-ui/modal": "3.0.0-beta.2",
393
393
  "@faceless-ui/scroll-info": "2.0.0",
394
394
  "react": "^19.0.0 || ^19.0.0-rc-65a56d0e-20241020",
395
395
  "react-dom": "^19.0.0 || ^19.0.0-rc-65a56d0e-20241020",
396
- "@payloadcms/next": "3.29.0-internal.e4e913b",
397
- "payload": "3.29.0-internal.e4e913b"
396
+ "@payloadcms/next": "3.29.0",
397
+ "payload": "3.29.0"
398
398
  },
399
399
  "engines": {
400
400
  "node": "^18.20.2 || >=20.9.0"
@@ -1,12 +0,0 @@
1
- var R=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";var j=class{_x;_y;constructor(t,e){this._x=t,this._y=e}calcDeltaXTo({x:t}){return this.x-t}calcDeltaYTo({y:t}){return this.y-t}calcDistanceTo(t){return Math.sqrt(Math.pow(this.calcDeltaXTo(t),2)+Math.pow(this.calcDeltaYTo(t),2))}calcHorizontalDistanceTo(t){return Math.abs(this.calcDeltaXTo(t))}calcVerticalDistance(t){return Math.abs(this.calcDeltaYTo(t))}equals({x:t,y:e}){return this.x===t&&this.y===e}get x(){return this._x}get y(){return this._y}};function ft(r){return r instanceof j}import{c as Oe}from"react/compiler-runtime";import{jsx as ye}from"react/jsx-runtime";import{useLexicalComposerContext as be}from"@lexical/react/LexicalComposerContext.js";import{mergeRegister as ke}from"@lexical/utils";import{$getSelection as Z,$isRangeSelection as J,$isTextNode as Me,COMMAND_PRIORITY_LOW as Le,createCommand as $e,getDOMSelection as De}from"lexical";import{useEffect as Tt,useState as Be}from"react";import*as V from"react";import{c as pt}from"react/compiler-runtime";import{useLexicalComposerContext as ht}from"@lexical/react/LexicalComposerContext.js";import{mergeRegister as ut}from"@lexical/utils";import{$getSelection as xt,$isRangeSelection as ue,$setSelection as de,COMMAND_PRIORITY_LOW as M,createCommand as me,KEY_ARROW_DOWN_COMMAND as ge,KEY_ARROW_UP_COMMAND as pe,KEY_ENTER_COMMAND as he,KEY_ESCAPE_COMMAND as xe,KEY_TAB_COMMAND as Ee}from"lexical";import{useCallback as q,useEffect as L,useLayoutEffect as _e,useMemo as Te,useRef as Se,useState as we}from"react";var Re="slash-menu-popup",dt=r=>{let t=document.getElementById("slash-menu");if(!t)return;let e=t.getBoundingClientRect();e.top+e.height>window.innerHeight&&t.scrollIntoView({block:"center"}),e.top<0&&t.scrollIntoView({block:"center"}),r.scrollIntoView({block:"nearest"})};function Ce(r,t,e){let o=e;for(let n=o;n<=t.length;n++)r.substring(r.length-n)===t.substring(0,n)&&(o=n);return o}function Ie(r){let t=xt();if(!ue(t)||!t.isCollapsed())return;let e=t.anchor;if(e.type!=="text")return;let o=e.getNode();if(!o.isSimpleText())return;let n=e.offset,i=o.getTextContent().slice(0,n),c=r.replaceableString.length,s=Ce(i,r.matchingString,c),a=n-s;if(a<0)return;let f;return a===0?[f]=o.splitText(n):[,f]=o.splitText(a,n),f}function Fe(r,t){let e=getComputedStyle(r),o=e.position==="absolute",n=t?/(auto|scroll|hidden)/:/(auto|scroll)/;if(e.position==="fixed")return document.body;for(let i=r;i=i.parentElement;)if(e=getComputedStyle(i),!(o&&e.position==="static")&&n.test(e.overflow+e.overflowY+e.overflowX))return i;return document.body}function mt(r,t){let e=r.getBoundingClientRect(),o=t.getBoundingClientRect();return e.top>o.top&&e.top<o.bottom}function Ne(r,t,e,o){let n=pt(12),[i]=ht(),c;n[0]!==i||n[1]!==e||n[2]!==o||n[3]!==r||n[4]!==t.current?(c=()=>{let a=t.current;if(a!=null&&r!=null){let f=i.getRootElement(),l=f!=null?Fe(f,!1):document.body,m;m=!1;let g;g=mt(a,l);let p=function(){m||(window.requestAnimationFrame(function(){e(),m=!1}),m=!0);let u=mt(a,l);u!==g&&(g=u,o?.(u))},d=new ResizeObserver(e);return window.addEventListener("resize",e),document.addEventListener("scroll",p,{capture:!0,passive:!0}),d.observe(a),()=>{d.disconnect(),window.removeEventListener("resize",e),document.removeEventListener("scroll",p,!0)}}},n[0]=i,n[1]=e,n[2]=o,n[3]=r,n[4]=t.current,n[5]=c):c=n[5];let s;n[6]!==i||n[7]!==e||n[8]!==o||n[9]!==r||n[10]!==t?(s=[i,o,e,r,t],n[6]=i,n[7]=e,n[8]=o,n[9]=r,n[10]=t,n[11]=s):s=n[11],L(c,s)}var gt=me("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");function Et({anchorElementRef:r,close:t,editor:e,groups:o,menuRenderFn:n,resolution:i,shouldSplitNodeWithQuery:c=!1}){let[s,a]=we(null),f=i.match&&i.match.matchingString||"",l=q(d=>{let u=e.getRootElement();u!==null&&(u.setAttribute("aria-activedescendant",`${Re}__item-${d.key}`),a(d.key))},[e]),m=q(()=>{if(o!==null&&f!=null){let d=o.flatMap(u=>u.items);if(d.length){let u=d[0];l(u)}}},[o,l,f]);L(()=>{m()},[f,m]);let g=q(d=>{t(),e.update(()=>{let u=i.match!=null&&c?Ie(i.match):null;u&&u.remove()}),setTimeout(()=>{let u;e.read(()=>{u=xt()?.clone()}),e.update(()=>{u&&de(u)}),d.onSelect({editor:e,queryString:i.match?i.match.matchingString:""})},0)},[e,c,i.match,t]);L(()=>()=>{let d=e.getRootElement();d!==null&&d.removeAttribute("aria-activedescendant")},[e]),_e(()=>{o===null?a(null):s===null&&m()},[o,s,l,m]),L(()=>ut(e.registerCommand(gt,({item:d})=>d.ref&&d.ref.current!=null?(dt(d.ref.current),!0):!1,M)),[e,l]),L(()=>ut(e.registerCommand(ge,d=>{let u=d;if(o!==null&&o.length&&s!==null){let x=o.flatMap(T=>T.items),h=x.findIndex(T=>T.key===s),E=h!==x.length-1?h+1:0,_=x[E];if(!_)return!1;l(_),_.ref!=null&&_.ref.current&&e.dispatchCommand(gt,{index:E,item:_}),u.preventDefault(),u.stopImmediatePropagation()}return!0},M),e.registerCommand(pe,d=>{let u=d;if(o!==null&&o.length&&s!==null){let x=o.flatMap(T=>T.items),h=x.findIndex(T=>T.key===s),E=h!==0?h-1:x.length-1,_=x[E];if(!_)return!1;l(_),_.ref!=null&&_.ref.current&&dt(_.ref.current),u.preventDefault(),u.stopImmediatePropagation()}return!0},M),e.registerCommand(xe,d=>{let u=d;return u.preventDefault(),u.stopImmediatePropagation(),t(),!0},M),e.registerCommand(Ee,d=>{let u=d;if(o===null||s===null)return!1;let h=o.flatMap(E=>E.items).find(E=>E.key===s);return h?(u.preventDefault(),u.stopImmediatePropagation(),g(h),!0):!1},M),e.registerCommand(he,d=>{if(o===null||s===null)return!1;let x=o.flatMap(h=>h.items).find(h=>h.key===s);return x?(d!==null&&(d.preventDefault(),d.stopImmediatePropagation()),g(x),!0):!1},M)),[g,t,e,o,s,l]);let p=Te(()=>({groups:o,selectedItemKey:s,selectItemAndCleanUp:g,setSelectedItemKey:a}),[g,s,o]);return n(r,p,i.match?i.match.matchingString:"")}function Ae(r,t){t!=null&&(r.className=t),r.setAttribute("aria-label","Slash menu"),r.setAttribute("role","listbox"),r.style.display="block",r.style.position="absolute"}function _t(r,t,e,o){let n=pt(14),[i]=ht(),c;n[0]===Symbol.for("react.memo_cache_sentinel")?(c=R?document.createElement("div"):null,n[0]=c):c=n[0];let s=Se(c),a;n[1]!==r||n[2]!==o||n[3]!==i||n[4]!==t?(a=()=>{if(s.current===null||parent===void 0)return;let d=i.getRootElement(),u=s.current,x=u.firstChild;if(d!==null&&t!==null){let{height:h,width:E}=t.getRect(),{left:_,top:T}=t.getRect(),N=T;if(T=T-(r.getBoundingClientRect().top+window.scrollY),_=_-(r.getBoundingClientRect().left+window.scrollX),u.style.left=`${_+window.scrollX}px`,u.style.height=`${h}px`,u.style.width=`${E}px`,x!==null){let S=x.getBoundingClientRect(),F=S.height,w=S.width,A=d.getBoundingClientRect();_+w>A.right&&(u.style.left=`${A.right-w+window.scrollX}px`);let O=N+F+32>window.innerHeight,b=N<0;O&&!b?u.style.top=`${T+32-F+window.scrollY-(h+24)}px`:u.style.top=`${T+window.scrollY+32}px`}u.isConnected||(Ae(u,o),r.append(u)),u.setAttribute("id","slash-menu"),s.current=u,d.setAttribute("aria-controls","slash-menu")}},n[1]=r,n[2]=o,n[3]=i,n[4]=t,n[5]=a):a=n[5];let f=a,l,m;n[6]!==i||n[7]!==f||n[8]!==t?(l=()=>{let d=i.getRootElement();if(t!==null)return f(),()=>{d!==null&&d.removeAttribute("aria-controls");let u=s.current;u!==null&&u.isConnected&&(u.remove(),u.removeAttribute("id"))}},m=[i,f,t],n[6]=i,n[7]=f,n[8]=t,n[9]=l,n[10]=m):(l=n[9],m=n[10]),L(l,m);let g;return n[11]!==t||n[12]!==e?(g=d=>{t!==null&&(d||e(null))},n[11]=t,n[12]=e,n[13]=g):g=n[13],Ne(t,s,f,g),s}var so=`\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'"~=<>_:;`;function Pe(r){let t=r.anchor;if(t.type!=="text")return null;let e=t.getNode();if(!e.isSimpleText())return null;let o=t.offset;return e.getTextContent().slice(0,o)}function St(r,t,e){let o=De(e);if(o===null||!o.isCollapsed)return!1;let n=o.anchorNode,i=r,c=o.anchorOffset;if(n==null||c==null)return!1;try{t.setStart(n,i),t.setEnd(n,c>1?c:1)}catch{return!1}return!0}function ve(r){let t;return r.getEditorState().read(()=>{let e=Z();J(e)&&(t=Pe(e))}),t}function wt(r,t){return t!==0?!1:r.getEditorState().read(()=>{let e=Z();if(J(e)){let i=e.anchor.getNode().getPreviousSibling();return Me(i)&&i.isTextEntity()}return!1})}function Rt(r){V.startTransition?V.startTransition(r):r()}var He=$e("ENABLE_SLASH_MENU_COMMAND");function co(r){let t=Oe(30),{anchorClassName:e,anchorElem:o,groups:n,menuRenderFn:i,onClose:c,onOpen:s,onQueryChange:a,triggerFn:f}=r,[l]=be(),[m,g]=Be(null),p=_t(o,m,g,e),d;t[0]!==c||t[1]!==m?(d=()=>{g(null),c!=null&&m!==null&&c()},t[0]=c,t[1]=m,t[2]=d):d=t[2];let u=d,x;t[3]!==s||t[4]!==m?(x=F=>{g(F),s!=null&&m===null&&s(F)},t[3]=s,t[4]=m,t[5]=x):x=t[5];let h=x,E,_;t[6]!==l||t[7]!==h?(E=()=>ke(l.registerCommand(He,F=>{let{node:w}=F;return l.getEditorState().read(()=>{let A={leadOffset:0,matchingString:"",replaceableString:""};if(!wt(l,A.leadOffset)&&w!==null){let O=l._window??window,b=O.document.createRange();St(A.leadOffset,b,O)!==null&&Rt(()=>h({getRect:()=>b.getBoundingClientRect(),match:A}));return}}),!0},Le)),_=[l,h],t[6]=l,t[7]=h,t[8]=E,t[9]=_):(E=t[8],_=t[9]),Tt(E,_);let T;t[10]!==u||t[11]!==l||t[12]!==a||t[13]!==h||t[14]!==f?(T=()=>{let F=()=>{l.getEditorState().read(()=>{let A=l._window??window,O=A.document.createRange(),b=Z(),Q=ve(l);if(!J(b)||!b.isCollapsed()||Q===void 0||O===null){u();return}let k=f({editor:l,query:Q});if(a(k?k.matchingString:null),k!==null&&!wt(l,k.leadOffset)&&St(k.leadOffset,O,A)!==null){Rt(()=>h({getRect:()=>O.getBoundingClientRect(),match:k}));return}u()})},w=l.registerUpdateListener(F);return()=>{w()}},t[10]=u,t[11]=l,t[12]=a,t[13]=h,t[14]=f,t[15]=T):T=t[15];let N;t[16]!==u||t[17]!==l||t[18]!==a||t[19]!==h||t[20]!==m||t[21]!==f?(N=[l,f,a,m,u,h],t[16]=u,t[17]=l,t[18]=a,t[19]=h,t[20]=m,t[21]=f,t[22]=N):N=t[22],Tt(T,N);let S;return t[23]!==p||t[24]!==u||t[25]!==l||t[26]!==n||t[27]!==i||t[28]!==m?(S=p.current===null||m===null||l===null?null:ye(Et,{anchorElementRef:p,close:u,editor:l,groups:n,menuRenderFn:i,resolution:m,shouldSplitNodeWithQuery:!0}),t[23]=p,t[24]=u,t[25]=l,t[26]=n,t[27]=i,t[28]=m,t[29]=S):S=t[29],S}var Ct=class r{_bottom;_left;_right;_top;constructor(t,e,o,n){let[i,c]=e<=n?[e,n]:[n,e],[s,a]=t<=o?[t,o]:[o,t];this._top=i,this._right=a,this._left=s,this._bottom=c}static fromDOM(t){let{height:e,left:o,top:n,width:i}=t.getBoundingClientRect();return r.fromLWTH(o,i,n,e)}static fromDOMRect(t){let{height:e,left:o,top:n,width:i}=t;return r.fromLWTH(o,i,n,e)}static fromLTRB(t,e,o,n){return new r(t,e,o,n)}static fromLWTH(t,e,o,n){return new r(t,o,t+e,o+n)}static fromPoints(t,e){let{x:o,y:n}=t,{x:i,y:c}=e;return r.fromLTRB(o,n,i,c)}contains(t){if(ft(t)){let{x:c,y:s}=t,a=s<this._top,f=s>this._bottom,l=c<this._left,m=c>this._right;return{reason:{isOnBottomSide:f,isOnLeftSide:l,isOnRightSide:m,isOnTopSide:a},result:!a&&!f&&!l&&!m}}let{bottom:e,left:o,right:n,top:i}=t;return i>=this._top&&i<=this._bottom&&e>=this._top&&e<=this._bottom&&o>=this._left&&o<=this._right&&n>=this._left&&n<=this._right}distanceFromPoint(t){let e=this.contains(t);if(e.result)return{distance:0,isOnBottomSide:e.reason.isOnBottomSide,isOnLeftSide:e.reason.isOnLeftSide,isOnRightSide:e.reason.isOnRightSide,isOnTopSide:e.reason.isOnTopSide};let o=0,n=0;return t.x<this._left?o=this._left-t.x:t.x>this._right&&(o=t.x-this._right),t.y<this._top?n=this._top-t.y:t.y>this._bottom&&(n=t.y-this._bottom),{distance:Math.sqrt(o*o+n*n),isOnBottomSide:t.y>this._bottom,isOnLeftSide:t.x<this._left,isOnRightSide:t.x>this._right,isOnTopSide:t.y<this._top}}equals({bottom:t,left:e,right:o,top:n}){return n===this._top&&t===this._bottom&&e===this._left&&o===this._right}generateNewRect({bottom:t=this.bottom,left:e=this.left,right:o=this.right,top:n=this.top}){return new r(e,n,o,t)}intersectsWith(t){let{height:e,left:o,top:n,width:i}=t,{height:c,left:s,top:a,width:f}=this,l=o+i>=s+f?o+i:s+f,m=n+e>=a+c?n+e:a+c,g=o<=s?o:s,p=n<=a?n:a;return l-g<=i+f&&m-p<=e+c}get bottom(){return this._bottom}get height(){return Math.abs(this._bottom-this._top)}get left(){return this._left}get right(){return this._right}get top(){return this._top}get width(){return Math.abs(this._left-this._right)}};function uo({editorConfig:r}){return Ke({nodes:r.features.nodes})}function Ke({nodes:r}){return r.map(t=>"node"in t?t.node:t)}var Ue=R&&"documentMode"in document?document.documentMode:null,po=R&&/Mac|iPod|iPhone|iPad/.test(navigator.platform),ho=R&&/^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent),xo=R&&"InputEvent"in window&&!Ue?"getTargetRanges"in new window.InputEvent("input"):!1,tt=R&&/Version\/[\d.].*Safari/.test(navigator.userAgent),et=R&&/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream,Eo=R&&/Android/.test(navigator.userAgent),_o=R&&/Win/.test(navigator.platform),Ge=R&&/^(?=.*Chrome).*/i.test(navigator.userAgent),nt=R&&/AppleWebKit\/[\d.]+/.test(navigator.userAgent)&&!Ge;import{$getRoot as Ze,$isDecoratorNode as Ot,$isElementNode as G,$isLineBreakNode as Je,$isTextNode as W}from"lexical";import{$isListItemNode as We,$isListNode as It}from"@lexical/list";import{$isHeadingNode as Xe,$isQuoteNode as ze}from"@lexical/rich-text";import{$isParagraphNode as Ye,$isTextNode as Qe}from"lexical";var C={markdownFormatKind:null,regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:!1},I={...C,requiresParagraphStart:!0},Co={...I,export:$(1),markdownFormatKind:"paragraphH1",regEx:/^# /,regExForAutoFormatting:/^# /},Io={...I,export:$(2),markdownFormatKind:"paragraphH2",regEx:/^## /,regExForAutoFormatting:/^## /},Fo={...I,export:$(3),markdownFormatKind:"paragraphH3",regEx:/^### /,regExForAutoFormatting:/^### /},No={...I,export:$(4),markdownFormatKind:"paragraphH4",regEx:/^#### /,regExForAutoFormatting:/^#### /},Ao={...I,export:$(5),markdownFormatKind:"paragraphH5",regEx:/^##### /,regExForAutoFormatting:/^##### /},Oo={...I,export:$(6),markdownFormatKind:"paragraphH6",regEx:/^###### /,regExForAutoFormatting:/^###### /},yo={...I,export:qe,markdownFormatKind:"paragraphBlockQuote",regEx:/^> /,regExForAutoFormatting:/^> /},bo={...I,export:ot,markdownFormatKind:"paragraphUnorderedList",regEx:/^(\s{0,10})- /,regExForAutoFormatting:/^(\s{0,10})- /},ko={...I,export:ot,markdownFormatKind:"paragraphUnorderedList",regEx:/^(\s{0,10})\* /,regExForAutoFormatting:/^(\s{0,10})\* /},Mo={...I,export:ot,markdownFormatKind:"paragraphOrderedList",regEx:/^(\s{0,10})(\d+)\.\s/,regExForAutoFormatting:/^(\s{0,10})(\d+)\.\s/},Lo={...I,markdownFormatKind:"horizontalRule",regEx:/^\*\*\*$/,regExForAutoFormatting:/^\*\*\* /},$o={...I,markdownFormatKind:"horizontalRule",regEx:/^---$/,regExForAutoFormatting:/^--- /},Do={...C,exportFormat:"code",exportTag:"`",markdownFormatKind:"code",regEx:/(`)(\s*)([^`]*)(\s*)(`)()/,regExForAutoFormatting:/(`)(\s*\b)([^`]*)(\b\s*)(`)(\s)$/},Bo={...C,exportFormat:"bold",exportTag:"**",markdownFormatKind:"bold",regEx:/(\*\*)(\s*)([^*]*)(\s*)(\*\*)()/,regExForAutoFormatting:/(\*\*)(\s*\b)([^*]*)(\b\s*)(\*\*)(\s)$/},Po={...C,exportFormat:"italic",exportTag:"*",markdownFormatKind:"italic",regEx:/(\*)(\s*)([^*]*)(\s*)(\*)()/,regExForAutoFormatting:/(\*)(\s*\b)([^*]*)(\b\s*)(\*)(\s)$/},vo={...C,exportFormat:"bold",exportTag:"_",markdownFormatKind:"bold",regEx:/(__)(\s*)([^_]*)(\s*)(__)()/,regExForAutoFormatting:/(__)(\s*)([^_]*)(\s*)(__)(\s)$/},Ho={...C,exportFormat:"italic",exportTag:"_",markdownFormatKind:"italic",regEx:/(_)()([^_]*)()(_)()/,regExForAutoFormatting:/(_)()([^_]*)()(_)(\s)$/},Ko={...C,exportFormat:"underline",exportTag:"<u>",exportTagClose:"</u>",markdownFormatKind:"underline",regEx:/(<u>)(\s*)([^<]*)(\s*)(<\/u>)()/,regExForAutoFormatting:/(<u>)(\s*\b)([^<]*)(\b\s*)(<\/u>)(\s)$/},Uo={...C,exportFormat:"strikethrough",exportTag:"~~",markdownFormatKind:"strikethrough",regEx:/(~~)(\s*)([^~]*)(\s*)(~~)()/,regExForAutoFormatting:/(~~)(\s*\b)([^~]*)(\b\s*)(~~)(\s)$/},Go={...C,markdownFormatKind:"strikethrough_italic_bold",regEx:/(~~_\*\*)(\s*\b)([^*_~]+)(\b\s*)(\*\*_~~)()/,regExForAutoFormatting:/(~~_\*\*)(\s*\b)([^*_~]+)(\b\s*)(\*\*_~~)(\s)$/},Wo={...C,markdownFormatKind:"italic_bold",regEx:/(_\*\*)(\s*\b)([^*_]+)(\b\s*)(\*\*_)/,regExForAutoFormatting:/(_\*\*)(\s*\b)([^*_]+)(\b\s*)(\*\*_)(\s)$/},Xo={...C,markdownFormatKind:"strikethrough_italic",regEx:/(~~_)(\s*)([^_~]+)(\s*)(_~~)/,regExForAutoFormatting:/(~~_)(\s*)([^_~]+)(\s*)(_~~)(\s)$/},zo={...C,markdownFormatKind:"strikethrough_bold",regEx:/(~~\*\*)(\s*\b)([^*~]+)(\b\s*)(\*\*~~)/,regExForAutoFormatting:/(~~\*\*)(\s*\b)([^*~]+)(\b\s*)(\*\*~~)(\s)$/},Yo={...C,markdownFormatKind:"link",regEx:/(\[)([^\]]*)(\]\()([^)]*)(\)*)()/,regExForAutoFormatting:/(\[)([^\]]*)(\]\()([^)]*)(\)*)(\s)$/};function $(r){return(t,e)=>Xe(t)&&t.getTag()==="h"+r?"#".repeat(r)+" "+e(t):null}function ot(r,t){return It(r)?Ft(r,t,0):null}var je=4;function Ft(r,t,e){let o=[],n=r.getChildren(),i=0;for(let c of n)if(We(c)){if(c.getChildrenSize()===1){let f=c.getFirstChild();if(It(f)){o.push(Ft(f,t,e+1));continue}}let s=" ".repeat(e*je),a=r.getListType()==="bullet"?"- ":`${r.getStart()+i}. `;o.push(s+a+t(c)),i++}return o.join(`
2
- `)}function qe(r,t){return ze(r)?"> "+t(r):null}function K(r,t){let e={};for(let o of r){let n=t(o);n&&(e[n]?e[n].push(o):e[n]=[o])}return e}function D(r){let t=K(r,e=>e.type);return{element:t.element||[],multilineElement:t["multiline-element"]||[],textFormat:t["text-format"]||[],textMatch:t["text-match"]||[]}}var B=/[!-/:-@[-`{-~\s]/,Ve=/^\s{0,3}$/;function H(r){if(!Ye(r))return!1;let t=r.getFirstChild();return t==null||r.getChildrenSize()===1&&Qe(t)&&Ve.test(t.getTextContent())}function yt(r,t=!1){let e=D(r),o=[...e.multilineElement,...e.element],n=!t,i=e.textFormat.filter(c=>c.format.length===1).sort((c,s)=>c.format.includes("code")&&!s.format.includes("code")?1:!c.format.includes("code")&&s.format.includes("code")?-1:0);return c=>{let s=[],a=(c||Ze()).getChildren();return a.forEach((f,l)=>{let m=tn(f,o,i,e.textMatch);m!=null&&s.push(n&&l>0&&!H(f)&&!H(a[l-1])?`
3
- `.concat(m):m)}),s.join(`
4
- `)}}function tn(r,t,e,o){for(let n of t){if(!n.export)continue;let i=n.export(r,c=>X(c,e,o));if(i!=null)return i}return G(r)?X(r,e,o):Ot(r)?r.getTextContent():null}function X(r,t,e,o,n){let i=[],c=r.getChildren();o||(o=[]),n||(n=[]);t:for(let s of c){for(let a of e){if(!a.export)continue;let f=a.export(s,l=>X(l,t,e,o,[...n,...o]),(l,m)=>Nt(l,m,t,o,n));if(f!=null){i.push(f);continue t}}Je(s)?i.push(`
5
- `):W(s)?i.push(Nt(s,s.getTextContent(),t,o,n)):G(s)?i.push(X(s,t,e,o,n)):Ot(s)&&i.push(s.getTextContent())}return i.join("")}function Nt(r,t,e,o,n){let i=t.trim(),c=i,s="",a="",f="",l=At(r,!0),m=At(r,!1),g=new Set;for(let p of e){let d=p.format[0],u=p.tag;U(r,d)&&!g.has(d)&&(g.add(d),(!U(l,d)||!o.find(x=>x.tag===u))&&(o.push({format:d,tag:u}),s+=u))}for(let p=0;p<o.length;p++){let d=o[p],u=U(r,d.format),x=U(m,d.format);if(u&&x)continue;let h=[...o];for(;h.length>p;){let E=h.pop();n&&E&&n.find(_=>_.tag===E.tag)||(E&&typeof E.tag=="string"&&(u?x||(f+=E.tag):a+=E.tag),o.pop())}break}return c=s+c+f,a+t.replace(i,()=>c)}function At(r,t){let e=t?r.getPreviousSibling():r.getNextSibling();if(!e){let o=r.getParentOrThrow();o.isInline()&&(e=t?o.getPreviousSibling():o.getNextSibling())}for(;e;){if(G(e)){if(!e.isInline())break;let o=t?e.getLastDescendant():e.getFirstDescendant();if(W(o))return o;e=t?e.getPreviousSibling():e.getNextSibling()}if(W(e))return e;if(!G(e))return null}return null}function U(r,t){return W(r)&&r.hasFormat(t)}import{$isListItemNode as nn,$isListNode as $t}from"@lexical/list";import{$isQuoteNode as on}from"@lexical/rich-text";import{$findMatchingParent as rn}from"@lexical/utils";import{$createLineBreakNode as sn,$createParagraphNode as cn,$createTextNode as an,$getRoot as ln,$getSelection as fn,$isParagraphNode as un}from"lexical";import{$isTextNode as P}from"lexical";function bt(r,t){let e=r.getTextContent(),o=en(e,t);if(!o)return null;let n=o.index||0,i=n+o[0].length,c=t.transformersByTag[o[1]];return{endIndex:i,match:o,startIndex:n,transformer:c}}function en(r,t){let e=r.match(t.openTagsRegExp);if(e==null)return null;for(let o of e){let n=o.replace(/^\s/,""),i=t.fullMatchRegExpByTag[n];if(i==null)continue;let c=r.match(i),s=t.transformersByTag[n];if(c!=null&&s!=null){if(s.intraword!==!1)return c;let{index:a=0}=c,f=r[a-1],l=r[a+c[0].length];if((!f||B.test(f))&&(!l||B.test(l)))return c}}return null}function kt(r,t,e,o,n){let i=r.getTextContent(),c,s,a;if(n[0]===i?a=r:t===0?[a,c]=r.splitText(e):[s,a,c]=r.splitText(t,e),a.setTextContent(n[2]),o)for(let f of o.format)a.hasFormat(f)||a.toggleFormat(f);return{nodeAfter:c,nodeBefore:s,transformedNode:a}}function Mt(r,t){let e=r,o,n,i,c;for(let s of t){if(!s.replace||!s.importRegExp)continue;let a=e.getTextContent().match(s.importRegExp);if(!a)continue;let f=a.index||0,l=s.getEndIndex?s.getEndIndex(e,a):f+a[0].length;l!==!1&&(o===void 0||n===void 0||f<o&&l>n)&&(o=f,n=l,i=s,c=a)}return o===void 0||n===void 0||i===void 0||c===void 0?null:{endIndex:n,match:c,startIndex:o,transformer:i}}function Lt(r,t,e,o,n){let i,c,s;if(t===0?[s,i]=r.splitText(e):[c,s,i]=r.splitText(t,e),!o.replace)return null;let a=s?o.replace(s,n):void 0;return{nodeAfter:i,nodeBefore:c,transformedNode:a||void 0}}function y(r,t,e){let o=bt(r,t),n=Mt(r,e);if(o&&n&&(o.startIndex<=n.startIndex&&o.endIndex>=n.endIndex?n=null:o=null),o){let i=kt(r,o.startIndex,o.endIndex,o.transformer,o.match);i.nodeAfter&&P(i.nodeAfter)&&!i.nodeAfter.hasFormat("code")&&y(i.nodeAfter,t,e),i.nodeBefore&&P(i.nodeBefore)&&!i.nodeBefore.hasFormat("code")&&y(i.nodeBefore,t,e),i.transformedNode&&P(i.transformedNode)&&!i.transformedNode.hasFormat("code")&&y(i.transformedNode,t,e);return}else if(n){let i=Lt(r,n.startIndex,n.endIndex,n.transformer,n.match);if(!i)return;i.nodeAfter&&P(i.nodeAfter)&&!i.nodeAfter.hasFormat("code")&&y(i.nodeAfter,t,e),i.nodeBefore&&P(i.nodeBefore)&&!i.nodeBefore.hasFormat("code")&&y(i.nodeBefore,t,e),i.transformedNode&&P(i.transformedNode)&&!i.transformedNode.hasFormat("code")&&y(i.transformedNode,t,e);return}else return}function Dt(r,t=!1){let e=D(r),o=gn(e.textFormat);return(n,i)=>{let c=n.split(`
6
- `),s=c.length,a=i||ln();a.clear();for(let l=0;l<s;l++){let m=c[l],[g,p]=dn(c,l,e.multilineElement,a);if(g){l=p;continue}mn(m,a,e.element,o,e.textMatch)}let f=a.getChildren();for(let l of f)!t&&H(l)&&a.getChildrenSize()>1&&l.remove();fn()!==null&&a.selectStart()}}function dn(r,t,e,o){for(let n of e){let{handleImportAfterStartMatch:i,regExpEnd:c,regExpStart:s,replace:a}=n,f=r[t]?.match(s);if(!f)continue;if(i){let d=i({lines:r,rootNode:o,startLineIndex:t,startMatch:f,transformer:n});if(d===null)continue;if(d)return d}let l=typeof c=="object"&&"regExp"in c?c.regExp:c,m=c&&typeof c=="object"&&"optional"in c?c.optional:!c,g=t,p=r.length;for(;g<p;){let d=l?r[g]?.match(l):null;if(!d&&(!m||m&&g<p-1)){g++;continue}if(d&&t===g&&d.index===f.index){g++;continue}let u=[];if(d&&t===g)u.push(r[t].slice(f[0].length,-d[0].length));else for(let x=t;x<=g;x++){let h=r[x];if(x===t){let E=h.slice(f[0].length);u.push(E)}else if(x===g&&d){let E=h.slice(0,-d[0].length);u.push(E)}else u.push(h)}if(a(o,null,f,d,u,!0)!==!1)return[!0,g];break}}return[!1,t]}function mn(r,t,e,o,n){let i=an(r),c=cn();c.append(i),t.append(c);for(let{regExp:s,replace:a}of e){let f=r.match(s);if(f&&(i.setTextContent(r.slice(f[0].length)),a(c,[i],f,!0)!==!1))break}if(y(i,o,n),c.isAttached()&&r.length>0){let s=c.getPreviousSibling();if(un(s)||on(s)||$t(s)){let a=s;if($t(s)){let f=s.getLastDescendant();f==null?a=null:a=rn(f,nn)}a!=null&&a.getTextContentSize()>0&&(a.splice(a.getChildrenSize(),0,[sn(),...c.getChildren()]),c.remove())}}}function gn(r){let t={},e={},o=[],n="(?<![\\\\])";for(let i of r){let{tag:c}=i;t[c]=i;let s=c.replace(/([*^+])/g,"\\$1");o.push(s),tt||et||nt?e[c]=new RegExp(`(${s})(?![${s}\\s])(.*?[^${s}\\s])${s}(?!${s})`):e[c]=new RegExp(`(?<![\\\\${s}])(${s})((\\\\${s})?.*?[^${s}\\s](\\\\${s})?)((?<!\\\\)|(?<=\\\\\\\\))(${s})(?![\\\\${s}])`)}return{fullMatchRegExpByTag:e,openTagsRegExp:new RegExp((tt||et||nt?"":`${n}`)+"("+o.join("|")+")","g"),transformersByTag:t}}import{$createRangeSelection as pn,$getSelection as rt,$isLineBreakNode as hn,$isRangeSelection as it,$isRootOrShadowRoot as Pt,$isTextNode as vt,$setSelection as xn}from"lexical";function En(r,t,e,o){let n=r.getParent();if(!Pt(n)||r.getFirstChild()!==t)return!1;let i=t.getTextContent();if(i[e-1]!==" ")return!1;for(let{regExp:c,replace:s}of o){let a=i.match(c);if(a&&a[0].length===(a[0].endsWith(" ")?e:e-1)){let f=t.getNextSiblings(),[l,m]=t.splitText(e);l?.remove();let g=m?[m,...f]:f;if(s(r,g,a,!1)!==!1)return!0}}return!1}function _n(r,t,e,o){let n=r.getParent();if(!Pt(n)||r.getFirstChild()!==t)return!1;let i=t.getTextContent();if(i[e-1]!==" ")return!1;for(let{regExpEnd:c,regExpStart:s,replace:a}of o){if(c&&!("optional"in c)||c&&"optional"in c&&!c.optional)continue;let f=i.match(s);if(f&&f[0].length===(f[0].endsWith(" ")?e:e-1)){let l=t.getNextSiblings(),[m,g]=t.splitText(e);m?.remove();let p=g?[g,...l]:l;if(a(r,p,f,null,null,!1)!==!1)return!0}}return!1}function Tn(r,t,e){let o=r.getTextContent(),n=o[t-1],i=e[n];if(i==null)return!1;t<o.length&&(o=o.slice(0,t));for(let c of i){if(!c.replace||!c.regExp)continue;let s=o.match(c.regExp);if(s===null)continue;let a=s.index||0,f=a+s[0].length,l;return a===0?[l]=r.splitText(f):[,l]=r.splitText(a,f),l&&(l.selectNext(0,0),c.replace(l,s)),!0}return!1}function Sn(r,t,e){let o=r.getTextContent(),n=t-1,i=o[n],c=e[i];if(!c)return!1;for(let s of c){let{tag:a}=s,f=a.length,l=n-f+1;if(f>1&&!Ht(o,l,a,0,f)||o[l-1]===" ")continue;let m=o[n+1];if(s.intraword===!1&&m&&!B.test(m))continue;let g=r,p=g,d=Bt(o,l,a),u=p;for(;d<0&&(u=u.getPreviousSibling())&&!hn(u);)if(vt(u)){let w=u.getTextContent();p=u,d=Bt(w,w.length,a)}if(d<0||p===g&&d+f===l)continue;let x=p.getTextContent();if(d>0&&x[d-1]===i)continue;let h=x[d-1];if(s.intraword===!1&&h&&!B.test(h))continue;let E=g.getTextContent(),_=E.slice(0,l)+E.slice(n+1);g.setTextContent(_);let T=p===g?_:x;p.setTextContent(T.slice(0,d)+T.slice(d+f));let N=rt(),S=pn();xn(S);let F=n-f*(p===g?2:1)+1;S.anchor.set(p.__key,d,"text"),S.focus.set(g.__key,F,"text");for(let w of s.format)S.hasFormat(w)||S.formatText(w);S.anchor.set(S.focus.key,S.focus.offset,S.focus.type);for(let w of s.format)S.hasFormat(w)&&S.toggleFormat(w);return it(N)&&(S.format=N.format),!0}return!1}function Bt(r,t,e){let o=e.length;for(let n=t;n>=o;n--){let i=n-o;if(Ht(r,i,e,0,o)&&r[i+o]!==" ")return i}return-1}function Ht(r,t,e,o,n){for(let i=0;i<n;i++)if(r[t+i]!==e[o+i])return!1;return!0}function hr(r,t=z){let e=D(t),o=K(e.textFormat,({tag:c})=>c[c.length-1]),n=K(e.textMatch,({trigger:c})=>c);for(let c of t){let s=c.type;if(s==="element"||s==="text-match"||s==="multiline-element"){let a=c.dependencies;for(let f of a)if(!r.hasNode(f))throw new Error("MarkdownShortcuts: missing dependency %s for transformer. Ensure node dependency is included in editor initial config."+f.getType())}}let i=(c,s,a)=>{En(c,s,a,e.element)||_n(c,s,a,e.multilineElement)||Tn(s,a,n)||Sn(s,a,o)};return r.registerUpdateListener(({dirtyLeaves:c,editorState:s,prevEditorState:a,tags:f})=>{if(f.has("collaboration")||f.has("historic")||r.isComposing())return;let l=s.read(rt),m=a.read(rt);if(!it(m)||!it(l)||!l.isCollapsed()||l.is(m))return;let g=l.anchor.key,p=l.anchor.offset,d=s._nodeMap.get(g);!vt(d)||!c.has(g)||p!==1&&p>m.anchor.offset+1||r.update(()=>{if(d.hasFormat("code"))return;let u=d.getParent();u!==null&&i(u,d,l.anchor.offset)})})}import{$createListItemNode as wn,$createListNode as Rn,$isListItemNode as Cn,$isListNode as v,ListItemNode as ct,ListNode as at}from"@lexical/list";import{$createHeadingNode as In,$createQuoteNode as Fn,$isHeadingNode as Nn,$isQuoteNode as Kt,HeadingNode as An,QuoteNode as On}from"@lexical/rich-text";import{$createLineBreakNode as yn}from"lexical";var Ut=/^[\t ]*$/,zt=/^(\s*)(\d+)\.\s/,Yt=/^(\s*)[-*+]\s/,Qt=/^(\s*)(?:-\s)?\s?(\[(\s|x)?\])\s/i,st=/^(#{1,6})\s/,jt=/^>\s/,bn=/^[ \t]*(\\`\\`\\`|```)(\w+)?/,Gt=/[ \t]*(\\`\\`\\`|```)$/,kn=/^[ \t]*```[^`]+(?:(?:`{1,2}|`{4,})[^`]+)*```(?:[^`]|$)/,Mn=/^\|(.+)\|\s?$/,Ln=/^(\| ?:?-*:? ?)+\|\s?$/,Wt=/^[ \t]*<[a-z_][\w-]*(?:\s[^<>]*)?\/?>/i,Xt=/^[ \t]*<\/[a-z_][\w-]*\s*>/i,$n=r=>(t,e,o)=>{let n=r(o);n.append(...e),t.replace(n),n.select(0,0)},qt=4;function Dn(r){let t=r.match(/\t/g),e=r.match(/ /g),o=0;return t&&(o+=t.length),e&&(o+=Math.floor(e.length/qt)),o}var lt=r=>(t,e,o)=>{let n=t.getPreviousSibling(),i=t.getNextSibling(),c=wn(r==="check"?o[3]==="x":void 0);if(v(i)&&i.getListType()===r){let a=i.getFirstChild();a!==null?a.insertBefore(c):i.append(c),t.remove()}else if(v(n)&&n.getListType()===r)n.append(c),t.remove();else{let a=Rn(r,r==="number"?Number(o[2]):void 0);a.append(c),t.replace(a)}c.append(...e),c.select(0,0);let s=Dn(o[1]);s&&c.setIndent(s)},Y=(r,t,e)=>{let o=[],n=r.getChildren(),i=0;for(let c of n)if(Cn(c)){if(c.getChildrenSize()===1){let l=c.getFirstChild();if(v(l)){o.push(Y(l,t,e+1));continue}}let s=" ".repeat(e*qt),a=r.getListType(),f=a==="number"?`${r.getStart()+i}. `:a==="check"?`- [${c.getChecked()?"x":" "}] `:"- ";o.push(s+f+t(c)),i++}return o.join(`
7
- `)},Vt={type:"element",dependencies:[An],export:(r,t)=>{if(!Nn(r))return null;let e=Number(r.getTag().slice(1));return"#".repeat(e)+" "+t(r)},regExp:st,replace:$n(r=>{let t="h"+r[1].length;return In(t)})},Zt={type:"element",dependencies:[On],export:(r,t)=>{if(!Kt(r))return null;let e=t(r).split(`
8
- `),o=[];for(let n of e)o.push("> "+n);return o.join(`
9
- `)},regExp:jt,replace:(r,t,e,o)=>{if(o){let i=r.getPreviousSibling();if(Kt(i)){i.splice(i.getChildrenSize(),0,[yn(),...t]),i.select(0,0),r.remove();return}}let n=Fn();n.append(...t),r.replace(n),n.select(0,0)}},Jt={type:"element",dependencies:[at,ct],export:(r,t)=>v(r)?Y(r,t,0):null,regExp:Yt,replace:lt("bullet")},Bn={type:"element",dependencies:[at,ct],export:(r,t)=>v(r)?Y(r,t,0):null,regExp:Qt,replace:lt("check")},te={type:"element",dependencies:[at,ct],export:(r,t)=>v(r)?Y(r,t,0):null,regExp:zt,replace:lt("number")},ee={type:"text-format",format:["code"],tag:"`"},ne={type:"text-format",format:["highlight"],tag:"=="},oe={type:"text-format",format:["bold","italic"],tag:"***"},re={type:"text-format",format:["bold","italic"],intraword:!1,tag:"___"},ie={type:"text-format",format:["bold"],tag:"**"},se={type:"text-format",format:["bold"],intraword:!1,tag:"__"},ce={type:"text-format",format:["strikethrough"],tag:"~~"},ae={type:"text-format",format:["italic"],tag:"*"},le={type:"text-format",format:["italic"],intraword:!1,tag:"_"};function fe(r,t){let e=r.split(`
10
- `),o=!1,n=[],i=0;for(let c=0;c<e.length;c++){let s=e[c],a=n[n.length-1];if(kn.test(s)){n.push(s);continue}if(Gt.test(s)){i===0&&(o=!0),i===1&&(o=!1),i>0&&i--,n.push(s);continue}if(bn.test(s)){o=!0,i++,n.push(s);continue}if(o){n.push(s);continue}Ut.test(s)||Ut.test(a)||!a||st.test(a)||st.test(s)||jt.test(s)||zt.test(s)||Yt.test(s)||Qt.test(s)||Mn.test(s)||Ln.test(s)||!t||Wt.test(s)||Xt.test(s)||Wt.test(a)||Xt.test(a)||Gt.test(a)?n.push(s):n[n.length-1]=a+" "+s.trim()}return n.join(`
11
- `)}var Pn=[Vt,Zt,Jt,te],vn=[],Hn=[ee,oe,re,ie,se,ne,ae,le,ce],Kn=[],z=[...Pn,...vn,...Hn,...Kn];function Ir(r,t=z,e,o=!1,n=!0){let i=o?r:fe(r,n);return Dt(t,o)(i,e)}function Fr(r=z,t,e=!1){return yt(r,e)(t)}export{R as a,po as b,hr as c,Ir as d,Fr as e,j as f,ft as g,so as h,He as i,co as j,Ct as k,uo as l};
12
- //# sourceMappingURL=chunk-XO6X2M3F.js.map