@lobehub/editor 4.15.0 → 4.15.2
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/es/_virtual/_rolldown/runtime.js +28 -0
- package/es/codemirror/components/CopyButton.d.ts +7 -0
- package/es/codemirror/components/CopyButton.js +24 -0
- package/es/codemirror/components/LanguageSelect.d.ts +7 -0
- package/es/codemirror/components/LanguageSelect.js +59 -0
- package/es/codemirror/components/MoreOptions.d.ts +7 -0
- package/es/codemirror/components/MoreOptions.js +66 -0
- package/es/codemirror/components/Toolbar.d.ts +7 -0
- package/es/codemirror/components/Toolbar.js +51 -0
- package/es/codemirror/components/style.js +7 -0
- package/es/codemirror/constants.d.ts +6 -0
- package/es/codemirror/constants.js +512 -0
- package/es/codemirror/loader.d.ts +61 -0
- package/es/codemirror/loader.js +77 -0
- package/es/codemirror/style.d.ts +4 -0
- package/es/codemirror/style.js +82 -0
- package/es/codemirror/theme.d.ts +132 -0
- package/es/codemirror/theme.js +75 -0
- package/es/codemirror/types.d.ts +53 -0
- package/es/codemirror.d.ts +9 -263
- package/es/codemirror.js +8 -1
- package/es/common/canUseDOM.js +11 -0
- package/es/common/sys.js +27 -0
- package/es/const/hotkey.js +100 -0
- package/es/editor-kernel/data-source.d.ts +15 -0
- package/es/editor-kernel/data-source.js +15 -0
- package/es/editor-kernel/event.d.ts +7 -0
- package/es/editor-kernel/event.js +19 -0
- package/es/editor-kernel/index.d.ts +5 -0
- package/es/editor-kernel/index.js +17 -0
- package/es/editor-kernel/inode/helper.js +87 -0
- package/es/editor-kernel/inode/i-element-node.d.ts +6 -0
- package/es/editor-kernel/inode/i-node.d.ts +6 -0
- package/es/editor-kernel/inode/index.d.ts +4 -0
- package/es/editor-kernel/inode/paragraph-node.d.ts +1 -0
- package/es/editor-kernel/inode/root-node.d.ts +9 -0
- package/es/editor-kernel/inode/text-node.d.ts +9 -0
- package/es/editor-kernel/kernel.d.ts +122 -0
- package/es/editor-kernel/kernel.js +661 -0
- package/es/editor-kernel/plugin.js +59 -0
- package/es/editor-kernel/react/LexicalErrorBoundary.d.ts +13 -0
- package/es/editor-kernel/react/LexicalErrorBoundary.js +19 -0
- package/es/editor-kernel/react/PortalAnchor.js +12 -0
- package/es/editor-kernel/react/PortalContainer.d.ts +14 -0
- package/es/editor-kernel/react/PortalContainer.js +25 -0
- package/es/editor-kernel/react/index.d.ts +5 -0
- package/es/editor-kernel/react/react-context.d.ts +11 -0
- package/es/editor-kernel/react/react-context.js +21 -0
- package/es/editor-kernel/react/react-editor.d.ts +16 -0
- package/es/editor-kernel/react/react-editor.js +32 -0
- package/es/editor-kernel/react/useAnchor.js +17 -0
- package/es/editor-kernel/react/useDecorators.js +54 -0
- package/es/editor-kernel/react/useEditable.js +25 -0
- package/es/editor-kernel/react/useLexicalEditor.d.ts +6 -0
- package/es/editor-kernel/react/useLexicalEditor.js +23 -0
- package/es/editor-kernel/react/useLexicalNodeSelection.js +86 -0
- package/es/editor-kernel/react/useTranslation.js +9 -0
- package/es/editor-kernel/utils.d.ts +46 -0
- package/es/editor-kernel/utils.js +138 -0
- package/es/headless/extract-media-from-editor-state.d.ts +22 -0
- package/es/headless/extract-media-from-editor-state.js +49 -0
- package/es/headless/index.d.ts +69 -0
- package/es/headless/index.js +189 -0
- package/es/headless/plugins/codeblock.js +82 -0
- package/es/headless.d.ts +20 -1
- package/es/headless.js +219 -20307
- package/es/index.d.ts +112 -3059
- package/es/index.js +100 -8484
- package/es/locale/index.d.ts +61 -0
- package/es/locale/index.js +62 -0
- package/es/node_modules/.pnpm/@types_mdast@4.0.4/node_modules/@types/mdast/index.d.ts +953 -0
- package/es/node_modules/.pnpm/@types_unist@3.0.3/node_modules/@types/unist/index.d.ts +83 -0
- package/es/plugins/auto-complete/index.d.ts +2 -0
- package/es/plugins/auto-complete/node/placeholderNode.js +89 -0
- package/es/plugins/auto-complete/plugin/index.d.ts +31 -0
- package/es/plugins/auto-complete/plugin/index.js +395 -0
- package/es/plugins/auto-complete/react/ReactAutoCompletePlugin.d.ts +7 -0
- package/es/plugins/auto-complete/react/ReactAutoCompletePlugin.js +60 -0
- package/es/plugins/auto-complete/react/index.d.ts +1 -0
- package/es/plugins/auto-complete/react/style.js +12 -0
- package/es/plugins/auto-complete/react/type.d.ts +25 -0
- package/es/plugins/block/command/index.d.ts +13 -0
- package/es/plugins/block/command/index.js +161 -0
- package/es/plugins/block/index.d.ts +5 -0
- package/es/plugins/block/plugin/index.d.ts +9 -0
- package/es/plugins/block/plugin/index.js +86 -0
- package/es/plugins/block/react/ReactBlockPlugin.d.ts +18 -0
- package/es/plugins/block/react/ReactBlockPlugin.js +457 -0
- package/es/plugins/block/react/core/runtime-context.js +19 -0
- package/es/plugins/block/react/core/types.d.ts +6 -0
- package/es/plugins/block/react/drag/drag-session.js +264 -0
- package/es/plugins/block/react/drag/drag-utils.js +95 -0
- package/es/plugins/block/react/index.d.ts +2 -0
- package/es/plugins/block/react/style.js +66 -0
- package/es/plugins/block/service/i-block-menu-service.d.ts +44 -0
- package/es/plugins/block/service/i-block-menu-service.js +43 -0
- package/es/plugins/block/service/index.d.ts +1 -0
- package/es/plugins/code/command/index.d.ts +7 -0
- package/es/plugins/code/command/index.js +30 -0
- package/es/plugins/code/index.d.ts +3 -0
- package/es/plugins/code/node/code.js +91 -0
- package/es/plugins/code/plugin/index.d.ts +9 -0
- package/es/plugins/code/plugin/index.js +74 -0
- package/es/plugins/code/plugin/registry.js +33 -0
- package/es/plugins/code/react/CodeReactPlugin.d.ts +7 -0
- package/es/plugins/code/react/CodeReactPlugin.js +27 -0
- package/es/plugins/code/react/index.d.ts +1 -0
- package/es/plugins/code/react/style.js +21 -0
- package/es/plugins/code/react/type.d.ts +7 -0
- package/es/plugins/codeblock/command/index.d.ts +8 -0
- package/es/plugins/codeblock/command/index.js +40 -0
- package/es/plugins/codeblock/index.d.ts +6 -0
- package/es/plugins/codeblock/index.js +5 -0
- package/es/plugins/codeblock/plugin/CodeHighlighterShiki.js +415 -0
- package/es/plugins/codeblock/plugin/FacadeShiki.js +193 -0
- package/es/plugins/codeblock/plugin/index.d.ts +16 -0
- package/es/plugins/codeblock/plugin/index.js +157 -0
- package/es/plugins/codeblock/plugin/invariant.js +14 -0
- package/es/plugins/codeblock/react/ReactCodeblockPlugin.d.ts +7 -0
- package/es/plugins/codeblock/react/ReactCodeblockPlugin.js +27 -0
- package/es/plugins/codeblock/react/index.d.ts +2 -0
- package/es/plugins/codeblock/react/style.js +58 -0
- package/es/plugins/codeblock/react/type.d.ts +8 -0
- package/es/plugins/codeblock/utils/language.js +9 -0
- package/es/plugins/codemirror-block/command/index.d.ts +13 -0
- package/es/plugins/codemirror-block/command/index.js +67 -0
- package/es/plugins/codemirror-block/index.d.ts +3 -0
- package/es/plugins/codemirror-block/lib/mode.js +8 -0
- package/es/plugins/codemirror-block/node/CodeMirrorNode.d.ts +48 -0
- package/es/plugins/codemirror-block/node/CodeMirrorNode.js +205 -0
- package/es/plugins/codemirror-block/plugin/index.d.ts +12 -0
- package/es/plugins/codemirror-block/plugin/index.js +80 -0
- package/es/plugins/codemirror-block/react/CodemirrorNode.js +219 -0
- package/es/plugins/codemirror-block/react/ReactCodemirrorNode.d.ts +7 -0
- package/es/plugins/codemirror-block/react/ReactCodemirrorNode.js +26 -0
- package/es/plugins/codemirror-block/react/index.d.ts +1 -0
- package/es/plugins/codemirror-block/react/type.d.ts +6 -0
- package/es/plugins/common/command/index.d.ts +11 -0
- package/es/plugins/common/command/index.js +24 -0
- package/es/plugins/common/data-source/json-data-source.js +133 -0
- package/es/plugins/common/data-source/text-data-source.js +32 -0
- package/es/plugins/common/index.d.ts +6 -0
- package/es/plugins/common/node/ElementDOMSlot.js +30 -0
- package/es/plugins/common/node/cursor.d.ts +16 -0
- package/es/plugins/common/node/cursor.js +189 -0
- package/es/plugins/common/plugin/index.d.ts +43 -0
- package/es/plugins/common/plugin/index.js +338 -0
- package/es/plugins/common/plugin/mdReader.js +62 -0
- package/es/plugins/common/plugin/paste-handler.d.ts +11 -0
- package/es/plugins/common/plugin/paste-handler.js +61 -0
- package/es/plugins/common/plugin/register.js +306 -0
- package/es/plugins/common/react/Placeholder/index.js +65 -0
- package/es/plugins/common/react/Placeholder/style.js +22 -0
- package/es/plugins/common/react/ReactEditorContent.d.ts +7 -0
- package/es/plugins/common/react/ReactEditorContent.js +8 -0
- package/es/plugins/common/react/ReactPlainText.d.ts +7 -0
- package/es/plugins/common/react/ReactPlainText.js +192 -0
- package/es/plugins/common/react/index.d.ts +3 -0
- package/es/plugins/common/react/style.js +206 -0
- package/es/plugins/common/react/type.d.ts +94 -0
- package/es/plugins/common/utils/index.js +135 -0
- package/es/plugins/content-blocks/data-source/content-blocks-data-source.d.ts +15 -0
- package/es/plugins/content-blocks/data-source/content-blocks-data-source.js +21 -0
- package/es/plugins/content-blocks/index.d.ts +6 -0
- package/es/plugins/content-blocks/plugin/index.d.ts +10 -0
- package/es/plugins/content-blocks/plugin/index.js +24 -0
- package/es/plugins/content-blocks/types.d.ts +33 -0
- package/es/plugins/content-blocks/types.js +4 -0
- package/es/plugins/content-blocks/utils/extract-media-lists.d.ts +7 -0
- package/es/plugins/content-blocks/utils/extract-media-lists.js +32 -0
- package/es/plugins/content-blocks/utils/extract.d.ts +8 -0
- package/es/plugins/content-blocks/utils/extract.js +188 -0
- package/es/plugins/file/command/index.d.ts +9 -0
- package/es/plugins/file/command/index.js +31 -0
- package/es/plugins/file/index.d.ts +4 -0
- package/es/plugins/file/node/FileNode.d.ts +38 -0
- package/es/plugins/file/node/FileNode.js +106 -0
- package/es/plugins/file/plugin/index.d.ts +18 -0
- package/es/plugins/file/plugin/index.js +103 -0
- package/es/plugins/file/react/ReactFilePlugin.d.ts +7 -0
- package/es/plugins/file/react/ReactFilePlugin.js +35 -0
- package/es/plugins/file/react/components/ReactFile.js +50 -0
- package/es/plugins/file/react/index.d.ts +2 -0
- package/es/plugins/file/react/style.js +32 -0
- package/es/plugins/file/react/type.d.ts +17 -0
- package/es/plugins/file/utils/index.js +29 -0
- package/es/plugins/hr/command/index.d.ts +7 -0
- package/es/plugins/hr/command/index.js +14 -0
- package/es/plugins/hr/index.d.ts +4 -0
- package/es/plugins/hr/node/HorizontalRuleNode.d.ts +18 -0
- package/es/plugins/hr/node/HorizontalRuleNode.js +59 -0
- package/es/plugins/hr/plugin/index.d.ts +12 -0
- package/es/plugins/hr/plugin/index.js +60 -0
- package/es/plugins/hr/react/ReactHRPlugin.d.ts +7 -0
- package/es/plugins/hr/react/ReactHRPlugin.js +28 -0
- package/es/plugins/hr/react/components/HRNode.js +36 -0
- package/es/plugins/hr/react/index.d.ts +2 -0
- package/es/plugins/hr/react/style.js +32 -0
- package/es/plugins/hr/react/type.d.ts +6 -0
- package/es/plugins/image/command/index.d.ts +12 -0
- package/es/plugins/image/command/index.js +53 -0
- package/es/plugins/image/index.d.ts +4 -0
- package/es/plugins/image/node/basie-image-node.d.ts +33 -0
- package/es/plugins/image/node/basie-image-node.js +68 -0
- package/es/plugins/image/node/block-image-node.d.ts +43 -0
- package/es/plugins/image/node/block-image-node.js +137 -0
- package/es/plugins/image/node/image-node.d.ts +41 -0
- package/es/plugins/image/node/image-node.js +128 -0
- package/es/plugins/image/plugin/index.d.ts +24 -0
- package/es/plugins/image/plugin/index.js +183 -0
- package/es/plugins/image/react/ReactImagePlugin.d.ts +7 -0
- package/es/plugins/image/react/ReactImagePlugin.js +41 -0
- package/es/plugins/image/react/components/BrokenImage.js +16 -0
- package/es/plugins/image/react/components/Image.js +190 -0
- package/es/plugins/image/react/components/ImageEditPopover.js +160 -0
- package/es/plugins/image/react/components/LazyImage.js +73 -0
- package/es/plugins/image/react/components/ResizeHandle.js +62 -0
- package/es/plugins/image/react/components/style.js +135 -0
- package/es/plugins/image/react/components/useSupenseImage.js +22 -0
- package/es/plugins/image/react/index.d.ts +2 -0
- package/es/plugins/image/react/style.js +31 -0
- package/es/plugins/image/react/type.d.ts +23 -0
- package/es/plugins/inode/index.d.ts +3 -0
- package/es/plugins/inode/plugin/index.d.ts +19 -0
- package/es/plugins/inode/plugin/index.js +23 -0
- package/es/plugins/inode/react/index.d.ts +6 -0
- package/es/plugins/inode/react/index.js +15 -0
- package/es/plugins/inode/service/index.d.ts +17 -0
- package/es/plugins/inode/service/index.js +22 -0
- package/es/plugins/link/command/index.d.ts +10 -0
- package/es/plugins/link/command/index.js +33 -0
- package/es/plugins/link/index.d.ts +5 -0
- package/es/plugins/link/node/LinkNode.d.ts +10 -0
- package/es/plugins/link/node/LinkNode.js +448 -0
- package/es/plugins/link/plugin/index.d.ts +16 -0
- package/es/plugins/link/plugin/index.js +106 -0
- package/es/plugins/link/plugin/registry.js +82 -0
- package/es/plugins/link/react/ReactLinkPlugin.d.ts +7 -0
- package/es/plugins/link/react/ReactLinkPlugin.js +50 -0
- package/es/plugins/link/react/components/LinkEdit.js +204 -0
- package/es/plugins/link/react/components/LinkToolbar.js +148 -0
- package/es/plugins/link/react/index.d.ts +2 -0
- package/es/plugins/link/react/style.js +34 -0
- package/es/plugins/link/react/type.d.ts +14 -0
- package/es/plugins/link/service/i-link-service.d.ts +10 -0
- package/es/plugins/link/service/i-link-service.js +19 -0
- package/es/plugins/link/utils/index.js +45 -0
- package/es/plugins/link-highlight/command/index.d.ts +8 -0
- package/es/plugins/link-highlight/command/index.js +30 -0
- package/es/plugins/link-highlight/index.d.ts +3 -0
- package/es/plugins/link-highlight/node/link-highlight.js +80 -0
- package/es/plugins/link-highlight/plugin/index.d.ts +18 -0
- package/es/plugins/link-highlight/plugin/index.js +109 -0
- package/es/plugins/link-highlight/plugin/registry.js +33 -0
- package/es/plugins/link-highlight/react/ReactLinkHighlightPlugin.d.ts +7 -0
- package/es/plugins/link-highlight/react/ReactLinkHighlightPlugin.js +29 -0
- package/es/plugins/link-highlight/react/index.d.ts +1 -0
- package/es/plugins/link-highlight/react/style.js +14 -0
- package/es/plugins/link-highlight/react/type.d.ts +16 -0
- package/es/plugins/list/command/index.d.ts +3 -0
- package/es/plugins/list/command/index.js +3 -0
- package/es/plugins/list/index.d.ts +5 -0
- package/es/plugins/list/plugin/checkList.d.ts +6 -0
- package/es/plugins/list/plugin/checkList.js +140 -0
- package/es/plugins/list/plugin/index.d.ts +9 -0
- package/es/plugins/list/plugin/index.js +195 -0
- package/es/plugins/list/plugin/registry.js +68 -0
- package/es/plugins/list/react/ReactListPlugin.d.ts +7 -0
- package/es/plugins/list/react/ReactListPlugin.js +21 -0
- package/es/plugins/list/react/index.d.ts +2 -0
- package/es/plugins/list/react/style.js +123 -0
- package/es/plugins/list/react/type.d.ts +7 -0
- package/es/plugins/list/utils/index.js +58 -0
- package/es/plugins/litexml/command/diffCommand.d.ts +17 -0
- package/es/plugins/litexml/command/diffCommand.js +97 -0
- package/es/plugins/litexml/command/index.d.ts +38 -0
- package/es/plugins/litexml/command/index.js +333 -0
- package/es/plugins/litexml/data-source/litexml-data-source.d.ts +65 -0
- package/es/plugins/litexml/data-source/litexml-data-source.js +286 -0
- package/es/plugins/litexml/index.d.ts +7 -0
- package/es/plugins/litexml/node/DiffNode.d.ts +29 -0
- package/es/plugins/litexml/node/DiffNode.js +95 -0
- package/es/plugins/litexml/plugin/index.d.ts +24 -0
- package/es/plugins/litexml/plugin/index.js +100 -0
- package/es/plugins/litexml/react/DiffNodeToolbar/index.js +60 -0
- package/es/plugins/litexml/react/DiffNodeToolbar/style.js +24 -0
- package/es/plugins/litexml/react/hooks/useHasDiffNode.d.ts +7 -0
- package/es/plugins/litexml/react/hooks/useHasDiffNode.js +35 -0
- package/es/plugins/litexml/react/index.d.ts +6 -0
- package/es/plugins/litexml/react/index.js +26 -0
- package/es/plugins/litexml/react/style.js +124 -0
- package/es/plugins/litexml/service/litexml-service.d.ts +93 -0
- package/es/plugins/litexml/service/litexml-service.js +42 -0
- package/es/plugins/litexml/utils/index.js +59 -0
- package/es/plugins/markdown/command/index.d.ts +14 -0
- package/es/plugins/markdown/command/index.js +74 -0
- package/es/plugins/markdown/data-source/markdown/parse.d.ts +14 -0
- package/es/plugins/markdown/data-source/markdown/parse.js +195 -0
- package/es/plugins/markdown/data-source/markdown-data-source.js +148 -0
- package/es/plugins/markdown/data-source/markdown-writer-context.js +40 -0
- package/es/plugins/markdown/index.d.ts +7 -0
- package/es/plugins/markdown/plugin/index.d.ts +22 -0
- package/es/plugins/markdown/plugin/index.js +285 -0
- package/es/plugins/markdown/react/index.d.ts +6 -0
- package/es/plugins/markdown/react/index.js +31 -0
- package/es/plugins/markdown/service/shortcut.d.ts +57 -0
- package/es/plugins/markdown/service/shortcut.js +101 -0
- package/es/plugins/markdown/service/transformers.d.ts +61 -0
- package/es/plugins/markdown/service/transformers.js +119 -0
- package/es/plugins/markdown/utils/detectLanguage.d.ts +22 -0
- package/es/plugins/markdown/utils/detectLanguage.js +251 -0
- package/es/plugins/markdown/utils/index.d.ts +11 -0
- package/es/plugins/markdown/utils/index.js +143 -0
- package/es/plugins/markdown/utils/logger.js +6 -0
- package/es/plugins/math/command/index.d.ts +9 -0
- package/es/plugins/math/command/index.js +38 -0
- package/es/plugins/math/index.d.ts +3 -0
- package/es/plugins/math/node/index.d.ts +44 -0
- package/es/plugins/math/node/index.js +161 -0
- package/es/plugins/math/plugin/index.d.ts +15 -0
- package/es/plugins/math/plugin/index.js +119 -0
- package/es/plugins/math/react/components/MathEditor.js +198 -0
- package/es/plugins/math/react/components/MathEditorContainer.js +101 -0
- package/es/plugins/math/react/components/MathEditorContent.js +133 -0
- package/es/plugins/math/react/components/MathInline.js +86 -0
- package/es/plugins/math/react/components/Placeholder.js +24 -0
- package/es/plugins/math/react/index.d.ts +7 -0
- package/es/plugins/math/react/index.js +35 -0
- package/es/plugins/math/react/style.js +96 -0
- package/es/plugins/math/react/type.d.ts +17 -0
- package/es/plugins/math/utils/index.js +23 -0
- package/es/plugins/mention/command/index.d.ts +10 -0
- package/es/plugins/mention/command/index.js +18 -0
- package/es/plugins/mention/index.d.ts +5 -0
- package/es/plugins/mention/node/MentionNode.d.ts +28 -0
- package/es/plugins/mention/node/MentionNode.js +86 -0
- package/es/plugins/mention/plugin/index.d.ts +18 -0
- package/es/plugins/mention/plugin/index.js +63 -0
- package/es/plugins/mention/plugin/register.js +30 -0
- package/es/plugins/mention/react/ReactMentionPlugin.d.ts +7 -0
- package/es/plugins/mention/react/ReactMentionPlugin.js +36 -0
- package/es/plugins/mention/react/components/Mention.js +33 -0
- package/es/plugins/mention/react/index.d.ts +2 -0
- package/es/plugins/mention/react/style.js +34 -0
- package/es/plugins/mention/react/type.d.ts +12 -0
- package/es/plugins/slash/index.d.ts +6 -0
- package/es/plugins/slash/plugin/index.d.ts +27 -0
- package/es/plugins/slash/plugin/index.js +160 -0
- package/es/plugins/slash/react/ReactSlashOption.d.ts +7 -0
- package/es/plugins/slash/react/ReactSlashOption.js +8 -0
- package/es/plugins/slash/react/ReactSlashPlugin.d.ts +7 -0
- package/es/plugins/slash/react/ReactSlashPlugin.js +190 -0
- package/es/plugins/slash/react/components/DefaultSlashMenu.js +168 -0
- package/es/plugins/slash/react/components/SlashMenu.d.ts +11 -0
- package/es/plugins/slash/react/components/SlashMenu.js +40 -0
- package/es/plugins/slash/react/index.d.ts +4 -0
- package/es/plugins/slash/react/type.d.ts +114 -0
- package/es/plugins/slash/react/utils.js +18 -0
- package/es/plugins/slash/service/i-slash-service.d.ts +50 -0
- package/es/plugins/slash/service/i-slash-service.js +55 -0
- package/es/plugins/slash/utils/utils.d.ts +1 -0
- package/es/plugins/slash/utils/utils.js +97 -0
- package/es/plugins/table/command/index.d.ts +17 -0
- package/es/plugins/table/command/index.js +57 -0
- package/es/plugins/table/index.d.ts +3 -0
- package/es/plugins/table/node/index.js +18 -0
- package/es/plugins/table/plugin/index.d.ts +8 -0
- package/es/plugins/table/plugin/index.js +172 -0
- package/es/plugins/table/react/TableActionMenu/ActionMenu.js +220 -0
- package/es/plugins/table/react/TableActionMenu/index.js +128 -0
- package/es/plugins/table/react/TableActionMenu/style.js +20 -0
- package/es/plugins/table/react/TableActionMenu/utils.js +34 -0
- package/es/plugins/table/react/TableHoverActions/index.js +147 -0
- package/es/plugins/table/react/TableHoverActions/style.js +14 -0
- package/es/plugins/table/react/TableHoverActions/utils.js +32 -0
- package/es/plugins/table/react/TableResize/index.js +253 -0
- package/es/plugins/table/react/TableResize/style.js +16 -0
- package/es/plugins/table/react/TableResize/utils.js +9 -0
- package/es/plugins/table/react/index.d.ts +7 -0
- package/es/plugins/table/react/index.js +49 -0
- package/es/plugins/table/react/style.js +63 -0
- package/es/plugins/table/react/type.d.ts +8 -0
- package/es/plugins/table/utils/index.js +48 -0
- package/es/plugins/toolbar/command/index.d.ts +12 -0
- package/es/plugins/toolbar/command/index.js +17 -0
- package/es/plugins/toolbar/index.d.ts +2 -0
- package/es/plugins/toolbar/react/index.d.ts +7 -0
- package/es/plugins/toolbar/react/index.js +109 -0
- package/es/plugins/toolbar/react/style.js +55 -0
- package/es/plugins/toolbar/react/type.d.ts +9 -0
- package/es/plugins/toolbar/utils/getDOMRangeRect.js +20 -0
- package/es/plugins/toolbar/utils/setFloatingElemPosition.js +50 -0
- package/es/plugins/upload/index.d.ts +2 -0
- package/es/plugins/upload/plugin/index.d.ts +6 -0
- package/es/plugins/upload/plugin/index.js +47 -0
- package/es/plugins/upload/service/i-upload-service.d.ts +13 -0
- package/es/plugins/upload/service/i-upload-service.js +30 -0
- package/es/plugins/upload/utils/index.js +15 -0
- package/es/plugins/virtual-block/index.d.ts +2 -0
- package/es/plugins/virtual-block/plugin/index.d.ts +8 -0
- package/es/plugins/virtual-block/plugin/index.js +19 -0
- package/es/plugins/virtual-block/plugin/register.js +150 -0
- package/es/plugins/virtual-block/react/ReactVirtualBlock.d.ts +6 -0
- package/es/plugins/virtual-block/react/ReactVirtualBlock.js +15 -0
- package/es/plugins/virtual-block/react/index.d.ts +1 -0
- package/es/react/ChatInput/ChatInput.d.ts +7 -0
- package/es/react/ChatInput/ChatInput.js +91 -0
- package/es/react/ChatInput/index.d.ts +2 -0
- package/es/react/ChatInput/style.js +115 -0
- package/es/react/ChatInput/type.d.ts +32 -0
- package/es/react/ChatInputActionBar/ChatInputActionBar.d.ts +7 -0
- package/es/react/ChatInputActionBar/ChatInputActionBar.js +22 -0
- package/es/react/ChatInputActionBar/index.d.ts +2 -0
- package/es/react/ChatInputActionBar/style.js +7 -0
- package/es/react/ChatInputActionBar/type.d.ts +10 -0
- package/es/react/ChatInputActions/ChatInputActions.d.ts +7 -0
- package/es/react/ChatInputActions/ChatInputActions.js +65 -0
- package/es/react/ChatInputActions/components/ActionItem.js +46 -0
- package/es/react/ChatInputActions/components/ActionRender.js +45 -0
- package/es/react/ChatInputActions/components/CollapsedActions.js +60 -0
- package/es/react/ChatInputActions/components/useDisplayActionCount.js +45 -0
- package/es/react/ChatInputActions/index.d.ts +2 -0
- package/es/react/ChatInputActions/style.js +20 -0
- package/es/react/ChatInputActions/type.d.ts +36 -0
- package/es/react/CodeLanguageSelect/CodeLanguageSelect.d.ts +7 -0
- package/es/react/CodeLanguageSelect/CodeLanguageSelect.js +67 -0
- package/es/react/CodeLanguageSelect/index.d.ts +2 -0
- package/es/react/CodeLanguageSelect/style.js +7 -0
- package/es/react/CodeLanguageSelect/type.d.ts +6 -0
- package/es/react/Editor/Editor.js +108 -0
- package/es/react/Editor/index.d.ts +16 -0
- package/es/react/Editor/index.js +11 -0
- package/es/react/Editor/type.d.ts +64 -0
- package/es/react/Editor/utils.d.ts +6 -0
- package/es/react/Editor/utils.js +6 -0
- package/es/react/EditorProvider/index.d.ts +28 -0
- package/es/react/EditorProvider/index.js +18 -0
- package/es/react/FloatActions/FloatActions.d.ts +7 -0
- package/es/react/FloatActions/FloatActions.js +34 -0
- package/es/react/FloatActions/components/ActionItem.js +46 -0
- package/es/react/FloatActions/components/ActionRender.js +45 -0
- package/es/react/FloatActions/components/CollapsedActions.js +60 -0
- package/es/react/FloatActions/index.d.ts +2 -0
- package/es/react/FloatActions/style.js +19 -0
- package/es/react/FloatActions/type.d.ts +33 -0
- package/es/react/FloatMenu/FloatMenu.d.ts +7 -0
- package/es/react/FloatMenu/FloatMenu.js +32 -0
- package/es/react/FloatMenu/index.d.ts +2 -0
- package/es/react/FloatMenu/style.js +28 -0
- package/es/react/FloatMenu/type.d.ts +25 -0
- package/es/react/SendButton/SendButton.d.ts +7 -0
- package/es/react/SendButton/SendButton.js +107 -0
- package/es/react/SendButton/components/SendIcon.js +23 -0
- package/es/react/SendButton/components/StopIcon.js +56 -0
- package/es/react/SendButton/index.d.ts +2 -0
- package/es/react/SendButton/style.js +68 -0
- package/es/react/SendButton/type.d.ts +12 -0
- package/es/react/SlashMenu/SlashMenu.d.ts +7 -0
- package/es/react/SlashMenu/SlashMenu.js +40 -0
- package/es/react/SlashMenu/index.d.ts +2 -0
- package/es/react/SlashMenu/type.d.ts +17 -0
- package/es/react/hooks/useEditor.d.ts +5 -0
- package/es/react/hooks/useEditor.js +8 -0
- package/es/react/hooks/useEditorState/index.d.ts +71 -0
- package/es/react/hooks/useEditorState/index.js +347 -0
- package/es/react/hooks/useEditorState/utils.js +28 -0
- package/es/react/hooks/useSize.js +61 -0
- package/es/react.d.ts +22 -334
- package/es/react.js +13 -1573
- package/es/renderer/LexicalDiff.d.ts +41 -0
- package/es/renderer/LexicalDiff.js +96 -0
- package/es/renderer/LexicalRenderer.d.ts +16 -0
- package/es/renderer/LexicalRenderer.js +48 -0
- package/es/renderer/diff/compute.js +396 -0
- package/es/renderer/diff/style.d.ts +4 -0
- package/es/renderer/diff/style.js +104 -0
- package/es/renderer/diff/types.d.ts +32 -0
- package/es/renderer/engine/render-builtin-node.js +196 -0
- package/es/renderer/engine/render-text-node.js +33 -0
- package/es/renderer/engine/render-tree.js +35 -0
- package/es/renderer/engine/shiki.d.ts +4 -0
- package/es/renderer/engine/shiki.js +24 -0
- package/es/renderer/engine/utils.js +16 -0
- package/es/renderer/nodes/index.d.ts +6 -0
- package/es/renderer/nodes/index.js +44 -0
- package/es/renderer/renderers/codeblock.js +21 -0
- package/es/renderer/renderers/file.js +29 -0
- package/es/renderer/renderers/horizontalrule.js +29 -0
- package/es/renderer/renderers/image.js +35 -0
- package/es/renderer/renderers/index.d.ts +6 -0
- package/es/renderer/renderers/index.js +21 -0
- package/es/renderer/renderers/math.js +19 -0
- package/es/renderer/renderers/mention.js +15 -0
- package/es/renderer/renderers/mermaid.js +17 -0
- package/es/renderer/style.js +52 -0
- package/es/renderer/types.d.ts +29 -0
- package/es/renderer.d.ts +8 -114
- package/es/renderer.js +5 -1153
- package/es/types/hotkey.d.ts +76 -0
- package/es/types/hotkey.js +65 -0
- package/es/types/index.d.ts +2 -0
- package/es/types/kernel.d.ts +359 -0
- package/es/types/locale.d.ts +11 -0
- package/es/utils/cx.js +4 -0
- package/es/utils/debug.d.ts +425 -0
- package/es/{debug-CIvbNHJu.js → utils/debug.js} +3 -35
- package/es/utils/hotkey/isHotkeyMatch.js +17 -0
- package/es/utils/hotkey/parseHotkeys.js +53 -0
- package/es/utils/hotkey/registerHotkey.d.ts +18 -0
- package/es/utils/hotkey/registerHotkey.js +35 -0
- package/es/utils/scrollIntoView.d.ts +8 -0
- package/es/utils/scrollIntoView.js +29 -0
- package/es/utils/updatePosition.js +26 -0
- package/es/utils/url.d.ts +18 -0
- package/es/utils/url.js +34 -0
- package/package.json +4 -1
- package/es/ReactSlashPlugin-BiVy_Iwf.js +0 -23072
- package/es/codemirror-3POv7f__.js +0 -923
- package/es/index-DHGp94p0.d.ts +0 -916
- package/es/style-DADgHVA1.js +0 -2889
- package/es/style-DMdPzCo-.js +0 -999
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { createDebugLogger, init_debug } from "../../../utils/debug.js";
|
|
2
|
+
import { KernelPlugin, init_plugin } from "../../../editor-kernel/plugin.js";
|
|
3
|
+
import { canContainTransformableMarkdown } from "../utils/index.js";
|
|
4
|
+
import { INSERT_MARKDOWN_COMMAND, registerMarkdownCommand } from "../command/index.js";
|
|
5
|
+
import MarkdownDataSource from "../data-source/markdown-data-source.js";
|
|
6
|
+
import { IMarkdownShortCutService, MarkdownShortCutService } from "../service/shortcut.js";
|
|
7
|
+
import { detectCodeLanguage, detectLanguage } from "../utils/detectLanguage.js";
|
|
8
|
+
import { $getNodeByKey, $getSelection, $isRangeSelection, $isTextNode, COLLABORATION_TAG, COMMAND_PRIORITY_CRITICAL, COMMAND_PRIORITY_LOW, COPY_COMMAND, HISTORIC_TAG, KEY_ENTER_COMMAND, PASTE_COMMAND } from "lexical";
|
|
9
|
+
import { $getClipboardDataFromSelection, setLexicalClipboardDataTransfer } from "@lexical/clipboard";
|
|
10
|
+
import { $isCodeNode } from "@lexical/code-core";
|
|
11
|
+
//#region src/plugins/markdown/plugin/index.ts
|
|
12
|
+
init_plugin();
|
|
13
|
+
init_debug();
|
|
14
|
+
const DEFAULT_PASTE_MARKDOWN_AUTO_CONVERT_THRESHOLD = 5;
|
|
15
|
+
const RICH_HTML_SELECTOR = "strong,em,b,i,h1,h2,h3,h4,h5,h6,ul,ol,table,img,blockquote,pre>code,a[href]";
|
|
16
|
+
const MARKDOWN_DETECTION_RULES = [
|
|
17
|
+
{
|
|
18
|
+
name: "headers",
|
|
19
|
+
score: 5,
|
|
20
|
+
test: (text) => /^#{1,6}\s+\S/m.test(text)
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: "code-fence-start",
|
|
24
|
+
score: 5,
|
|
25
|
+
test: (text) => /^```[\w-]*$/m.test(text)
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "links",
|
|
29
|
+
score: 4,
|
|
30
|
+
test: (text) => /\[[^\]]+]\([^)]+\)/.test(text)
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "images",
|
|
34
|
+
score: 5,
|
|
35
|
+
test: (text) => /!\[[^\]]*]\([^)]+\)/.test(text)
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "tables",
|
|
39
|
+
score: 5,
|
|
40
|
+
test: (text) => /^\|.+\|$/m.test(text) && /^\|[\s:|-]+\|$/m.test(text)
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "admonitions",
|
|
44
|
+
score: 5,
|
|
45
|
+
test: (text) => /^>\s*\[!(?:note|tip|warning|caution|important)]/im.test(text)
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: "task-lists",
|
|
49
|
+
score: 4,
|
|
50
|
+
test: (text) => /^[*-]\s+\[[ x]]/m.test(text)
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "bold",
|
|
54
|
+
score: 2,
|
|
55
|
+
test: (text) => /\*\*.+?\*\*/.test(text)
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: "italic",
|
|
59
|
+
score: 1,
|
|
60
|
+
test: (text) => /(?<!\*)\*(?!\*)(?!\s).+?(?<!\s)(?<!\*)\*(?!\*)/.test(text)
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: "unordered-lists",
|
|
64
|
+
score: 1,
|
|
65
|
+
test: (text) => /^[*+-]\s+\S/m.test(text)
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "ordered-lists",
|
|
69
|
+
score: 1,
|
|
70
|
+
test: (text) => /^\d+\.\s+\S/m.test(text)
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "blockquotes",
|
|
74
|
+
score: 1,
|
|
75
|
+
test: (text) => /^>\s+\S/m.test(text)
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: "inline-code",
|
|
79
|
+
score: 1,
|
|
80
|
+
test: (text) => /`.+?`/.test(text)
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: "horizontal-rules",
|
|
84
|
+
score: 2,
|
|
85
|
+
test: (text) => /^[*_-]{3,}$/m.test(text)
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "multi-paragraph",
|
|
89
|
+
score: 5,
|
|
90
|
+
test: (text) => text.split(/\n{2,}/).filter(Boolean).length >= 2
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: "short-text-penalty",
|
|
94
|
+
score: -3,
|
|
95
|
+
test: (text) => text.length < 20
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: "single-line-penalty",
|
|
99
|
+
score: -2,
|
|
100
|
+
test: (text) => !text.includes("\n")
|
|
101
|
+
}
|
|
102
|
+
];
|
|
103
|
+
const MarkdownPlugin = class extends KernelPlugin {
|
|
104
|
+
static {
|
|
105
|
+
this.pluginName = "MarkdownPlugin";
|
|
106
|
+
}
|
|
107
|
+
constructor(kernel, config) {
|
|
108
|
+
super();
|
|
109
|
+
this.kernel = kernel;
|
|
110
|
+
this.config = config;
|
|
111
|
+
this.logger = createDebugLogger("plugin", "markdown");
|
|
112
|
+
this.service = new MarkdownShortCutService(kernel);
|
|
113
|
+
kernel.registerService(IMarkdownShortCutService, this.service);
|
|
114
|
+
this.markdownDataSource = new MarkdownDataSource("markdown", this.service, (serviceId) => {
|
|
115
|
+
return kernel.requireService(serviceId);
|
|
116
|
+
});
|
|
117
|
+
kernel.registerDataSource(this.markdownDataSource);
|
|
118
|
+
}
|
|
119
|
+
onInit(editor) {
|
|
120
|
+
this.register(editor.registerUpdateListener(({ tags, dirtyLeaves, editorState, prevEditorState }) => {
|
|
121
|
+
if (tags.has(COLLABORATION_TAG) || tags.has(HISTORIC_TAG)) return;
|
|
122
|
+
if (editor.isComposing()) return;
|
|
123
|
+
const selection = editorState.read($getSelection);
|
|
124
|
+
const prevSelection = prevEditorState.read($getSelection);
|
|
125
|
+
if (!$isRangeSelection(prevSelection) || !$isRangeSelection(selection) || !selection.isCollapsed() || selection.is(prevSelection)) return;
|
|
126
|
+
const anchorKey = selection.anchor.key;
|
|
127
|
+
const anchorOffset = selection.anchor.offset;
|
|
128
|
+
const anchorNode = editorState._nodeMap.get(anchorKey);
|
|
129
|
+
if (!$isTextNode(anchorNode) || !dirtyLeaves.has(anchorKey) || anchorOffset !== 1 && anchorOffset > prevSelection.anchor.offset + 1) return;
|
|
130
|
+
editor.update(() => {
|
|
131
|
+
if (!canContainTransformableMarkdown(anchorNode)) return;
|
|
132
|
+
const parentNode = anchorNode.getParent();
|
|
133
|
+
if (parentNode === null || $isCodeNode(parentNode)) return;
|
|
134
|
+
this.service.runTransformers(parentNode, anchorNode, selection.anchor.offset);
|
|
135
|
+
});
|
|
136
|
+
}));
|
|
137
|
+
this.register(editor.registerCommand(KEY_ENTER_COMMAND, (payload) => {
|
|
138
|
+
const ret = editor.getEditorState().read(() => {
|
|
139
|
+
const selection = $getSelection();
|
|
140
|
+
if (!$isRangeSelection(selection) || !selection.isCollapsed()) return false;
|
|
141
|
+
const anchorKey = selection.anchor.key;
|
|
142
|
+
const anchorNode = $getNodeByKey(anchorKey);
|
|
143
|
+
if (!anchorNode) return false;
|
|
144
|
+
return {
|
|
145
|
+
anchorNode,
|
|
146
|
+
offset: selection.anchor.offset
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
if (!ret) return false;
|
|
150
|
+
const { anchorNode, offset } = ret;
|
|
151
|
+
if (!canContainTransformableMarkdown(anchorNode)) return false;
|
|
152
|
+
const parentNode = anchorNode.getParent();
|
|
153
|
+
if (parentNode === null || $isCodeNode(parentNode)) return false;
|
|
154
|
+
if (this.service.testTransformers(parentNode, anchorNode, offset, "enter")) {
|
|
155
|
+
queueMicrotask(() => {
|
|
156
|
+
editor.update(() => {
|
|
157
|
+
this.service.runTransformers(parentNode, anchorNode, offset, "enter");
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
payload?.stopPropagation();
|
|
161
|
+
payload?.stopImmediatePropagation();
|
|
162
|
+
payload?.preventDefault();
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
return false;
|
|
166
|
+
}, COMMAND_PRIORITY_CRITICAL));
|
|
167
|
+
this.register(editor.registerCommand(PASTE_COMMAND, (event) => {
|
|
168
|
+
if (!(event instanceof ClipboardEvent)) return false;
|
|
169
|
+
if (!this.shouldHandlePasteMarkdown()) return false;
|
|
170
|
+
const clipboardData = event.clipboardData;
|
|
171
|
+
if (!clipboardData) return false;
|
|
172
|
+
const text = clipboardData.getData("text/plain").trimEnd().replaceAll(/[\u200B-\u200D\u2060\uFEFF]/g, "");
|
|
173
|
+
const html = clipboardData.getData("text/html").trimEnd();
|
|
174
|
+
if (!text) return false;
|
|
175
|
+
this.logger.debug("paste content analysis:", {
|
|
176
|
+
clipboardTypes: Array.from(clipboardData.types || []),
|
|
177
|
+
hasHTML: !!(html && html.trim()),
|
|
178
|
+
htmlLength: html?.length || 0,
|
|
179
|
+
textLength: text.length
|
|
180
|
+
});
|
|
181
|
+
if (this.hasRichHTML(clipboardData)) {
|
|
182
|
+
this.logger.debug("rich HTML detected, skipping markdown auto-convert");
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
const detectionResult = this.getMarkdownDetectionResult(text);
|
|
186
|
+
if (detectionResult.shouldAutoConvert) {
|
|
187
|
+
this.logger.debug("markdown auto-convert detected:", detectionResult);
|
|
188
|
+
const historyState = this.kernel.getHistoryState().current;
|
|
189
|
+
setTimeout(() => {
|
|
190
|
+
editor.dispatchCommand(INSERT_MARKDOWN_COMMAND, {
|
|
191
|
+
historyState,
|
|
192
|
+
markdown: text
|
|
193
|
+
});
|
|
194
|
+
this.kernel.emit("markdownParse", {
|
|
195
|
+
cacheState: editor.getEditorState(),
|
|
196
|
+
historyState,
|
|
197
|
+
markdown: text,
|
|
198
|
+
matchedPatterns: detectionResult.matchedPatterns,
|
|
199
|
+
score: detectionResult.score
|
|
200
|
+
});
|
|
201
|
+
}, 10);
|
|
202
|
+
} else this.logger.debug("markdown score below auto-convert threshold, keeping as plain text:", detectionResult);
|
|
203
|
+
return false;
|
|
204
|
+
}, COMMAND_PRIORITY_CRITICAL));
|
|
205
|
+
this.register(registerMarkdownCommand(editor, this.kernel, this.service));
|
|
206
|
+
this.register(editor.registerCommand(COPY_COMMAND, (event) => {
|
|
207
|
+
if (!(event instanceof ClipboardEvent)) return false;
|
|
208
|
+
const clipboardData = event.clipboardData;
|
|
209
|
+
if (!clipboardData) return false;
|
|
210
|
+
const selection = $getSelection();
|
|
211
|
+
if (!selection || selection.isCollapsed()) return false;
|
|
212
|
+
const markdown = this.markdownDataSource.write(editor, { selection: true });
|
|
213
|
+
if (!markdown) return false;
|
|
214
|
+
event.preventDefault();
|
|
215
|
+
setLexicalClipboardDataTransfer(clipboardData, $getClipboardDataFromSelection(selection));
|
|
216
|
+
clipboardData.setData("text/plain", markdown);
|
|
217
|
+
clipboardData.setData("text/markdown", markdown);
|
|
218
|
+
this.logger.debug("copy with text/markdown:", { markdownLength: markdown.length });
|
|
219
|
+
return true;
|
|
220
|
+
}, COMMAND_PRIORITY_LOW));
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Detect if content is code and should be inserted as code block
|
|
224
|
+
* Uses advanced language detection with pattern matching
|
|
225
|
+
* Excludes markdown because markdown content is handled by the paste auto-convert flow
|
|
226
|
+
*/
|
|
227
|
+
detectCodeContent(text) {
|
|
228
|
+
const detected = detectLanguage(text);
|
|
229
|
+
if (detected && detected.confidence > 50) {
|
|
230
|
+
if (detected.language === "markdown") return null;
|
|
231
|
+
this.logger.debug("language detected:", detected);
|
|
232
|
+
return detected;
|
|
233
|
+
}
|
|
234
|
+
const fastDetected = detectCodeLanguage(text);
|
|
235
|
+
if (fastDetected) {
|
|
236
|
+
if (fastDetected === "markdown") return null;
|
|
237
|
+
return {
|
|
238
|
+
confidence: 80,
|
|
239
|
+
language: fastDetected
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
hasRichHTML(clipboardData) {
|
|
245
|
+
const html = clipboardData.getData("text/html");
|
|
246
|
+
if (!html) return false;
|
|
247
|
+
if (/data-vscode|vscode-/i.test(html)) return false;
|
|
248
|
+
if (typeof DOMParser === "undefined") return false;
|
|
249
|
+
return new DOMParser().parseFromString(html, "text/html").body.querySelectorAll(RICH_HTML_SELECTOR).length > 0;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Analyze pasted text and determine whether it should auto convert to markdown
|
|
253
|
+
*/
|
|
254
|
+
getMarkdownDetectionResult(text) {
|
|
255
|
+
if (this.detectCodeContent(text)) return {
|
|
256
|
+
matchedPatterns: [],
|
|
257
|
+
score: 0,
|
|
258
|
+
shouldAutoConvert: false
|
|
259
|
+
};
|
|
260
|
+
const matchedPatterns = [];
|
|
261
|
+
let score = 0;
|
|
262
|
+
const threshold = this.getPasteMarkdownAutoConvertThreshold();
|
|
263
|
+
for (const rule of MARKDOWN_DETECTION_RULES) {
|
|
264
|
+
if (!rule.test(text)) continue;
|
|
265
|
+
matchedPatterns.push(rule.name);
|
|
266
|
+
score += rule.score;
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
matchedPatterns,
|
|
270
|
+
score,
|
|
271
|
+
shouldAutoConvert: score >= threshold
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
getPasteMarkdownAutoConvertThreshold() {
|
|
275
|
+
const threshold = this.config?.pasteMarkdownAutoConvertThreshold;
|
|
276
|
+
if (typeof threshold !== "number" || Number.isNaN(threshold)) return DEFAULT_PASTE_MARKDOWN_AUTO_CONVERT_THRESHOLD;
|
|
277
|
+
return Math.max(1, threshold);
|
|
278
|
+
}
|
|
279
|
+
shouldHandlePasteMarkdown() {
|
|
280
|
+
if (this.config?.enablePasteMarkdown === false) return false;
|
|
281
|
+
return this.config?.autoFormatMarkdown !== false;
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
//#endregion
|
|
285
|
+
export { MarkdownPlugin };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useLexicalComposerContext } from "../../../editor-kernel/react/react-context.js";
|
|
3
|
+
import { INodePlugin } from "../../inode/plugin/index.js";
|
|
4
|
+
import { MarkdownPlugin } from "../plugin/index.js";
|
|
5
|
+
import { useTranslation } from "../../../editor-kernel/react/useTranslation.js";
|
|
6
|
+
import { toast } from "@lobehub/ui";
|
|
7
|
+
import { useLayoutEffect } from "react";
|
|
8
|
+
//#region src/plugins/markdown/react/index.tsx
|
|
9
|
+
const ReactMarkdownPlugin = () => {
|
|
10
|
+
const [editor] = useLexicalComposerContext();
|
|
11
|
+
const t = useTranslation();
|
|
12
|
+
useLayoutEffect(() => {
|
|
13
|
+
editor.registerPlugin(INodePlugin);
|
|
14
|
+
editor.registerPlugin(MarkdownPlugin);
|
|
15
|
+
const handleEvent = () => {
|
|
16
|
+
toast.info({
|
|
17
|
+
description: t("markdown.autoFormatMessage"),
|
|
18
|
+
duration: 5e3,
|
|
19
|
+
title: t("markdown.autoFormatTitle")
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
editor.on("markdownParse", handleEvent);
|
|
23
|
+
return () => {
|
|
24
|
+
editor.off("markdownParse", handleEvent);
|
|
25
|
+
};
|
|
26
|
+
}, [editor, t]);
|
|
27
|
+
return null;
|
|
28
|
+
};
|
|
29
|
+
ReactMarkdownPlugin.displayName = "ReactMarkdownPlugin";
|
|
30
|
+
//#endregion
|
|
31
|
+
export { ReactMarkdownPlugin as default };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { IServiceID } from "../../../types/kernel.js";
|
|
2
|
+
import { IRootNode } from "../../../editor-kernel/inode/root-node.js";
|
|
3
|
+
import { MarkdownReaderFunc, TransformerRecord } from "../data-source/markdown/parse.js";
|
|
4
|
+
import { Transformer } from "./transformers.js";
|
|
5
|
+
import { BaseSelection, ElementNode, LexicalEditor, LexicalNode, TextNode } from "lexical";
|
|
6
|
+
|
|
7
|
+
//#region src/plugins/markdown/service/shortcut.d.ts
|
|
8
|
+
interface IMarkdownWriterContext {
|
|
9
|
+
/**
|
|
10
|
+
* Add processor
|
|
11
|
+
* @param processor
|
|
12
|
+
*/
|
|
13
|
+
addProcessor(processor: (before: string, content: string, after: string) => string): void;
|
|
14
|
+
/**
|
|
15
|
+
* Direct output
|
|
16
|
+
* @param line
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
19
|
+
appendLine: (line: string) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Control child node to markdown
|
|
22
|
+
* @param parentCtx
|
|
23
|
+
* @param child
|
|
24
|
+
* @returns
|
|
25
|
+
*/
|
|
26
|
+
processChild: (parentCtx: IMarkdownWriterContext, child: LexicalNode) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Wrap child elements
|
|
29
|
+
* @param before
|
|
30
|
+
* @param after
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
33
|
+
wrap: (before: string, after: string) => void;
|
|
34
|
+
}
|
|
35
|
+
declare const MARKDOWN_WRITER_LEVEL_MAX = 0;
|
|
36
|
+
declare const MARKDOWN_READER_LEVEL_HIGH = 1;
|
|
37
|
+
declare const MARKDOWN_READER_LEVEL_NORMAL = 2;
|
|
38
|
+
type MARKDOWN_READER_LEVEL = typeof MARKDOWN_READER_LEVEL_HIGH | typeof MARKDOWN_READER_LEVEL_NORMAL | typeof MARKDOWN_WRITER_LEVEL_MAX;
|
|
39
|
+
interface IMarkdownShortCutService {
|
|
40
|
+
insertIRootNode(editor: LexicalEditor, root: IRootNode, selection: BaseSelection): void;
|
|
41
|
+
parseMarkdownToLexical(markdown: string): IRootNode;
|
|
42
|
+
/**
|
|
43
|
+
* Register Markdown reader
|
|
44
|
+
*/
|
|
45
|
+
registerMarkdownReader<K extends keyof TransformerRecord>(type: K, reader: MarkdownReaderFunc<K>, level?: MARKDOWN_READER_LEVEL): void;
|
|
46
|
+
registerMarkdownShortCut(transformer: Transformer): void;
|
|
47
|
+
registerMarkdownShortCuts(transformers: Transformer[]): void;
|
|
48
|
+
/**
|
|
49
|
+
* Register Markdown writer
|
|
50
|
+
* @param type Lexical Node type
|
|
51
|
+
* @param writer
|
|
52
|
+
*/
|
|
53
|
+
registerMarkdownWriter(type: string, writer: (ctx: IMarkdownWriterContext, node: LexicalNode) => void | boolean): void;
|
|
54
|
+
}
|
|
55
|
+
declare const IMarkdownShortCutService: IServiceID<IMarkdownShortCutService>;
|
|
56
|
+
//#endregion
|
|
57
|
+
export { IMarkdownShortCutService, MARKDOWN_READER_LEVEL, MARKDOWN_READER_LEVEL_HIGH, MARKDOWN_READER_LEVEL_NORMAL, MARKDOWN_WRITER_LEVEL_MAX };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { createDebugLogger, init_debug } from "../../../utils/debug.js";
|
|
2
|
+
import { genServiceId } from "../../../editor-kernel/utils.js";
|
|
3
|
+
import { parseMarkdownToLexical } from "../data-source/markdown/parse.js";
|
|
4
|
+
import { indexBy, insertIRootNode } from "../utils/index.js";
|
|
5
|
+
import { $runTextFormatTransformers, runElementTransformers, runTextMatchTransformers, testElementTransformers } from "./transformers.js";
|
|
6
|
+
//#region src/plugins/markdown/service/shortcut.ts
|
|
7
|
+
init_debug();
|
|
8
|
+
const MARKDOWN_WRITER_LEVEL_MAX = 0;
|
|
9
|
+
const MARKDOWN_READER_LEVEL_HIGH = 1;
|
|
10
|
+
const MARKDOWN_READER_LEVEL_NORMAL = 2;
|
|
11
|
+
const IMarkdownShortCutService = genServiceId("MarkdownShortCutService");
|
|
12
|
+
var MarkdownShortCutService = class {
|
|
13
|
+
constructor(kernel) {
|
|
14
|
+
this.kernel = kernel;
|
|
15
|
+
this.elementTransformers = [];
|
|
16
|
+
this.textFormatTransformers = [];
|
|
17
|
+
this.textMatchTransformers = [];
|
|
18
|
+
this.logger = createDebugLogger("service", "markdown");
|
|
19
|
+
this._markdownWriters = {};
|
|
20
|
+
this._markdownReaders = [
|
|
21
|
+
{},
|
|
22
|
+
{},
|
|
23
|
+
{}
|
|
24
|
+
];
|
|
25
|
+
this._textFormatTransformersByTrigger = null;
|
|
26
|
+
this._textMatchTransformersByTrigger = null;
|
|
27
|
+
}
|
|
28
|
+
get markdownWriters() {
|
|
29
|
+
return this._markdownWriters;
|
|
30
|
+
}
|
|
31
|
+
get markdownReaders() {
|
|
32
|
+
return this._markdownReaders.reduce((acc, curr) => {
|
|
33
|
+
Object.keys(curr).forEach((key) => {
|
|
34
|
+
if (!acc[key]) acc[key] = [];
|
|
35
|
+
const existing = acc[key];
|
|
36
|
+
const adding = curr[key];
|
|
37
|
+
existing.push(...adding);
|
|
38
|
+
});
|
|
39
|
+
return acc;
|
|
40
|
+
}, {});
|
|
41
|
+
}
|
|
42
|
+
get textMatchTransformersByTrigger() {
|
|
43
|
+
if (!this._textMatchTransformersByTrigger) this._textMatchTransformersByTrigger = indexBy(this.textMatchTransformers, ({ trigger }) => trigger);
|
|
44
|
+
return this._textMatchTransformersByTrigger;
|
|
45
|
+
}
|
|
46
|
+
get textFormatTransformersByTrigger() {
|
|
47
|
+
if (!this._textFormatTransformersByTrigger) this._textFormatTransformersByTrigger = indexBy(this.textFormatTransformers, ({ tag }) => tag.at(-1));
|
|
48
|
+
return this._textFormatTransformersByTrigger;
|
|
49
|
+
}
|
|
50
|
+
registerMarkdownShortCut(transformer) {
|
|
51
|
+
switch (transformer.type) {
|
|
52
|
+
case "element":
|
|
53
|
+
this.elementTransformers.push(transformer);
|
|
54
|
+
break;
|
|
55
|
+
case "text-format":
|
|
56
|
+
this.textFormatTransformers.push(transformer);
|
|
57
|
+
break;
|
|
58
|
+
case "text-match":
|
|
59
|
+
this.textMatchTransformers.push(transformer);
|
|
60
|
+
break;
|
|
61
|
+
default: throw new Error(`Unknown transformer type: ${transformer}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
registerMarkdownShortCuts(transformers) {
|
|
65
|
+
for (const transformer of transformers) this.registerMarkdownShortCut(transformer);
|
|
66
|
+
}
|
|
67
|
+
testTransformers(parentNode, anchorNode, anchorOffset, trigger) {
|
|
68
|
+
if (testElementTransformers(parentNode, anchorNode, anchorOffset, this.elementTransformers, trigger)) return true;
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
runTransformers(parentNode, anchorNode, anchorOffset, trigger) {
|
|
72
|
+
if (runElementTransformers(parentNode, anchorNode, anchorOffset, this.elementTransformers, trigger)) return true;
|
|
73
|
+
if (runTextMatchTransformers(anchorNode, anchorOffset, this.textMatchTransformersByTrigger)) return true;
|
|
74
|
+
if ($runTextFormatTransformers(anchorNode, anchorOffset, this.textFormatTransformersByTrigger)) return true;
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
registerMarkdownWriter(type, writer) {
|
|
78
|
+
if (!this._markdownWriters[type]) {
|
|
79
|
+
this._markdownWriters[type] = writer;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (this.kernel?.isHotReloadMode()) {
|
|
83
|
+
this.logger.warn(`🔄 Hot reload: markdown writer "${type}"`);
|
|
84
|
+
this._markdownWriters[type] = writer;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
throw new Error(`Markdown writer for type "${type}" is already registered.`);
|
|
88
|
+
}
|
|
89
|
+
registerMarkdownReader(type, reader, level = 2) {
|
|
90
|
+
if (!this._markdownReaders[level][type]) this._markdownReaders[level][type] = [];
|
|
91
|
+
if (this._markdownReaders[level]) this._markdownReaders[level][type]?.push(reader);
|
|
92
|
+
}
|
|
93
|
+
parseMarkdownToLexical(markdown) {
|
|
94
|
+
return parseMarkdownToLexical(markdown, this.markdownReaders);
|
|
95
|
+
}
|
|
96
|
+
insertIRootNode(editor, root, selection) {
|
|
97
|
+
insertIRootNode(editor, root, selection);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
//#endregion
|
|
101
|
+
export { IMarkdownShortCutService, MARKDOWN_READER_LEVEL_HIGH, MARKDOWN_READER_LEVEL_NORMAL, MARKDOWN_WRITER_LEVEL_MAX, MarkdownShortCutService };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ElementNode, LexicalNode, RangeSelection, TextFormatType, TextNode } from "lexical";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/markdown/service/transformers.d.ts
|
|
4
|
+
type TextFormatTransformer = Readonly<{
|
|
5
|
+
format?: ReadonlyArray<TextFormatType>;
|
|
6
|
+
intraword?: boolean;
|
|
7
|
+
process?: (selection: RangeSelection) => boolean | void;
|
|
8
|
+
tag: string;
|
|
9
|
+
type: 'text-format';
|
|
10
|
+
}>;
|
|
11
|
+
type TextMatchTransformer = Readonly<{
|
|
12
|
+
/**
|
|
13
|
+
* For import operations, this function can be used to determine the end index of the match, after `importRegExp` has matched.
|
|
14
|
+
* 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
|
|
15
|
+
* 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`
|
|
16
|
+
* can be used to match the end of the node.
|
|
17
|
+
*
|
|
18
|
+
* @returns The end index of the match, or false if the match was unsuccessful and a different transformer should be tried.
|
|
19
|
+
*/
|
|
20
|
+
getEndIndex?: (node: TextNode, match: RegExpMatchArray) => number | false;
|
|
21
|
+
/**
|
|
22
|
+
* This regex determines what text is matched during markdown imports
|
|
23
|
+
*/
|
|
24
|
+
importRegExp?: RegExp;
|
|
25
|
+
/**
|
|
26
|
+
* This regex determines what text is matched for markdown shortcuts while typing in the editor
|
|
27
|
+
*/
|
|
28
|
+
regExp: RegExp;
|
|
29
|
+
/**
|
|
30
|
+
* Determines how the matched markdown text should be transformed into a node during the markdown import process
|
|
31
|
+
*
|
|
32
|
+
* @returns nothing, or a TextNode that may be a child of the new node that is created.
|
|
33
|
+
* If a TextNode is returned, text format matching will be applied to it (e.g. bold, italic, etc.)
|
|
34
|
+
*/
|
|
35
|
+
replace?: (node: TextNode, match: RegExpMatchArray) => void | TextNode;
|
|
36
|
+
/**
|
|
37
|
+
* 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.
|
|
38
|
+
* If the trigger is matched, the `regExp` will be used to match the text in the second step.
|
|
39
|
+
*/
|
|
40
|
+
trigger?: string;
|
|
41
|
+
type: 'text-match';
|
|
42
|
+
}>;
|
|
43
|
+
type ElementTransformer = {
|
|
44
|
+
regExp: RegExp;
|
|
45
|
+
/**
|
|
46
|
+
* `replace` is called when markdown is imported or typed in the editor
|
|
47
|
+
*
|
|
48
|
+
* @return return false to cancel the transform, even though the regex matched. Lexical will then search for the next transformer.
|
|
49
|
+
*/
|
|
50
|
+
replace: (parentNode: ElementNode, children: Array<LexicalNode>, match: Array<string>,
|
|
51
|
+
/**
|
|
52
|
+
* Whether the match is from an import operation (e.g. through `$convertFromMarkdownString`) or not (e.g. through typing in the editor).
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
isImport: boolean) => boolean | void;
|
|
56
|
+
trigger?: 'enter';
|
|
57
|
+
type: 'element';
|
|
58
|
+
};
|
|
59
|
+
type Transformer = ElementTransformer | TextFormatTransformer | TextMatchTransformer;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { Transformer };
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { PUNCTUATION_OR_SPACE, getOpenTagStartIndex, isEqualSubString } from "../utils/index.js";
|
|
2
|
+
import { $createRangeSelection, $getNodeByKey, $getSelection, $isLineBreakNode, $isRangeSelection, $isRootOrShadowRoot, $isTextNode, $setSelection } from "lexical";
|
|
3
|
+
//#region src/plugins/markdown/service/transformers.ts
|
|
4
|
+
function testElementTransformers(parentNode, anchorNode, anchorOffset, elementTransformers, fromTrigger) {
|
|
5
|
+
if (!$isRootOrShadowRoot(parentNode.getParent()) || parentNode.getFirstChild() !== anchorNode) return false;
|
|
6
|
+
const textContent = anchorNode.getTextContent();
|
|
7
|
+
if (fromTrigger !== "enter" && textContent[anchorOffset - 1] !== " ") return false;
|
|
8
|
+
for (const { regExp, trigger } of elementTransformers) {
|
|
9
|
+
const match = textContent.match(regExp);
|
|
10
|
+
if (fromTrigger === trigger && match && match[0].length === (fromTrigger === "enter" || match[0].endsWith(" ") ? anchorOffset : anchorOffset - 1)) return true;
|
|
11
|
+
}
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
function runElementTransformers(parentNode, anchorNode, anchorOffset, elementTransformers, fromTrigger) {
|
|
15
|
+
if (!$isRootOrShadowRoot(parentNode.getParent()) || parentNode.getFirstChild() !== anchorNode) return false;
|
|
16
|
+
const textContent = anchorNode.getTextContent();
|
|
17
|
+
if (fromTrigger !== "enter" && textContent[anchorOffset - 1] !== " ") return false;
|
|
18
|
+
for (const { regExp, replace, trigger } of elementTransformers) {
|
|
19
|
+
const match = textContent.match(regExp);
|
|
20
|
+
if (fromTrigger === trigger && match && match[0].length === (fromTrigger === "enter" || match[0].endsWith(" ") ? anchorOffset : anchorOffset - 1)) {
|
|
21
|
+
const nextSiblings = anchorNode.getNextSiblings();
|
|
22
|
+
const [leadingNode, remainderNode] = anchorNode.splitText(anchorOffset);
|
|
23
|
+
if (replace(parentNode, remainderNode ? [remainderNode, ...nextSiblings] : nextSiblings, match, false) !== false) {
|
|
24
|
+
leadingNode.remove();
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
function runTextMatchTransformers(anchorNode, anchorOffset, transformersByTrigger) {
|
|
32
|
+
let textContent = anchorNode.getTextContent();
|
|
33
|
+
const transformers = transformersByTrigger[textContent[anchorOffset - 1]];
|
|
34
|
+
if (!transformers) return false;
|
|
35
|
+
if (anchorOffset < textContent.length) textContent = textContent.slice(0, anchorOffset);
|
|
36
|
+
for (const transformer of transformers) {
|
|
37
|
+
if (!transformer.replace || !transformer.regExp) continue;
|
|
38
|
+
const match = textContent.match(transformer.regExp);
|
|
39
|
+
if (match === null) continue;
|
|
40
|
+
const startIndex = match.index || 0;
|
|
41
|
+
const endIndex = startIndex + match[0].length;
|
|
42
|
+
let replaceNode;
|
|
43
|
+
if (startIndex === 0) [replaceNode] = anchorNode.splitText(endIndex);
|
|
44
|
+
else [, replaceNode] = anchorNode.splitText(startIndex, endIndex);
|
|
45
|
+
replaceNode.selectNext(0, 0);
|
|
46
|
+
transformer.replace(replaceNode, match);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
function $runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransformers) {
|
|
52
|
+
const textContent = anchorNode.getTextContent();
|
|
53
|
+
const closeTagEndIndex = anchorOffset - 1;
|
|
54
|
+
const closeChar = textContent[closeTagEndIndex];
|
|
55
|
+
const matchers = textFormatTransformers[closeChar];
|
|
56
|
+
if (!matchers) return false;
|
|
57
|
+
for (const matcher of matchers) {
|
|
58
|
+
const { tag } = matcher;
|
|
59
|
+
const tagLength = tag.length;
|
|
60
|
+
const closeTagStartIndex = closeTagEndIndex - tagLength + 1;
|
|
61
|
+
if (tagLength > 1 && !isEqualSubString(textContent, closeTagStartIndex, tag, 0, tagLength)) continue;
|
|
62
|
+
if (textContent[closeTagStartIndex - 1] === " ") continue;
|
|
63
|
+
const afterCloseTagChar = textContent[closeTagEndIndex + 1];
|
|
64
|
+
if (matcher.intraword === false && afterCloseTagChar && !PUNCTUATION_OR_SPACE.test(afterCloseTagChar)) continue;
|
|
65
|
+
const closeNode = anchorNode;
|
|
66
|
+
let openNode = closeNode;
|
|
67
|
+
let openTagStartIndex = getOpenTagStartIndex(textContent, closeTagStartIndex, tag);
|
|
68
|
+
let sibling = openNode;
|
|
69
|
+
while (openTagStartIndex < 0 && (sibling = sibling.getPreviousSibling())) {
|
|
70
|
+
if ($isLineBreakNode(sibling)) break;
|
|
71
|
+
if ($isTextNode(sibling)) {
|
|
72
|
+
if (sibling.hasFormat("code")) continue;
|
|
73
|
+
const siblingTextContent = sibling.getTextContent();
|
|
74
|
+
openNode = sibling;
|
|
75
|
+
openTagStartIndex = getOpenTagStartIndex(siblingTextContent, siblingTextContent.length, tag);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (openTagStartIndex < 0) continue;
|
|
79
|
+
if (openNode === closeNode && openTagStartIndex + tagLength === closeTagStartIndex) continue;
|
|
80
|
+
const prevOpenNodeText = openNode.getTextContent();
|
|
81
|
+
if (openTagStartIndex > 0 && prevOpenNodeText[openTagStartIndex - 1] === closeChar) continue;
|
|
82
|
+
const beforeOpenTagChar = prevOpenNodeText[openTagStartIndex - 1];
|
|
83
|
+
if (matcher.intraword === false && beforeOpenTagChar && !PUNCTUATION_OR_SPACE.test(beforeOpenTagChar)) continue;
|
|
84
|
+
const prevCloseNodeText = closeNode.getTextContent();
|
|
85
|
+
const closeNodeText = prevCloseNodeText.slice(0, closeTagStartIndex) + prevCloseNodeText.slice(closeTagEndIndex + 1);
|
|
86
|
+
closeNode.setTextContent(closeNodeText);
|
|
87
|
+
const openNodeText = openNode === closeNode ? closeNodeText : prevOpenNodeText;
|
|
88
|
+
openNode.setTextContent(openNodeText.slice(0, openTagStartIndex) + openNodeText.slice(openTagStartIndex + tagLength));
|
|
89
|
+
const selection = $getSelection();
|
|
90
|
+
const nextSelection = $createRangeSelection();
|
|
91
|
+
$setSelection(nextSelection);
|
|
92
|
+
const newOffset = closeTagEndIndex - tagLength * (openNode === closeNode ? 2 : 1) + 1;
|
|
93
|
+
nextSelection.anchor.set(openNode.__key, openTagStartIndex, "text");
|
|
94
|
+
nextSelection.focus.set(closeNode.__key, newOffset, "text");
|
|
95
|
+
if (matcher.process) {
|
|
96
|
+
if (matcher.process(nextSelection) === false) {
|
|
97
|
+
const currentOpenNode = $getNodeByKey(openNode.__key);
|
|
98
|
+
const currentCloseNode = $getNodeByKey(closeNode.__key);
|
|
99
|
+
if ($isTextNode(currentOpenNode)) currentOpenNode.setTextContent(prevOpenNodeText);
|
|
100
|
+
if (currentCloseNode !== currentOpenNode && $isTextNode(currentCloseNode)) currentCloseNode.setTextContent(prevCloseNodeText);
|
|
101
|
+
$setSelection(anchorNode.selectEnd());
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
return true;
|
|
105
|
+
} else if (matcher.format) {
|
|
106
|
+
for (const format of matcher.format) if (!nextSelection.hasFormat(format)) nextSelection.formatText(format);
|
|
107
|
+
nextSelection.anchor.set(nextSelection.focus.key, nextSelection.focus.offset, nextSelection.focus.type);
|
|
108
|
+
for (const format of matcher.format) if (nextSelection.hasFormat(format)) nextSelection.toggleFormat(format);
|
|
109
|
+
if ($isRangeSelection(selection)) nextSelection.format = selection.format;
|
|
110
|
+
} else {
|
|
111
|
+
$setSelection(selection);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
export { $runTextFormatTransformers, runElementTransformers, runTextMatchTransformers, testElementTransformers };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/plugins/markdown/utils/detectLanguage.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Language detection utility for code snippets
|
|
4
|
+
* Uses pattern matching and heuristics to identify programming languages
|
|
5
|
+
*/
|
|
6
|
+
interface LanguageDetectionResult {
|
|
7
|
+
confidence: number;
|
|
8
|
+
language: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Detect the programming language of a code snippet
|
|
12
|
+
* @param code - The code snippet to analyze
|
|
13
|
+
* @returns Language detection result with confidence score
|
|
14
|
+
*/
|
|
15
|
+
declare function detectLanguage(code: string): LanguageDetectionResult | null;
|
|
16
|
+
/**
|
|
17
|
+
* Simple detection for common formats with high confidence
|
|
18
|
+
* Falls back to detectLanguage for more complex detection
|
|
19
|
+
*/
|
|
20
|
+
declare function detectCodeLanguage(code: string): string | null;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { detectCodeLanguage, detectLanguage };
|