@payloadcms/richtext-lexical 3.71.0-internal.cbf546e → 3.71.0-internal.ef75fa0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/exports/client/Field-2A2VQXKP.js +2 -0
  2. package/dist/exports/client/Field-2A2VQXKP.js.map +7 -0
  3. package/dist/exports/client/bundled.css +1 -1
  4. package/dist/exports/client/chunk-AFXLIYGL.js +12 -0
  5. package/dist/exports/client/chunk-AFXLIYGL.js.map +7 -0
  6. package/dist/exports/client/index.d.ts +0 -1
  7. package/dist/exports/client/index.d.ts.map +1 -1
  8. package/dist/exports/client/index.js +20 -20
  9. package/dist/exports/client/index.js.map +3 -3
  10. package/dist/exports/react/index.d.ts +1 -1
  11. package/dist/exports/react/index.d.ts.map +1 -1
  12. package/dist/exports/react/index.js.map +1 -1
  13. package/dist/features/converters/lexicalToJSX/Component/index.d.ts +14 -2
  14. package/dist/features/converters/lexicalToJSX/Component/index.d.ts.map +1 -1
  15. package/dist/features/converters/lexicalToJSX/Component/index.js +2 -4
  16. package/dist/features/converters/lexicalToJSX/Component/index.js.map +1 -1
  17. package/dist/features/converters/lexicalToJSX/converter/index.d.ts +1 -16
  18. package/dist/features/converters/lexicalToJSX/converter/index.d.ts.map +1 -1
  19. package/dist/features/converters/lexicalToJSX/converter/index.js +4 -76
  20. package/dist/features/converters/lexicalToJSX/converter/index.js.map +1 -1
  21. package/dist/features/converters/lexicalToJSX/converter/types.d.ts +10 -14
  22. package/dist/features/converters/lexicalToJSX/converter/types.d.ts.map +1 -1
  23. package/dist/features/converters/lexicalToJSX/converter/types.js.map +1 -1
  24. package/dist/features/debug/jsxConverter/client/plugin/index.js +1 -1
  25. package/dist/features/debug/jsxConverter/client/plugin/index.js.map +1 -1
  26. package/dist/field/Field.d.ts.map +1 -1
  27. package/dist/field/Field.js +6 -11
  28. package/dist/field/Field.js.map +1 -1
  29. package/dist/field/bundled.css +1 -1
  30. package/dist/field/index.d.ts +0 -1
  31. package/dist/field/index.d.ts.map +1 -1
  32. package/dist/field/index.js +29 -47
  33. package/dist/field/index.js.map +1 -1
  34. package/dist/field/rscEntry.d.ts +1 -1
  35. package/dist/field/rscEntry.d.ts.map +1 -1
  36. package/dist/field/rscEntry.js +0 -12
  37. package/dist/field/rscEntry.js.map +1 -1
  38. package/dist/index.d.ts +1 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +1 -3
  41. package/dist/index.js.map +1 -1
  42. package/dist/lexical/LexicalEditor.d.ts.map +1 -1
  43. package/dist/lexical/LexicalEditor.js +1 -2
  44. package/dist/lexical/LexicalEditor.js.map +1 -1
  45. package/dist/lexical/LexicalProvider.d.ts.map +1 -1
  46. package/dist/lexical/LexicalProvider.js +3 -12
  47. package/dist/lexical/LexicalProvider.js.map +1 -1
  48. package/dist/lexical/config/client/sanitize.d.ts +1 -1
  49. package/dist/lexical/config/client/sanitize.d.ts.map +1 -1
  50. package/dist/lexical/config/client/sanitize.js +2 -3
  51. package/dist/lexical/config/client/sanitize.js.map +1 -1
  52. package/dist/lexical/config/types.d.ts +0 -4
  53. package/dist/lexical/config/types.d.ts.map +1 -1
  54. package/dist/lexical/config/types.js.map +1 -1
  55. package/dist/lexical/nodes/index.d.ts +2 -12
  56. package/dist/lexical/nodes/index.d.ts.map +1 -1
  57. package/dist/lexical/nodes/index.js +2 -195
  58. package/dist/lexical/nodes/index.js.map +1 -1
  59. package/dist/types.d.ts +2 -152
  60. package/dist/types.d.ts.map +1 -1
  61. package/dist/types.js.map +1 -1
  62. package/dist/utilities/generateImportMap.d.ts.map +1 -1
  63. package/dist/utilities/generateImportMap.js +0 -1
  64. package/dist/utilities/generateImportMap.js.map +1 -1
  65. package/dist/validate/hasText.d.ts +1 -6
  66. package/dist/validate/hasText.d.ts.map +1 -1
  67. package/dist/validate/hasText.js +4 -10
  68. package/dist/validate/hasText.js.map +1 -1
  69. package/package.json +6 -11
  70. package/dist/exports/client/Field-YM44WOON.js +0 -2
  71. package/dist/exports/client/Field-YM44WOON.js.map +0 -7
  72. package/dist/exports/client/chunk-6NIGQP6A.js +0 -12
  73. package/dist/exports/client/chunk-6NIGQP6A.js.map +0 -7
  74. package/dist/exports/client/internal-client.d.ts +0 -3
  75. package/dist/exports/client/internal-client.d.ts.map +0 -1
  76. package/dist/field/RichTextViewProvider.d.ts +0 -83
  77. package/dist/field/RichTextViewProvider.d.ts.map +0 -1
  78. package/dist/field/RichTextViewProvider.js +0 -87
  79. package/dist/field/RichTextViewProvider.js.map +0 -1
  80. package/dist/field/ViewSelector.d.ts +0 -4
  81. package/dist/field/ViewSelector.d.ts.map +0 -1
  82. package/dist/field/ViewSelector.js +0 -89
  83. package/dist/field/ViewSelector.js.map +0 -1
  84. package/dist/lexical/plugins/NodeViewOverridePlugin/index.d.ts +0 -2
  85. package/dist/lexical/plugins/NodeViewOverridePlugin/index.d.ts.map +0 -1
  86. package/dist/lexical/plugins/NodeViewOverridePlugin/index.js +0 -48
  87. package/dist/lexical/plugins/NodeViewOverridePlugin/index.js.map +0 -1
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/lexical/utils/canUseDOM.ts", "../../../src/utilities/useRunDeprioritized.ts", "../../../src/field/RichTextViewProvider.tsx", "../../../src/lexical/utils/point.ts", "../../../src/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/index.tsx", "../../../src/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu.tsx", "../../../src/lexical/utils/rect.ts", "../../../src/lexical/nodes/index.ts", "../../../src/packages/@lexical/markdown/MarkdownExport.ts", "../../../src/packages/@lexical/markdown/utils.ts", "../../../src/packages/@lexical/markdown/MarkdownImport.ts", "../../../src/packages/@lexical/markdown/importTextTransformers.ts", "../../../src/packages/@lexical/markdown/importTextFormatTransformer.ts", "../../../src/packages/@lexical/markdown/importTextMatchTransformer.ts", "../../../src/packages/@lexical/markdown/MarkdownShortcuts.ts", "../../../src/packages/@lexical/markdown/MarkdownTransformers.ts", "../../../src/packages/@lexical/markdown/index.ts"],
4
- "sourcesContent": ["'use client'\nexport const CAN_USE_DOM: boolean =\n typeof window !== 'undefined' &&\n typeof window.document !== 'undefined' &&\n typeof window.document.createElement !== 'undefined'\n", "'use client'\nimport { useCallback, useRef } from 'react'\n\n/**\n * Simple hook that lets you run any callback once the main thread is idle\n * (via `requestIdleCallback`) or when that API is missing (Safari) - after the\n * next animation frame (`interactionResponse`).\n *\n * This will help you to avoid blocking the main thread with heavy work.\n *\n * The latest invocation wins: if a new run is queued before the previous one\n * executes, the previous task is cancelled.\n *\n * Usage:\n * ```ts\n * const runDeprioritized = useRunDeprioritized();\n *\n * const onEditorChange = (state: EditorState) => {\n * runDeprioritized(() => {\n * // heavy work here …\n * });\n * };\n * ```\n *\n * @param timeout Optional timeout (ms) for `requestIdleCallback`; defaults to 500 ms.\n * @returns A `runDeprioritized(fn)` helper.\n */\n\nexport function useRunDeprioritized(timeout = 500) {\n const idleHandleRef = useRef<number>(undefined)\n\n /**\n * Schedule `fn` and resolve when it has executed.\n */\n const runDeprioritized = useCallback(\n (fn: () => void): Promise<void> => {\n return new Promise<void>((resolve) => {\n const exec = () => {\n fn()\n resolve()\n }\n\n if ('requestIdleCallback' in window) {\n // Cancel any previously queued task so only the latest runs.\n if ('cancelIdleCallback' in window && idleHandleRef.current !== undefined) {\n // Cancel earlier scheduled value updates,\n // so that a CPU-limited event loop isn't flooded with n callbacks for n keystrokes into the rich text field,\n // but that there's only ever the latest one state update\n // dispatch task, to be executed with the next idle time,\n // or the deadline of 500ms.\n cancelIdleCallback(idleHandleRef.current)\n }\n // Schedule the state update to happen the next time the browser has sufficient resources,\n // or the latest after 500ms.\n idleHandleRef.current = requestIdleCallback(exec, { timeout })\n } else {\n // Safari fallback: rAF + setTimeout shim.\n void interactionResponse().then(exec)\n }\n })\n },\n [timeout],\n )\n\n return runDeprioritized\n}\n\nfunction interactionResponse(): Promise<unknown> {\n // Taken from https://github.com/vercel-labs/await-interaction-response/tree/main/packages/await-interaction-response/src\n\n return new Promise((resolve) => {\n setTimeout(resolve, 100) // Fallback for the case where the animation frame never fires.\n requestAnimationFrame(() => {\n setTimeout(resolve, 0)\n })\n })\n}\n", "'use client'\nimport { useControllableState } from '@payloadcms/ui'\nimport React, { createContext, use, useMemo } from 'react'\n\nimport type { LexicalEditorNodeMap, LexicalEditorViewMap } from '../types.js'\n\n/**\n * Context type for rich text view management.\n */\ntype RichTextViewContextType = {\n /**\n * The name of the currently active view (e.g., 'default', 'frontend', 'debug')\n */\n currentView: string\n /**\n * The node map for the currently active view, containing rendering overrides for each node type.\n * This is the resolved view from the views map based on currentView.\n */\n currentViewMap?: LexicalEditorNodeMap\n /**\n * If true, the current view will be inherited by nested richtext editors.\n */\n inheritable?: boolean\n /**\n * Function to change the current view.\n */\n setCurrentView: (view: string) => void\n /**\n * The complete map of all available views for this field.\n */\n views?: LexicalEditorViewMap\n}\n\nconst RichTextViewContext = createContext<RichTextViewContextType>({\n currentView: 'default',\n inheritable: false,\n setCurrentView: () => {},\n})\n\n/**\n * Provider component for rich text view context.\n *\n * This provider manages the current view state internally and makes it accessible to child components\n * via the useRichTextView hook. It automatically resolves the current view's node map\n * based on the active view name.\n *\n * @example\n * ```tsx\n * <RichTextViewProvider\n * currentView=\"frontend\"\n * views={myViews}\n * >\n * <MyEditor />\n * </RichTextViewProvider>\n * ```\n */\nexport const RichTextViewProvider: React.FC<{\n children: React.ReactNode\n currentView?: string\n inheritable?: boolean\n views?: LexicalEditorViewMap\n}> = (args) => {\n const parentContext = useRichTextView()\n\n const {\n children,\n currentView: currentViewFromProps,\n inheritable,\n views,\n } = parentContext.inheritable\n ? {\n ...parentContext,\n ...args,\n }\n : args\n\n const [currentView, setCurrentView] = useControllableState(currentViewFromProps, 'default')\n\n const value = useMemo(() => {\n const currentViewMap = views ? views[currentView] || views.default : undefined\n return {\n currentView,\n currentViewMap,\n inheritable,\n setCurrentView,\n views,\n }\n }, [currentView, inheritable, setCurrentView, views])\n\n return <RichTextViewContext value={value}>{children}</RichTextViewContext>\n}\n\n/**\n * Hook to access the current rich text view context.\n *\n * Use this hook to access the currently active view and its node map,\n * or to programmatically switch between views.\n *\n * @returns An object containing:\n * - `currentView`: The name of the active view\n * - `currentViewMap`: The node overrides for the current view\n * - `setCurrentView`: Function to change views\n * - `views`: All available views\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { currentView, currentViewMap, setCurrentView } = useRichTextView()\n *\n * return (\n * <div>\n * <p>Current view: {currentView}</p>\n * {currentViewMap?.heading && <p>Heading overrides are active</p>}\n * <button onClick={() => setCurrentView('frontend')}>\n * Switch to frontend view\n * </button>\n * </div>\n * )\n * }\n * ```\n */\nexport function useRichTextView(): RichTextViewContextType {\n return use(RichTextViewContext)\n}\n", "'use client'\nexport class Point {\n private readonly _x: number\n\n private readonly _y: number\n\n constructor(x: number, y: number) {\n this._x = x\n this._y = y\n }\n\n public calcDeltaXTo({ x }: Point): number {\n return this.x - x\n }\n\n public calcDeltaYTo({ y }: Point): number {\n return this.y - y\n }\n\n public calcDistanceTo(point: Point): number {\n return Math.sqrt(Math.pow(this.calcDeltaXTo(point), 2) + Math.pow(this.calcDeltaYTo(point), 2))\n }\n\n public calcHorizontalDistanceTo(point: Point): number {\n return Math.abs(this.calcDeltaXTo(point))\n }\n\n public calcVerticalDistance(point: Point): number {\n return Math.abs(this.calcDeltaYTo(point))\n }\n\n public equals({ x, y }: Point): boolean {\n return this.x === x && this.y === y\n }\n\n get x(): number {\n return this._x\n }\n\n get y(): number {\n return this._y\n }\n}\n\nexport function isPoint(x: unknown): x is Point {\n return x instanceof Point\n}\n", "'use client'\nimport type { LexicalCommand, LexicalEditor, ParagraphNode, RangeSelection } from 'lexical'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { mergeRegister } from '@lexical/utils'\nimport {\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n COMMAND_PRIORITY_LOW,\n createCommand,\n getDOMSelection,\n} from 'lexical'\nimport { type JSX, useCallback, useEffect, useState } from 'react'\nimport * as React from 'react'\n\nimport type { MenuTextMatch, TriggerFn } from '../useMenuTriggerMatch.js'\nimport type { MenuRenderFn, MenuResolution } from './LexicalMenu.js'\nimport type { SlashMenuGroupInternal } from './types.js'\n\nimport { LexicalMenu, useMenuAnchorRef } from './LexicalMenu.js'\n\nexport const PUNCTUATION = '\\\\.,\\\\+\\\\*\\\\?\\\\$\\\\@\\\\|#{}\\\\(\\\\)\\\\^\\\\-\\\\[\\\\]\\\\\\\\/!%\\'\"~=<>_:;'\n\nfunction getTextUpToAnchor(selection: RangeSelection): null | string {\n const anchor = selection.anchor\n if (anchor.type !== 'text') {\n return null\n }\n const anchorNode = anchor.getNode()\n if (!anchorNode.isSimpleText()) {\n return null\n }\n const anchorOffset = anchor.offset\n return anchorNode.getTextContent().slice(0, anchorOffset)\n}\n\nfunction tryToPositionRange(leadOffset: number, range: Range, editorWindow: Window): boolean {\n const domSelection = getDOMSelection(editorWindow)\n if (domSelection === null || !domSelection.isCollapsed) {\n return false\n }\n\n const anchorNode = domSelection.anchorNode\n const startOffset = leadOffset\n const endOffset = domSelection.anchorOffset\n\n if (anchorNode == null || endOffset == null) {\n return false\n }\n\n try {\n range.setStart(anchorNode, startOffset)\n // if endOffset is 0, positioning the range for when you click the plus button to open the slash menu will fial\n range.setEnd(anchorNode, endOffset > 1 ? endOffset : 1)\n } catch (error) {\n return false\n }\n\n return true\n}\n\nfunction getQueryTextForSearch(editor: LexicalEditor): string | undefined {\n let text\n editor.getEditorState().read(() => {\n const selection = $getSelection()\n if (!$isRangeSelection(selection)) {\n return\n }\n text = getTextUpToAnchor(selection)\n })\n return text\n}\n\nfunction isSelectionOnEntityBoundary(editor: LexicalEditor, offset: number): boolean {\n if (offset !== 0) {\n return false\n }\n return editor.getEditorState().read(() => {\n const selection = $getSelection()\n if ($isRangeSelection(selection)) {\n const anchor = selection.anchor\n const anchorNode = anchor.getNode()\n const prevSibling = anchorNode.getPreviousSibling()\n return $isTextNode(prevSibling) && prevSibling.isTextEntity()\n }\n return false\n })\n}\n\nfunction startTransition(callback: () => void) {\n if (React.startTransition) {\n React.startTransition(callback)\n } else {\n callback()\n }\n}\n\nexport { useDynamicPositioning } from './LexicalMenu.js'\n\nexport type TypeaheadMenuPluginProps = {\n anchorClassName?: string\n anchorElem: HTMLElement\n groups: Array<SlashMenuGroupInternal>\n menuRenderFn: MenuRenderFn\n onClose?: () => void\n onOpen?: (resolution: MenuResolution) => void\n onQueryChange: (matchingString: null | string) => void\n triggerFn: TriggerFn\n}\n\nexport const ENABLE_SLASH_MENU_COMMAND: LexicalCommand<{\n node: ParagraphNode\n}> = createCommand('ENABLE_SLASH_MENU_COMMAND')\n\nexport function LexicalTypeaheadMenuPlugin({\n anchorClassName,\n anchorElem,\n groups,\n menuRenderFn,\n onClose,\n onOpen,\n onQueryChange,\n triggerFn,\n}: TypeaheadMenuPluginProps): JSX.Element | null {\n const [editor] = useLexicalComposerContext()\n const [resolution, setResolution] = useState<MenuResolution | null>(null)\n const anchorElementRef = useMenuAnchorRef(anchorElem, resolution, setResolution, anchorClassName)\n\n const closeTypeahead = useCallback(() => {\n setResolution(null)\n if (onClose != null && resolution !== null) {\n onClose()\n }\n }, [onClose, resolution])\n\n const openTypeahead = useCallback(\n (res: MenuResolution) => {\n setResolution(res)\n if (onOpen != null && resolution === null) {\n onOpen(res)\n }\n },\n [onOpen, resolution],\n )\n\n // This is mainly used for the AddBlockHandlePlugin, so that the slash menu can be opened from there\n useEffect(() => {\n return mergeRegister(\n editor.registerCommand(\n ENABLE_SLASH_MENU_COMMAND,\n ({ node }) => {\n editor.getEditorState().read(() => {\n const match: MenuTextMatch = {\n leadOffset: 0,\n matchingString: '',\n replaceableString: '',\n }\n if (!isSelectionOnEntityBoundary(editor, match.leadOffset)) {\n if (node !== null) {\n const editorWindow = editor._window ?? window\n const range = editorWindow.document.createRange()\n\n const isRangePositioned = tryToPositionRange(match.leadOffset, range, editorWindow)\n if (isRangePositioned !== null) {\n startTransition(() =>\n openTypeahead({\n getRect: () => {\n return range.getBoundingClientRect()\n },\n match,\n }),\n )\n }\n\n return\n }\n }\n })\n\n return true\n },\n COMMAND_PRIORITY_LOW,\n ),\n )\n }, [editor, openTypeahead])\n\n useEffect(() => {\n const updateListener = () => {\n editor.getEditorState().read(() => {\n const editorWindow = editor._window ?? window\n const range = editorWindow.document.createRange()\n const selection = $getSelection()\n const text = getQueryTextForSearch(editor)\n\n if (\n !$isRangeSelection(selection) ||\n !selection.isCollapsed() ||\n text === undefined ||\n range === null\n ) {\n closeTypeahead()\n return\n }\n\n const match = triggerFn({ editor, query: text })\n onQueryChange(match ? match.matchingString : null)\n\n if (match !== null && !isSelectionOnEntityBoundary(editor, match.leadOffset)) {\n const isRangePositioned = tryToPositionRange(match.leadOffset, range, editorWindow)\n if (isRangePositioned !== null) {\n startTransition(() =>\n openTypeahead({\n getRect: () => {\n return range.getBoundingClientRect()\n },\n match,\n }),\n )\n return\n }\n }\n closeTypeahead()\n })\n }\n\n const removeUpdateListener = editor.registerUpdateListener(updateListener)\n\n return () => {\n removeUpdateListener()\n }\n }, [editor, triggerFn, onQueryChange, resolution, closeTypeahead, openTypeahead])\n\n return anchorElementRef.current === null || resolution === null || editor === null ? null : (\n <LexicalMenu\n anchorElementRef={anchorElementRef}\n close={closeTypeahead}\n editor={editor}\n groups={groups}\n menuRenderFn={menuRenderFn}\n resolution={resolution}\n shouldSplitNodeWithQuery\n />\n )\n}\n\nexport type { MenuRenderFn, MenuResolution, MenuTextMatch, TriggerFn }\n", "'use client'\nimport type { BaseSelection, LexicalCommand, LexicalEditor, TextNode } from 'lexical'\nimport type { JSX, ReactPortal, RefObject } from 'react'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { mergeRegister } from '@lexical/utils'\nimport {\n $getSelection,\n $isRangeSelection,\n $setSelection,\n COMMAND_PRIORITY_LOW,\n COMMAND_PRIORITY_NORMAL,\n createCommand,\n KEY_ARROW_DOWN_COMMAND,\n KEY_ARROW_UP_COMMAND,\n KEY_ENTER_COMMAND,\n KEY_ESCAPE_COMMAND,\n KEY_TAB_COMMAND,\n} from 'lexical'\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'\n\nimport type { MenuTextMatch } from '../useMenuTriggerMatch.js'\nimport type { SlashMenuGroupInternal, SlashMenuItem, SlashMenuItemInternal } from './types.js'\n\nimport { CAN_USE_DOM } from '../../../utils/canUseDOM.js'\n\nexport type MenuResolution = {\n getRect: () => DOMRect\n match?: MenuTextMatch\n}\n\nconst baseClass = 'slash-menu-popup'\n\nexport type MenuRenderFn = (\n anchorElementRef: RefObject<HTMLElement | null>,\n itemProps: {\n groups: Array<SlashMenuGroupInternal>\n selectedItemKey: null | string\n selectItemAndCleanUp: (selectedItem: SlashMenuItem) => void\n setSelectedItemKey: (itemKey: string) => void\n },\n matchingString: null | string,\n) => JSX.Element | null | ReactPortal\n\nconst scrollIntoViewIfNeeded = (target: HTMLElement) => {\n const typeaheadContainerNode = document.getElementById('slash-menu')\n if (!typeaheadContainerNode) {\n return\n }\n\n const typeaheadRect = typeaheadContainerNode.getBoundingClientRect()\n\n if (typeaheadRect.top + typeaheadRect.height > window.innerHeight) {\n typeaheadContainerNode.scrollIntoView({\n block: 'center',\n })\n }\n\n if (typeaheadRect.top < 0) {\n typeaheadContainerNode.scrollIntoView({\n block: 'center',\n })\n }\n\n target.scrollIntoView({ block: 'nearest' })\n}\n\n/**\n * Walk backwards along user input and forward through entity title to try\n * and replace more of the user's text with entity.\n */\nfunction getFullMatchOffset(documentText: string, entryText: string, offset: number) {\n let triggerOffset = offset\n for (let i = triggerOffset; i <= entryText.length; i++) {\n if (documentText.substring(documentText.length - i) === entryText.substring(0, i)) {\n triggerOffset = i\n }\n }\n return triggerOffset\n}\n\n/**\n * Split Lexical TextNode and return a new TextNode only containing matched text.\n * Common use cases include: removing the node, replacing with a new node.\n */\nfunction $splitNodeContainingQuery(match: MenuTextMatch): TextNode | undefined {\n const selection = $getSelection()\n if (!$isRangeSelection(selection) || !selection.isCollapsed()) {\n return\n }\n const anchor = selection.anchor\n if (anchor.type !== 'text') {\n return\n }\n const anchorNode = anchor.getNode()\n if (!anchorNode.isSimpleText()) {\n return\n }\n const selectionOffset = anchor.offset\n const textContent = anchorNode.getTextContent().slice(0, selectionOffset)\n const characterOffset = match.replaceableString.length\n const queryOffset = getFullMatchOffset(textContent, match.matchingString, characterOffset)\n const startOffset = selectionOffset - queryOffset\n if (startOffset < 0) {\n return\n }\n let newNode\n if (startOffset === 0) {\n ;[newNode] = anchorNode.splitText(selectionOffset)\n } else {\n ;[, newNode] = anchorNode.splitText(startOffset, selectionOffset)\n }\n\n return newNode\n}\n\n// Got from https://stackoverflow.com/a/42543908/2013580\nexport function getScrollParent(\n element: HTMLElement,\n includeHidden: boolean,\n): HTMLBodyElement | HTMLElement {\n let style = getComputedStyle(element)\n const excludeStaticParent = style.position === 'absolute'\n const overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/\n if (style.position === 'fixed') {\n return document.body\n }\n for (let parent: HTMLElement | null = element; (parent = parent.parentElement); ) {\n style = getComputedStyle(parent)\n if (excludeStaticParent && style.position === 'static') {\n continue\n }\n if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) {\n return parent\n }\n }\n return document.body\n}\n\nfunction isTriggerVisibleInNearestScrollContainer(\n targetElement: HTMLElement,\n containerElement: HTMLElement,\n): boolean {\n const tRect = targetElement.getBoundingClientRect()\n const cRect = containerElement.getBoundingClientRect()\n return tRect.top > cRect.top && tRect.top < cRect.bottom\n}\n\n// Reposition the menu on scroll, window resize, and element resize.\nexport function useDynamicPositioning(\n resolution: MenuResolution | null,\n targetElementRef: RefObject<HTMLElement | null>,\n onReposition: () => void,\n onVisibilityChange?: (isInView: boolean) => void,\n) {\n const [editor] = useLexicalComposerContext()\n useEffect(() => {\n const targetElement = targetElementRef.current\n if (targetElement != null && resolution != null) {\n const rootElement = editor.getRootElement()\n const rootScrollParent =\n rootElement != null ? getScrollParent(rootElement, false) : document.body\n let ticking = false\n let previousIsInView = isTriggerVisibleInNearestScrollContainer(\n targetElement,\n rootScrollParent,\n )\n const handleScroll = function () {\n if (!ticking) {\n window.requestAnimationFrame(function () {\n onReposition()\n ticking = false\n })\n ticking = true\n }\n const isInView = isTriggerVisibleInNearestScrollContainer(targetElement, rootScrollParent)\n if (isInView !== previousIsInView) {\n previousIsInView = isInView\n if (onVisibilityChange != null) {\n onVisibilityChange(isInView)\n }\n }\n }\n const resizeObserver = new ResizeObserver(onReposition)\n window.addEventListener('resize', onReposition)\n document.addEventListener('scroll', handleScroll, {\n capture: true,\n passive: true,\n })\n resizeObserver.observe(targetElement)\n return () => {\n resizeObserver.disconnect()\n window.removeEventListener('resize', onReposition)\n document.removeEventListener('scroll', handleScroll, true)\n }\n }\n }, [editor, onVisibilityChange, onReposition, resolution, targetElementRef])\n}\n\nexport const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND: LexicalCommand<{\n index: number\n item: SlashMenuItemInternal\n}> = createCommand('SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND')\n\nexport function LexicalMenu({\n anchorElementRef,\n close,\n editor,\n // groups filtering is already handled in SlashMenu/index.tsx. Thus, groups always contains the matching items.\n groups,\n menuRenderFn,\n resolution,\n shouldSplitNodeWithQuery = false,\n}: {\n anchorElementRef: RefObject<HTMLElement | null>\n close: () => void\n editor: LexicalEditor\n groups: Array<SlashMenuGroupInternal>\n menuRenderFn: MenuRenderFn\n resolution: MenuResolution\n shouldSplitNodeWithQuery?: boolean\n}): JSX.Element | null {\n const [selectedItemKey, setSelectedItemKey] = useState<null | string>(null)\n\n const matchingString = (resolution.match && resolution.match.matchingString) || ''\n\n const updateSelectedItem = useCallback(\n (item: SlashMenuItem) => {\n const rootElem = editor.getRootElement()\n if (rootElem !== null) {\n rootElem.setAttribute('aria-activedescendant', `${baseClass}__item-${item.key}`)\n setSelectedItemKey(item.key)\n }\n },\n [editor],\n )\n\n const setSelectedItemKeyToFirstMatchingItem = useCallback(() => {\n // set selected item to the first of the matching ones\n if (groups !== null && matchingString != null) {\n // groups filtering is already handled in SlashMenu/index.tsx. Thus, groups always contains the matching items.\n const allItems = groups.flatMap((group) => group.items)\n\n if (allItems.length) {\n const firstMatchingItem = allItems[0]!\n updateSelectedItem(firstMatchingItem)\n }\n }\n }, [groups, updateSelectedItem, matchingString])\n\n useEffect(() => {\n setSelectedItemKeyToFirstMatchingItem()\n }, [matchingString, setSelectedItemKeyToFirstMatchingItem])\n\n const selectItemAndCleanUp = useCallback(\n (selectedItem: SlashMenuItem) => {\n close()\n\n editor.update(() => {\n const textNodeContainingQuery =\n resolution.match != null && shouldSplitNodeWithQuery\n ? $splitNodeContainingQuery(resolution.match)\n : null\n\n if (textNodeContainingQuery) {\n textNodeContainingQuery.remove()\n }\n })\n\n setTimeout(() => {\n // Needed in Firefox. See https://github.com/payloadcms/payload/issues/10724\n let selection: BaseSelection | undefined\n editor.read(() => {\n selection = $getSelection()?.clone()\n })\n editor.update(() => {\n if (selection) {\n $setSelection(selection)\n }\n })\n\n selectedItem.onSelect({\n editor,\n queryString: resolution.match ? resolution.match.matchingString : '',\n })\n }, 0)\n },\n [editor, shouldSplitNodeWithQuery, resolution.match, close],\n )\n\n useEffect(() => {\n return () => {\n const rootElem = editor.getRootElement()\n if (rootElem !== null) {\n rootElem.removeAttribute('aria-activedescendant')\n }\n }\n }, [editor])\n\n useLayoutEffect(() => {\n if (groups === null) {\n setSelectedItemKey(null)\n } else if (selectedItemKey === null) {\n setSelectedItemKeyToFirstMatchingItem()\n }\n }, [groups, selectedItemKey, updateSelectedItem, setSelectedItemKeyToFirstMatchingItem])\n\n useEffect(() => {\n return mergeRegister(\n editor.registerCommand(\n SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND,\n ({ item }) => {\n if (item.ref && item.ref.current != null) {\n scrollIntoViewIfNeeded(item.ref.current)\n return true\n }\n\n return false\n },\n COMMAND_PRIORITY_LOW,\n ),\n )\n }, [editor, updateSelectedItem])\n\n useEffect(() => {\n return mergeRegister(\n editor.registerCommand<KeyboardEvent>(\n KEY_ARROW_DOWN_COMMAND,\n (payload) => {\n const event = payload\n if (groups !== null && groups.length && selectedItemKey !== null) {\n const allItems = groups.flatMap((group) => group.items)\n const selectedIndex = allItems.findIndex((item) => item.key === selectedItemKey)\n\n const newSelectedIndex = selectedIndex !== allItems.length - 1 ? selectedIndex + 1 : 0\n\n const newSelectedItem = allItems[newSelectedIndex]\n if (!newSelectedItem) {\n return false\n }\n\n updateSelectedItem(newSelectedItem)\n if (newSelectedItem.ref != null && newSelectedItem.ref.current) {\n editor.dispatchCommand(SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, {\n index: newSelectedIndex,\n item: newSelectedItem,\n })\n }\n event.preventDefault()\n event.stopImmediatePropagation()\n }\n return true\n },\n COMMAND_PRIORITY_NORMAL,\n ),\n editor.registerCommand<KeyboardEvent>(\n KEY_ARROW_UP_COMMAND,\n (payload) => {\n const event = payload\n if (groups !== null && groups.length && selectedItemKey !== null) {\n const allItems = groups.flatMap((group) => group.items)\n const selectedIndex = allItems.findIndex((item) => item.key === selectedItemKey)\n\n const newSelectedIndex = selectedIndex !== 0 ? selectedIndex - 1 : allItems.length - 1\n\n const newSelectedItem = allItems[newSelectedIndex]\n if (!newSelectedItem) {\n return false\n }\n\n updateSelectedItem(newSelectedItem)\n if (newSelectedItem.ref != null && newSelectedItem.ref.current) {\n scrollIntoViewIfNeeded(newSelectedItem.ref.current)\n }\n event.preventDefault()\n event.stopImmediatePropagation()\n }\n return true\n },\n COMMAND_PRIORITY_NORMAL,\n ),\n editor.registerCommand<KeyboardEvent>(\n KEY_ESCAPE_COMMAND,\n (payload) => {\n const event = payload\n event.preventDefault()\n event.stopImmediatePropagation()\n close()\n return true\n },\n COMMAND_PRIORITY_LOW,\n ),\n editor.registerCommand<KeyboardEvent>(\n KEY_TAB_COMMAND,\n (payload) => {\n const event = payload\n\n if (groups === null || selectedItemKey === null) {\n return false\n }\n const allItems = groups.flatMap((group) => group.items)\n const selectedItem = allItems.find((item) => item.key === selectedItemKey)\n if (!selectedItem) {\n return false\n }\n\n event.preventDefault()\n event.stopImmediatePropagation()\n selectItemAndCleanUp(selectedItem)\n return true\n },\n COMMAND_PRIORITY_NORMAL,\n ),\n editor.registerCommand(\n KEY_ENTER_COMMAND,\n (event: KeyboardEvent | null) => {\n if (groups === null || selectedItemKey === null) {\n return false\n }\n const allItems = groups.flatMap((group) => group.items)\n const selectedItem = allItems.find((item) => item.key === selectedItemKey)\n if (!selectedItem) {\n return false\n }\n\n if (event !== null) {\n event.preventDefault()\n event.stopImmediatePropagation()\n }\n selectItemAndCleanUp(selectedItem)\n return true\n },\n COMMAND_PRIORITY_NORMAL,\n ),\n )\n }, [selectItemAndCleanUp, close, editor, groups, selectedItemKey, updateSelectedItem])\n\n const listItemProps = useMemo(\n () => ({\n groups,\n selectedItemKey,\n selectItemAndCleanUp,\n setSelectedItemKey,\n }),\n [selectItemAndCleanUp, selectedItemKey, groups],\n )\n\n return menuRenderFn(\n anchorElementRef,\n listItemProps,\n resolution.match ? resolution.match.matchingString : '',\n )\n}\n\nfunction setContainerDivAttributes(containerDiv: HTMLElement, className?: string) {\n if (className != null) {\n containerDiv.className = className\n }\n containerDiv.setAttribute('aria-label', 'Slash menu')\n containerDiv.setAttribute('role', 'listbox')\n containerDiv.style.display = 'block'\n containerDiv.style.position = 'absolute'\n}\n\nexport function useMenuAnchorRef(\n anchorElem: HTMLElement,\n resolution: MenuResolution | null,\n setResolution: (r: MenuResolution | null) => void,\n className?: string,\n): RefObject<HTMLElement | null> {\n const [editor] = useLexicalComposerContext()\n const anchorElementRef = useRef<HTMLElement | null>(\n CAN_USE_DOM ? document.createElement('div') : null,\n )\n const positionMenu = useCallback(() => {\n if (anchorElementRef.current === null || parent === undefined) {\n return\n }\n const rootElement = editor.getRootElement()\n const containerDiv = anchorElementRef.current\n\n const VERTICAL_OFFSET = 32\n\n const menuEle = containerDiv.firstChild as Element\n if (rootElement !== null && resolution !== null) {\n const { height, width } = resolution.getRect()\n let { left, top } = resolution.getRect()\n\n const rawTop = top\n top -= anchorElem.getBoundingClientRect().top + window.scrollY\n left -= anchorElem.getBoundingClientRect().left + window.scrollX\n containerDiv.style.left = `${left + window.scrollX}px`\n containerDiv.style.height = `${height}px`\n containerDiv.style.width = `${width}px`\n if (menuEle !== null) {\n const menuRect = menuEle.getBoundingClientRect()\n const menuHeight = menuRect.height\n const menuWidth = menuRect.width\n\n const rootElementRect = rootElement.getBoundingClientRect()\n\n const isRTL = document.dir === 'rtl' || document.documentElement.dir === 'rtl'\n const anchorRect = anchorElem.getBoundingClientRect()\n const leftBoundary = Math.max(0, rootElementRect.left)\n\n if (!isRTL && left + menuWidth > rootElementRect.right) {\n containerDiv.style.left = `${rootElementRect.right - menuWidth + window.scrollX}px`\n } else if (isRTL && menuRect.left < leftBoundary) {\n const newLeft = leftBoundary + menuWidth - anchorRect.left\n containerDiv.style.left = `${newLeft + window.scrollX}px`\n }\n\n const wouldGoOffBottomOfScreen = rawTop + menuHeight + VERTICAL_OFFSET > window.innerHeight\n //const wouldGoOffBottomOfContainer = top + menuHeight > rootElementRect.bottom\n const wouldGoOffTopOfScreen = rawTop < 0\n\n // Position slash menu above the cursor instead of below (default) if it would otherwise go off the bottom of the screen.\n if (wouldGoOffBottomOfScreen && !wouldGoOffTopOfScreen) {\n const margin = 24\n containerDiv.style.top = `${\n top + VERTICAL_OFFSET - menuHeight + window.scrollY - (height + margin)\n }px`\n } else {\n containerDiv.style.top = `${top + window.scrollY + VERTICAL_OFFSET}px`\n }\n }\n\n if (!containerDiv.isConnected) {\n setContainerDivAttributes(containerDiv, className)\n anchorElem.append(containerDiv)\n }\n containerDiv.setAttribute('id', 'slash-menu')\n anchorElementRef.current = containerDiv\n rootElement.setAttribute('aria-controls', 'slash-menu')\n }\n }, [editor, resolution, className, anchorElem])\n\n useEffect(() => {\n const rootElement = editor.getRootElement()\n if (resolution !== null) {\n positionMenu()\n return () => {\n if (rootElement !== null) {\n rootElement.removeAttribute('aria-controls')\n }\n\n const containerDiv = anchorElementRef.current\n if (containerDiv !== null && containerDiv.isConnected) {\n containerDiv.remove()\n containerDiv.removeAttribute('id')\n }\n }\n }\n }, [editor, positionMenu, resolution])\n\n const onVisibilityChange = useCallback(\n (isInView: boolean) => {\n if (resolution !== null) {\n if (!isInView) {\n setResolution(null)\n }\n }\n },\n [resolution, setResolution],\n )\n\n useDynamicPositioning(resolution, anchorElementRef, positionMenu, onVisibilityChange)\n\n return anchorElementRef\n}\n", "'use client'\nimport { isPoint, type Point } from './point.js'\n\ninterface ContainsPointReturn {\n reason: {\n isOnBottomSide: boolean\n isOnLeftSide: boolean\n isOnRightSide: boolean\n isOnTopSide: boolean\n }\n result: boolean\n}\n\nexport class Rect {\n private readonly _bottom: number\n\n private readonly _left: number\n\n private readonly _right: number\n\n private readonly _top: number\n\n constructor(left: number, top: number, right: number, bottom: number) {\n const [physicTop, physicBottom] = top <= bottom ? [top, bottom] : [bottom, top]\n\n const [physicLeft, physicRight] = left <= right ? [left, right] : [right, left]\n\n this._top = physicTop\n this._right = physicRight\n this._left = physicLeft\n this._bottom = physicBottom\n }\n\n static fromDOM(dom: HTMLElement): Rect {\n const { height, left, top, width } = dom.getBoundingClientRect()\n return Rect.fromLWTH(left, width, top, height)\n }\n\n static fromDOMRect(domRect: DOMRect): Rect {\n const { height, left, top, width } = domRect\n return Rect.fromLWTH(left, width, top, height)\n }\n\n static fromLTRB(left: number, top: number, right: number, bottom: number): Rect {\n return new Rect(left, top, right, bottom)\n }\n\n static fromLWTH(left: number, width: number, top: number, height: number): Rect {\n return new Rect(left, top, left + width, top + height)\n }\n\n static fromPoints(startPoint: Point, endPoint: Point): Rect {\n const { x: left, y: top } = startPoint\n const { x: right, y: bottom } = endPoint\n return Rect.fromLTRB(left, top, right, bottom)\n }\n\n public contains({ x, y }: Point): ContainsPointReturn\n\n public contains({ bottom, left, right, top }: Rect): boolean\n\n public contains(target: Point | Rect): boolean | ContainsPointReturn {\n if (isPoint(target)) {\n const { x, y } = target\n\n const isOnTopSide = y < this._top\n const isOnBottomSide = y > this._bottom\n const isOnLeftSide = x < this._left\n const isOnRightSide = x > this._right\n\n const result = !isOnTopSide && !isOnBottomSide && !isOnLeftSide && !isOnRightSide\n\n return {\n reason: {\n isOnBottomSide,\n isOnLeftSide,\n isOnRightSide,\n isOnTopSide,\n },\n result,\n }\n }\n const { bottom, left, right, top } = target\n\n return (\n top >= this._top &&\n top <= this._bottom &&\n bottom >= this._top &&\n bottom <= this._bottom &&\n left >= this._left &&\n left <= this._right &&\n right >= this._left &&\n right <= this._right\n )\n }\n\n public distanceFromPoint(point: Point): {\n distance: number\n isOnBottomSide: boolean\n isOnLeftSide: boolean\n isOnRightSide: boolean\n isOnTopSide: boolean\n } {\n const containsResult = this.contains(point)\n if (containsResult.result) {\n return {\n distance: 0,\n isOnBottomSide: containsResult.reason.isOnBottomSide,\n isOnLeftSide: containsResult.reason.isOnLeftSide,\n isOnRightSide: containsResult.reason.isOnRightSide,\n isOnTopSide: containsResult.reason.isOnTopSide,\n }\n }\n\n let dx = 0 // Horizontal distance to the closest edge\n let dy = 0 // Vertical distance to the closest edge\n\n // If the point is to the left of the rectangle\n if (point.x < this._left) {\n dx = this._left - point.x\n }\n // If the point is to the right of the rectangle\n else if (point.x > this._right) {\n dx = point.x - this._right\n }\n\n // If the point is above the rectangle\n if (point.y < this._top) {\n dy = this._top - point.y\n }\n // If the point is below the rectangle\n else if (point.y > this._bottom) {\n dy = point.y - this._bottom\n }\n\n // Use the Pythagorean theorem to calculate the distance\n return {\n distance: Math.sqrt(dx * dx + dy * dy),\n isOnBottomSide: point.y > this._bottom,\n isOnLeftSide: point.x < this._left,\n isOnRightSide: point.x > this._right,\n isOnTopSide: point.y < this._top,\n }\n }\n\n public equals({ bottom, left, right, top }: Rect): boolean {\n return (\n top === this._top && bottom === this._bottom && left === this._left && right === this._right\n )\n }\n\n public generateNewRect({\n bottom = this.bottom,\n left = this.left,\n right = this.right,\n top = this.top,\n }): Rect {\n return new Rect(left, top, right, bottom)\n }\n\n public intersectsWith(rect: Rect): boolean {\n const { height: h1, left: x1, top: y1, width: w1 } = rect\n const { height: h2, left: x2, top: y2, width: w2 } = this\n const maxX = x1 + w1 >= x2 + w2 ? x1 + w1 : x2 + w2\n const maxY = y1 + h1 >= y2 + h2 ? y1 + h1 : y2 + h2\n const minX = x1 <= x2 ? x1 : x2\n const minY = y1 <= y2 ? y1 : y2\n return maxX - minX <= w1 + w2 && maxY - minY <= h1 + h2\n }\n\n get bottom(): number {\n return this._bottom\n }\n\n get height(): number {\n return Math.abs(this._bottom - this._top)\n }\n\n get left(): number {\n return this._left\n }\n\n get right(): number {\n return this._right\n }\n\n get top(): number {\n return this._top\n }\n\n get width(): number {\n return Math.abs(this._left - this._right)\n }\n}\n", "import type {\n EditorConfig,\n Klass,\n LexicalEditor,\n LexicalNode,\n LexicalNodeReplacement,\n} from 'lexical'\n\nimport React from 'react'\n\nimport type { NodeWithHooks } from '../../features/typesServer.js'\nimport type { LexicalEditorNodeMap, NodeMapValue } from '../../types.js'\nimport type { SanitizedClientEditorConfig, SanitizedServerEditorConfig } from '../config/types.js'\n\n// Store view definitions for each editor and node type\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst editorNodeViews = new WeakMap<LexicalEditor, Map<string, NodeMapValue<any>>>()\n\n/**\n * Register view definitions for an editor\n */\nexport function registerEditorNodeViews(\n editor: LexicalEditor,\n nodeViews: LexicalEditorNodeMap,\n): void {\n if (!editorNodeViews.has(editor)) {\n editorNodeViews.set(editor, new Map())\n }\n const editorViews = editorNodeViews.get(editor)!\n\n // Register each node type's view\n for (const [nodeType, value] of Object.entries(nodeViews)) {\n if (!value || typeof value !== 'object') {\n continue\n }\n\n // Handle blocks specially - store each block type with key 'block:blockType'\n if (nodeType === 'blocks') {\n for (const [blockType, viewDef] of Object.entries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value as Record<string, NodeMapValue<any>>,\n )) {\n editorViews.set(`block:${blockType}`, viewDef)\n }\n continue\n }\n\n // Handle inlineBlocks specially - store each block type with key 'inlineBlock:blockType'\n if (nodeType === 'inlineBlocks') {\n for (const [blockType, viewDef] of Object.entries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value as Record<string, NodeMapValue<any>>,\n )) {\n editorViews.set(`inlineBlock:${blockType}`, viewDef)\n }\n continue\n }\n\n // Regular node types\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editorViews.set(nodeType, value as NodeMapValue<any>)\n }\n}\n\n/**\n * Clear all view overrides for an editor (restores default rendering)\n */\nexport function clearEditorNodeViews(editor: LexicalEditor): void {\n editorNodeViews.delete(editor)\n}\n\n/**\n * Get the view definition for a specific editor and node\n */\nfunction getEditorNodeView(\n editor: LexicalEditor,\n nodeType: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n node?: any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): NodeMapValue<any> | undefined {\n const editorViews = editorNodeViews.get(editor)\n\n // For block nodes, look up by blockType\n if (nodeType === 'block' && node?.['__fields']?.blockType) {\n const blockType = node['__fields'].blockType\n return editorViews?.get(`block:${blockType}`)\n }\n\n // For inlineBlock nodes, look up by blockType\n if (nodeType === 'inlineBlock' && node?.['__fields']?.blockType) {\n const blockType = node['__fields'].blockType\n return editorViews?.get(`inlineBlock:${blockType}`)\n }\n\n // Regular node types\n return editorViews?.get(nodeType)\n}\n\n/**\n * Apply view overrides to a specific node type by modifying its prototype\n * Uses WeakMap to check per-editor at runtime\n */\nfunction applyNodeOverride({\n node,\n nodeType,\n}: {\n node: Klass<LexicalNode>\n nodeType: string\n}): void {\n if (!('getType' in node) || node.getType() !== nodeType) {\n return\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const NodeClass = node as any\n\n // Store original methods if not already stored\n if (!NodeClass.prototype._originalDecorate) {\n NodeClass.prototype._originalDecorate = NodeClass.prototype.decorate\n }\n if (!NodeClass.prototype._originalCreateDOM) {\n NodeClass.prototype._originalCreateDOM = NodeClass.prototype.createDOM\n }\n\n // Override decorate method (for DecoratorNodes)\n if (NodeClass.prototype.decorate && !NodeClass.prototype._decorateOverridden) {\n NodeClass.prototype._decorateOverridden = true\n const hasCreateDOM = !!NodeClass.prototype.createDOM\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n NodeClass.prototype.decorate = function (editor: LexicalEditor, config: EditorConfig): any {\n const viewDef = getEditorNodeView(editor, nodeType, this)\n\n if (viewDef) {\n // Priority 1: If Component is provided, use it\n if (viewDef.Component) {\n return viewDef.Component({\n config,\n editor,\n isEditor: true,\n isJSXConverter: false,\n node: this,\n })\n }\n\n // Priority 2: If custom createDOM is provided, use html in decorate\n if (viewDef.createDOM && viewDef.html) {\n const htmlContent =\n typeof viewDef.html === 'function'\n ? viewDef.html({ config, editor, isEditor: true, isJSXConverter: false, node: this })\n : viewDef.html\n return React.createElement('span', {\n dangerouslySetInnerHTML: { __html: htmlContent },\n })\n }\n\n // Priority 3: If only html is provided (no custom createDOM),\n // createDOM will handle it, so decorate returns empty fragment\n if (viewDef.html && hasCreateDOM && !viewDef.createDOM) {\n return React.createElement(React.Fragment)\n }\n }\n\n // Otherwise use original\n return NodeClass.prototype._originalDecorate.call(this, editor, config)\n }\n }\n\n // Override createDOM method (for ElementNodes)\n if (NodeClass.prototype.createDOM && !NodeClass.prototype._createDOMOverridden) {\n NodeClass.prototype._createDOMOverridden = true\n NodeClass.prototype.createDOM = function (\n config: EditorConfig,\n editor: LexicalEditor,\n ): HTMLElement {\n const viewDef = getEditorNodeView(editor, nodeType, this)\n\n if (viewDef) {\n // If createDOM is provided, use it\n if (viewDef.createDOM) {\n return viewDef.createDOM({ config, editor, node: this })\n }\n\n // If html is provided (as a function or string), create element from it\n if (viewDef.html) {\n const htmlContent =\n typeof viewDef.html === 'function'\n ? viewDef.html({ config, editor, isEditor: true, isJSXConverter: false, node: this })\n : viewDef.html\n const tempDiv = document.createElement('div')\n tempDiv.innerHTML = htmlContent\n return (tempDiv.firstElementChild as HTMLElement) || tempDiv\n }\n }\n\n // Otherwise use original\n return NodeClass.prototype._originalCreateDOM.call(this, config, editor)\n }\n }\n}\n\nexport function getEnabledNodes({\n editorConfig,\n nodeViews,\n}: {\n editorConfig: SanitizedClientEditorConfig | SanitizedServerEditorConfig\n nodeViews?: LexicalEditorNodeMap\n}): Array<Klass<LexicalNode> | LexicalNodeReplacement> {\n const nodes = getEnabledNodesFromServerNodes({\n nodes: editorConfig.features.nodes,\n })\n\n if (nodeViews) {\n // Apply node overrides by modifying prototypes (once globally)\n // The overrides check per-editor at runtime using WeakMap\n const nodeTypesToOverride = new Set<string>()\n\n for (const [key, value] of Object.entries(nodeViews)) {\n if (!value || typeof value !== 'object') {\n continue\n }\n\n // If 'blocks' key exists with content, we need to override 'block' nodes\n if (key === 'blocks' && Object.keys(value).length > 0) {\n nodeTypesToOverride.add('block')\n }\n // If 'inlineBlocks' key exists with content, we need to override 'inlineBlock' nodes\n else if (key === 'inlineBlocks' && Object.keys(value).length > 0) {\n nodeTypesToOverride.add('inlineBlock')\n }\n // Regular node types\n else {\n nodeTypesToOverride.add(key)\n }\n }\n\n for (const node of nodes) {\n if ('getType' in node) {\n const nodeType = node.getType()\n\n if (nodeTypesToOverride.has(nodeType)) {\n applyNodeOverride({ node, nodeType })\n }\n }\n }\n }\n\n return nodes\n}\n\nexport function getEnabledNodesFromServerNodes({\n nodes,\n}: {\n nodes: Array<Klass<LexicalNode> | LexicalNodeReplacement> | Array<NodeWithHooks>\n}): Array<Klass<LexicalNode> | LexicalNodeReplacement> {\n return nodes.map((node) => {\n if ('node' in node) {\n return node.node\n }\n return node\n })\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 */\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", "/* eslint-disable regexp/no-obscure-range */\n/* eslint-disable regexp/no-empty-group */\n/* eslint-disable regexp/no-empty-capturing-group */\n/* eslint-disable regexp/optimal-quantifier-concatenation */\n/* eslint-disable regexp/no-misleading-capturing-group */\n/* eslint-disable regexp/no-contradiction-with-assertion */\n/* eslint-disable regexp/no-super-linear-backtracking */\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 */\n\nimport type { ListNode } from '@lexical/list'\n\nimport { $isListItemNode, $isListNode } from '@lexical/list'\nimport { $isHeadingNode, $isQuoteNode } from '@lexical/rich-text'\nimport {\n $isParagraphNode,\n $isTextNode,\n type ElementNode,\n type LexicalNode,\n type TextFormatType,\n} from 'lexical'\n\nimport type {\n ElementTransformer,\n MultilineElementTransformer,\n TextFormatTransformer,\n TextMatchTransformer,\n Transformer,\n} from './MarkdownTransformers.js'\n\ntype MarkdownFormatKind =\n | 'bold'\n | 'code'\n | 'horizontalRule'\n | 'italic'\n | 'italic_bold'\n | 'link'\n | 'noTransformation'\n | 'paragraphBlockQuote'\n | 'paragraphCodeBlock'\n | 'paragraphH1'\n | 'paragraphH2'\n | 'paragraphH3'\n | 'paragraphH4'\n | 'paragraphH5'\n | 'paragraphH6'\n | 'paragraphOrderedList'\n | 'paragraphUnorderedList'\n | 'strikethrough'\n | 'strikethrough_bold'\n | 'strikethrough_italic'\n | 'strikethrough_italic_bold'\n | 'underline'\n\ntype MarkdownCriteria = Readonly<{\n export?: (\n node: LexicalNode,\n traverseChildren: (elementNode: ElementNode) => string,\n ) => null | string\n exportFormat?: TextFormatType\n exportTag?: string\n exportTagClose?: string\n markdownFormatKind: MarkdownFormatKind | null | undefined\n regEx: RegExp\n regExForAutoFormatting: RegExp\n requiresParagraphStart: boolean | null | undefined\n}>\n\ntype MarkdownCriteriaArray = Array<MarkdownCriteria>\n\nconst autoFormatBase: MarkdownCriteria = {\n markdownFormatKind: null,\n regEx: /(?:)/,\n regExForAutoFormatting: /(?:)/,\n requiresParagraphStart: false,\n}\n\nconst paragraphStartBase: MarkdownCriteria = {\n ...autoFormatBase,\n requiresParagraphStart: true,\n}\n\nconst markdownHeader1: MarkdownCriteria = {\n ...paragraphStartBase,\n export: createHeadingExport(1),\n markdownFormatKind: 'paragraphH1',\n regEx: /^# /,\n regExForAutoFormatting: /^# /,\n}\n\nconst markdownHeader2: MarkdownCriteria = {\n ...paragraphStartBase,\n export: createHeadingExport(2),\n markdownFormatKind: 'paragraphH2',\n regEx: /^## /,\n regExForAutoFormatting: /^## /,\n}\n\nconst markdownHeader3: MarkdownCriteria = {\n ...paragraphStartBase,\n export: createHeadingExport(3),\n markdownFormatKind: 'paragraphH3',\n regEx: /^### /,\n regExForAutoFormatting: /^### /,\n}\n\nconst markdownHeader4: MarkdownCriteria = {\n ...paragraphStartBase,\n export: createHeadingExport(4),\n markdownFormatKind: 'paragraphH4',\n regEx: /^#### /,\n regExForAutoFormatting: /^#### /,\n}\n\nconst markdownHeader5: MarkdownCriteria = {\n ...paragraphStartBase,\n export: createHeadingExport(5),\n markdownFormatKind: 'paragraphH5',\n regEx: /^##### /,\n regExForAutoFormatting: /^##### /,\n}\n\nconst markdownHeader6: MarkdownCriteria = {\n ...paragraphStartBase,\n export: createHeadingExport(6),\n markdownFormatKind: 'paragraphH6',\n regEx: /^###### /,\n regExForAutoFormatting: /^###### /,\n}\n\nconst markdownBlockQuote: MarkdownCriteria = {\n ...paragraphStartBase,\n export: blockQuoteExport,\n markdownFormatKind: 'paragraphBlockQuote',\n regEx: /^> /,\n regExForAutoFormatting: /^> /,\n}\n\nconst markdownUnorderedListDash: MarkdownCriteria = {\n ...paragraphStartBase,\n export: listExport,\n markdownFormatKind: 'paragraphUnorderedList',\n regEx: /^(\\s{0,10})- /,\n regExForAutoFormatting: /^(\\s{0,10})- /,\n}\n\nconst markdownUnorderedListAsterisk: MarkdownCriteria = {\n ...paragraphStartBase,\n export: listExport,\n markdownFormatKind: 'paragraphUnorderedList',\n regEx: /^(\\s{0,10})\\* /,\n regExForAutoFormatting: /^(\\s{0,10})\\* /,\n}\n\nconst markdownOrderedList: MarkdownCriteria = {\n ...paragraphStartBase,\n export: listExport,\n markdownFormatKind: 'paragraphOrderedList',\n regEx: /^(\\s{0,10})(\\d+)\\.\\s/,\n regExForAutoFormatting: /^(\\s{0,10})(\\d+)\\.\\s/,\n}\n\nconst markdownHorizontalRule: MarkdownCriteria = {\n ...paragraphStartBase,\n markdownFormatKind: 'horizontalRule',\n regEx: /^\\*\\*\\*$/,\n regExForAutoFormatting: /^\\*\\*\\* /,\n}\n\nconst markdownHorizontalRuleUsingDashes: MarkdownCriteria = {\n ...paragraphStartBase,\n markdownFormatKind: 'horizontalRule',\n regEx: /^---$/,\n regExForAutoFormatting: /^--- /,\n}\n\nconst markdownInlineCode: MarkdownCriteria = {\n ...autoFormatBase,\n exportFormat: 'code',\n exportTag: '`',\n markdownFormatKind: 'code',\n regEx: /(`)(\\s*)([^`]*)(\\s*)(`)()/,\n regExForAutoFormatting: /(`)(\\s*\\b)([^`]*)(\\b\\s*)(`)(\\s)$/,\n}\n\nconst markdownBold: MarkdownCriteria = {\n ...autoFormatBase,\n exportFormat: 'bold',\n exportTag: '**',\n markdownFormatKind: 'bold',\n regEx: /(\\*\\*)(\\s*)([^*]*)(\\s*)(\\*\\*)()/,\n regExForAutoFormatting: /(\\*\\*)(\\s*\\b)([^*]*)(\\b\\s*)(\\*\\*)(\\s)$/,\n}\n\nconst markdownItalic: MarkdownCriteria = {\n ...autoFormatBase,\n exportFormat: 'italic',\n exportTag: '*',\n markdownFormatKind: 'italic',\n regEx: /(\\*)(\\s*)([^*]*)(\\s*)(\\*)()/,\n regExForAutoFormatting: /(\\*)(\\s*\\b)([^*]*)(\\b\\s*)(\\*)(\\s)$/,\n}\n\nconst markdownBold2: MarkdownCriteria = {\n ...autoFormatBase,\n exportFormat: 'bold',\n exportTag: '_',\n markdownFormatKind: 'bold',\n regEx: /(__)(\\s*)([^_]*)(\\s*)(__)()/,\n regExForAutoFormatting: /(__)(\\s*)([^_]*)(\\s*)(__)(\\s)$/,\n}\n\nconst markdownItalic2: MarkdownCriteria = {\n ...autoFormatBase,\n exportFormat: 'italic',\n exportTag: '_',\n markdownFormatKind: 'italic',\n regEx: /(_)()([^_]*)()(_)()/,\n regExForAutoFormatting: /(_)()([^_]*)()(_)(\\s)$/, // Maintain 7 groups.\n}\n\nconst fakeMarkdownUnderline: MarkdownCriteria = {\n ...autoFormatBase,\n exportFormat: 'underline',\n exportTag: '<u>',\n exportTagClose: '</u>',\n markdownFormatKind: 'underline',\n regEx: /(<u>)(\\s*)([^<]*)(\\s*)(<\\/u>)()/,\n regExForAutoFormatting: /(<u>)(\\s*\\b)([^<]*)(\\b\\s*)(<\\/u>)(\\s)$/,\n}\n\nconst markdownStrikethrough: MarkdownCriteria = {\n ...autoFormatBase,\n exportFormat: 'strikethrough',\n exportTag: '~~',\n markdownFormatKind: 'strikethrough',\n regEx: /(~~)(\\s*)([^~]*)(\\s*)(~~)()/,\n regExForAutoFormatting: /(~~)(\\s*\\b)([^~]*)(\\b\\s*)(~~)(\\s)$/,\n}\n\nconst markdownStrikethroughItalicBold: MarkdownCriteria = {\n ...autoFormatBase,\n markdownFormatKind: 'strikethrough_italic_bold',\n regEx: /(~~_\\*\\*)(\\s*\\b)([^*_~]+)(\\b\\s*)(\\*\\*_~~)()/,\n regExForAutoFormatting: /(~~_\\*\\*)(\\s*\\b)([^*_~]+)(\\b\\s*)(\\*\\*_~~)(\\s)$/,\n}\n\nconst markdownItalicbold: MarkdownCriteria = {\n ...autoFormatBase,\n markdownFormatKind: 'italic_bold',\n regEx: /(_\\*\\*)(\\s*\\b)([^*_]+)(\\b\\s*)(\\*\\*_)/,\n regExForAutoFormatting: /(_\\*\\*)(\\s*\\b)([^*_]+)(\\b\\s*)(\\*\\*_)(\\s)$/,\n}\n\nconst markdownStrikethroughItalic: MarkdownCriteria = {\n ...autoFormatBase,\n markdownFormatKind: 'strikethrough_italic',\n regEx: /(~~_)(\\s*)([^_~]+)(\\s*)(_~~)/,\n regExForAutoFormatting: /(~~_)(\\s*)([^_~]+)(\\s*)(_~~)(\\s)$/,\n}\n\nconst markdownStrikethroughBold: MarkdownCriteria = {\n ...autoFormatBase,\n markdownFormatKind: 'strikethrough_bold',\n regEx: /(~~\\*\\*)(\\s*\\b)([^*~]+)(\\b\\s*)(\\*\\*~~)/,\n regExForAutoFormatting: /(~~\\*\\*)(\\s*\\b)([^*~]+)(\\b\\s*)(\\*\\*~~)(\\s)$/,\n}\n\nconst markdownLink: MarkdownCriteria = {\n ...autoFormatBase,\n markdownFormatKind: 'link',\n regEx: /(\\[)([^\\]]*)(\\]\\()([^)]*)(\\)*)()/,\n regExForAutoFormatting: /(\\[)([^\\]]*)(\\]\\()([^)]*)(\\)*)(\\s)$/,\n}\n\nconst allMarkdownCriteriaForTextNodes: MarkdownCriteriaArray = [\n // Place the combination formats ahead of the individual formats.\n // Combos\n markdownStrikethroughItalicBold,\n markdownItalicbold,\n markdownStrikethroughItalic,\n markdownStrikethroughBold, // Individuals\n markdownInlineCode,\n markdownBold,\n markdownItalic, // Must appear after markdownBold\n markdownBold2,\n markdownItalic2, // Must appear after markdownBold2.\n fakeMarkdownUnderline,\n markdownStrikethrough,\n markdownLink,\n]\n\nconst allMarkdownCriteriaForParagraphs: MarkdownCriteriaArray = [\n markdownHeader1,\n markdownHeader2,\n markdownHeader3,\n markdownHeader4,\n markdownHeader5,\n markdownHeader6,\n markdownBlockQuote,\n markdownUnorderedListDash,\n markdownUnorderedListAsterisk,\n markdownOrderedList,\n markdownHorizontalRule,\n markdownHorizontalRuleUsingDashes,\n]\n\nexport function getAllMarkdownCriteriaForParagraphs(): MarkdownCriteriaArray {\n return allMarkdownCriteriaForParagraphs\n}\n\nexport function getAllMarkdownCriteriaForTextNodes(): MarkdownCriteriaArray {\n return allMarkdownCriteriaForTextNodes\n}\n\ntype Block = (\n node: LexicalNode,\n exportChildren: (elementNode: ElementNode) => string,\n) => null | string\n\nfunction createHeadingExport(level: number): Block {\n return (node, exportChildren) => {\n return $isHeadingNode(node) && node.getTag() === 'h' + level\n ? '#'.repeat(level) + ' ' + exportChildren(node)\n : null\n }\n}\n\nfunction listExport(node: LexicalNode, exportChildren: (_node: ElementNode) => string) {\n return $isListNode(node) ? processNestedLists(node, exportChildren, 0) : null\n}\n\n// TODO: should be param\nconst LIST_INDENT_SIZE = 4\n\nfunction processNestedLists(\n listNode: ListNode,\n exportChildren: (node: ElementNode) => string,\n depth: number,\n): string {\n const output: string[] = []\n const children = listNode.getChildren()\n let index = 0\n\n for (const listItemNode of children) {\n if ($isListItemNode(listItemNode)) {\n if (listItemNode.getChildrenSize() === 1) {\n const firstChild = listItemNode.getFirstChild()\n\n if ($isListNode(firstChild)) {\n output.push(processNestedLists(firstChild, exportChildren, depth + 1))\n continue\n }\n }\n\n const indent = ' '.repeat(depth * LIST_INDENT_SIZE)\n const prefix = listNode.getListType() === 'bullet' ? '- ' : `${listNode.getStart() + index}. `\n output.push(indent + prefix + exportChildren(listItemNode))\n index++\n }\n }\n\n return output.join('\\n')\n}\n\nfunction blockQuoteExport(node: LexicalNode, exportChildren: (_node: ElementNode) => string) {\n return $isQuoteNode(node) ? '> ' + exportChildren(node) : null\n}\n\nexport function indexBy<T>(\n list: Array<T>,\n callback: (arg0: T) => string | undefined,\n): Readonly<Record<string, Array<T>>> {\n const index: Record<string, Array<T>> = {}\n\n for (const item of list) {\n const key = callback(item)\n\n if (!key) {\n continue\n }\n\n if (index[key]) {\n index[key].push(item)\n } else {\n index[key] = [item]\n }\n }\n\n return index\n}\n\nexport function transformersByType(transformers: Array<Transformer>): Readonly<{\n element: Array<ElementTransformer>\n multilineElement: Array<MultilineElementTransformer>\n textFormat: Array<TextFormatTransformer>\n textMatch: Array<TextMatchTransformer>\n}> {\n const byType = indexBy(transformers, (t) => t.type)\n\n return {\n element: (byType.element || []) as Array<ElementTransformer>,\n multilineElement: (byType['multiline-element'] || []) as Array<MultilineElementTransformer>,\n textFormat: (byType['text-format'] || []) as Array<TextFormatTransformer>,\n textMatch: (byType['text-match'] || []) as Array<TextMatchTransformer>,\n }\n}\n\nexport const PUNCTUATION_OR_SPACE = /[!-/:-@[-`{-~\\s]/\n\nconst MARKDOWN_EMPTY_LINE_REG_EXP = /^\\s{0,3}$/\n\nexport function isEmptyParagraph(node: LexicalNode): boolean {\n if (!$isParagraphNode(node)) {\n return false\n }\n\n const firstChild = node.getFirstChild()\n return (\n firstChild == null ||\n (node.getChildrenSize() === 1 &&\n $isTextNode(firstChild) &&\n MARKDOWN_EMPTY_LINE_REG_EXP.test(firstChild.getTextContent()))\n )\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 */\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", "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", "/**\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 { TextNode } from 'lexical'\n\nimport type { TextFormatTransformersIndex } from './MarkdownImport.js'\nimport type { TextFormatTransformer } from './MarkdownTransformers.js'\n\nimport { PUNCTUATION_OR_SPACE } from './utils.js'\n\nexport function findOutermostTextFormatTransformer(\n textNode: TextNode,\n textFormatTransformersIndex: TextFormatTransformersIndex,\n): {\n endIndex: number\n match: RegExpMatchArray\n startIndex: number\n transformer: TextFormatTransformer\n} | null {\n const textContent = textNode.getTextContent()\n const match = findOutermostMatch(textContent, textFormatTransformersIndex)\n\n if (!match) {\n return null\n }\n\n const textFormatMatchStart: number = match.index || 0\n const textFormatMatchEnd = textFormatMatchStart + match[0].length\n\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n const transformer: TextFormatTransformer = textFormatTransformersIndex.transformersByTag[match[1]]\n\n return {\n endIndex: textFormatMatchEnd,\n match,\n startIndex: textFormatMatchStart,\n transformer,\n }\n}\n\n// Finds first \"<tag>content<tag>\" match that is not nested into another tag\nfunction findOutermostMatch(\n textContent: string,\n textTransformersIndex: TextFormatTransformersIndex,\n): null | RegExpMatchArray {\n const openTagsMatch = textContent.match(textTransformersIndex.openTagsRegExp)\n\n if (openTagsMatch == null) {\n return null\n }\n\n for (const match of openTagsMatch) {\n // Open tags reg exp might capture leading space so removing it\n // before using match to find transformer\n const tag = match.replace(/^\\s/, '')\n const fullMatchRegExp = textTransformersIndex.fullMatchRegExpByTag[tag]\n if (fullMatchRegExp == null) {\n continue\n }\n\n const fullMatch = textContent.match(fullMatchRegExp)\n const transformer = textTransformersIndex.transformersByTag[tag]\n if (fullMatch != null && transformer != null) {\n if (transformer.intraword !== false) {\n return fullMatch\n }\n\n // For non-intraword transformers checking if it's within a word\n // or surrounded with space/punctuation/newline\n const { index = 0 } = fullMatch\n const beforeChar = textContent[index - 1]\n const afterChar = textContent[index + fullMatch[0].length]\n\n if (\n (!beforeChar || PUNCTUATION_OR_SPACE.test(beforeChar)) &&\n (!afterChar || PUNCTUATION_OR_SPACE.test(afterChar))\n ) {\n return fullMatch\n }\n }\n }\n\n return null\n}\n\nexport function importTextFormatTransformer(\n textNode: TextNode,\n startIndex: number,\n endIndex: number,\n transformer: TextFormatTransformer,\n match: RegExpMatchArray,\n): {\n nodeAfter: TextNode | undefined // If split\n nodeBefore: TextNode | undefined // If split\n transformedNode: TextNode\n} {\n const textContent = textNode.getTextContent()\n\n // No text matches - we can safely process the text format match\n let nodeAfter: TextNode | undefined\n let nodeBefore: TextNode | undefined\n let transformedNode: TextNode\n\n // If matching full content there's no need to run splitText and can reuse existing textNode\n // to update its content and apply format. E.g. for **_Hello_** string after applying bold\n // format (**) it will reuse the same text node to apply italic (_)\n if (match[0] === textContent) {\n transformedNode = textNode\n } else {\n if (startIndex === 0) {\n ;[transformedNode, nodeAfter] = textNode.splitText(endIndex) as [\n TextNode,\n TextNode | undefined,\n ]\n } else {\n ;[nodeBefore, transformedNode, nodeAfter] = textNode.splitText(startIndex, endIndex) as [\n TextNode,\n TextNode,\n TextNode | undefined,\n ]\n }\n }\n\n transformedNode.setTextContent(match[2]!)\n if (transformer) {\n for (const format of transformer.format) {\n if (!transformedNode.hasFormat(format)) {\n transformedNode.toggleFormat(format)\n }\n }\n }\n\n return {\n nodeAfter,\n nodeBefore,\n transformedNode,\n }\n}\n", "import { 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 { TextMatchTransformer } from './MarkdownTransformers.js'\n\nexport function findOutermostTextMatchTransformer(\n textNode_: TextNode,\n textMatchTransformers: Array<TextMatchTransformer>,\n): {\n endIndex: number\n match: RegExpMatchArray\n startIndex: number\n transformer: TextMatchTransformer\n} | null {\n const textNode = textNode_\n\n let foundMatchStartIndex: number | undefined = undefined\n let foundMatchEndIndex: number | undefined = undefined\n let foundMatchTransformer: TextMatchTransformer | undefined = undefined\n let foundMatch: RegExpMatchArray | undefined = undefined\n\n for (const transformer of textMatchTransformers) {\n if (!transformer.replace || !transformer.importRegExp) {\n continue\n }\n const match = textNode.getTextContent().match(transformer.importRegExp)\n\n if (!match) {\n continue\n }\n\n const startIndex = match.index || 0\n const endIndex = transformer.getEndIndex\n ? transformer.getEndIndex(textNode, match)\n : startIndex + match[0].length\n\n if (endIndex === false) {\n continue\n }\n\n if (\n foundMatchStartIndex === undefined ||\n foundMatchEndIndex === undefined ||\n (startIndex < foundMatchStartIndex && endIndex > foundMatchEndIndex)\n ) {\n foundMatchStartIndex = startIndex\n foundMatchEndIndex = endIndex\n foundMatchTransformer = transformer\n foundMatch = match\n }\n }\n\n if (\n foundMatchStartIndex === undefined ||\n foundMatchEndIndex === undefined ||\n foundMatchTransformer === undefined ||\n foundMatch === undefined\n ) {\n return null\n }\n\n return {\n endIndex: foundMatchEndIndex,\n match: foundMatch,\n startIndex: foundMatchStartIndex,\n transformer: foundMatchTransformer,\n }\n}\n\nexport function importFoundTextMatchTransformer(\n textNode: TextNode,\n startIndex: number,\n endIndex: number,\n transformer: TextMatchTransformer,\n match: RegExpMatchArray,\n): {\n nodeAfter: TextNode | undefined // If split\n nodeBefore: TextNode | undefined // If split\n transformedNode?: TextNode\n} | null {\n let nodeAfter, nodeBefore, transformedNode\n\n if (startIndex === 0) {\n ;[transformedNode, nodeAfter] = textNode.splitText(endIndex)\n } else {\n ;[nodeBefore, transformedNode, nodeAfter] = textNode.splitText(startIndex, endIndex)\n }\n\n if (!transformer.replace) {\n return null\n }\n const potentialTransformedNode = transformedNode\n ? transformer.replace(transformedNode, match)\n : undefined\n\n return {\n nodeAfter,\n nodeBefore,\n transformedNode: potentialTransformedNode || undefined,\n }\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 */\n\nimport type { ElementNode, LexicalEditor, TextNode } from 'lexical'\n\nimport {\n $createRangeSelection,\n $getSelection,\n $isLineBreakNode,\n $isRangeSelection,\n $isRootOrShadowRoot,\n $isTextNode,\n $setSelection,\n} from 'lexical'\n\nimport type {\n ElementTransformer,\n MultilineElementTransformer,\n TextFormatTransformer,\n TextMatchTransformer,\n Transformer,\n} from './MarkdownTransformers.js'\n\nimport { TRANSFORMERS } from './index.js'\nimport { indexBy, PUNCTUATION_OR_SPACE, transformersByType } from './utils.js'\n\nfunction runElementTransformers(\n parentNode: ElementNode,\n anchorNode: TextNode,\n anchorOffset: number,\n elementTransformers: ReadonlyArray<ElementTransformer>,\n): boolean {\n const grandParentNode = parentNode.getParent()\n\n if (!$isRootOrShadowRoot(grandParentNode) || parentNode.getFirstChild() !== anchorNode) {\n return false\n }\n\n const textContent = anchorNode.getTextContent()\n\n // Checking for anchorOffset position to prevent any checks for cases when caret is too far\n // from a line start to be a part of block-level markdown trigger.\n //\n // TODO:\n // Can have a quick check if caret is close enough to the beginning of the string (e.g. offset less than 10-20)\n // since otherwise it won't be a markdown shortcut, but tables are exception\n if (textContent[anchorOffset - 1] !== ' ') {\n return false\n }\n\n for (const { regExp, replace } of elementTransformers) {\n const match = textContent.match(regExp)\n\n if (match && match[0].length === (match[0].endsWith(' ') ? anchorOffset : anchorOffset - 1)) {\n const nextSiblings = anchorNode.getNextSiblings()\n const [leadingNode, remainderNode] = anchorNode.splitText(anchorOffset)\n leadingNode?.remove()\n const siblings = remainderNode ? [remainderNode, ...nextSiblings] : nextSiblings\n if (replace(parentNode, siblings, match, false) !== false) {\n return true\n }\n }\n }\n\n return false\n}\n\nfunction runMultilineElementTransformers(\n parentNode: ElementNode,\n anchorNode: TextNode,\n anchorOffset: number,\n elementTransformers: ReadonlyArray<MultilineElementTransformer>,\n): boolean {\n const grandParentNode = parentNode.getParent()\n\n if (!$isRootOrShadowRoot(grandParentNode) || parentNode.getFirstChild() !== anchorNode) {\n return false\n }\n\n const textContent = anchorNode.getTextContent()\n\n // Checking for anchorOffset position to prevent any checks for cases when caret is too far\n // from a line start to be a part of block-level markdown trigger.\n //\n // TODO:\n // Can have a quick check if caret is close enough to the beginning of the string (e.g. offset less than 10-20)\n // since otherwise it won't be a markdown shortcut, but tables are exception\n if (textContent[anchorOffset - 1] !== ' ') {\n return false\n }\n\n for (const { regExpEnd, regExpStart, replace } of elementTransformers) {\n if (\n (regExpEnd && !('optional' in regExpEnd)) ||\n (regExpEnd && 'optional' in regExpEnd && !regExpEnd.optional)\n ) {\n continue\n }\n\n const match = textContent.match(regExpStart)\n\n if (match && match[0].length === (match[0].endsWith(' ') ? anchorOffset : anchorOffset - 1)) {\n const nextSiblings = anchorNode.getNextSiblings()\n const [leadingNode, remainderNode] = anchorNode.splitText(anchorOffset)\n leadingNode?.remove()\n const siblings = remainderNode ? [remainderNode, ...nextSiblings] : nextSiblings\n\n if (replace(parentNode, siblings, match, null, null, false) !== false) {\n return true\n }\n }\n }\n\n return false\n}\n\nfunction runTextMatchTransformers(\n anchorNode: TextNode,\n anchorOffset: number,\n transformersByTrigger: Readonly<Record<string, Array<TextMatchTransformer>>>,\n): boolean {\n let textContent = anchorNode.getTextContent()\n const lastChar = textContent[anchorOffset - 1]!\n const transformers = transformersByTrigger[lastChar]\n\n if (transformers == null) {\n return false\n }\n\n // If typing in the middle of content, remove the tail to do\n // reg exp match up to a string end (caret position)\n if (anchorOffset < textContent.length) {\n textContent = textContent.slice(0, anchorOffset)\n }\n\n for (const transformer of transformers) {\n if (!transformer.replace || !transformer.regExp) {\n continue\n }\n const match = textContent.match(transformer.regExp)\n\n if (match === null) {\n continue\n }\n\n const startIndex = match.index || 0\n const endIndex = startIndex + match[0].length\n let replaceNode\n\n if (startIndex === 0) {\n ;[replaceNode] = anchorNode.splitText(endIndex)\n } else {\n ;[, replaceNode] = anchorNode.splitText(startIndex, endIndex)\n }\n if (replaceNode) {\n replaceNode.selectNext(0, 0)\n transformer.replace(replaceNode, match)\n }\n return true\n }\n\n return false\n}\n\nfunction $runTextFormatTransformers(\n anchorNode: TextNode,\n anchorOffset: number,\n textFormatTransformers: Readonly<Record<string, ReadonlyArray<TextFormatTransformer>>>,\n): boolean {\n const textContent = anchorNode.getTextContent()\n const closeTagEndIndex = anchorOffset - 1\n const closeChar = textContent[closeTagEndIndex]!\n // Quick check if we're possibly at the end of inline markdown style\n const matchers = textFormatTransformers[closeChar]\n\n if (!matchers) {\n return false\n }\n\n for (const matcher of matchers) {\n const { tag } = matcher\n const tagLength = tag.length\n const closeTagStartIndex = closeTagEndIndex - tagLength + 1\n\n // If tag is not single char check if rest of it matches with text content\n if (tagLength > 1) {\n if (!isEqualSubString(textContent, closeTagStartIndex, tag, 0, tagLength)) {\n continue\n }\n }\n\n // Space before closing tag cancels inline markdown\n if (textContent[closeTagStartIndex - 1] === ' ') {\n continue\n }\n\n // Some tags can not be used within words, hence should have newline/space/punctuation after it\n const afterCloseTagChar = textContent[closeTagEndIndex + 1]\n\n if (\n matcher.intraword === false &&\n afterCloseTagChar &&\n !PUNCTUATION_OR_SPACE.test(afterCloseTagChar)\n ) {\n continue\n }\n\n const closeNode = anchorNode\n let openNode = closeNode\n let openTagStartIndex = getOpenTagStartIndex(textContent, closeTagStartIndex, tag)\n\n // Go through text node siblings and search for opening tag\n // if haven't found it within the same text node as closing tag\n let sibling: null | TextNode = openNode\n\n while (openTagStartIndex < 0 && (sibling = sibling.getPreviousSibling<TextNode>())) {\n if ($isLineBreakNode(sibling)) {\n break\n }\n\n if ($isTextNode(sibling)) {\n const siblingTextContent = sibling.getTextContent()\n openNode = sibling\n openTagStartIndex = getOpenTagStartIndex(siblingTextContent, siblingTextContent.length, tag)\n }\n }\n\n // Opening tag is not found\n if (openTagStartIndex < 0) {\n continue\n }\n\n // No content between opening and closing tag\n if (openNode === closeNode && openTagStartIndex + tagLength === closeTagStartIndex) {\n continue\n }\n\n // Checking longer tags for repeating chars (e.g. *** vs **)\n const prevOpenNodeText = openNode.getTextContent()\n\n if (openTagStartIndex > 0 && prevOpenNodeText[openTagStartIndex - 1] === closeChar) {\n continue\n }\n\n // Some tags can not be used within words, hence should have newline/space/punctuation before it\n const beforeOpenTagChar = prevOpenNodeText[openTagStartIndex - 1]\n\n if (\n matcher.intraword === false &&\n beforeOpenTagChar &&\n !PUNCTUATION_OR_SPACE.test(beforeOpenTagChar)\n ) {\n continue\n }\n\n // Clean text from opening and closing tags (starting from closing tag\n // to prevent any offset shifts if we start from opening one)\n const prevCloseNodeText = closeNode.getTextContent()\n const closeNodeText =\n prevCloseNodeText.slice(0, closeTagStartIndex) + prevCloseNodeText.slice(closeTagEndIndex + 1)\n closeNode.setTextContent(closeNodeText)\n const openNodeText = openNode === closeNode ? closeNodeText : prevOpenNodeText\n openNode.setTextContent(\n openNodeText.slice(0, openTagStartIndex) + openNodeText.slice(openTagStartIndex + tagLength),\n )\n const selection = $getSelection()\n const nextSelection = $createRangeSelection()\n $setSelection(nextSelection)\n // Adjust offset based on deleted chars\n const newOffset = closeTagEndIndex - tagLength * (openNode === closeNode ? 2 : 1) + 1\n nextSelection.anchor.set(openNode.__key, openTagStartIndex, 'text')\n nextSelection.focus.set(closeNode.__key, newOffset, 'text')\n\n // Apply formatting to selected text\n for (const format of matcher.format) {\n if (!nextSelection.hasFormat(format)) {\n nextSelection.formatText(format)\n }\n }\n\n // Collapse selection up to the focus point\n nextSelection.anchor.set(\n nextSelection.focus.key,\n nextSelection.focus.offset,\n nextSelection.focus.type,\n )\n\n // Remove formatting from collapsed selection\n for (const format of matcher.format) {\n if (nextSelection.hasFormat(format)) {\n nextSelection.toggleFormat(format)\n }\n }\n\n if ($isRangeSelection(selection)) {\n nextSelection.format = selection.format\n }\n\n return true\n }\n\n return false\n}\n\nfunction getOpenTagStartIndex(string: string, maxIndex: number, tag: string): number {\n const tagLength = tag.length\n\n for (let i = maxIndex; i >= tagLength; i--) {\n const startIndex = i - tagLength\n\n if (\n isEqualSubString(string, startIndex, tag, 0, tagLength) && // Space after opening tag cancels transformation\n string[startIndex + tagLength] !== ' '\n ) {\n return startIndex\n }\n }\n\n return -1\n}\n\nfunction isEqualSubString(\n stringA: string,\n aStart: number,\n stringB: string,\n bStart: number,\n length: number,\n): boolean {\n for (let i = 0; i < length; i++) {\n if (stringA[aStart + i] !== stringB[bStart + i]) {\n return false\n }\n }\n\n return true\n}\n\nexport function registerMarkdownShortcuts(\n editor: LexicalEditor,\n transformers: Array<Transformer> = TRANSFORMERS,\n): () => void {\n const byType = transformersByType(transformers)\n const textFormatTransformersByTrigger = indexBy(\n byType.textFormat,\n ({ tag }) => tag[tag.length - 1],\n )\n const textMatchTransformersByTrigger = indexBy(byType.textMatch, ({ trigger }) => trigger)\n\n for (const transformer of transformers) {\n const type = transformer.type\n if (type === 'element' || type === 'text-match' || type === 'multiline-element') {\n const dependencies = transformer.dependencies\n for (const node of dependencies) {\n if (!editor.hasNode(node)) {\n throw new Error(\n 'MarkdownShortcuts: missing dependency %s for transformer. Ensure node dependency is included in editor initial config.' +\n node.getType(),\n )\n }\n }\n }\n }\n\n const $transform = (parentNode: ElementNode, anchorNode: TextNode, anchorOffset: number) => {\n if (runElementTransformers(parentNode, anchorNode, anchorOffset, byType.element)) {\n return\n }\n\n if (\n runMultilineElementTransformers(parentNode, anchorNode, anchorOffset, byType.multilineElement)\n ) {\n return\n }\n\n if (runTextMatchTransformers(anchorNode, anchorOffset, textMatchTransformersByTrigger)) {\n return\n }\n\n $runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransformersByTrigger)\n }\n\n return editor.registerUpdateListener(({ dirtyLeaves, editorState, prevEditorState, tags }) => {\n // Ignore updates from collaboration and undo/redo (as changes already calculated)\n if (tags.has('collaboration') || tags.has('historic')) {\n return\n }\n\n // If editor is still composing (i.e. backticks) we must wait before the user confirms the key\n if (editor.isComposing()) {\n return\n }\n\n const selection = editorState.read($getSelection)\n const prevSelection = prevEditorState.read($getSelection)\n\n // We expect selection to be a collapsed range and not match previous one (as we want\n // to trigger transforms only as user types)\n if (\n !$isRangeSelection(prevSelection) ||\n !$isRangeSelection(selection) ||\n !selection.isCollapsed() ||\n selection.is(prevSelection)\n ) {\n return\n }\n\n const anchorKey = selection.anchor.key\n const anchorOffset = selection.anchor.offset\n\n const anchorNode = editorState._nodeMap.get(anchorKey)\n\n if (\n !$isTextNode(anchorNode) ||\n !dirtyLeaves.has(anchorKey) ||\n (anchorOffset !== 1 && anchorOffset > prevSelection.anchor.offset + 1)\n ) {\n return\n }\n\n editor.update(() => {\n // Markdown is not available inside code\n if (anchorNode.hasFormat('code')) {\n return\n }\n\n const parentNode = anchorNode.getParent()\n\n if (parentNode === null) {\n return\n }\n\n $transform(parentNode, anchorNode, selection.anchor.offset)\n })\n })\n}\n", "/* eslint-disable regexp/no-unused-capturing-group */\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 */\n\nimport type { ListType } from '@lexical/list'\nimport type { HeadingTagType } from '@lexical/rich-text'\nimport type { ElementNode, Klass, LexicalNode, TextFormatType, TextNode } from 'lexical'\n\nimport {\n $createListItemNode,\n $createListNode,\n $isListItemNode,\n $isListNode,\n ListItemNode,\n ListNode,\n} from '@lexical/list'\nimport {\n $createHeadingNode,\n $createQuoteNode,\n $isHeadingNode,\n $isQuoteNode,\n HeadingNode,\n QuoteNode,\n} from '@lexical/rich-text'\nimport { $createLineBreakNode } from 'lexical'\n\nexport type Transformer =\n | ElementTransformer\n | MultilineElementTransformer\n | TextFormatTransformer\n | TextMatchTransformer\n\nexport type ElementTransformer = {\n dependencies: Array<Klass<LexicalNode>>\n /**\n * `export` is called when the `$convertToMarkdownString` is called to convert the editor state into markdown.\n *\n * @return return null to cancel the export, even though the regex matched. Lexical will then search for the next transformer.\n */\n export: (\n node: LexicalNode,\n\n traverseChildren: (node: ElementNode) => string,\n ) => null | string\n regExp: RegExp\n /**\n * `replace` is called when markdown is imported or typed in the editor\n *\n * @return return false to cancel the transform, even though the regex matched. Lexical will then search for the next transformer.\n */\n replace: (\n parentNode: ElementNode,\n children: Array<LexicalNode>,\n match: Array<string>,\n /**\n * Whether the match is from an import operation (e.g. through `$convertFromMarkdownString`) or not (e.g. through typing in the editor).\n */\n isImport: boolean,\n ) => boolean | void\n type: 'element'\n}\n\nexport type MultilineElementTransformer = {\n dependencies: Array<Klass<LexicalNode>>\n /**\n * `export` is called when the `$convertToMarkdownString` is called to convert the editor state into markdown.\n *\n * @return return null to cancel the export, even though the regex matched. Lexical will then search for the next transformer.\n */\n export?: (\n node: LexicalNode,\n\n traverseChildren: (node: ElementNode) => string,\n ) => null | string\n /**\n * Use this function to manually handle the import process, once the `regExpStart` has matched successfully.\n * Without providing this function, the default behavior is to match until `regExpEnd` is found, or until the end of the document if `regExpEnd.optional` is true.\n *\n * @returns a tuple or null. The 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. If null is returned, the next multilineElementTransformer will be tried. If undefined is returned, the default behavior will be used.\n */\n handleImportAfterStartMatch?: (args: {\n lines: Array<string>\n rootNode: ElementNode\n startLineIndex: number\n startMatch: RegExpMatchArray\n transformer: MultilineElementTransformer\n }) => [boolean, number] | null | undefined\n /**\n * This regex determines when to stop matching. Anything in between regExpStart and regExpEnd will be matched\n */\n regExpEnd?:\n | {\n /**\n * Whether the end match is optional. If true, the end match is not required to match for the transformer to be triggered.\n * The entire text from regexpStart to the end of the document will then be matched.\n */\n optional?: true\n regExp: RegExp\n }\n | RegExp\n /**\n * This regex determines when to start matching\n */\n regExpStart: RegExp\n /**\n * `replace` is called only when markdown is imported in the editor, not when it's typed\n *\n * @return return false to cancel the transform, even though the regex matched. Lexical will then search for the next transformer.\n */\n replace: (\n rootNode: ElementNode,\n /**\n * During markdown shortcut transforms, children nodes may be provided to the transformer. If this is the case, no `linesInBetween` will be provided and\n * the children nodes should be used instead of the `linesInBetween` to create the new node.\n */\n children: Array<LexicalNode> | null,\n startMatch: Array<string>,\n endMatch: Array<string> | null,\n /**\n * linesInBetween includes the text between the start & end matches, split up by lines, not including the matches themselves.\n * This is null when the transformer is triggered through markdown shortcuts (by typing in the editor)\n */\n linesInBetween: Array<string> | null,\n /**\n * Whether the match is from an import operation (e.g. through `$convertFromMarkdownString`) or not (e.g. through typing in the editor).\n */\n isImport: boolean,\n ) => boolean | void\n type: 'multiline-element'\n}\n\nexport type TextFormatTransformer = Readonly<{\n format: ReadonlyArray<TextFormatType>\n intraword?: boolean\n tag: string\n type: 'text-format'\n}>\n\nexport type TextMatchTransformer = Readonly<{\n dependencies: Array<Klass<LexicalNode>>\n /**\n * Determines how a node should be exported to markdown\n */\n export?: (\n node: LexicalNode,\n\n exportChildren: (node: ElementNode) => string,\n\n exportFormat: (node: TextNode, textContent: string) => string,\n ) => null | string\n /**\n * For import operations, this function can be used to determine the end index of the match, after `importRegExp` has matched.\n * Without this function, the end index will be determined by the length of the match from `importRegExp`. Manually determining the end index can be useful if\n * the match from `importRegExp` is not the entire text content of the node. That way, `importRegExp` can be used to match only the start of the node, and `getEndIndex`\n * can be used to match the end of the node.\n *\n * @returns The end index of the match, or false if the match was unsuccessful and a different transformer should be tried.\n */\n getEndIndex?: (node: TextNode, match: RegExpMatchArray) => false | number\n /**\n * This regex determines what text is matched during markdown imports\n */\n importRegExp?: RegExp\n /**\n * This regex determines what text is matched for markdown shortcuts while typing in the editor\n */\n regExp: RegExp\n /**\n * Determines how the matched markdown text should be transformed into a node during the markdown import process\n *\n * @returns nothing, or a TextNode that may be a child of the new node that is created.\n * If a TextNode is returned, text format matching will be applied to it (e.g. bold, italic, etc.)\n */\n replace?: (node: TextNode, match: RegExpMatchArray) => TextNode | void\n /**\n * Single character that allows the transformer to trigger when typed in the editor. This does not affect markdown imports outside of the markdown shortcut plugin.\n * If the trigger is matched, the `regExp` will be used to match the text in the second step.\n */\n trigger?: string\n type: 'text-match'\n}>\n\nconst EMPTY_OR_WHITESPACE_ONLY = /^[\\t ]*$/\nconst ORDERED_LIST_REGEX = /^(\\s*)(\\d+)\\.\\s/\nconst UNORDERED_LIST_REGEX = /^(\\s*)[-*+]\\s/\nconst CHECK_LIST_REGEX = /^(\\s*)(?:-\\s)?\\s?(\\[(\\s|x)?\\])\\s/i\nconst HEADING_REGEX = /^(#{1,6})\\s/\nconst QUOTE_REGEX = /^>\\s/\nconst CODE_START_REGEX = /^[ \\t]*(\\\\`\\\\`\\\\`|```)(\\w+)?/\nconst CODE_END_REGEX = /[ \\t]*(\\\\`\\\\`\\\\`|```)$/\nconst CODE_SINGLE_LINE_REGEX = /^[ \\t]*```[^`]+(?:(?:`{1,2}|`{4,})[^`]+)*```(?:[^`]|$)/\nconst TABLE_ROW_REG_EXP = /^\\|(.+)\\|\\s?$/\nconst TABLE_ROW_DIVIDER_REG_EXP = /^(\\| ?:?-*:? ?)+\\|\\s?$/\nconst TAG_START_REGEX = /^[ \\t]*<[a-z_][\\w-]*(?:\\s[^<>]*)?\\/?>/i\nconst TAG_END_REGEX = /^[ \\t]*<\\/[a-z_][\\w-]*\\s*>/i\n\nconst createBlockNode = (\n createNode: (match: Array<string>) => ElementNode,\n): ElementTransformer['replace'] => {\n return (parentNode, children, match) => {\n const node = createNode(match)\n node.append(...children)\n parentNode.replace(node)\n node.select(0, 0)\n }\n}\n\n// Amount of spaces that define indentation level\n// TODO: should be an option\nconst LIST_INDENT_SIZE = 4\n\nfunction getIndent(whitespaces: string): number {\n const tabs = whitespaces.match(/\\t/g)\n const spaces = whitespaces.match(/ /g)\n\n let indent = 0\n\n if (tabs) {\n indent += tabs.length\n }\n\n if (spaces) {\n indent += Math.floor(spaces.length / LIST_INDENT_SIZE)\n }\n\n return indent\n}\n\nconst listReplace = (listType: ListType): ElementTransformer['replace'] => {\n return (parentNode, children, match) => {\n const previousNode = parentNode.getPreviousSibling()\n const nextNode = parentNode.getNextSibling()\n const listItem = $createListItemNode(listType === 'check' ? match[3] === 'x' : undefined)\n if ($isListNode(nextNode) && nextNode.getListType() === listType) {\n const firstChild = nextNode.getFirstChild()\n if (firstChild !== null) {\n firstChild.insertBefore(listItem)\n } else {\n // should never happen, but let's handle gracefully, just in case.\n nextNode.append(listItem)\n }\n parentNode.remove()\n } else if ($isListNode(previousNode) && previousNode.getListType() === listType) {\n previousNode.append(listItem)\n parentNode.remove()\n } else {\n const list = $createListNode(listType, listType === 'number' ? Number(match[2]) : undefined)\n list.append(listItem)\n parentNode.replace(list)\n }\n listItem.append(...children)\n listItem.select(0, 0)\n const indent = getIndent(match[1]!)\n if (indent) {\n listItem.setIndent(indent)\n }\n }\n}\n\nconst listExport = (\n listNode: ListNode,\n exportChildren: (node: ElementNode) => string,\n depth: number,\n): string => {\n const output: string[] = []\n const children = listNode.getChildren()\n let index = 0\n for (const listItemNode of children) {\n if ($isListItemNode(listItemNode)) {\n if (listItemNode.getChildrenSize() === 1) {\n const firstChild = listItemNode.getFirstChild()\n if ($isListNode(firstChild)) {\n output.push(listExport(firstChild, exportChildren, depth + 1))\n continue\n }\n }\n const indent = ' '.repeat(depth * LIST_INDENT_SIZE)\n const listType = listNode.getListType()\n const prefix =\n listType === 'number'\n ? `${listNode.getStart() + index}. `\n : listType === 'check'\n ? `- [${listItemNode.getChecked() ? 'x' : ' '}] `\n : '- '\n output.push(indent + prefix + exportChildren(listItemNode))\n index++\n }\n }\n\n return output.join('\\n')\n}\n\nexport const HEADING: ElementTransformer = {\n type: 'element',\n dependencies: [HeadingNode],\n export: (node, exportChildren) => {\n if (!$isHeadingNode(node)) {\n return null\n }\n const level = Number(node.getTag().slice(1))\n return '#'.repeat(level) + ' ' + exportChildren(node)\n },\n regExp: HEADING_REGEX,\n replace: createBlockNode((match) => {\n const tag = ('h' + match[1]!.length) as HeadingTagType\n return $createHeadingNode(tag)\n }),\n}\n\nexport const QUOTE: ElementTransformer = {\n type: 'element',\n dependencies: [QuoteNode],\n export: (node, exportChildren) => {\n if (!$isQuoteNode(node)) {\n return null\n }\n\n const lines = exportChildren(node).split('\\n')\n const output: string[] = []\n for (const line of lines) {\n output.push('> ' + line)\n }\n return output.join('\\n')\n },\n regExp: QUOTE_REGEX,\n replace: (parentNode, children, _match, isImport) => {\n if (isImport) {\n const previousNode = parentNode.getPreviousSibling()\n if ($isQuoteNode(previousNode)) {\n previousNode.splice(previousNode.getChildrenSize(), 0, [\n $createLineBreakNode(),\n ...children,\n ])\n previousNode.select(0, 0)\n parentNode.remove()\n return\n }\n }\n\n const node = $createQuoteNode()\n node.append(...children)\n parentNode.replace(node)\n node.select(0, 0)\n },\n}\n\nexport const UNORDERED_LIST: ElementTransformer = {\n type: 'element',\n dependencies: [ListNode, ListItemNode],\n export: (node, exportChildren) => {\n return $isListNode(node) ? listExport(node, exportChildren, 0) : null\n },\n regExp: UNORDERED_LIST_REGEX,\n replace: listReplace('bullet'),\n}\n\nexport const CHECK_LIST: ElementTransformer = {\n type: 'element',\n dependencies: [ListNode, ListItemNode],\n export: (node, exportChildren) => {\n return $isListNode(node) ? listExport(node, exportChildren, 0) : null\n },\n regExp: CHECK_LIST_REGEX,\n replace: listReplace('check'),\n}\n\nexport const ORDERED_LIST: ElementTransformer = {\n type: 'element',\n dependencies: [ListNode, ListItemNode],\n export: (node, exportChildren) => {\n return $isListNode(node) ? listExport(node, exportChildren, 0) : null\n },\n regExp: ORDERED_LIST_REGEX,\n replace: listReplace('number'),\n}\n\nexport const INLINE_CODE: TextFormatTransformer = {\n type: 'text-format',\n format: ['code'],\n tag: '`',\n}\n\nexport const HIGHLIGHT: TextFormatTransformer = {\n type: 'text-format',\n format: ['highlight'],\n tag: '==',\n}\n\nexport const BOLD_ITALIC_STAR: TextFormatTransformer = {\n type: 'text-format',\n format: ['bold', 'italic'],\n tag: '***',\n}\n\nexport const BOLD_ITALIC_UNDERSCORE: TextFormatTransformer = {\n type: 'text-format',\n format: ['bold', 'italic'],\n intraword: false,\n tag: '___',\n}\n\nexport const BOLD_STAR: TextFormatTransformer = {\n type: 'text-format',\n format: ['bold'],\n tag: '**',\n}\n\nexport const BOLD_UNDERSCORE: TextFormatTransformer = {\n type: 'text-format',\n format: ['bold'],\n intraword: false,\n tag: '__',\n}\n\nexport const STRIKETHROUGH: TextFormatTransformer = {\n type: 'text-format',\n format: ['strikethrough'],\n tag: '~~',\n}\n\nexport const ITALIC_STAR: TextFormatTransformer = {\n type: 'text-format',\n format: ['italic'],\n tag: '*',\n}\n\nexport const ITALIC_UNDERSCORE: TextFormatTransformer = {\n type: 'text-format',\n format: ['italic'],\n intraword: false,\n tag: '_',\n}\n\nexport function normalizeMarkdown(input: string, shouldMergeAdjacentLines: boolean): string {\n const lines = input.split('\\n')\n let inCodeBlock = false\n const sanitizedLines: string[] = []\n let nestedDeepCodeBlock = 0\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n const lastLine = sanitizedLines[sanitizedLines.length - 1]\n\n // Code blocks of ```single line``` don't toggle the inCodeBlock flag\n if (CODE_SINGLE_LINE_REGEX.test(line)) {\n sanitizedLines.push(line)\n continue\n }\n\n if (CODE_END_REGEX.test(line)) {\n if (nestedDeepCodeBlock === 0) {\n inCodeBlock = true\n }\n if (nestedDeepCodeBlock === 1) {\n inCodeBlock = false\n }\n if (nestedDeepCodeBlock > 0) {\n nestedDeepCodeBlock--\n }\n sanitizedLines.push(line)\n continue\n }\n\n // Toggle inCodeBlock state when encountering start or end of a code block\n if (CODE_START_REGEX.test(line)) {\n inCodeBlock = true\n nestedDeepCodeBlock++\n sanitizedLines.push(line)\n continue\n }\n\n // If we are inside a code block, keep the line unchanged\n if (inCodeBlock) {\n sanitizedLines.push(line)\n continue\n }\n\n // In markdown the concept of \"empty paragraphs\" does not exist.\n // Blocks must be separated by an empty line. Non-empty adjacent lines must be merged.\n if (\n EMPTY_OR_WHITESPACE_ONLY.test(line) ||\n EMPTY_OR_WHITESPACE_ONLY.test(lastLine!) ||\n !lastLine ||\n HEADING_REGEX.test(lastLine) ||\n HEADING_REGEX.test(line) ||\n QUOTE_REGEX.test(line) ||\n ORDERED_LIST_REGEX.test(line) ||\n UNORDERED_LIST_REGEX.test(line) ||\n CHECK_LIST_REGEX.test(line) ||\n TABLE_ROW_REG_EXP.test(line) ||\n TABLE_ROW_DIVIDER_REG_EXP.test(line) ||\n !shouldMergeAdjacentLines ||\n TAG_START_REGEX.test(line) ||\n TAG_END_REGEX.test(line) ||\n TAG_START_REGEX.test(lastLine) ||\n TAG_END_REGEX.test(lastLine) ||\n CODE_END_REGEX.test(lastLine)\n ) {\n sanitizedLines.push(line)\n } else {\n sanitizedLines[sanitizedLines.length - 1] = lastLine + ' ' + line.trim()\n }\n }\n\n return sanitizedLines.join('\\n')\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 */\n\nimport type { ElementNode } from 'lexical'\n\nimport type {\n ElementTransformer,\n MultilineElementTransformer,\n TextFormatTransformer,\n TextMatchTransformer,\n Transformer,\n} from './MarkdownTransformers.js'\n\nimport { createMarkdownExport } from './MarkdownExport.js'\nimport { createMarkdownImport } from './MarkdownImport.js'\nimport { registerMarkdownShortcuts } from './MarkdownShortcuts.js'\nimport {\n BOLD_ITALIC_STAR,\n BOLD_ITALIC_UNDERSCORE,\n BOLD_STAR,\n BOLD_UNDERSCORE,\n CHECK_LIST,\n HEADING,\n HIGHLIGHT,\n INLINE_CODE,\n ITALIC_STAR,\n ITALIC_UNDERSCORE,\n normalizeMarkdown,\n ORDERED_LIST,\n QUOTE,\n STRIKETHROUGH,\n UNORDERED_LIST,\n} from './MarkdownTransformers.js'\n\nconst ELEMENT_TRANSFORMERS: Array<ElementTransformer> = [\n HEADING,\n QUOTE,\n UNORDERED_LIST,\n ORDERED_LIST,\n]\n\nconst MULTILINE_ELEMENT_TRANSFORMERS: Array<MultilineElementTransformer> = []\n\n// Order of text format transformers matters:\n//\n// - code should go first as it prevents any transformations inside\n// - then longer tags match (e.g. ** or __ should go before * or _)\nconst TEXT_FORMAT_TRANSFORMERS: Array<TextFormatTransformer> = [\n INLINE_CODE,\n BOLD_ITALIC_STAR,\n BOLD_ITALIC_UNDERSCORE,\n BOLD_STAR,\n BOLD_UNDERSCORE,\n HIGHLIGHT,\n ITALIC_STAR,\n ITALIC_UNDERSCORE,\n STRIKETHROUGH,\n]\n\nconst TEXT_MATCH_TRANSFORMERS: Array<TextMatchTransformer> = []\n\nconst TRANSFORMERS: Array<Transformer> = [\n ...ELEMENT_TRANSFORMERS,\n ...MULTILINE_ELEMENT_TRANSFORMERS,\n ...TEXT_FORMAT_TRANSFORMERS,\n ...TEXT_MATCH_TRANSFORMERS,\n]\n\n/**\n * Renders markdown from a string. The selection is moved to the start after the operation.\n *\n * @param {boolean} [shouldPreserveNewLines] By setting this to true, new lines will be preserved between conversions\n * @param {boolean} [shouldMergeAdjacentLines] By setting this to true, adjacent non empty lines will be merged according to commonmark spec: https://spec.commonmark.org/0.24/#example-177. Not applicable if shouldPreserveNewLines = true.\n */\nfunction $convertFromMarkdownString(\n markdown: string,\n transformers: Array<Transformer> = TRANSFORMERS,\n node?: ElementNode,\n shouldPreserveNewLines = false,\n shouldMergeAdjacentLines = true,\n): void {\n const sanitizedMarkdown = shouldPreserveNewLines\n ? markdown\n : normalizeMarkdown(markdown, shouldMergeAdjacentLines)\n const importMarkdown = createMarkdownImport(transformers, shouldPreserveNewLines)\n return importMarkdown(sanitizedMarkdown, node)\n}\n\n/**\n * Renders string from markdown. The selection is moved to the start after the operation.\n */\nfunction $convertToMarkdownString(\n transformers: Array<Transformer> = TRANSFORMERS,\n node?: ElementNode,\n shouldPreserveNewLines: boolean = false,\n): string {\n const exportMarkdown = createMarkdownExport(transformers, shouldPreserveNewLines)\n return exportMarkdown(node)\n}\n\nexport {\n $convertFromMarkdownString,\n $convertToMarkdownString,\n BOLD_ITALIC_STAR,\n BOLD_ITALIC_UNDERSCORE,\n BOLD_STAR,\n BOLD_UNDERSCORE,\n CHECK_LIST,\n ELEMENT_TRANSFORMERS,\n type ElementTransformer,\n HEADING,\n HIGHLIGHT,\n INLINE_CODE,\n ITALIC_STAR,\n ITALIC_UNDERSCORE,\n MULTILINE_ELEMENT_TRANSFORMERS,\n type MultilineElementTransformer,\n ORDERED_LIST,\n QUOTE,\n registerMarkdownShortcuts,\n STRIKETHROUGH,\n TEXT_FORMAT_TRANSFORMERS,\n TEXT_MATCH_TRANSFORMERS,\n type TextFormatTransformer,\n type TextMatchTransformer,\n type Transformer,\n TRANSFORMERS,\n UNORDERED_LIST,\n}\n"],
5
- "mappings": "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",
6
- "names": ["CAN_USE_DOM", "window", "document", "createElement", "c", "_c", "useRef", "useRunDeprioritized", "t0", "$", "timeout", "undefined", "idleHandleRef", "t1", "fn", "Promise", "resolve", "exec", "window", "current", "cancelIdleCallback", "requestIdleCallback", "interactionResponse", "then", "setTimeout", "requestAnimationFrame", "useControllableState", "createContext", "use", "useMemo", "RichTextViewContext", "currentView", "inheritable", "setCurrentView", "RichTextViewProvider", "args", "parentContext", "useRichTextView", "children", "currentViewFromProps", "views", "value", "currentViewMap", "default", "undefined", "_jsx", "Point", "_x", "_y", "constructor", "x", "y", "calcDeltaXTo", "calcDeltaYTo", "calcDistanceTo", "point", "Math", "sqrt", "pow", "calcHorizontalDistanceTo", "abs", "calcVerticalDistance", "equals", "isPoint", "useLexicalComposerContext", "mergeRegister", "$getSelection", "$isRangeSelection", "$isTextNode", "COMMAND_PRIORITY_LOW", "createCommand", "getDOMSelection", "useCallback", "useEffect", "useState", "React", "c", "_c", "useLexicalComposerContext", "mergeRegister", "$getSelection", "$isRangeSelection", "$setSelection", "COMMAND_PRIORITY_LOW", "COMMAND_PRIORITY_NORMAL", "createCommand", "KEY_ARROW_DOWN_COMMAND", "KEY_ARROW_UP_COMMAND", "KEY_ENTER_COMMAND", "KEY_ESCAPE_COMMAND", "KEY_TAB_COMMAND", "useCallback", "useEffect", "useLayoutEffect", "useMemo", "useRef", "useState", "baseClass", "scrollIntoViewIfNeeded", "target", "typeaheadContainerNode", "document", "getElementById", "typeaheadRect", "getBoundingClientRect", "top", "height", "window", "innerHeight", "scrollIntoView", "block", "getFullMatchOffset", "documentText", "entryText", "offset", "triggerOffset", "i", "length", "substring", "$splitNodeContainingQuery", "match", "selection", "$getSelection", "$isRangeSelection", "isCollapsed", "anchor", "type", "anchorNode", "getNode", "isSimpleText", "selectionOffset", "textContent", "getTextContent", "slice", "characterOffset", "replaceableString", "queryOffset", "matchingString", "startOffset", "newNode", "splitText", "getScrollParent", "element", "includeHidden", "style", "getComputedStyle", "excludeStaticParent", "position", "overflowRegex", "body", "parent1", "parentElement", "test", "overflow", "overflowY", "overflowX", "isTriggerVisibleInNearestScrollContainer", "targetElement", "containerElement", "tRect", "cRect", "bottom", "useDynamicPositioning", "resolution", "targetElementRef", "onReposition", "onVisibilityChange", "$", "_c", "editor", "useLexicalComposerContext", "t0", "t1", "current", "rootElement", "getRootElement", "rootScrollParent", "ticking", "previousIsInView", "handleScroll", "requestAnimationFrame", "isInView", "resizeObserver", "ResizeObserver", "addEventListener", "capture", "passive", "observe", "disconnect", "removeEventListener", "useEffect", "SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND", "createCommand", "LexicalMenu", "anchorElementRef", "close", "groups", "menuRenderFn", "shouldSplitNodeWithQuery", "selectedItemKey", "setSelectedItemKey", "useState", "updateSelectedItem", "useCallback", "item", "rootElem", "setAttribute", "key", "setSelectedItemKeyToFirstMatchingItem", "allItems", "flatMap", "group", "items", "firstMatchingItem", "selectItemAndCleanUp", "selectedItem", "update", "textNodeContainingQuery", "remove", "setTimeout", "read", "clone", "$setSelection", "onSelect", "queryString", "removeAttribute", "useLayoutEffect", "mergeRegister", "registerCommand", "ref", "COMMAND_PRIORITY_LOW", "KEY_ARROW_DOWN_COMMAND", "payload", "event", "selectedIndex", "findIndex", "newSelectedIndex", "newSelectedItem", "dispatchCommand", "index", "preventDefault", "stopImmediatePropagation", "COMMAND_PRIORITY_NORMAL", "KEY_ARROW_UP_COMMAND", "KEY_ESCAPE_COMMAND", "KEY_TAB_COMMAND", "find", "KEY_ENTER_COMMAND", "listItemProps", "useMemo", "setContainerDivAttributes", "containerDiv", "className", "display", "useMenuAnchorRef", "anchorElem", "setResolution", "Symbol", "for", "CAN_USE_DOM", "createElement", "useRef", "parent", "undefined", "menuEle", "firstChild", "width", "getRect", "left", "rawTop", "scrollY", "scrollX", "menuRect", "menuHeight", "menuWidth", "rootElementRect", "isRTL", "dir", "documentElement", "anchorRect", "leftBoundary", "Math", "max", "right", "newLeft", "wouldGoOffBottomOfScreen", "wouldGoOffTopOfScreen", "isConnected", "append", "positionMenu", "t2", "t3", "rootElement_0", "containerDiv_0", "t4", "PUNCTUATION", "getTextUpToAnchor", "selection", "anchor", "type", "anchorNode", "getNode", "isSimpleText", "anchorOffset", "offset", "getTextContent", "slice", "tryToPositionRange", "leadOffset", "range", "editorWindow", "domSelection", "getDOMSelection", "isCollapsed", "startOffset", "endOffset", "setStart", "setEnd", "getQueryTextForSearch", "editor", "text", "getEditorState", "read", "$getSelection", "$isRangeSelection", "isSelectionOnEntityBoundary", "prevSibling", "getPreviousSibling", "$isTextNode", "isTextEntity", "startTransition", "callback", "ENABLE_SLASH_MENU_COMMAND", "createCommand", "LexicalTypeaheadMenuPlugin", "anchorClassName", "anchorElem", "groups", "menuRenderFn", "onClose", "onOpen", "onQueryChange", "triggerFn", "useLexicalComposerContext", "resolution", "setResolution", "useState", "anchorElementRef", "useMenuAnchorRef", "closeTypeahead", "useCallback", "openTypeahead", "res", "useEffect", "mergeRegister", "registerCommand", "node", "match", "matchingString", "replaceableString", "_window", "window", "document", "createRange", "getRect", "getBoundingClientRect", "COMMAND_PRIORITY_LOW", "updateListener", "undefined", "query", "removeUpdateListener", "registerUpdateListener", "current", "_jsx", "LexicalMenu", "close", "shouldSplitNodeWithQuery", "Rect", "_bottom", "_left", "_right", "_top", "constructor", "left", "top", "right", "bottom", "physicTop", "physicBottom", "physicLeft", "physicRight", "fromDOM", "dom", "height", "width", "getBoundingClientRect", "fromLWTH", "fromDOMRect", "domRect", "fromLTRB", "fromPoints", "startPoint", "endPoint", "x", "y", "contains", "target", "isPoint", "isOnTopSide", "isOnBottomSide", "isOnLeftSide", "isOnRightSide", "reason", "result", "distanceFromPoint", "point", "containsResult", "distance", "dx", "dy", "Math", "sqrt", "equals", "generateNewRect", "intersectsWith", "rect", "h1", "x1", "y1", "w1", "h2", "x2", "y2", "w2", "maxX", "maxY", "minX", "minY", "abs", "React", "editorNodeViews", "WeakMap", "registerEditorNodeViews", "editor", "nodeViews", "has", "set", "Map", "editorViews", "get", "nodeType", "value", "Object", "entries", "blockType", "viewDef", "clearEditorNodeViews", "delete", "getEditorNodeView", "node", "applyNodeOverride", "getType", "NodeClass", "prototype", "_originalDecorate", "decorate", "_originalCreateDOM", "createDOM", "_decorateOverridden", "hasCreateDOM", "config", "Component", "isEditor", "isJSXConverter", "html", "htmlContent", "createElement", "dangerouslySetInnerHTML", "__html", "Fragment", "call", "_createDOMOverridden", "tempDiv", "document", "innerHTML", "firstElementChild", "getEnabledNodes", "editorConfig", "nodes", "getEnabledNodesFromServerNodes", "features", "nodeTypesToOverride", "Set", "key", "keys", "length", "add", "map", "$getRoot", "$isDecoratorNode", "$isElementNode", "$isLineBreakNode", "$isTextNode", "$isListItemNode", "$isListNode", "$isHeadingNode", "$isQuoteNode", "$isParagraphNode", "$isTextNode", "autoFormatBase", "markdownFormatKind", "regEx", "regExForAutoFormatting", "requiresParagraphStart", "paragraphStartBase", "markdownHeader1", "export", "createHeadingExport", "markdownHeader2", "markdownHeader3", "markdownHeader4", "markdownHeader5", "markdownHeader6", "markdownBlockQuote", "blockQuoteExport", "markdownUnorderedListDash", "listExport", "markdownUnorderedListAsterisk", "markdownOrderedList", "markdownHorizontalRule", "markdownHorizontalRuleUsingDashes", "markdownInlineCode", "exportFormat", "exportTag", "markdownBold", "markdownItalic", "markdownBold2", "markdownItalic2", "fakeMarkdownUnderline", "exportTagClose", "markdownStrikethrough", "markdownStrikethroughItalicBold", "markdownItalicbold", "markdownStrikethroughItalic", "markdownStrikethroughBold", "markdownLink", "createHeadingExport", "level", "node", "exportChildren", "$isHeadingNode", "getTag", "repeat", "listExport", "$isListNode", "processNestedLists", "LIST_INDENT_SIZE", "listNode", "depth", "output", "children", "getChildren", "index", "listItemNode", "$isListItemNode", "getChildrenSize", "firstChild", "getFirstChild", "push", "indent", "prefix", "getListType", "getStart", "join", "blockQuoteExport", "$isQuoteNode", "indexBy", "list", "callback", "item", "key", "transformersByType", "transformers", "byType", "t", "type", "element", "multilineElement", "textFormat", "textMatch", "PUNCTUATION_OR_SPACE", "MARKDOWN_EMPTY_LINE_REG_EXP", "isEmptyParagraph", "$isParagraphNode", "$isTextNode", "test", "getTextContent", "createMarkdownExport", "transformers", "shouldPreserveNewLines", "byType", "transformersByType", "elementTransformers", "multilineElement", "element", "isNewlineDelimited", "textFormatTransformers", "textFormat", "filter", "transformer", "format", "length", "sort", "a", "b", "includes", "node", "output", "children", "$getRoot", "getChildren", "forEach", "child", "i", "result", "exportTopLevelElements", "textMatch", "push", "isEmptyParagraph", "concat", "join", "textTransformersIndex", "textMatchTransformers", "export", "_node", "exportChildren", "$isElementNode", "$isDecoratorNode", "getTextContent", "unclosedTags", "unclosableTags", "mainLoop", "parentNode", "textNode", "textContent", "exportTextFormat", "$isLineBreakNode", "$isTextNode", "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", "$isListItemNode", "$isListNode", "$isQuoteNode", "$findMatchingParent", "$createLineBreakNode", "$createParagraphNode", "$createTextNode", "$getRoot", "$getSelection", "$isParagraphNode", "$isTextNode", "findOutermostTextFormatTransformer", "textNode", "textFormatTransformersIndex", "textContent", "getTextContent", "match", "findOutermostMatch", "textFormatMatchStart", "index", "textFormatMatchEnd", "length", "transformer", "transformersByTag", "endIndex", "startIndex", "textTransformersIndex", "openTagsMatch", "openTagsRegExp", "tag", "replace", "fullMatchRegExp", "fullMatchRegExpByTag", "fullMatch", "intraword", "beforeChar", "afterChar", "PUNCTUATION_OR_SPACE", "test", "importTextFormatTransformer", "nodeAfter", "nodeBefore", "transformedNode", "splitText", "setTextContent", "format", "hasFormat", "toggleFormat", "findOutermostTextMatchTransformer", "textNode_", "textMatchTransformers", "textNode", "foundMatchStartIndex", "foundMatchEndIndex", "foundMatchTransformer", "foundMatch", "transformer", "replace", "importRegExp", "match", "getTextContent", "startIndex", "index", "endIndex", "getEndIndex", "length", "undefined", "importFoundTextMatchTransformer", "nodeAfter", "nodeBefore", "transformedNode", "splitText", "potentialTransformedNode", "importTextTransformers", "textNode", "textFormatTransformersIndex", "textMatchTransformers", "foundTextFormat", "findOutermostTextFormatTransformer", "foundTextMatch", "findOutermostTextMatchTransformer", "startIndex", "endIndex", "result", "importTextFormatTransformer", "transformer", "match", "nodeAfter", "$isTextNode", "hasFormat", "nodeBefore", "transformedNode", "importFoundTextMatchTransformer", "escapedText", "getTextContent", "replace", "setTextContent", "createMarkdownImport", "transformers", "shouldPreserveNewLines", "byType", "transformersByType", "textFormatTransformersIndex", "createTextFormatTransformersIndex", "textFormat", "markdownString", "node", "lines", "split", "linesLength", "length", "root", "$getRoot", "clear", "i", "lineText", "imported", "shiftedIndex", "$importMultiline", "multilineElement", "$importBlocks", "element", "textMatch", "children", "getChildren", "child", "isEmptyParagraph", "getChildrenSize", "remove", "$getSelection", "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", "$createTextNode", "elementNode", "$createParagraphNode", "append", "setTextContent", "importTextTransformers", "isAttached", "previousNode", "getPreviousSibling", "$isParagraphNode", "$isQuoteNode", "$isListNode", "targetNode", "lastDescendant", "getLastDescendant", "$findMatchingParent", "$isListItemNode", "getTextContentSize", "splice", "$createLineBreakNode", "textTransformers", "transformersByTag", "fullMatchRegExpByTag", "openTagsRegExp", "escapeRegExp", "tag", "tagRegExp", "RegExp", "join", "$createRangeSelection", "$getSelection", "$isLineBreakNode", "$isRangeSelection", "$isRootOrShadowRoot", "$isTextNode", "$setSelection", "runElementTransformers", "parentNode", "anchorNode", "anchorOffset", "elementTransformers", "grandParentNode", "getParent", "$isRootOrShadowRoot", "getFirstChild", "textContent", "getTextContent", "regExp", "replace", "match", "length", "endsWith", "nextSiblings", "getNextSiblings", "leadingNode", "remainderNode", "splitText", "remove", "siblings", "runMultilineElementTransformers", "regExpEnd", "regExpStart", "optional", "runTextMatchTransformers", "transformersByTrigger", "lastChar", "transformers", "slice", "transformer", "startIndex", "index", "endIndex", "replaceNode", "selectNext", "$runTextFormatTransformers", "textFormatTransformers", "closeTagEndIndex", "closeChar", "matchers", "matcher", "tag", "tagLength", "closeTagStartIndex", "isEqualSubString", "afterCloseTagChar", "intraword", "PUNCTUATION_OR_SPACE", "test", "closeNode", "openNode", "openTagStartIndex", "getOpenTagStartIndex", "sibling", "getPreviousSibling", "$isLineBreakNode", "$isTextNode", "siblingTextContent", "prevOpenNodeText", "beforeOpenTagChar", "prevCloseNodeText", "closeNodeText", "setTextContent", "openNodeText", "selection", "$getSelection", "nextSelection", "$createRangeSelection", "$setSelection", "newOffset", "anchor", "set", "__key", "focus", "format", "hasFormat", "formatText", "key", "offset", "type", "toggleFormat", "$isRangeSelection", "string", "maxIndex", "i", "stringA", "aStart", "stringB", "bStart", "registerMarkdownShortcuts", "editor", "TRANSFORMERS", "byType", "transformersByType", "textFormatTransformersByTrigger", "indexBy", "textFormat", "textMatchTransformersByTrigger", "textMatch", "trigger", "dependencies", "node", "hasNode", "Error", "getType", "$transform", "element", "multilineElement", "registerUpdateListener", "dirtyLeaves", "editorState", "prevEditorState", "tags", "has", "isComposing", "read", "prevSelection", "isCollapsed", "is", "anchorKey", "_nodeMap", "get", "update", "$createListItemNode", "$createListNode", "$isListItemNode", "$isListNode", "ListItemNode", "ListNode", "$createHeadingNode", "$createQuoteNode", "$isHeadingNode", "$isQuoteNode", "HeadingNode", "QuoteNode", "$createLineBreakNode", "EMPTY_OR_WHITESPACE_ONLY", "ORDERED_LIST_REGEX", "UNORDERED_LIST_REGEX", "CHECK_LIST_REGEX", "HEADING_REGEX", "QUOTE_REGEX", "CODE_START_REGEX", "CODE_END_REGEX", "CODE_SINGLE_LINE_REGEX", "TABLE_ROW_REG_EXP", "TABLE_ROW_DIVIDER_REG_EXP", "TAG_START_REGEX", "TAG_END_REGEX", "createBlockNode", "createNode", "parentNode", "children", "match", "node", "append", "replace", "select", "LIST_INDENT_SIZE", "getIndent", "whitespaces", "tabs", "spaces", "indent", "length", "Math", "floor", "listReplace", "listType", "previousNode", "getPreviousSibling", "nextNode", "getNextSibling", "listItem", "undefined", "getListType", "firstChild", "getFirstChild", "insertBefore", "remove", "list", "Number", "setIndent", "listExport", "listNode", "exportChildren", "depth", "output", "getChildren", "index", "listItemNode", "getChildrenSize", "push", "repeat", "prefix", "getStart", "getChecked", "join", "HEADING", "type", "dependencies", "export", "level", "getTag", "slice", "regExp", "tag", "QUOTE", "lines", "split", "line", "_match", "isImport", "splice", "UNORDERED_LIST", "CHECK_LIST", "ORDERED_LIST", "INLINE_CODE", "format", "HIGHLIGHT", "BOLD_ITALIC_STAR", "BOLD_ITALIC_UNDERSCORE", "intraword", "BOLD_STAR", "BOLD_UNDERSCORE", "STRIKETHROUGH", "ITALIC_STAR", "ITALIC_UNDERSCORE", "normalizeMarkdown", "input", "shouldMergeAdjacentLines", "inCodeBlock", "sanitizedLines", "nestedDeepCodeBlock", "i", "lastLine", "test", "trim", "ELEMENT_TRANSFORMERS", "HEADING", "QUOTE", "UNORDERED_LIST", "ORDERED_LIST", "MULTILINE_ELEMENT_TRANSFORMERS", "TEXT_FORMAT_TRANSFORMERS", "INLINE_CODE", "BOLD_ITALIC_STAR", "BOLD_ITALIC_UNDERSCORE", "BOLD_STAR", "BOLD_UNDERSCORE", "HIGHLIGHT", "ITALIC_STAR", "ITALIC_UNDERSCORE", "STRIKETHROUGH", "TEXT_MATCH_TRANSFORMERS", "TRANSFORMERS", "$convertFromMarkdownString", "markdown", "transformers", "node", "shouldPreserveNewLines", "shouldMergeAdjacentLines", "sanitizedMarkdown", "normalizeMarkdown", "createMarkdownImport", "$convertToMarkdownString", "createMarkdownExport"]
7
- }
@@ -1,3 +0,0 @@
1
- export { BlockContent, useBlockComponentContext, } from '../../features/blocks/client/component/BlockContent.js';
2
- export { BlockComponent } from '../../features/blocks/client/component/index.js';
3
- //# sourceMappingURL=internal-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"internal-client.d.ts","sourceRoot":"","sources":["../../../src/exports/client/internal-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,wBAAwB,GACzB,MAAM,wDAAwD,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,iDAAiD,CAAA"}
@@ -1,83 +0,0 @@
1
- import React from 'react';
2
- import type { LexicalEditorNodeMap, LexicalEditorViewMap } from '../types.js';
3
- /**
4
- * Context type for rich text view management.
5
- */
6
- type RichTextViewContextType = {
7
- /**
8
- * The name of the currently active view (e.g., 'default', 'frontend', 'debug')
9
- */
10
- currentView: string;
11
- /**
12
- * The node map for the currently active view, containing rendering overrides for each node type.
13
- * This is the resolved view from the views map based on currentView.
14
- */
15
- currentViewMap?: LexicalEditorNodeMap;
16
- /**
17
- * If true, the current view will be inherited by nested richtext editors.
18
- */
19
- inheritable?: boolean;
20
- /**
21
- * Function to change the current view.
22
- */
23
- setCurrentView: (view: string) => void;
24
- /**
25
- * The complete map of all available views for this field.
26
- */
27
- views?: LexicalEditorViewMap;
28
- };
29
- /**
30
- * Provider component for rich text view context.
31
- *
32
- * This provider manages the current view state internally and makes it accessible to child components
33
- * via the useRichTextView hook. It automatically resolves the current view's node map
34
- * based on the active view name.
35
- *
36
- * @example
37
- * ```tsx
38
- * <RichTextViewProvider
39
- * currentView="frontend"
40
- * views={myViews}
41
- * >
42
- * <MyEditor />
43
- * </RichTextViewProvider>
44
- * ```
45
- */
46
- export declare const RichTextViewProvider: React.FC<{
47
- children: React.ReactNode;
48
- currentView?: string;
49
- inheritable?: boolean;
50
- views?: LexicalEditorViewMap;
51
- }>;
52
- /**
53
- * Hook to access the current rich text view context.
54
- *
55
- * Use this hook to access the currently active view and its node map,
56
- * or to programmatically switch between views.
57
- *
58
- * @returns An object containing:
59
- * - `currentView`: The name of the active view
60
- * - `currentViewMap`: The node overrides for the current view
61
- * - `setCurrentView`: Function to change views
62
- * - `views`: All available views
63
- *
64
- * @example
65
- * ```tsx
66
- * function MyComponent() {
67
- * const { currentView, currentViewMap, setCurrentView } = useRichTextView()
68
- *
69
- * return (
70
- * <div>
71
- * <p>Current view: {currentView}</p>
72
- * {currentViewMap?.heading && <p>Heading overrides are active</p>}
73
- * <button onClick={() => setCurrentView('frontend')}>
74
- * Switch to frontend view
75
- * </button>
76
- * </div>
77
- * )
78
- * }
79
- * ```
80
- */
81
- export declare function useRichTextView(): RichTextViewContextType;
82
- export {};
83
- //# sourceMappingURL=RichTextViewProvider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RichTextViewProvider.d.ts","sourceRoot":"","sources":["../../src/field/RichTextViewProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAA;AAE1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAE7E;;GAEG;AACH,KAAK,uBAAuB,GAAG;IAC7B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAA;IACrC;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;OAEG;IACH,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC;;OAEG;IACH,KAAK,CAAC,EAAE,oBAAoB,CAAA;CAC7B,CAAA;AAQD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC;IAC1C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,KAAK,CAAC,EAAE,oBAAoB,CAAA;CAC7B,CA6BA,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,eAAe,IAAI,uBAAuB,CAEzD"}