@payloadcms/richtext-lexical 3.12.0 → 3.12.1-canary.33ecab2
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.
- package/dist/exports/client/Field-DTQOXLGX.js +2 -0
- package/dist/exports/client/Field-DTQOXLGX.js.map +7 -0
- package/dist/exports/client/chunk-JSFV2MHZ.js +2 -0
- package/dist/exports/client/chunk-JSFV2MHZ.js.map +7 -0
- package/dist/exports/client/chunk-WCORQHZQ.js +12 -0
- package/dist/exports/client/chunk-WCORQHZQ.js.map +7 -0
- package/dist/exports/client/{component-NSAU5Y76.js → component-OQJ5KXCS.js} +2 -2
- package/dist/exports/client/index.js +11 -11
- package/dist/exports/client/index.js.map +3 -3
- package/dist/features/blocks/server/markdownTransformer.d.ts.map +1 -1
- package/dist/features/blocks/server/markdownTransformer.js +1 -2
- package/dist/features/blocks/server/markdownTransformer.js.map +1 -1
- package/dist/features/link/markdownTransformer.d.ts.map +1 -1
- package/dist/features/link/markdownTransformer.js +6 -11
- package/dist/features/link/markdownTransformer.js.map +1 -1
- package/dist/features/relationship/client/utils/EnabledRelationshipsCondition.d.ts +5 -1
- package/dist/features/relationship/client/utils/EnabledRelationshipsCondition.d.ts.map +1 -1
- package/dist/features/relationship/client/utils/EnabledRelationshipsCondition.js +42 -26
- package/dist/features/relationship/client/utils/EnabledRelationshipsCondition.js.map +1 -1
- package/dist/features/upload/client/drawer/index.d.ts.map +1 -1
- package/dist/features/upload/client/drawer/index.js +24 -0
- package/dist/features/upload/client/drawer/index.js.map +1 -1
- package/dist/field/rscEntry.d.ts.map +1 -1
- package/dist/field/rscEntry.js +3 -0
- package/dist/field/rscEntry.js.map +1 -1
- package/dist/lexical/LexicalEditor.js +5 -3
- package/dist/lexical/LexicalEditor.js.map +1 -1
- package/dist/lexical/ui/ContentEditable.d.ts +3 -1
- package/dist/lexical/ui/ContentEditable.d.ts.map +1 -1
- package/dist/lexical/ui/ContentEditable.js +18 -7
- package/dist/lexical/ui/ContentEditable.js.map +1 -1
- package/dist/packages/@lexical/markdown/MarkdownExport.js +68 -14
- package/dist/packages/@lexical/markdown/MarkdownExport.js.map +1 -1
- package/dist/packages/@lexical/markdown/MarkdownImport.d.ts +6 -1
- package/dist/packages/@lexical/markdown/MarkdownImport.d.ts.map +1 -1
- package/dist/packages/@lexical/markdown/MarkdownImport.js +3 -119
- package/dist/packages/@lexical/markdown/MarkdownImport.js.map +1 -1
- package/dist/packages/@lexical/markdown/MarkdownTransformers.d.ts +4 -1
- package/dist/packages/@lexical/markdown/MarkdownTransformers.d.ts.map +1 -1
- package/dist/packages/@lexical/markdown/MarkdownTransformers.js.map +1 -1
- package/dist/packages/@lexical/markdown/importTextFormatTransformer.d.ts +22 -0
- package/dist/packages/@lexical/markdown/importTextFormatTransformer.d.ts.map +1 -0
- package/dist/packages/@lexical/markdown/importTextFormatTransformer.js +88 -0
- package/dist/packages/@lexical/markdown/importTextFormatTransformer.js.map +1 -0
- package/dist/packages/@lexical/markdown/importTextMatchTransformer.d.ts +21 -0
- package/dist/packages/@lexical/markdown/importTextMatchTransformer.d.ts.map +1 -0
- package/dist/packages/@lexical/markdown/importTextMatchTransformer.js +54 -0
- package/dist/packages/@lexical/markdown/importTextMatchTransformer.js.map +1 -0
- package/dist/packages/@lexical/markdown/importTextTransformers.d.ts +18 -0
- package/dist/packages/@lexical/markdown/importTextTransformers.d.ts.map +1 -0
- package/dist/packages/@lexical/markdown/importTextTransformers.js +55 -0
- package/dist/packages/@lexical/markdown/importTextTransformers.js.map +1 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/jsx/lexicalMarkdownCopy.d.ts.map +1 -1
- package/dist/utilities/jsx/lexicalMarkdownCopy.js +11 -6
- package/dist/utilities/jsx/lexicalMarkdownCopy.js.map +1 -1
- package/package.json +7 -7
- package/dist/exports/client/Field-7XFZE2MU.js +0 -2
- package/dist/exports/client/Field-7XFZE2MU.js.map +0 -7
- package/dist/exports/client/chunk-H3D3IU3G.js +0 -2
- package/dist/exports/client/chunk-H3D3IU3G.js.map +0 -7
- package/dist/exports/client/chunk-XOABLBHB.js +0 -12
- package/dist/exports/client/chunk-XOABLBHB.js.map +0 -7
- /package/dist/exports/client/{component-NSAU5Y76.js.map → component-OQJ5KXCS.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LexicalEditor.js","names":["c","_c","useLexicalComposerContext","LexicalErrorBoundary","HistoryPlugin","OnChangePlugin","RichTextPlugin","BLUR_COMMAND","COMMAND_PRIORITY_LOW","FOCUS_COMMAND","React","useEffect","useState","useEditorConfigContext","EditorPlugin","AddBlockHandlePlugin","DraggableBlockPlugin","MarkdownShortcutPlugin","SlashMenuPlugin","TextPlugin","LexicalContentEditable","LexicalEditor","props","$","editorConfig","editorContainerRef","onChange","editorConfigContext","editor","floatingAnchorElem","setFloatingAnchorElem","t0","Symbol","for","_floatingAnchorElem","onRef","t1","t2","uuid","console","error","parentEditor","registerChild","handleFocus","focusEditor","handleBlur","blurEditor","unregisterFocus","registerCommand","unregisterBlur","unregisterChild","isSmallWidthViewport","setIsSmallWidthViewport","t3","t4","updateViewPortWidth","isNextSmallWidthViewport","window","matchMedia","matches","addEventListener","removeEventListener","t5","features","t6","editorState","editor_0","tags","has","size","t7","plugins","_jsxs","Fragment","children","isEditable","_jsx","anchorElem","map","plugin_1","plugin","position","desktopOnly","clientProps","key","_temp","className","ref","_temp2","contentEditable","tabIndex","ignoreSelectionChange","markdownTransformers","length","_temp3","_temp4","_temp5","plugin_0","plugin_2","plugin_3","plugin_4"],"sources":["../../src/lexical/LexicalEditor.tsx"],"sourcesContent":["'use client'\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary.js'\nimport { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin.js'\nimport { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin.js'\nimport { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin.js'\nimport { BLUR_COMMAND, COMMAND_PRIORITY_LOW, FOCUS_COMMAND } from 'lexical'\nimport * as React from 'react'\nimport { useEffect, useState } from 'react'\n\nimport type { LexicalProviderProps } from './LexicalProvider.js'\n\nimport { useEditorConfigContext } from './config/client/EditorConfigProvider.js'\nimport { EditorPlugin } from './EditorPlugin.js'\nimport './LexicalEditor.scss'\nimport { AddBlockHandlePlugin } from './plugins/handles/AddBlockHandlePlugin/index.js'\nimport { DraggableBlockPlugin } from './plugins/handles/DraggableBlockPlugin/index.js'\nimport { MarkdownShortcutPlugin } from './plugins/MarkdownShortcut/index.js'\nimport { SlashMenuPlugin } from './plugins/SlashMenu/index.js'\nimport { TextPlugin } from './plugins/TextPlugin/index.js'\nimport { LexicalContentEditable } from './ui/ContentEditable.js'\n\nexport const LexicalEditor: React.FC<\n {\n editorContainerRef: React.RefObject<HTMLDivElement | null>\n } & Pick<LexicalProviderProps, 'editorConfig' | 'onChange'>\n> = (props) => {\n const { editorConfig, editorContainerRef, onChange } = props\n const editorConfigContext = useEditorConfigContext()\n const [editor] = useLexicalComposerContext()\n\n const [floatingAnchorElem, setFloatingAnchorElem] = useState<HTMLDivElement | null>(null)\n const onRef = (_floatingAnchorElem: HTMLDivElement) => {\n if (_floatingAnchorElem !== null) {\n setFloatingAnchorElem(_floatingAnchorElem)\n }\n }\n\n useEffect(() => {\n if (!editorConfigContext?.uuid) {\n console.error('Lexical Editor must be used within an EditorConfigProvider')\n return\n }\n if (editorConfigContext?.parentEditor?.uuid) {\n editorConfigContext.parentEditor?.registerChild(editorConfigContext.uuid, editorConfigContext)\n }\n\n const handleFocus = () => {\n editorConfigContext.focusEditor(editorConfigContext)\n }\n\n const handleBlur = () => {\n editorConfigContext.blurEditor(editorConfigContext)\n }\n\n const unregisterFocus = editor.registerCommand<MouseEvent>(\n FOCUS_COMMAND,\n () => {\n handleFocus()\n return true\n },\n COMMAND_PRIORITY_LOW,\n )\n\n const unregisterBlur = editor.registerCommand<MouseEvent>(\n BLUR_COMMAND,\n () => {\n handleBlur()\n return true\n },\n COMMAND_PRIORITY_LOW,\n )\n\n return () => {\n unregisterFocus()\n unregisterBlur()\n editorConfigContext.parentEditor?.unregisterChild?.(editorConfigContext.uuid)\n }\n }, [editor, editorConfigContext])\n\n const [isSmallWidthViewport, setIsSmallWidthViewport] = useState<boolean>(false)\n\n useEffect(() => {\n const updateViewPortWidth = () => {\n const isNextSmallWidthViewport = window.matchMedia('(max-width: 768px)').matches\n\n if (isNextSmallWidthViewport !== isSmallWidthViewport) {\n setIsSmallWidthViewport(isNextSmallWidthViewport)\n }\n }\n updateViewPortWidth()\n window.addEventListener('resize', updateViewPortWidth)\n\n return () => {\n window.removeEventListener('resize', updateViewPortWidth)\n }\n }, [isSmallWidthViewport])\n\n return (\n <React.Fragment>\n {editorConfig.features.plugins?.map((plugin) => {\n if (plugin.position === 'aboveContainer') {\n return <EditorPlugin clientProps={plugin.clientProps} key={plugin.key} plugin={plugin} />\n }\n })}\n <div className=\"editor-container\" ref={editorContainerRef}>\n {editorConfig.features.plugins?.map((plugin) => {\n if (plugin.position === 'top') {\n return (\n <EditorPlugin clientProps={plugin.clientProps} key={plugin.key} plugin={plugin} />\n )\n }\n })}\n <RichTextPlugin\n contentEditable={\n <div className=\"editor-scroller\">\n <div className=\"editor\" ref={onRef} tabIndex={-1}>\n <LexicalContentEditable />\n </div>\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n <TextPlugin features={editorConfig.features} />\n <OnChangePlugin\n // Selection changes can be ignored here, reducing the\n // frequency that the FieldComponent and Payload receive updates.\n // Selection changes are only needed if you are saving selection state\n ignoreSelectionChange\n onChange={(editorState, editor, tags) => {\n // Ignore any onChange event triggered by focus only\n if (!tags.has('focus') || tags.size > 1) {\n if (onChange != null) {\n onChange(editorState, editor, tags)\n }\n }\n }}\n />\n {floatingAnchorElem && (\n <React.Fragment>\n {!isSmallWidthViewport && editor.isEditable() && (\n <React.Fragment>\n <DraggableBlockPlugin anchorElem={floatingAnchorElem} />\n <AddBlockHandlePlugin anchorElem={floatingAnchorElem} />\n </React.Fragment>\n )}\n {editorConfig.features.plugins?.map((plugin) => {\n if (\n plugin.position === 'floatingAnchorElem' &&\n !(plugin.desktopOnly === true && isSmallWidthViewport)\n ) {\n return (\n <EditorPlugin\n anchorElem={floatingAnchorElem}\n clientProps={plugin.clientProps}\n key={plugin.key}\n plugin={plugin}\n />\n )\n }\n })}\n {editor.isEditable() && (\n <React.Fragment>\n <SlashMenuPlugin anchorElem={floatingAnchorElem} />\n </React.Fragment>\n )}\n </React.Fragment>\n )}\n {editor.isEditable() && (\n <React.Fragment>\n <HistoryPlugin />\n {editorConfig?.features?.markdownTransformers?.length > 0 && <MarkdownShortcutPlugin />}\n </React.Fragment>\n )}\n {editorConfig.features.plugins?.map((plugin) => {\n if (plugin.position === 'normal') {\n return (\n <EditorPlugin clientProps={plugin.clientProps} key={plugin.key} plugin={plugin} />\n )\n }\n })}\n {editorConfig.features.plugins?.map((plugin) => {\n if (plugin.position === 'bottom') {\n return (\n <EditorPlugin clientProps={plugin.clientProps} key={plugin.key} plugin={plugin} />\n )\n }\n })}\n </div>\n {editorConfig.features.plugins?.map((plugin) => {\n if (plugin.position === 'belowContainer') {\n return <EditorPlugin clientProps={plugin.clientProps} key={plugin.key} plugin={plugin} />\n }\n })}\n </React.Fragment>\n )\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"LexicalEditor.js","names":["c","_c","useLexicalComposerContext","LexicalErrorBoundary","HistoryPlugin","OnChangePlugin","RichTextPlugin","BLUR_COMMAND","COMMAND_PRIORITY_LOW","FOCUS_COMMAND","React","useEffect","useState","useEditorConfigContext","EditorPlugin","AddBlockHandlePlugin","DraggableBlockPlugin","MarkdownShortcutPlugin","SlashMenuPlugin","TextPlugin","LexicalContentEditable","LexicalEditor","props","$","editorConfig","editorContainerRef","onChange","editorConfigContext","editor","floatingAnchorElem","setFloatingAnchorElem","t0","Symbol","for","_floatingAnchorElem","onRef","t1","t2","uuid","console","error","parentEditor","registerChild","handleFocus","focusEditor","handleBlur","blurEditor","unregisterFocus","registerCommand","unregisterBlur","unregisterChild","isSmallWidthViewport","setIsSmallWidthViewport","t3","t4","updateViewPortWidth","isNextSmallWidthViewport","window","matchMedia","matches","addEventListener","removeEventListener","t5","t6","editorState","editor_0","tags","has","size","t7","features","plugins","_jsxs","Fragment","children","isEditable","_jsx","anchorElem","map","plugin_1","plugin","position","desktopOnly","clientProps","key","_temp","className","ref","_temp2","contentEditable","tabIndex","ignoreSelectionChange","markdownTransformers","length","_temp3","_temp4","_temp5","plugin_0","plugin_2","plugin_3","plugin_4"],"sources":["../../src/lexical/LexicalEditor.tsx"],"sourcesContent":["'use client'\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary.js'\nimport { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin.js'\nimport { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin.js'\nimport { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin.js'\nimport { BLUR_COMMAND, COMMAND_PRIORITY_LOW, FOCUS_COMMAND } from 'lexical'\nimport * as React from 'react'\nimport { useEffect, useState } from 'react'\n\nimport type { LexicalProviderProps } from './LexicalProvider.js'\n\nimport { useEditorConfigContext } from './config/client/EditorConfigProvider.js'\nimport { EditorPlugin } from './EditorPlugin.js'\nimport './LexicalEditor.scss'\nimport { AddBlockHandlePlugin } from './plugins/handles/AddBlockHandlePlugin/index.js'\nimport { DraggableBlockPlugin } from './plugins/handles/DraggableBlockPlugin/index.js'\nimport { MarkdownShortcutPlugin } from './plugins/MarkdownShortcut/index.js'\nimport { SlashMenuPlugin } from './plugins/SlashMenu/index.js'\nimport { TextPlugin } from './plugins/TextPlugin/index.js'\nimport { LexicalContentEditable } from './ui/ContentEditable.js'\n\nexport const LexicalEditor: React.FC<\n {\n editorContainerRef: React.RefObject<HTMLDivElement | null>\n } & Pick<LexicalProviderProps, 'editorConfig' | 'onChange'>\n> = (props) => {\n const { editorConfig, editorContainerRef, onChange } = props\n const editorConfigContext = useEditorConfigContext()\n const [editor] = useLexicalComposerContext()\n\n const [floatingAnchorElem, setFloatingAnchorElem] = useState<HTMLDivElement | null>(null)\n const onRef = (_floatingAnchorElem: HTMLDivElement) => {\n if (_floatingAnchorElem !== null) {\n setFloatingAnchorElem(_floatingAnchorElem)\n }\n }\n\n useEffect(() => {\n if (!editorConfigContext?.uuid) {\n console.error('Lexical Editor must be used within an EditorConfigProvider')\n return\n }\n if (editorConfigContext?.parentEditor?.uuid) {\n editorConfigContext.parentEditor?.registerChild(editorConfigContext.uuid, editorConfigContext)\n }\n\n const handleFocus = () => {\n editorConfigContext.focusEditor(editorConfigContext)\n }\n\n const handleBlur = () => {\n editorConfigContext.blurEditor(editorConfigContext)\n }\n\n const unregisterFocus = editor.registerCommand<MouseEvent>(\n FOCUS_COMMAND,\n () => {\n handleFocus()\n return true\n },\n COMMAND_PRIORITY_LOW,\n )\n\n const unregisterBlur = editor.registerCommand<MouseEvent>(\n BLUR_COMMAND,\n () => {\n handleBlur()\n return true\n },\n COMMAND_PRIORITY_LOW,\n )\n\n return () => {\n unregisterFocus()\n unregisterBlur()\n editorConfigContext.parentEditor?.unregisterChild?.(editorConfigContext.uuid)\n }\n }, [editor, editorConfigContext])\n\n const [isSmallWidthViewport, setIsSmallWidthViewport] = useState<boolean>(false)\n\n useEffect(() => {\n const updateViewPortWidth = () => {\n const isNextSmallWidthViewport = window.matchMedia('(max-width: 768px)').matches\n\n if (isNextSmallWidthViewport !== isSmallWidthViewport) {\n setIsSmallWidthViewport(isNextSmallWidthViewport)\n }\n }\n updateViewPortWidth()\n window.addEventListener('resize', updateViewPortWidth)\n\n return () => {\n window.removeEventListener('resize', updateViewPortWidth)\n }\n }, [isSmallWidthViewport])\n\n return (\n <React.Fragment>\n {editorConfig.features.plugins?.map((plugin) => {\n if (plugin.position === 'aboveContainer') {\n return <EditorPlugin clientProps={plugin.clientProps} key={plugin.key} plugin={plugin} />\n }\n })}\n <div className=\"editor-container\" ref={editorContainerRef}>\n {editorConfig.features.plugins?.map((plugin) => {\n if (plugin.position === 'top') {\n return (\n <EditorPlugin clientProps={plugin.clientProps} key={plugin.key} plugin={plugin} />\n )\n }\n })}\n <RichTextPlugin\n contentEditable={\n <div className=\"editor-scroller\">\n <div className=\"editor\" ref={onRef} tabIndex={-1}>\n <LexicalContentEditable editorConfig={editorConfig} />\n </div>\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n <TextPlugin features={editorConfig.features} />\n <OnChangePlugin\n // Selection changes can be ignored here, reducing the\n // frequency that the FieldComponent and Payload receive updates.\n // Selection changes are only needed if you are saving selection state\n ignoreSelectionChange\n onChange={(editorState, editor, tags) => {\n // Ignore any onChange event triggered by focus only\n if (!tags.has('focus') || tags.size > 1) {\n if (onChange != null) {\n onChange(editorState, editor, tags)\n }\n }\n }}\n />\n {floatingAnchorElem && (\n <React.Fragment>\n {!isSmallWidthViewport && editor.isEditable() && (\n <React.Fragment>\n <DraggableBlockPlugin anchorElem={floatingAnchorElem} />\n <AddBlockHandlePlugin anchorElem={floatingAnchorElem} />\n </React.Fragment>\n )}\n {editorConfig.features.plugins?.map((plugin) => {\n if (\n plugin.position === 'floatingAnchorElem' &&\n !(plugin.desktopOnly === true && isSmallWidthViewport)\n ) {\n return (\n <EditorPlugin\n anchorElem={floatingAnchorElem}\n clientProps={plugin.clientProps}\n key={plugin.key}\n plugin={plugin}\n />\n )\n }\n })}\n {editor.isEditable() && (\n <React.Fragment>\n <SlashMenuPlugin anchorElem={floatingAnchorElem} />\n </React.Fragment>\n )}\n </React.Fragment>\n )}\n {editor.isEditable() && (\n <React.Fragment>\n <HistoryPlugin />\n {editorConfig?.features?.markdownTransformers?.length > 0 && <MarkdownShortcutPlugin />}\n </React.Fragment>\n )}\n {editorConfig.features.plugins?.map((plugin) => {\n if (plugin.position === 'normal') {\n return (\n <EditorPlugin clientProps={plugin.clientProps} key={plugin.key} plugin={plugin} />\n )\n }\n })}\n {editorConfig.features.plugins?.map((plugin) => {\n if (plugin.position === 'bottom') {\n return (\n <EditorPlugin clientProps={plugin.clientProps} key={plugin.key} plugin={plugin} />\n )\n }\n })}\n </div>\n {editorConfig.features.plugins?.map((plugin) => {\n if (plugin.position === 'belowContainer') {\n return <EditorPlugin clientProps={plugin.clientProps} key={plugin.key} plugin={plugin} />\n }\n })}\n </React.Fragment>\n )\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { JSX } from 'react';
|
|
2
2
|
import './ContentEditable.scss';
|
|
3
|
-
|
|
3
|
+
import type { SanitizedClientEditorConfig } from '../config/types.js';
|
|
4
|
+
export declare function LexicalContentEditable({ className, editorConfig, }: {
|
|
4
5
|
className?: string;
|
|
6
|
+
editorConfig: SanitizedClientEditorConfig;
|
|
5
7
|
}): JSX.Element;
|
|
6
8
|
//# sourceMappingURL=ContentEditable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentEditable.d.ts","sourceRoot":"","sources":["../../../src/lexical/ui/ContentEditable.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAMhC,OAAO,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"ContentEditable.d.ts","sourceRoot":"","sources":["../../../src/lexical/ui/ContentEditable.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAMhC,OAAO,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAA;AAErE,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,YAAY,GACb,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,2BAA2B,CAAA;CAC1C,GAAG,GAAG,CAAC,OAAO,CAcd"}
|
|
@@ -6,28 +6,39 @@ import { ContentEditable } from '@lexical/react/LexicalContentEditable.js';
|
|
|
6
6
|
import { useTranslation } from '@payloadcms/ui';
|
|
7
7
|
import * as React from 'react';
|
|
8
8
|
export function LexicalContentEditable(t0) {
|
|
9
|
-
const $ = _c(
|
|
9
|
+
const $ = _c(7);
|
|
10
10
|
const {
|
|
11
|
-
className
|
|
11
|
+
className,
|
|
12
|
+
editorConfig
|
|
12
13
|
} = t0;
|
|
13
14
|
const {
|
|
14
15
|
t
|
|
15
16
|
} = useTranslation();
|
|
16
17
|
let t1;
|
|
17
|
-
if ($[0] !== className || $[1] !== t) {
|
|
18
|
+
if ($[0] !== className || $[1] !== editorConfig?.admin?.placeholder || $[2] !== t) {
|
|
19
|
+
let t2;
|
|
20
|
+
if ($[4] !== editorConfig?.admin?.placeholder || $[5] !== t) {
|
|
21
|
+
t2 = editorConfig?.admin?.placeholder ?? t("lexical:general:placeholder");
|
|
22
|
+
$[4] = editorConfig?.admin?.placeholder;
|
|
23
|
+
$[5] = t;
|
|
24
|
+
$[6] = t2;
|
|
25
|
+
} else {
|
|
26
|
+
t2 = $[6];
|
|
27
|
+
}
|
|
18
28
|
t1 = _jsx(ContentEditable, {
|
|
19
29
|
"aria-placeholder": t("lexical:general:placeholder"),
|
|
20
30
|
className: className ?? "ContentEditable__root",
|
|
21
31
|
placeholder: _jsx("p", {
|
|
22
32
|
className: "editor-placeholder",
|
|
23
|
-
children:
|
|
33
|
+
children: t2
|
|
24
34
|
})
|
|
25
35
|
});
|
|
26
36
|
$[0] = className;
|
|
27
|
-
$[1] =
|
|
28
|
-
$[2] =
|
|
37
|
+
$[1] = editorConfig?.admin?.placeholder;
|
|
38
|
+
$[2] = t;
|
|
39
|
+
$[3] = t1;
|
|
29
40
|
} else {
|
|
30
|
-
t1 = $[
|
|
41
|
+
t1 = $[3];
|
|
31
42
|
}
|
|
32
43
|
return t1;
|
|
33
44
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentEditable.js","names":["c","_c","ContentEditable","useTranslation","React","LexicalContentEditable","t0","$","className","t","t1","
|
|
1
|
+
{"version":3,"file":"ContentEditable.js","names":["c","_c","ContentEditable","useTranslation","React","LexicalContentEditable","t0","$","className","editorConfig","t","t1","admin","placeholder","t2","_jsx","children"],"sources":["../../../src/lexical/ui/ContentEditable.tsx"],"sourcesContent":["'use client'\nimport type { JSX } from 'react'\n\nimport { ContentEditable } from '@lexical/react/LexicalContentEditable.js'\nimport { useTranslation } from '@payloadcms/ui'\nimport * as React from 'react'\n\nimport './ContentEditable.scss'\nimport type { SanitizedClientEditorConfig } from '../config/types.js'\n\nexport function LexicalContentEditable({\n className,\n editorConfig,\n}: {\n className?: string\n editorConfig: SanitizedClientEditorConfig\n}): JSX.Element {\n const { t } = useTranslation<{}, string>()\n\n return (\n <ContentEditable\n aria-placeholder={t('lexical:general:placeholder')}\n className={className ?? 'ContentEditable__root'}\n placeholder={\n <p className=\"editor-placeholder\">\n {editorConfig?.admin?.placeholder ?? t('lexical:general:placeholder')}\n </p>\n }\n />\n )\n}\n"],"mappings":"AAAA;;AAAA,SAAAA,CAAA,IAAAC,EAAA;;AAGA,SAASC,eAAe,QAAQ;AAChC,SAASC,cAAc,QAAQ;AAC/B,YAAYC,KAAA,MAAW;AAKvB,OAAO,SAAAC,uBAAAC,EAAA;EAAA,MAAAC,CAAA,GAAAN,EAAA;EAAgC;IAAAO,SAAA;IAAAC;EAAA,IAAAH,EAMtC;EACC;IAAAI;EAAA,IAAcP,cAAA;EAAA,IAAAQ,EAAA;EAAA,IAAAJ,CAAA,QAAAC,SAAA,IAAAD,CAAA,QAAAE,YAAA,EAAAG,KAAA,EAAAC,WAAA,IAAAN,CAAA,QAAAG,CAAA;IAAA,IAAAI,EAAA;IAAA,IAAAP,CAAA,QAAAE,YAAA,EAAAG,KAAA,EAAAC,WAAA,IAAAN,CAAA,QAAAG,CAAA;MAQLI,EAAA,GAAAL,YAAA,EAAAG,KAAA,EAAAC,WAAA,IAAoCH,CAAA,CAAE;MAAAH,CAAA,MAAAE,YAAA,EAAAG,KAAA,EAAAC,WAAA;MAAAN,CAAA,MAAAG,CAAA;MAAAH,CAAA,MAAAO,EAAA;IAAA;MAAAA,EAAA,GAAAP,CAAA;IAAA;IAL7CI,EAAA,GAAAI,IAAA,CAAAb,eAAA;MAAA,oBACoBQ,CAAA,CAAE;MAAAF,SAAA,EACTA,SAAA,IAAa;MAAAK,WAAA,EAEtBE,IAAA,CAAC;QAAAP,SAAA,EAAY;QAAAQ,QAAA,EACVF;MAAsC,C;;;;;;;;;SAL7CH,E","ignoreList":[]}
|
|
@@ -51,15 +51,28 @@ function exportTopLevelElements(node, elementTransformers, textTransformersIndex
|
|
|
51
51
|
return null;
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
function exportChildren(node, textTransformersIndex, textMatchTransformers) {
|
|
54
|
+
function exportChildren(node, textTransformersIndex, textMatchTransformers, unclosedTags, unclosableTags) {
|
|
55
55
|
const output = [];
|
|
56
56
|
const children = node.getChildren();
|
|
57
|
+
// keep track of unclosed tags from the very beginning
|
|
58
|
+
if (!unclosedTags) {
|
|
59
|
+
unclosedTags = [];
|
|
60
|
+
}
|
|
61
|
+
if (!unclosableTags) {
|
|
62
|
+
unclosableTags = [];
|
|
63
|
+
}
|
|
57
64
|
mainLoop: for (const child of children) {
|
|
58
65
|
for (const transformer of textMatchTransformers) {
|
|
59
66
|
if (!transformer.export) {
|
|
60
67
|
continue;
|
|
61
68
|
}
|
|
62
|
-
const result = transformer.export(child, parentNode => exportChildren(parentNode, textTransformersIndex, textMatchTransformers
|
|
69
|
+
const result = transformer.export(child, parentNode => exportChildren(parentNode, textTransformersIndex, textMatchTransformers, unclosedTags,
|
|
70
|
+
// Add current unclosed tags to the list of unclosable tags - we don't want nested tags from
|
|
71
|
+
// textmatch transformers to close the outer ones, as that may result in invalid markdown.
|
|
72
|
+
// E.g. **text [text**](https://lexical.io)
|
|
73
|
+
// is invalid markdown, as the closing ** is inside the link.
|
|
74
|
+
//
|
|
75
|
+
[...unclosableTags, ...unclosedTags]), (textNode, textContent) => exportTextFormat(textNode, textContent, textTransformersIndex, unclosedTags, unclosableTags));
|
|
63
76
|
if (result != null) {
|
|
64
77
|
output.push(result);
|
|
65
78
|
continue mainLoop;
|
|
@@ -68,44 +81,85 @@ function exportChildren(node, textTransformersIndex, textMatchTransformers) {
|
|
|
68
81
|
if ($isLineBreakNode(child)) {
|
|
69
82
|
output.push('\n');
|
|
70
83
|
} else if ($isTextNode(child)) {
|
|
71
|
-
output.push(exportTextFormat(child, child.getTextContent(), textTransformersIndex));
|
|
84
|
+
output.push(exportTextFormat(child, child.getTextContent(), textTransformersIndex, unclosedTags, unclosableTags));
|
|
72
85
|
} else if ($isElementNode(child)) {
|
|
73
86
|
// empty paragraph returns ""
|
|
74
|
-
output.push(exportChildren(child, textTransformersIndex, textMatchTransformers));
|
|
87
|
+
output.push(exportChildren(child, textTransformersIndex, textMatchTransformers, unclosedTags, unclosableTags));
|
|
75
88
|
} else if ($isDecoratorNode(child)) {
|
|
76
89
|
output.push(child.getTextContent());
|
|
77
90
|
}
|
|
78
91
|
}
|
|
79
92
|
return output.join('');
|
|
80
93
|
}
|
|
81
|
-
function exportTextFormat(node, textContent, textTransformers
|
|
94
|
+
function exportTextFormat(node, textContent, textTransformers,
|
|
95
|
+
// unclosed tags include the markdown tags that haven't been closed yet, and their associated formats
|
|
96
|
+
unclosedTags, unclosableTags) {
|
|
82
97
|
// This function handles the case of a string looking like this: " foo "
|
|
83
98
|
// Where it would be invalid markdown to generate: "** foo **"
|
|
84
99
|
// We instead want to trim the whitespace out, apply formatting, and then
|
|
85
100
|
// bring the whitespace back. So our returned string looks like this: " **foo** "
|
|
86
101
|
const frozenString = textContent.trim();
|
|
87
102
|
let output = frozenString;
|
|
103
|
+
// the opening tags to be added to the result
|
|
104
|
+
let openingTags = '';
|
|
105
|
+
// the closing tags to be added to the result
|
|
106
|
+
let closingTagsBefore = '';
|
|
107
|
+
let closingTagsAfter = '';
|
|
108
|
+
const prevNode = getTextSibling(node, true);
|
|
109
|
+
const nextNode = getTextSibling(node, false);
|
|
88
110
|
const applied = new Set();
|
|
89
111
|
for (const transformer of textTransformers) {
|
|
90
112
|
const format = transformer.format[0];
|
|
91
113
|
const tag = transformer.tag;
|
|
114
|
+
// dedup applied formats
|
|
92
115
|
if (hasFormat(node, format) && !applied.has(format)) {
|
|
93
116
|
// Multiple tags might be used for the same format (*, _)
|
|
94
117
|
applied.add(format);
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
if (!hasFormat(
|
|
98
|
-
|
|
118
|
+
// append the tag to openningTags, if it's not applied to the previous nodes,
|
|
119
|
+
// or the nodes before that (which would result in an unclosed tag)
|
|
120
|
+
if (!hasFormat(prevNode, format) || !unclosedTags.find(element => element.tag === tag)) {
|
|
121
|
+
unclosedTags.push({
|
|
122
|
+
format,
|
|
123
|
+
tag
|
|
124
|
+
});
|
|
125
|
+
openingTags += tag;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// close any tags in the same order they were applied, if necessary
|
|
130
|
+
for (let i = 0; i < unclosedTags.length; i++) {
|
|
131
|
+
const nodeHasFormat = hasFormat(node, unclosedTags[i].format);
|
|
132
|
+
const nextNodeHasFormat = hasFormat(nextNode, unclosedTags[i].format);
|
|
133
|
+
// prevent adding closing tag if next sibling will do it
|
|
134
|
+
if (nodeHasFormat && nextNodeHasFormat) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const unhandledUnclosedTags = [...unclosedTags] // Shallow copy to avoid modifying the original array
|
|
138
|
+
;
|
|
139
|
+
while (unhandledUnclosedTags.length > i) {
|
|
140
|
+
const unclosedTag = unhandledUnclosedTags.pop();
|
|
141
|
+
// If tag is unclosable, don't close it and leave it in the original array,
|
|
142
|
+
// So that it can be closed when it's no longer unclosable
|
|
143
|
+
if (unclosableTags && unclosedTag && unclosableTags.find(element => element.tag === unclosedTag.tag)) {
|
|
144
|
+
continue;
|
|
99
145
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
146
|
+
if (unclosedTag && typeof unclosedTag.tag === 'string') {
|
|
147
|
+
if (!nodeHasFormat) {
|
|
148
|
+
// Handles cases where the tag has not been closed before, e.g. if the previous node
|
|
149
|
+
// was a text match transformer that did not account for closing tags of the next node (e.g. a link)
|
|
150
|
+
closingTagsBefore += unclosedTag.tag;
|
|
151
|
+
} else if (!nextNodeHasFormat) {
|
|
152
|
+
closingTagsAfter += unclosedTag.tag;
|
|
153
|
+
}
|
|
104
154
|
}
|
|
155
|
+
// Mutate the original array to remove the closed tag
|
|
156
|
+
unclosedTags.pop();
|
|
105
157
|
}
|
|
158
|
+
break;
|
|
106
159
|
}
|
|
160
|
+
output = openingTags + output + closingTagsAfter;
|
|
107
161
|
// Replace trimmed version of textContent ensuring surrounding whitespace is not modified
|
|
108
|
-
return textContent.replace(frozenString, () => output);
|
|
162
|
+
return closingTagsBefore + textContent.replace(frozenString, () => output);
|
|
109
163
|
}
|
|
110
164
|
// Get next or previous text sibling a text node, including cases
|
|
111
165
|
// when it's a child of inline element (e.g. link)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownExport.js","names":["$getRoot","$isDecoratorNode","$isElementNode","$isLineBreakNode","$isTextNode","isEmptyParagraph","transformersByType","createMarkdownExport","transformers","shouldPreserveNewLines","byType","elementTransformers","multilineElement","element","isNewlineDelimited","textFormatTransformers","textFormat","filter","transformer","format","length","node","output","children","getChildren","i","child","result","exportTopLevelElements","textMatch","push","concat","join","textTransformersIndex","textMatchTransformers","export","_node","exportChildren","getTextContent","mainLoop","parentNode","textNode","textContent","exportTextFormat","textTransformers","frozenString","trim","applied","Set","tag","hasFormat","has","add","previousNode","getTextSibling","nextNode","replace","backward","sibling","getPreviousSibling","getNextSibling","parent","getParentOrThrow","isInline","descendant","getLastDescendant","getFirstDescendant"],"sources":["../../../../src/packages/@lexical/markdown/MarkdownExport.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport type { ElementNode, LexicalNode, TextFormatType, TextNode } from 'lexical'\n\nimport { $getRoot, $isDecoratorNode, $isElementNode, $isLineBreakNode, $isTextNode } from 'lexical'\n\nimport type {\n ElementTransformer,\n MultilineElementTransformer,\n TextFormatTransformer,\n TextMatchTransformer,\n Transformer,\n} from './MarkdownTransformers.js'\n\nimport { isEmptyParagraph, transformersByType } from './utils.js'\n\n/**\n * Renders string from markdown. The selection is moved to the start after the operation.\n */\nexport function createMarkdownExport(\n transformers: Array<Transformer>,\n shouldPreserveNewLines: boolean = false,\n): (node?: ElementNode) => string {\n const byType = transformersByType(transformers)\n const elementTransformers = [...byType.multilineElement, ...byType.element]\n const isNewlineDelimited = !shouldPreserveNewLines\n\n // Export only uses text formats that are responsible for single format\n // e.g. it will filter out *** (bold, italic) and instead use separate ** and *\n const textFormatTransformers = byType.textFormat.filter(\n (transformer) => transformer.format.length === 1,\n )\n\n return (node) => {\n const output: string[] = []\n const children = (node || $getRoot()).getChildren()\n\n for (let i = 0; i < children.length; i++) {\n const child = children[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): string {\n const output: string[] = []\n const children = node.getChildren()\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) => exportChildren(parentNode, textTransformersIndex, textMatchTransformers),\n (textNode, textContent) => exportTextFormat(textNode, textContent, textTransformersIndex),\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(exportTextFormat(child, child.getTextContent(), textTransformersIndex))\n } else if ($isElementNode(child)) {\n // empty paragraph returns \"\"\n output.push(exportChildren(child, textTransformersIndex, textMatchTransformers))\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): 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 const applied = new Set()\n\n for (const transformer of textTransformers) {\n const format = transformer.format[0]\n const tag = transformer.tag\n\n if (hasFormat(node, format) && !applied.has(format)) {\n // Multiple tags might be used for the same format (*, _)\n applied.add(format)\n // Prevent adding opening tag is already opened by the previous sibling\n const previousNode = getTextSibling(node, true)\n\n if (!hasFormat(previousNode, format)) {\n output = tag + output\n }\n\n // Prevent adding closing tag if next sibling will do it\n const nextNode = getTextSibling(node, false)\n\n if (!hasFormat(nextNode, format)) {\n output += tag\n }\n }\n }\n\n // Replace trimmed version of textContent ensuring surrounding whitespace is not modified\n return textContent.replace(frozenString, () => output)\n}\n\n// Get next or previous text sibling a text node, including cases\n// when it's a child of inline element (e.g. link)\nfunction getTextSibling(node: TextNode, backward: boolean): null | TextNode {\n let sibling = backward ? node.getPreviousSibling() : node.getNextSibling()\n\n if (!sibling) {\n const parent = node.getParentOrThrow()\n\n if (parent.isInline()) {\n sibling = backward ? parent.getPreviousSibling() : parent.getNextSibling()\n }\n }\n\n while (sibling) {\n if ($isElementNode(sibling)) {\n if (!sibling.isInline()) {\n break\n }\n\n const descendant = backward ? sibling.getLastDescendant() : sibling.getFirstDescendant()\n\n if ($isTextNode(descendant)) {\n return descendant\n } else {\n sibling = backward ? sibling.getPreviousSibling() : sibling.getNextSibling()\n }\n }\n\n if ($isTextNode(sibling)) {\n return sibling\n }\n\n if (!$isElementNode(sibling)) {\n return null\n }\n }\n\n return null\n}\n\nfunction hasFormat(node: LexicalNode | null | undefined, format: TextFormatType): boolean {\n return $isTextNode(node) && node.hasFormat(format)\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"MarkdownExport.js","names":["$getRoot","$isDecoratorNode","$isElementNode","$isLineBreakNode","$isTextNode","isEmptyParagraph","transformersByType","createMarkdownExport","transformers","shouldPreserveNewLines","byType","elementTransformers","multilineElement","element","isNewlineDelimited","textFormatTransformers","textFormat","filter","transformer","format","length","node","output","children","getChildren","i","child","result","exportTopLevelElements","textMatch","push","concat","join","textTransformersIndex","textMatchTransformers","export","_node","exportChildren","getTextContent","unclosedTags","unclosableTags","mainLoop","parentNode","textNode","textContent","exportTextFormat","textTransformers","frozenString","trim","openingTags","closingTagsBefore","closingTagsAfter","prevNode","getTextSibling","nextNode","applied","Set","tag","hasFormat","has","add","find","nodeHasFormat","nextNodeHasFormat","unhandledUnclosedTags","unclosedTag","pop","replace","backward","sibling","getPreviousSibling","getNextSibling","parent","getParentOrThrow","isInline","descendant","getLastDescendant","getFirstDescendant"],"sources":["../../../../src/packages/@lexical/markdown/MarkdownExport.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport type { ElementNode, LexicalNode, TextFormatType, TextNode } from 'lexical'\n\nimport { $getRoot, $isDecoratorNode, $isElementNode, $isLineBreakNode, $isTextNode } from 'lexical'\n\nimport type {\n ElementTransformer,\n MultilineElementTransformer,\n TextFormatTransformer,\n TextMatchTransformer,\n Transformer,\n} from './MarkdownTransformers.js'\n\nimport { isEmptyParagraph, transformersByType } from './utils.js'\n\n/**\n * Renders string from markdown. The selection is moved to the start after the operation.\n */\nexport function createMarkdownExport(\n transformers: Array<Transformer>,\n shouldPreserveNewLines: boolean = false,\n): (node?: ElementNode) => string {\n const byType = transformersByType(transformers)\n const elementTransformers = [...byType.multilineElement, ...byType.element]\n const isNewlineDelimited = !shouldPreserveNewLines\n\n // Export only uses text formats that are responsible for single format\n // e.g. it will filter out *** (bold, italic) and instead use separate ** and *\n const textFormatTransformers = byType.textFormat.filter(\n (transformer) => transformer.format.length === 1,\n )\n\n return (node) => {\n const output = []\n const children = (node || $getRoot()).getChildren()\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n const result = exportTopLevelElements(\n child,\n elementTransformers,\n textFormatTransformers,\n byType.textMatch,\n )\n\n if (result != null) {\n output.push(\n // separate consecutive group of texts with a line break: eg. [\"hello\", \"world\"] -> [\"hello\", \"/nworld\"]\n isNewlineDelimited &&\n i > 0 &&\n !isEmptyParagraph(child) &&\n !isEmptyParagraph(children[i - 1])\n ? '\\n'.concat(result)\n : result,\n )\n }\n }\n // Ensure consecutive groups of texts are at least \\n\\n apart while each empty paragraph render as a newline.\n // Eg. [\"hello\", \"\", \"\", \"hi\", \"\\nworld\"] -> \"hello\\n\\n\\nhi\\n\\nworld\"\n return output.join('\\n')\n }\n}\n\nfunction exportTopLevelElements(\n node: LexicalNode,\n elementTransformers: Array<ElementTransformer | MultilineElementTransformer>,\n textTransformersIndex: Array<TextFormatTransformer>,\n textMatchTransformers: Array<TextMatchTransformer>,\n): null | string {\n for (const transformer of elementTransformers) {\n if (!transformer.export) {\n continue\n }\n const result = transformer.export(node, (_node) =>\n exportChildren(_node, textTransformersIndex, textMatchTransformers),\n )\n\n if (result != null) {\n return result\n }\n }\n\n if ($isElementNode(node)) {\n return exportChildren(node, textTransformersIndex, textMatchTransformers)\n } else if ($isDecoratorNode(node)) {\n return node.getTextContent()\n } else {\n return null\n }\n}\n\nfunction exportChildren(\n node: ElementNode,\n textTransformersIndex: Array<TextFormatTransformer>,\n textMatchTransformers: Array<TextMatchTransformer>,\n unclosedTags?: Array<{ format: TextFormatType; tag: string }>,\n unclosableTags?: Array<{ format: TextFormatType; tag: string }>,\n): string {\n const output = []\n const children = node.getChildren()\n // keep track of unclosed tags from the very beginning\n if (!unclosedTags) {\n unclosedTags = []\n }\n if (!unclosableTags) {\n unclosableTags = []\n }\n\n mainLoop: for (const child of children) {\n for (const transformer of textMatchTransformers) {\n if (!transformer.export) {\n continue\n }\n\n const result = transformer.export(\n child,\n (parentNode) =>\n exportChildren(\n parentNode,\n textTransformersIndex,\n textMatchTransformers,\n unclosedTags,\n // Add current unclosed tags to the list of unclosable tags - we don't want nested tags from\n // textmatch transformers to close the outer ones, as that may result in invalid markdown.\n // E.g. **text [text**](https://lexical.io)\n // is invalid markdown, as the closing ** is inside the link.\n //\n [...unclosableTags, ...unclosedTags],\n ),\n (textNode, textContent) =>\n exportTextFormat(\n textNode,\n textContent,\n textTransformersIndex,\n unclosedTags,\n unclosableTags,\n ),\n )\n\n if (result != null) {\n output.push(result)\n continue mainLoop\n }\n }\n\n if ($isLineBreakNode(child)) {\n output.push('\\n')\n } else if ($isTextNode(child)) {\n output.push(\n exportTextFormat(\n child,\n child.getTextContent(),\n textTransformersIndex,\n unclosedTags,\n unclosableTags,\n ),\n )\n } else if ($isElementNode(child)) {\n // empty paragraph returns \"\"\n output.push(\n exportChildren(\n child,\n textTransformersIndex,\n textMatchTransformers,\n unclosedTags,\n unclosableTags,\n ),\n )\n } else if ($isDecoratorNode(child)) {\n output.push(child.getTextContent())\n }\n }\n\n return output.join('')\n}\n\nfunction exportTextFormat(\n node: TextNode,\n textContent: string,\n textTransformers: Array<TextFormatTransformer>,\n // unclosed tags include the markdown tags that haven't been closed yet, and their associated formats\n unclosedTags: Array<{ format: TextFormatType; tag: string }>,\n unclosableTags?: Array<{ format: TextFormatType; tag: string }>,\n): string {\n // This function handles the case of a string looking like this: \" foo \"\n // Where it would be invalid markdown to generate: \"** foo **\"\n // We instead want to trim the whitespace out, apply formatting, and then\n // bring the whitespace back. So our returned string looks like this: \" **foo** \"\n const frozenString = textContent.trim()\n let output = frozenString\n // the opening tags to be added to the result\n let openingTags = ''\n // the closing tags to be added to the result\n let closingTagsBefore = ''\n let closingTagsAfter = ''\n\n const prevNode = getTextSibling(node, true)\n const nextNode = getTextSibling(node, false)\n\n const applied = new Set()\n\n for (const transformer of textTransformers) {\n const format = transformer.format[0]\n const tag = transformer.tag\n\n // dedup applied formats\n if (hasFormat(node, format) && !applied.has(format)) {\n // Multiple tags might be used for the same format (*, _)\n applied.add(format)\n\n // append the tag to openningTags, if it's not applied to the previous nodes,\n // or the nodes before that (which would result in an unclosed tag)\n if (!hasFormat(prevNode, format) || !unclosedTags.find((element) => element.tag === tag)) {\n unclosedTags.push({ format, tag })\n openingTags += tag\n }\n }\n }\n\n // close any tags in the same order they were applied, if necessary\n for (let i = 0; i < unclosedTags.length; i++) {\n const nodeHasFormat = hasFormat(node, unclosedTags[i].format)\n const nextNodeHasFormat = hasFormat(nextNode, unclosedTags[i].format)\n\n // prevent adding closing tag if next sibling will do it\n if (nodeHasFormat && nextNodeHasFormat) {\n continue\n }\n\n const unhandledUnclosedTags = [...unclosedTags] // Shallow copy to avoid modifying the original array\n\n while (unhandledUnclosedTags.length > i) {\n const unclosedTag = unhandledUnclosedTags.pop()\n\n // If tag is unclosable, don't close it and leave it in the original array,\n // So that it can be closed when it's no longer unclosable\n if (\n unclosableTags &&\n unclosedTag &&\n unclosableTags.find((element) => element.tag === unclosedTag.tag)\n ) {\n continue\n }\n\n if (unclosedTag && typeof unclosedTag.tag === 'string') {\n if (!nodeHasFormat) {\n // Handles cases where the tag has not been closed before, e.g. if the previous node\n // was a text match transformer that did not account for closing tags of the next node (e.g. a link)\n closingTagsBefore += unclosedTag.tag\n } else if (!nextNodeHasFormat) {\n closingTagsAfter += unclosedTag.tag\n }\n }\n // Mutate the original array to remove the closed tag\n unclosedTags.pop()\n }\n break\n }\n\n output = openingTags + output + closingTagsAfter\n // Replace trimmed version of textContent ensuring surrounding whitespace is not modified\n return closingTagsBefore + textContent.replace(frozenString, () => output)\n}\n\n// Get next or previous text sibling a text node, including cases\n// when it's a child of inline element (e.g. link)\nfunction getTextSibling(node: TextNode, backward: boolean): null | TextNode {\n let sibling = backward ? node.getPreviousSibling() : node.getNextSibling()\n\n if (!sibling) {\n const parent = node.getParentOrThrow()\n\n if (parent.isInline()) {\n sibling = backward ? parent.getPreviousSibling() : parent.getNextSibling()\n }\n }\n\n while (sibling) {\n if ($isElementNode(sibling)) {\n if (!sibling.isInline()) {\n break\n }\n\n const descendant = backward ? sibling.getLastDescendant() : sibling.getFirstDescendant()\n\n if ($isTextNode(descendant)) {\n return descendant\n } else {\n sibling = backward ? sibling.getPreviousSibling() : sibling.getNextSibling()\n }\n }\n\n if ($isTextNode(sibling)) {\n return sibling\n }\n\n if (!$isElementNode(sibling)) {\n return null\n }\n }\n\n return null\n}\n\nfunction hasFormat(node: LexicalNode | null | undefined, format: TextFormatType): boolean {\n return $isTextNode(node) && node.hasFormat(format)\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -6,7 +6,12 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
import type { ElementNode } from 'lexical';
|
|
9
|
-
import type { Transformer } from './MarkdownTransformers.js';
|
|
9
|
+
import type { TextFormatTransformer, Transformer } from './MarkdownTransformers.js';
|
|
10
|
+
export type TextFormatTransformersIndex = Readonly<{
|
|
11
|
+
fullMatchRegExpByTag: Readonly<Record<string, RegExp>>;
|
|
12
|
+
openTagsRegExp: RegExp;
|
|
13
|
+
transformersByTag: Readonly<Record<string, TextFormatTransformer>>;
|
|
14
|
+
}>;
|
|
10
15
|
/**
|
|
11
16
|
* Renders markdown from a string. The selection is moved to the start after the operation.
|
|
12
17
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownImport.d.ts","sourceRoot":"","sources":["../../../../src/packages/@lexical/markdown/MarkdownImport.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"MarkdownImport.d.ts","sourceRoot":"","sources":["../../../../src/packages/@lexical/markdown/MarkdownImport.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAc1C,OAAO,KAAK,EAGV,qBAAqB,EAErB,WAAW,EACZ,MAAM,2BAA2B,CAAA;AAMlC,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IACjD,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACtD,cAAc,EAAE,MAAM,CAAA;IACtB,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAA;CACnE,CAAC,CAAA;AAEF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,EAChC,sBAAsB,UAAQ,GAC7B,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,IAAI,CAyCtD"}
|
|
@@ -9,7 +9,8 @@ import { $isQuoteNode } from '@lexical/rich-text';
|
|
|
9
9
|
import { $findMatchingParent } from '@lexical/utils';
|
|
10
10
|
import { $createLineBreakNode, $createParagraphNode, $createTextNode, $getRoot, $getSelection, $isParagraphNode } from 'lexical';
|
|
11
11
|
import { IS_APPLE_WEBKIT, IS_IOS, IS_SAFARI } from '../../../lexical/utils/environment.js';
|
|
12
|
-
import {
|
|
12
|
+
import { importTextTransformers } from './importTextTransformers.js';
|
|
13
|
+
import { isEmptyParagraph, transformersByType } from './utils.js';
|
|
13
14
|
/**
|
|
14
15
|
* Renders markdown from a string. The selection is moved to the start after the operation.
|
|
15
16
|
*/
|
|
@@ -146,7 +147,7 @@ function $importBlocks(lineText, rootNode, elementTransformers, textFormatTransf
|
|
|
146
147
|
}
|
|
147
148
|
}
|
|
148
149
|
}
|
|
149
|
-
|
|
150
|
+
importTextTransformers(textNode, textFormatTransformersIndex, textMatchTransformers);
|
|
150
151
|
// If no transformer found and we left with original paragraph node
|
|
151
152
|
// can check if its content can be appended to the previous node
|
|
152
153
|
// if it's a paragraph, quote or list
|
|
@@ -169,123 +170,6 @@ function $importBlocks(lineText, rootNode, elementTransformers, textFormatTransf
|
|
|
169
170
|
}
|
|
170
171
|
}
|
|
171
172
|
}
|
|
172
|
-
// Processing text content and replaces text format tags.
|
|
173
|
-
// It takes outermost tag match and its content, creates text node with
|
|
174
|
-
// format based on tag and then recursively executed over node's content
|
|
175
|
-
//
|
|
176
|
-
// E.g. for "*Hello **world**!*" string it will create text node with
|
|
177
|
-
// "Hello **world**!" content and italic format and run recursively over
|
|
178
|
-
// its content to transform "**world**" part
|
|
179
|
-
function importTextFormatTransformers(textNode, textFormatTransformersIndex, textMatchTransformers) {
|
|
180
|
-
const textContent = textNode.getTextContent();
|
|
181
|
-
const match = findOutermostMatch(textContent, textFormatTransformersIndex);
|
|
182
|
-
if (!match) {
|
|
183
|
-
// Once text format processing is done run text match transformers, as it
|
|
184
|
-
// only can span within single text node (unline formats that can cover multiple nodes)
|
|
185
|
-
importTextMatchTransformers(textNode, textMatchTransformers);
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
let currentNode, leadingNode, remainderNode;
|
|
189
|
-
// If matching full content there's no need to run splitText and can reuse existing textNode
|
|
190
|
-
// to update its content and apply format. E.g. for **_Hello_** string after applying bold
|
|
191
|
-
// format (**) it will reuse the same text node to apply italic (_)
|
|
192
|
-
if (match[0] === textContent) {
|
|
193
|
-
currentNode = textNode;
|
|
194
|
-
} else {
|
|
195
|
-
const startIndex = match.index || 0;
|
|
196
|
-
const endIndex = startIndex + match[0].length;
|
|
197
|
-
if (startIndex === 0) {
|
|
198
|
-
[currentNode, remainderNode] = textNode.splitText(endIndex);
|
|
199
|
-
} else {
|
|
200
|
-
[leadingNode, currentNode, remainderNode] = textNode.splitText(startIndex, endIndex);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
currentNode.setTextContent(match[2]);
|
|
204
|
-
const transformer = textFormatTransformersIndex.transformersByTag[match[1]];
|
|
205
|
-
if (transformer) {
|
|
206
|
-
for (const format of transformer.format) {
|
|
207
|
-
if (!currentNode.hasFormat(format)) {
|
|
208
|
-
currentNode.toggleFormat(format);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
// Recursively run over inner text if it's not inline code
|
|
213
|
-
if (!currentNode.hasFormat('code')) {
|
|
214
|
-
importTextFormatTransformers(currentNode, textFormatTransformersIndex, textMatchTransformers);
|
|
215
|
-
}
|
|
216
|
-
// Run over leading/remaining text if any
|
|
217
|
-
if (leadingNode) {
|
|
218
|
-
importTextFormatTransformers(leadingNode, textFormatTransformersIndex, textMatchTransformers);
|
|
219
|
-
}
|
|
220
|
-
if (remainderNode) {
|
|
221
|
-
importTextFormatTransformers(remainderNode, textFormatTransformersIndex, textMatchTransformers);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
function importTextMatchTransformers(textNode_, textMatchTransformers) {
|
|
225
|
-
let textNode = textNode_;
|
|
226
|
-
mainLoop: while (textNode) {
|
|
227
|
-
for (const transformer of textMatchTransformers) {
|
|
228
|
-
if (!transformer.replace || !transformer.importRegExp) {
|
|
229
|
-
continue;
|
|
230
|
-
}
|
|
231
|
-
const match = textNode.getTextContent().match(transformer.importRegExp);
|
|
232
|
-
if (!match) {
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
const startIndex = match.index || 0;
|
|
236
|
-
const endIndex = transformer.getEndIndex ? transformer.getEndIndex(textNode, match) : startIndex + match[0].length;
|
|
237
|
-
if (endIndex === false) {
|
|
238
|
-
continue;
|
|
239
|
-
}
|
|
240
|
-
let newTextNode, replaceNode;
|
|
241
|
-
if (startIndex === 0) {
|
|
242
|
-
[replaceNode, textNode] = textNode.splitText(endIndex);
|
|
243
|
-
} else {
|
|
244
|
-
[, replaceNode, newTextNode] = textNode.splitText(startIndex, endIndex);
|
|
245
|
-
}
|
|
246
|
-
if (newTextNode) {
|
|
247
|
-
importTextMatchTransformers(newTextNode, textMatchTransformers);
|
|
248
|
-
}
|
|
249
|
-
transformer.replace(replaceNode, match);
|
|
250
|
-
continue mainLoop;
|
|
251
|
-
}
|
|
252
|
-
break;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
// Finds first "<tag>content<tag>" match that is not nested into another tag
|
|
256
|
-
function findOutermostMatch(textContent, textTransformersIndex) {
|
|
257
|
-
const openTagsMatch = textContent.match(textTransformersIndex.openTagsRegExp);
|
|
258
|
-
if (openTagsMatch == null) {
|
|
259
|
-
return null;
|
|
260
|
-
}
|
|
261
|
-
for (const match of openTagsMatch) {
|
|
262
|
-
// Open tags reg exp might capture leading space so removing it
|
|
263
|
-
// before using match to find transformer
|
|
264
|
-
const tag = match.replace(/^\s/, '');
|
|
265
|
-
const fullMatchRegExp = textTransformersIndex.fullMatchRegExpByTag[tag];
|
|
266
|
-
if (fullMatchRegExp == null) {
|
|
267
|
-
continue;
|
|
268
|
-
}
|
|
269
|
-
const fullMatch = textContent.match(fullMatchRegExp);
|
|
270
|
-
const transformer = textTransformersIndex.transformersByTag[tag];
|
|
271
|
-
if (fullMatch != null && transformer != null) {
|
|
272
|
-
if (transformer.intraword !== false) {
|
|
273
|
-
return fullMatch;
|
|
274
|
-
}
|
|
275
|
-
// For non-intraword transformers checking if it's within a word
|
|
276
|
-
// or surrounded with space/punctuation/newline
|
|
277
|
-
const {
|
|
278
|
-
index = 0
|
|
279
|
-
} = fullMatch;
|
|
280
|
-
const beforeChar = textContent[index - 1];
|
|
281
|
-
const afterChar = textContent[index + fullMatch[0].length];
|
|
282
|
-
if ((!beforeChar || PUNCTUATION_OR_SPACE.test(beforeChar)) && (!afterChar || PUNCTUATION_OR_SPACE.test(afterChar))) {
|
|
283
|
-
return fullMatch;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
return null;
|
|
288
|
-
}
|
|
289
173
|
function createTextFormatTransformersIndex(textTransformers) {
|
|
290
174
|
const transformersByTag = {};
|
|
291
175
|
const fullMatchRegExpByTag = {};
|