@latentic/live-markdown 0.3.1 → 0.4.1
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/CHANGELOG.md +44 -0
- package/README.md +2 -2
- package/dist/chunk-V6TY7KAL.js +8 -0
- package/dist/chunk-V6TY7KAL.js.map +1 -0
- package/dist/codemirror/CodeMirrorMarkdownEditor.d.ts +106 -0
- package/dist/codemirror/CodeMirrorMarkdownEditor.js +482 -0
- package/dist/codemirror/CodeMirrorMarkdownEditor.js.map +1 -0
- package/dist/codemirror/byteOffset.d.ts +17 -0
- package/dist/codemirror/byteOffset.js +19 -0
- package/dist/codemirror/byteOffset.js.map +1 -0
- package/dist/codemirror/caretLayer.d.ts +19 -0
- package/dist/codemirror/caretLayer.js +44 -0
- package/dist/codemirror/caretLayer.js.map +1 -0
- package/dist/codemirror/clipboard/copyRich.d.ts +37 -0
- package/dist/codemirror/clipboard/copyRich.js +72 -0
- package/dist/codemirror/clipboard/copyRich.js.map +1 -0
- package/dist/codemirror/clipboard/htmlToMarkdown.d.ts +20 -0
- package/dist/codemirror/clipboard/htmlToMarkdown.js +91 -0
- package/dist/codemirror/clipboard/htmlToMarkdown.js.map +1 -0
- package/dist/codemirror/clipboard/pasteMarkdown.d.ts +18 -0
- package/dist/codemirror/clipboard/pasteMarkdown.js +41 -0
- package/dist/codemirror/clipboard/pasteMarkdown.js.map +1 -0
- package/dist/codemirror/code/codeHighlight.d.ts +13 -0
- package/dist/codemirror/code/codeHighlight.js +15 -0
- package/dist/codemirror/code/codeHighlight.js.map +1 -0
- package/dist/codemirror/code/codeLangAffordance.d.ts +17 -0
- package/dist/codemirror/code/codeLangAffordance.js +80 -0
- package/dist/codemirror/code/codeLangAffordance.js.map +1 -0
- package/dist/codemirror/code/codeLanguageMenu.d.ts +40 -0
- package/dist/codemirror/code/codeLanguageMenu.js +184 -0
- package/dist/codemirror/code/codeLanguageMenu.js.map +1 -0
- package/dist/codemirror/code/codePalette.d.ts +39 -0
- package/dist/codemirror/code/codePalette.js +53 -0
- package/dist/codemirror/code/codePalette.js.map +1 -0
- package/dist/codemirror/code/fenceAutoClose.d.ts +30 -0
- package/dist/codemirror/code/fenceAutoClose.js +171 -0
- package/dist/codemirror/code/fenceAutoClose.js.map +1 -0
- package/dist/codemirror/code/fenceCaretGuard.d.ts +28 -0
- package/dist/codemirror/code/fenceCaretGuard.js +66 -0
- package/dist/codemirror/code/fenceCaretGuard.js.map +1 -0
- package/dist/codemirror/code/fenceDeleteGuards.d.ts +22 -0
- package/dist/codemirror/code/fenceDeleteGuards.js +105 -0
- package/dist/codemirror/code/fenceDeleteGuards.js.map +1 -0
- package/dist/codemirror/code/fenceTabIndent.d.ts +8 -0
- package/dist/codemirror/code/fenceTabIndent.js +50 -0
- package/dist/codemirror/code/fenceTabIndent.js.map +1 -0
- package/dist/codemirror/code/highlightFence.d.ts +25 -0
- package/dist/codemirror/code/highlightFence.js +45 -0
- package/dist/codemirror/code/highlightFence.js.map +1 -0
- package/dist/codemirror/code/index.d.ts +9 -0
- package/dist/codemirror/code/index.js +8 -0
- package/dist/codemirror/code/index.js.map +1 -0
- package/dist/codemirror/core/codeContext.d.ts +32 -0
- package/dist/codemirror/core/codeContext.js +22 -0
- package/dist/codemirror/core/codeContext.js.map +1 -0
- package/dist/codemirror/core/editorTestHarness.d.ts +31 -0
- package/dist/codemirror/core/editorTestHarness.js +69 -0
- package/dist/codemirror/core/editorTestHarness.js.map +1 -0
- package/dist/codemirror/core/editorTheme.d.ts +39 -0
- package/dist/codemirror/core/editorTheme.js +498 -0
- package/dist/codemirror/core/editorTheme.js.map +1 -0
- package/dist/codemirror/core/hostFacets.d.ts +58 -0
- package/dist/codemirror/core/hostFacets.js +27 -0
- package/dist/codemirror/core/hostFacets.js.map +1 -0
- package/dist/codemirror/core/hrWidget.d.ts +22 -0
- package/dist/codemirror/core/hrWidget.js +22 -0
- package/dist/codemirror/core/hrWidget.js.map +1 -0
- package/dist/codemirror/core/htmlEscape.d.ts +6 -0
- package/dist/codemirror/core/htmlEscape.js +12 -0
- package/dist/codemirror/core/htmlEscape.js.map +1 -0
- package/dist/codemirror/core/index.d.ts +13 -0
- package/dist/codemirror/core/index.js +9 -0
- package/dist/codemirror/core/index.js.map +1 -0
- package/dist/codemirror/core/inlineScan.d.ts +49 -0
- package/dist/codemirror/core/inlineScan.js +31 -0
- package/dist/codemirror/core/inlineScan.js.map +1 -0
- package/dist/codemirror/core/lineStructure.d.ts +47 -0
- package/dist/codemirror/core/lineStructure.js +64 -0
- package/dist/codemirror/core/lineStructure.js.map +1 -0
- package/dist/codemirror/core/linkResolution.d.ts +36 -0
- package/dist/codemirror/core/linkResolution.js +58 -0
- package/dist/codemirror/core/linkResolution.js.map +1 -0
- package/dist/codemirror/core/paint.d.ts +118 -0
- package/dist/codemirror/core/paint.js +42 -0
- package/dist/codemirror/core/paint.js.map +1 -0
- package/dist/codemirror/core/parseToEnd.d.ts +24 -0
- package/dist/codemirror/core/parseToEnd.js +38 -0
- package/dist/codemirror/core/parseToEnd.js.map +1 -0
- package/dist/codemirror/core/plugin.d.ts +32 -0
- package/dist/codemirror/core/plugin.js +161 -0
- package/dist/codemirror/core/plugin.js.map +1 -0
- package/dist/codemirror/core/registry.d.ts +38 -0
- package/dist/codemirror/core/registry.js +133 -0
- package/dist/codemirror/core/registry.js.map +1 -0
- package/dist/codemirror/core/testKeys.d.ts +17 -0
- package/dist/codemirror/core/testKeys.js +11 -0
- package/dist/codemirror/core/testKeys.js.map +1 -0
- package/dist/codemirror/core/treeAt.d.ts +31 -0
- package/dist/codemirror/core/treeAt.js +10 -0
- package/dist/codemirror/core/treeAt.js.map +1 -0
- package/dist/codemirror/extensions/footnoteExtension.d.ts +9 -0
- package/dist/codemirror/extensions/footnoteExtension.js +14 -0
- package/dist/codemirror/extensions/footnoteExtension.js.map +1 -0
- package/dist/codemirror/extensions/highlightExtension.d.ts +9 -0
- package/dist/codemirror/extensions/highlightExtension.js +14 -0
- package/dist/codemirror/extensions/highlightExtension.js.map +1 -0
- package/dist/codemirror/extensions/index.d.ts +12 -0
- package/dist/codemirror/extensions/index.js +19 -0
- package/dist/codemirror/extensions/index.js.map +1 -0
- package/dist/codemirror/extensions/loader.d.ts +24 -0
- package/dist/codemirror/extensions/loader.js +33 -0
- package/dist/codemirror/extensions/loader.js.map +1 -0
- package/dist/codemirror/extensions/mathExtension.d.ts +9 -0
- package/dist/codemirror/extensions/mathExtension.js +14 -0
- package/dist/codemirror/extensions/mathExtension.js.map +1 -0
- package/dist/codemirror/extensions/mermaidExtension.d.ts +9 -0
- package/dist/codemirror/extensions/mermaidExtension.js +12 -0
- package/dist/codemirror/extensions/mermaidExtension.js.map +1 -0
- package/dist/codemirror/extensions/tableExtension.d.ts +13 -0
- package/dist/codemirror/extensions/tableExtension.js +39 -0
- package/dist/codemirror/extensions/tableExtension.js.map +1 -0
- package/dist/codemirror/extensions/types.d.ts +39 -0
- package/dist/codemirror/extensions/types.js +1 -0
- package/dist/codemirror/extensions/types.js.map +1 -0
- package/dist/codemirror/extensions/wikilinkExtension.d.ts +9 -0
- package/dist/codemirror/extensions/wikilinkExtension.js +14 -0
- package/dist/codemirror/extensions/wikilinkExtension.js.map +1 -0
- package/dist/codemirror/features/blockCommandSteps.d.ts +20 -0
- package/dist/codemirror/features/blockCommandSteps.js +83 -0
- package/dist/codemirror/features/blockCommandSteps.js.map +1 -0
- package/dist/codemirror/footnote/footnotePlugin.d.ts +10 -0
- package/dist/codemirror/footnote/footnotePlugin.js +78 -0
- package/dist/codemirror/footnote/footnotePlugin.js.map +1 -0
- package/dist/codemirror/footnote/footnoteScanRule.d.ts +9 -0
- package/dist/codemirror/footnote/footnoteScanRule.js +12 -0
- package/dist/codemirror/footnote/footnoteScanRule.js.map +1 -0
- package/dist/codemirror/footnote/index.d.ts +2 -0
- package/dist/codemirror/footnote/index.js +2 -0
- package/dist/codemirror/footnote/index.js.map +1 -0
- package/dist/codemirror/format/blockCommands.d.ts +17 -0
- package/dist/codemirror/format/blockCommands.js +176 -0
- package/dist/codemirror/format/blockCommands.js.map +1 -0
- package/dist/codemirror/format/formatCommands.d.ts +11 -0
- package/dist/codemirror/format/formatCommands.js +132 -0
- package/dist/codemirror/format/formatCommands.js.map +1 -0
- package/dist/codemirror/format/index.d.ts +4 -0
- package/dist/codemirror/format/index.js +3 -0
- package/dist/codemirror/format/index.js.map +1 -0
- package/dist/codemirror/highlight/highlightPlugin.d.ts +10 -0
- package/dist/codemirror/highlight/highlightPlugin.js +66 -0
- package/dist/codemirror/highlight/highlightPlugin.js.map +1 -0
- package/dist/codemirror/highlight/highlightScanRule.d.ts +8 -0
- package/dist/codemirror/highlight/highlightScanRule.js +12 -0
- package/dist/codemirror/highlight/highlightScanRule.js.map +1 -0
- package/dist/codemirror/highlight/index.d.ts +2 -0
- package/dist/codemirror/highlight/index.js +2 -0
- package/dist/codemirror/highlight/index.js.map +1 -0
- package/dist/codemirror/html/htmlWidget.d.ts +23 -0
- package/dist/codemirror/html/htmlWidget.js +67 -0
- package/dist/codemirror/html/htmlWidget.js.map +1 -0
- package/dist/codemirror/html/index.d.ts +4 -0
- package/dist/codemirror/html/index.js +2 -0
- package/dist/codemirror/html/index.js.map +1 -0
- package/dist/codemirror/image/imageActionMenu.d.ts +14 -0
- package/dist/codemirror/image/imageActionMenu.js +112 -0
- package/dist/codemirror/image/imageActionMenu.js.map +1 -0
- package/dist/codemirror/image/imageEditEvent.d.ts +20 -0
- package/dist/codemirror/image/imageEditEvent.js +6 -0
- package/dist/codemirror/image/imageEditEvent.js.map +1 -0
- package/dist/codemirror/image/imageInsertHandlers.d.ts +13 -0
- package/dist/codemirror/image/imageInsertHandlers.js +64 -0
- package/dist/codemirror/image/imageInsertHandlers.js.map +1 -0
- package/dist/codemirror/image/imageWidget.d.ts +49 -0
- package/dist/codemirror/image/imageWidget.js +83 -0
- package/dist/codemirror/image/imageWidget.js.map +1 -0
- package/dist/codemirror/image/index.d.ts +8 -0
- package/dist/codemirror/image/index.js +5 -0
- package/dist/codemirror/image/index.js.map +1 -0
- package/dist/codemirror/interaction/clickModel.d.ts +43 -0
- package/dist/codemirror/interaction/clickModel.js +99 -0
- package/dist/codemirror/interaction/clickModel.js.map +1 -0
- package/dist/codemirror/interaction/cursorModel.d.ts +10 -0
- package/dist/codemirror/interaction/cursorModel.js +58 -0
- package/dist/codemirror/interaction/cursorModel.js.map +1 -0
- package/dist/codemirror/interaction/deleteNormalizer.d.ts +18 -0
- package/dist/codemirror/interaction/deleteNormalizer.js +157 -0
- package/dist/codemirror/interaction/deleteNormalizer.js.map +1 -0
- package/dist/codemirror/interaction/flankingGuard.d.ts +20 -0
- package/dist/codemirror/interaction/flankingGuard.js +48 -0
- package/dist/codemirror/interaction/flankingGuard.js.map +1 -0
- package/dist/codemirror/interaction/index.d.ts +7 -0
- package/dist/codemirror/interaction/index.js +6 -0
- package/dist/codemirror/interaction/index.js.map +1 -0
- package/dist/codemirror/interaction/visiblePosition.d.ts +43 -0
- package/dist/codemirror/interaction/visiblePosition.js +98 -0
- package/dist/codemirror/interaction/visiblePosition.js.map +1 -0
- package/dist/codemirror/list/bulletWidget.d.ts +61 -0
- package/dist/codemirror/list/bulletWidget.js +84 -0
- package/dist/codemirror/list/bulletWidget.js.map +1 -0
- package/dist/codemirror/list/index.d.ts +4 -0
- package/dist/codemirror/list/index.js +3 -0
- package/dist/codemirror/list/index.js.map +1 -0
- package/dist/codemirror/list/listContinuation.d.ts +28 -0
- package/dist/codemirror/list/listContinuation.js +61 -0
- package/dist/codemirror/list/listContinuation.js.map +1 -0
- package/dist/codemirror/list/listIndent.d.ts +8 -0
- package/dist/codemirror/list/listIndent.js +95 -0
- package/dist/codemirror/list/listIndent.js.map +1 -0
- package/dist/codemirror/list/taskCheckboxWidget.d.ts +42 -0
- package/dist/codemirror/list/taskCheckboxWidget.js +47 -0
- package/dist/codemirror/list/taskCheckboxWidget.js.map +1 -0
- package/dist/codemirror/math/index.d.ts +3 -0
- package/dist/codemirror/math/index.js +2 -0
- package/dist/codemirror/math/index.js.map +1 -0
- package/dist/codemirror/math/mathPlugin.d.ts +10 -0
- package/dist/codemirror/math/mathPlugin.js +73 -0
- package/dist/codemirror/math/mathPlugin.js.map +1 -0
- package/dist/codemirror/math/mathScanRule.d.ts +16 -0
- package/dist/codemirror/math/mathScanRule.js +18 -0
- package/dist/codemirror/math/mathScanRule.js.map +1 -0
- package/dist/codemirror/math/mathWidget.d.ts +17 -0
- package/dist/codemirror/math/mathWidget.js +58 -0
- package/dist/codemirror/math/mathWidget.js.map +1 -0
- package/dist/codemirror/mermaid/index.d.ts +4 -0
- package/dist/codemirror/mermaid/index.js +3 -0
- package/dist/codemirror/mermaid/index.js.map +1 -0
- package/dist/codemirror/mermaid/mermaidPlugin.d.ts +25 -0
- package/dist/codemirror/mermaid/mermaidPlugin.js +78 -0
- package/dist/codemirror/mermaid/mermaidPlugin.js.map +1 -0
- package/dist/codemirror/mermaid/mermaidRender.d.ts +42 -0
- package/dist/codemirror/mermaid/mermaidRender.js +136 -0
- package/dist/codemirror/mermaid/mermaidRender.js.map +1 -0
- package/dist/codemirror/mermaid/mermaidWidget.d.ts +42 -0
- package/dist/codemirror/mermaid/mermaidWidget.js +142 -0
- package/dist/codemirror/mermaid/mermaidWidget.js.map +1 -0
- package/dist/codemirror/selectionLayer.d.ts +43 -0
- package/dist/codemirror/selectionLayer.js +135 -0
- package/dist/codemirror/selectionLayer.js.map +1 -0
- package/dist/codemirror/table/cellDividerWidget.d.ts +9 -0
- package/dist/codemirror/table/cellDividerWidget.js +19 -0
- package/dist/codemirror/table/cellDividerWidget.js.map +1 -0
- package/dist/codemirror/table/index.d.ts +5 -0
- package/dist/codemirror/table/index.js +4 -0
- package/dist/codemirror/table/index.js.map +1 -0
- package/dist/codemirror/table/tableArmed.d.ts +27 -0
- package/dist/codemirror/table/tableArmed.js +43 -0
- package/dist/codemirror/table/tableArmed.js.map +1 -0
- package/dist/codemirror/table/tableCell.d.ts +19 -0
- package/dist/codemirror/table/tableCell.js +15 -0
- package/dist/codemirror/table/tableCell.js.map +1 -0
- package/dist/codemirror/table/tableCellNav.d.ts +51 -0
- package/dist/codemirror/table/tableCellNav.js +47 -0
- package/dist/codemirror/table/tableCellNav.js.map +1 -0
- package/dist/codemirror/table/tableContextMenu.d.ts +22 -0
- package/dist/codemirror/table/tableContextMenu.js +139 -0
- package/dist/codemirror/table/tableContextMenu.js.map +1 -0
- package/dist/codemirror/table/tableEditCommands.d.ts +29 -0
- package/dist/codemirror/table/tableEditCommands.js +86 -0
- package/dist/codemirror/table/tableEditCommands.js.map +1 -0
- package/dist/codemirror/table/tableExcerpt.d.ts +29 -0
- package/dist/codemirror/table/tableExcerpt.js +34 -0
- package/dist/codemirror/table/tableExcerpt.js.map +1 -0
- package/dist/codemirror/table/tableField.d.ts +6 -0
- package/dist/codemirror/table/tableField.js +37 -0
- package/dist/codemirror/table/tableField.js.map +1 -0
- package/dist/codemirror/table/tableGeometry.d.ts +33 -0
- package/dist/codemirror/table/tableGeometry.js +28 -0
- package/dist/codemirror/table/tableGeometry.js.map +1 -0
- package/dist/codemirror/table/tableInline.d.ts +37 -0
- package/dist/codemirror/table/tableInline.js +105 -0
- package/dist/codemirror/table/tableInline.js.map +1 -0
- package/dist/codemirror/table/tableModel.d.ts +45 -0
- package/dist/codemirror/table/tableModel.js +98 -0
- package/dist/codemirror/table/tableModel.js.map +1 -0
- package/dist/codemirror/tablev2/bridgeRules.d.ts +48 -0
- package/dist/codemirror/tablev2/bridgeRules.js +42 -0
- package/dist/codemirror/tablev2/bridgeRules.js.map +1 -0
- package/dist/codemirror/tablev2/cellEditingSurface.d.ts +79 -0
- package/dist/codemirror/tablev2/cellEditingSurface.js +70 -0
- package/dist/codemirror/tablev2/cellEditingSurface.js.map +1 -0
- package/dist/codemirror/tablev2/cellText.d.ts +11 -0
- package/dist/codemirror/tablev2/cellText.js +12 -0
- package/dist/codemirror/tablev2/cellText.js.map +1 -0
- package/dist/codemirror/tablev2/inlineCellSurface.d.ts +38 -0
- package/dist/codemirror/tablev2/inlineCellSurface.js +162 -0
- package/dist/codemirror/tablev2/inlineCellSurface.js.map +1 -0
- package/dist/codemirror/tablev2/overlayCellSurface.d.ts +36 -0
- package/dist/codemirror/tablev2/overlayCellSurface.js +150 -0
- package/dist/codemirror/tablev2/overlayCellSurface.js.map +1 -0
- package/dist/codemirror/tablev2/tableEditingSteps.d.ts +12 -0
- package/dist/codemirror/tablev2/tableEditingSteps.js +518 -0
- package/dist/codemirror/tablev2/tableEditingSteps.js.map +1 -0
- package/dist/codemirror/tablev2/tableV2HoverControls.d.ts +23 -0
- package/dist/codemirror/tablev2/tableV2HoverControls.js +89 -0
- package/dist/codemirror/tablev2/tableV2HoverControls.js.map +1 -0
- package/dist/codemirror/tablev2/tableV2Interaction.d.ts +29 -0
- package/dist/codemirror/tablev2/tableV2Interaction.js +224 -0
- package/dist/codemirror/tablev2/tableV2Interaction.js.map +1 -0
- package/dist/codemirror/tablev2/tableV2Selection.d.ts +45 -0
- package/dist/codemirror/tablev2/tableV2Selection.js +81 -0
- package/dist/codemirror/tablev2/tableV2Selection.js.map +1 -0
- package/dist/codemirror/tablev2/tableV2Sync.d.ts +13 -0
- package/dist/codemirror/tablev2/tableV2Sync.js +13 -0
- package/dist/codemirror/tablev2/tableV2Sync.js.map +1 -0
- package/dist/codemirror/tablev2/tableWidgetV2.d.ts +46 -0
- package/dist/codemirror/tablev2/tableWidgetV2.js +139 -0
- package/dist/codemirror/tablev2/tableWidgetV2.js.map +1 -0
- package/dist/codemirror/updateBus.d.ts +29 -0
- package/dist/codemirror/updateBus.js +26 -0
- package/dist/codemirror/updateBus.js.map +1 -0
- package/dist/codemirror/wikilink/index.d.ts +3 -0
- package/dist/codemirror/wikilink/index.js +2 -0
- package/dist/codemirror/wikilink/index.js.map +1 -0
- package/dist/codemirror/wikilink/wikilinkPlugin.d.ts +40 -0
- package/dist/codemirror/wikilink/wikilinkPlugin.js +89 -0
- package/dist/codemirror/wikilink/wikilinkPlugin.js.map +1 -0
- package/dist/codemirror/wikilink/wikilinkScanRule.d.ts +9 -0
- package/dist/codemirror/wikilink/wikilinkScanRule.js +13 -0
- package/dist/codemirror/wikilink/wikilinkScanRule.js.map +1 -0
- package/dist/frontmatter.d.ts +79 -0
- package/dist/frontmatter.js +58 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/imageInsert.d.ts +66 -0
- package/dist/imageInsert.js +111 -0
- package/dist/imageInsert.js.map +1 -0
- package/dist/imageSrcResolver.d.ts +55 -0
- package/dist/imageSrcResolver.js +49 -0
- package/dist/imageSrcResolver.js.map +1 -0
- package/dist/index.d.ts +36 -880
- package/dist/index.js +130 -5996
- package/dist/index.js.map +1 -1
- package/dist/links/wikilink.d.ts +26 -0
- package/dist/links/wikilink.js +54 -0
- package/dist/links/wikilink.js.map +1 -0
- package/dist/links/workspaceLink.d.ts +34 -0
- package/dist/links/workspaceLink.js +60 -0
- package/dist/links/workspaceLink.js.map +1 -0
- package/dist/types.d.ts +20 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/package.json +7 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.1] - 2026-09-10
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- **KaTeX is fetched on the first expression, not at every launch.** It is the
|
|
8
|
+
largest single dependency this package pulls into a host's bundle — 293KB
|
|
9
|
+
measured in Compose, 13% of its eager chunk — and most documents contain no
|
|
10
|
+
`$` at all. Compose's eager chunk goes 2,061KB → 1,793KB and its `entry` mark
|
|
11
|
+
167ms → 150ms.
|
|
12
|
+
|
|
13
|
+
The cost is one frame on the first expression in a session; every one after is
|
|
14
|
+
synchronous. Until KaTeX lands the source stands in, which is also the existing
|
|
15
|
+
failure mode, so a document that never loads it still shows what was written.
|
|
16
|
+
|
|
17
|
+
- `mathTypesettingSettled()` is exported for anything that MEASURES rendered
|
|
18
|
+
math rather than displaying it — a document export, a test.
|
|
19
|
+
|
|
20
|
+
## [0.4.0] - 2026-09-10
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- **The caret was black in dark mode.** CodeMirror paints the cursor from
|
|
25
|
+
`caret-color`, which the theme never set, so it fell back to the page's text
|
|
26
|
+
colour instead of the editor's.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **The package ships a mirror of `src/` instead of one bundled module**, so a
|
|
31
|
+
consumer's bundler can follow the real import graph.
|
|
32
|
+
|
|
33
|
+
A single 216KB module is opaque to tree-shaking at the granularity that
|
|
34
|
+
matters. Reaching for one link helper retained everything it had been bundled
|
|
35
|
+
with — `yaml`, `dompurify` and the whole CodeMirror surface — and once any
|
|
36
|
+
eagerly-loaded module in a host app touched the package, all of it landed in
|
|
37
|
+
that app's launch bundle. Measured in Compose: importing `resolveWorkspaceLink`
|
|
38
|
+
from the chat panel put 468KB of unrelated source on the path to first paint.
|
|
39
|
+
The same app's eager chunk is 40% smaller against this build, with no change
|
|
40
|
+
to a single import site.
|
|
41
|
+
|
|
42
|
+
Import paths are unchanged: `.` still resolves to the same exports, now via a
|
|
43
|
+
2.7KB re-export barrel. Subpaths (`@latentic/live-markdown/links/wikilink`)
|
|
44
|
+
are additionally available. Relative specifiers in the output carry real `.js`
|
|
45
|
+
extensions, so the output is valid Node ESM as well — it was not before.
|
|
46
|
+
|
|
3
47
|
## [0.3.1] - 2026-08-29
|
|
4
48
|
|
|
5
49
|
### Fixed
|
package/README.md
CHANGED
|
@@ -49,9 +49,9 @@ The boundary semantics this demands — what every keystroke does at every const
|
|
|
49
49
|
| Tables | GFM, cell navigation | Plugin | Basic | Plugin | Slash command |
|
|
50
50
|
| Image paste/drop | Built-in | Plugin | No | Plugin | Plugin |
|
|
51
51
|
| Framework | React | React / Vue / vanilla | Vanilla / adapters | React | React |
|
|
52
|
-
| Bundle size |
|
|
52
|
+
| Bundle size | 67 KB gzipped* | ~120 KB+ | ~40 KB | ~150 KB+ | ~200 KB+ |
|
|
53
53
|
|
|
54
|
-
\*
|
|
54
|
+
\* The whole surface. The package ships one module per source file rather than one bundle, so a host pulls only what it reaches — Compose reaches 90 of 113 — at the cost of ~10 KB in lost cross-module minification if you use all of it. CodeMirror, KaTeX and Mermaid are external, so you pay for a renderer only where your documents use one — the other figures are the projects' own published numbers and are not all drawn on the same basis.
|
|
55
55
|
|
|
56
56
|
### Key differentiators
|
|
57
57
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
__publicField
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=chunk-V6TY7KAL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { EditorView } from '@codemirror/view';
|
|
4
|
+
import { DocumentTextChange, SourceRange } from '../types.js';
|
|
5
|
+
import { RenderClipboardHtml } from './clipboard/copyRich.js';
|
|
6
|
+
import { ResolveImageSrc, SaveImageBytes, OpenExternalUrl, CommentOnExcerpt } from './core/hostFacets.js';
|
|
7
|
+
import { MarkdownExtension, ToolbarContribution } from './extensions/types.js';
|
|
8
|
+
import '@codemirror/state';
|
|
9
|
+
import '../imageSrcResolver.js';
|
|
10
|
+
import './core/paint.js';
|
|
11
|
+
|
|
12
|
+
type CodeMirrorEditorMode = "wysiwyg" | "source";
|
|
13
|
+
/** A non-empty editor selection, in document byte offsets. */
|
|
14
|
+
interface EditorSelectionSnapshot {
|
|
15
|
+
range: SourceRange;
|
|
16
|
+
text: string;
|
|
17
|
+
}
|
|
18
|
+
interface CodeMirrorMarkdownEditorProps {
|
|
19
|
+
mode?: CodeMirrorEditorMode;
|
|
20
|
+
onChange: (value: string, changes: DocumentTextChange[]) => void;
|
|
21
|
+
value: string;
|
|
22
|
+
workspaceRoot?: string;
|
|
23
|
+
filePath?: string;
|
|
24
|
+
linkTargets?: ReadonlySet<string>;
|
|
25
|
+
onNavigateToLink?: (path: string) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Extension modules contributed by the host, merged AFTER the built-ins so a
|
|
28
|
+
* host can deliberately override a construct (the merger warns when a node
|
|
29
|
+
* rule is redefined).
|
|
30
|
+
*
|
|
31
|
+
* Read when an editor state is built — on mount, and on the swaps that
|
|
32
|
+
* rebuild one — not on every render, so passing a fresh array each time costs
|
|
33
|
+
* nothing and cannot remount the editor. Changing it mid-session therefore
|
|
34
|
+
* takes effect at the next rebuild.
|
|
35
|
+
*
|
|
36
|
+
* Applies in BOTH modes: a module's node rules simply go unread while the
|
|
37
|
+
* decoration painter is off, but its keymaps and plain CodeMirror extensions
|
|
38
|
+
* are not markdown-rendering concerns and should not be silently dropped in
|
|
39
|
+
* source mode.
|
|
40
|
+
*/
|
|
41
|
+
extensions?: readonly MarkdownExtension[];
|
|
42
|
+
/** Host-rendered toolbar. `contributions` carries the toolbar items the
|
|
43
|
+
* extension modules asked for; the host decides whether and how to render
|
|
44
|
+
* them alongside its own. */
|
|
45
|
+
toolbar?: (ctx: {
|
|
46
|
+
view: EditorView;
|
|
47
|
+
contributions: readonly ToolbarContribution[];
|
|
48
|
+
}) => ReactNode;
|
|
49
|
+
/**
|
|
50
|
+
* Host-rendered actions for the current text selection (e.g. a comment / ask
|
|
51
|
+
* bubble). Called with the live selection (or `null` when collapsed) and a
|
|
52
|
+
* `dismiss` that collapses the selection back to a caret. Omit for none.
|
|
53
|
+
*/
|
|
54
|
+
selectionActions?: (ctx: {
|
|
55
|
+
selection: EditorSelectionSnapshot | null;
|
|
56
|
+
dismiss: () => void;
|
|
57
|
+
}) => ReactNode;
|
|
58
|
+
/**
|
|
59
|
+
* Map a markdown image `src` to a loadable URL. Default: render the reference
|
|
60
|
+
* as-is. A desktop host maps workspace-relative paths onto its asset protocol.
|
|
61
|
+
*/
|
|
62
|
+
resolveImageSrc?: ResolveImageSrc;
|
|
63
|
+
/**
|
|
64
|
+
* Persist a pasted/dropped image's bytes at a workspace-relative path.
|
|
65
|
+
* Default: omitted ⇒ the image is inlined as a `data:` URL.
|
|
66
|
+
*/
|
|
67
|
+
saveImageBytes?: SaveImageBytes;
|
|
68
|
+
/**
|
|
69
|
+
* Open a clicked external link. Default: a new browser tab. A desktop host
|
|
70
|
+
* overrides this to leave the app's webview.
|
|
71
|
+
*/
|
|
72
|
+
onOpenExternalUrl?: OpenExternalUrl;
|
|
73
|
+
/**
|
|
74
|
+
* Comment on a selected table row/column — wired to the table context menu's
|
|
75
|
+
* "Comment on this row / column". The host opens its comment composer at the
|
|
76
|
+
* given anchor, seeded with the excerpt. Default: omitted ⇒ no such menu items.
|
|
77
|
+
*/
|
|
78
|
+
onCommentOnExcerpt?: CommentOnExcerpt;
|
|
79
|
+
/**
|
|
80
|
+
* Render a markdown selection to HTML for the clipboard, so a copy pastes
|
|
81
|
+
* formatted into Google Docs / Slack / Word (the markdown source always
|
|
82
|
+
* rides along as text/plain). Default: omitted ⇒ plain-only copies.
|
|
83
|
+
*/
|
|
84
|
+
renderClipboardHtml?: RenderClipboardHtml;
|
|
85
|
+
/**
|
|
86
|
+
* Called once, right after a tab-switch content swap commits and paints.
|
|
87
|
+
* Used by the host for latency instrumentation; no-op by default.
|
|
88
|
+
*/
|
|
89
|
+
onAfterContentSwap?: () => void;
|
|
90
|
+
/**
|
|
91
|
+
* Receives a synchronous `flush()` that pulls the editor's live (debounce-
|
|
92
|
+
* lagged) content into the last `onChange` immediately — the host calls it
|
|
93
|
+
* before persisting. `null` is passed on unmount. Lets a host avoid writing
|
|
94
|
+
* stale buffers on Cmd+S / tab close.
|
|
95
|
+
*/
|
|
96
|
+
onFlushReady?: (flush: (() => void) | null) => void;
|
|
97
|
+
}
|
|
98
|
+
declare function CodeMirrorMarkdownEditorInner({ mode, onChange, value, workspaceRoot, filePath, linkTargets, onNavigateToLink, extensions: hostExtensions, toolbar, selectionActions, resolveImageSrc, saveImageBytes, onOpenExternalUrl, onCommentOnExcerpt, renderClipboardHtml, onAfterContentSwap, onFlushReady, }: CodeMirrorMarkdownEditorProps): react.JSX.Element;
|
|
99
|
+
/**
|
|
100
|
+
* Memoised export — same reason as the Tiptap editor. AppShell
|
|
101
|
+
* re-renders on every chat-thread token; without memoisation each
|
|
102
|
+
* token would blow through the editor's render path.
|
|
103
|
+
*/
|
|
104
|
+
declare const CodeMirrorMarkdownEditor: react.MemoExoticComponent<typeof CodeMirrorMarkdownEditorInner>;
|
|
105
|
+
|
|
106
|
+
export { type CodeMirrorEditorMode, CodeMirrorMarkdownEditor, type CodeMirrorMarkdownEditorProps, type EditorSelectionSnapshot };
|
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
import "../chunk-V6TY7KAL.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import {
|
|
4
|
+
memo,
|
|
5
|
+
useCallback,
|
|
6
|
+
useEffect,
|
|
7
|
+
useLayoutEffect,
|
|
8
|
+
useMemo,
|
|
9
|
+
useRef,
|
|
10
|
+
useState
|
|
11
|
+
} from "react";
|
|
12
|
+
import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
|
|
13
|
+
import { markdown, markdownKeymap, markdownLanguage } from "@codemirror/lang-markdown";
|
|
14
|
+
import { languages } from "@codemirror/language-data";
|
|
15
|
+
import { Annotation, EditorSelection, EditorState } from "@codemirror/state";
|
|
16
|
+
import { EditorView, keymap } from "@codemirror/view";
|
|
17
|
+
import { parseFrontmatter, serializeMarkdown } from "../frontmatter.js";
|
|
18
|
+
import { byteRangeOf } from "./byteOffset.js";
|
|
19
|
+
import { drawnCaret } from "./caretLayer.js";
|
|
20
|
+
import { drawnSelection } from "./selectionLayer.js";
|
|
21
|
+
import { markdownPaste } from "./clipboard/pasteMarkdown.js";
|
|
22
|
+
import {
|
|
23
|
+
renderClipboardHtmlFacet,
|
|
24
|
+
richCopy
|
|
25
|
+
} from "./clipboard/copyRich.js";
|
|
26
|
+
import { onEditorUpdate, updateBus } from "./updateBus.js";
|
|
27
|
+
import {
|
|
28
|
+
codeHighlight,
|
|
29
|
+
codeLanguageUI,
|
|
30
|
+
fenceAutoCloseKeymap,
|
|
31
|
+
fenceCaretGuard,
|
|
32
|
+
fenceTabKeymap,
|
|
33
|
+
fenceTypeAutoClose
|
|
34
|
+
} from "./code/index.js";
|
|
35
|
+
import {
|
|
36
|
+
commentOnExcerptFacet,
|
|
37
|
+
editorBaseTheme,
|
|
38
|
+
markdownDecorationsPlugin,
|
|
39
|
+
openExternalUrlFacet,
|
|
40
|
+
parseToEnd,
|
|
41
|
+
resolveImageSrcFacet,
|
|
42
|
+
saveImageBytesFacet
|
|
43
|
+
} from "./core/index.js";
|
|
44
|
+
import {
|
|
45
|
+
clickModel,
|
|
46
|
+
cursorModelKeymap,
|
|
47
|
+
deleteNormalizerKeymap,
|
|
48
|
+
flankingGuard,
|
|
49
|
+
navigateToFacet
|
|
50
|
+
} from "./interaction/index.js";
|
|
51
|
+
import { tightListKeymap, listIndentKeymap } from "./list/index.js";
|
|
52
|
+
import { formatCommandsKeymap, blockCommandsKeymap } from "./format/index.js";
|
|
53
|
+
import { imageContextFacet, imageInsertHandlers } from "./image/index.js";
|
|
54
|
+
import { computeFileDir } from "../imageSrcResolver.js";
|
|
55
|
+
import { wikilinkFromPathFacet, wikilinkTargetsFacet } from "./wikilink/index.js";
|
|
56
|
+
import {
|
|
57
|
+
mergeExtensions,
|
|
58
|
+
footnoteExtension,
|
|
59
|
+
highlightExtension,
|
|
60
|
+
mathExtension,
|
|
61
|
+
mermaidExtension,
|
|
62
|
+
tableExtension,
|
|
63
|
+
wikilinkExtension
|
|
64
|
+
} from "./extensions/index.js";
|
|
65
|
+
const programmaticSwap = Annotation.define();
|
|
66
|
+
const AUTOSAVE_DEBOUNCE_MS = 500;
|
|
67
|
+
function hashString(s) {
|
|
68
|
+
let h = 2166136261;
|
|
69
|
+
for (let i = 0; i < s.length; i += 1) {
|
|
70
|
+
h ^= s.charCodeAt(i);
|
|
71
|
+
h = h * 16777619 >>> 0;
|
|
72
|
+
}
|
|
73
|
+
return h.toString(16);
|
|
74
|
+
}
|
|
75
|
+
function CodeMirrorMarkdownEditorInner({
|
|
76
|
+
mode = "wysiwyg",
|
|
77
|
+
onChange,
|
|
78
|
+
value,
|
|
79
|
+
workspaceRoot,
|
|
80
|
+
filePath,
|
|
81
|
+
linkTargets,
|
|
82
|
+
onNavigateToLink,
|
|
83
|
+
extensions: hostExtensions,
|
|
84
|
+
toolbar,
|
|
85
|
+
selectionActions,
|
|
86
|
+
resolveImageSrc,
|
|
87
|
+
saveImageBytes,
|
|
88
|
+
onOpenExternalUrl,
|
|
89
|
+
onCommentOnExcerpt,
|
|
90
|
+
renderClipboardHtml,
|
|
91
|
+
onAfterContentSwap,
|
|
92
|
+
onFlushReady
|
|
93
|
+
}) {
|
|
94
|
+
const parsedRef = useRef(parseFrontmatter(value));
|
|
95
|
+
const frontmatterRef = useRef(parsedRef.current.frontmatter);
|
|
96
|
+
const bodyRef = useRef(parsedRef.current.body);
|
|
97
|
+
const lastEmittedHashRef = useRef(hashString(value));
|
|
98
|
+
const autosaveTimerRef = useRef(null);
|
|
99
|
+
const hostRef = useRef(null);
|
|
100
|
+
const viewRef = useRef(null);
|
|
101
|
+
const [viewForToolbar, setViewForToolbar] = useState(null);
|
|
102
|
+
const [bubbleSelection, setBubbleSelection] = useState(null);
|
|
103
|
+
const onChangeRef = useRef(onChange);
|
|
104
|
+
useLayoutEffect(function syncLatestOnChangeRef() {
|
|
105
|
+
onChangeRef.current = onChange;
|
|
106
|
+
});
|
|
107
|
+
const resolveImageSrcRef = useRef(resolveImageSrc);
|
|
108
|
+
const saveImageBytesRef = useRef(saveImageBytes);
|
|
109
|
+
const openExternalUrlRef = useRef(onOpenExternalUrl);
|
|
110
|
+
const onCommentOnExcerptRef = useRef(onCommentOnExcerpt);
|
|
111
|
+
const renderClipboardHtmlRef = useRef(renderClipboardHtml);
|
|
112
|
+
const onAfterContentSwapRef = useRef(onAfterContentSwap);
|
|
113
|
+
const onFlushReadyRef = useRef(onFlushReady);
|
|
114
|
+
useLayoutEffect(function syncHostSeamRefs() {
|
|
115
|
+
resolveImageSrcRef.current = resolveImageSrc;
|
|
116
|
+
saveImageBytesRef.current = saveImageBytes;
|
|
117
|
+
openExternalUrlRef.current = onOpenExternalUrl;
|
|
118
|
+
onCommentOnExcerptRef.current = onCommentOnExcerpt;
|
|
119
|
+
renderClipboardHtmlRef.current = renderClipboardHtml;
|
|
120
|
+
onAfterContentSwapRef.current = onAfterContentSwap;
|
|
121
|
+
onFlushReadyRef.current = onFlushReady;
|
|
122
|
+
});
|
|
123
|
+
const decorationsEnabled = mode === "wysiwyg";
|
|
124
|
+
const imageCtx = useMemo(
|
|
125
|
+
() => ({ fileDir: computeFileDir(workspaceRoot, filePath) }),
|
|
126
|
+
[workspaceRoot, filePath]
|
|
127
|
+
);
|
|
128
|
+
const editorStatesRef = useRef(/* @__PURE__ */ new Map());
|
|
129
|
+
const syncedHashRef = useRef(/* @__PURE__ */ new Map());
|
|
130
|
+
const currentFileRef = useRef(filePath);
|
|
131
|
+
const modeInitializedRef = useRef(decorationsEnabled);
|
|
132
|
+
const hostExtensionsRef = useRef(hostExtensions);
|
|
133
|
+
hostExtensionsRef.current = hostExtensions;
|
|
134
|
+
const toolbarContributionsRef = useRef([]);
|
|
135
|
+
function buildExtensions() {
|
|
136
|
+
const base = [
|
|
137
|
+
history(),
|
|
138
|
+
// Update fan-out for reactive chrome (toolbar pressed-states, selection
|
|
139
|
+
// bubble). Must ride the BASE extensions: anything appended to a single
|
|
140
|
+
// state's config dies on the next setState (tab switch) and the chrome
|
|
141
|
+
// freezes at the previous document's context.
|
|
142
|
+
updateBus,
|
|
143
|
+
// Whitespace typed at a bold/italic/strike content edge lands outside
|
|
144
|
+
// the markers, or the closing delimiter stops parsing (#94).
|
|
145
|
+
flankingGuard,
|
|
146
|
+
// Caret and selection both draw from the editor's own selection state:
|
|
147
|
+
// the native contentEditable caret double-paints at atomic widget
|
|
148
|
+
// boundaries (#62), and native ::selection can only highlight rendered
|
|
149
|
+
// DOM, so a whole-document selection loses its highlight outside the
|
|
150
|
+
// virtualized viewport (#166). Table cells run their own subview
|
|
151
|
+
// without either, keeping their native caret and selection.
|
|
152
|
+
drawnCaret,
|
|
153
|
+
drawnSelection,
|
|
154
|
+
// Tight list continuation — Enter drops the next bullet directly below,
|
|
155
|
+
// never with a blank-line gap (overrides the stock markdown Enter for
|
|
156
|
+
// non-empty list items; see listContinuation.ts).
|
|
157
|
+
tightListKeymap,
|
|
158
|
+
// Enter on a just-typed ``` closes the fence with the caret inside —
|
|
159
|
+
// an unclosed fence would swallow the rest of the document (#91).
|
|
160
|
+
fenceAutoCloseKeymap,
|
|
161
|
+
// The keystroke completing a bare ``` closes the fence immediately, so
|
|
162
|
+
// an unclosed opener never swallows the document below (§9.5).
|
|
163
|
+
fenceTypeAutoClose,
|
|
164
|
+
// Tab indents inside a code block (Shift-Tab dedents) — otherwise the
|
|
165
|
+
// browser's focus navigation steals the key mid-code (§12.8).
|
|
166
|
+
fenceTabKeymap,
|
|
167
|
+
// The caret never parks on a fence's marker rows: clicks land on the
|
|
168
|
+
// nearest content edge, arrow motion crosses out of the block (§12.9).
|
|
169
|
+
fenceCaretGuard,
|
|
170
|
+
// Opener-row language pill (+ "plain" placeholder) opens the chooser;
|
|
171
|
+
// right-click a block for set-language / copy-code (ADR 0002).
|
|
172
|
+
codeLanguageUI,
|
|
173
|
+
// Tab / Shift-Tab nest / promote a list item by the parent marker width
|
|
174
|
+
// (list-aware; falls through to normal Tab outside a list — listIndent.ts).
|
|
175
|
+
listIndentKeymap,
|
|
176
|
+
keymap.of([...defaultKeymap, ...historyKeymap, ...markdownKeymap]),
|
|
177
|
+
// markdownLanguage = CommonMark + GFM (tables, task lists,
|
|
178
|
+
// strikethrough). Without `base`, `markdown()` uses bare
|
|
179
|
+
// CommonMark — Lezer never produces Table / Task / Strikethrough
|
|
180
|
+
// nodes and our registry can't decorate them.
|
|
181
|
+
//
|
|
182
|
+
// `remove: ["SetextHeading"]` disables setext headings — the rule that a
|
|
183
|
+
// line of text immediately followed by a line of `---` (or `===`) turns
|
|
184
|
+
// the text into a heading. That rule silently rewrites the line ABOVE
|
|
185
|
+
// when you type `-` under a paragraph, which is surprising in a rich
|
|
186
|
+
// editor (and fought our "lone `-` is literal until a space" bullet
|
|
187
|
+
// rule). ATX `#` headings are unaffected.
|
|
188
|
+
// `codeLanguages` gives fenced blocks a real nested parse (lazily
|
|
189
|
+
// loaded per info string) — actual syntax highlighting via
|
|
190
|
+
// codeHighlight, which styles only code-emitted tags (ADR 0002).
|
|
191
|
+
markdown({
|
|
192
|
+
base: markdownLanguage,
|
|
193
|
+
codeLanguages: languages,
|
|
194
|
+
extensions: [{ remove: ["SetextHeading"] }]
|
|
195
|
+
}),
|
|
196
|
+
codeHighlight,
|
|
197
|
+
EditorView.lineWrapping,
|
|
198
|
+
// Editor-internal styling (font, line-height, heading sizes,
|
|
199
|
+
// marker widget styling) lives in `editorBaseTheme` so it
|
|
200
|
+
// participates in CM6's line-metric measurement cycle. Don't
|
|
201
|
+
// duplicate these rules in `global.scss` — that's where the
|
|
202
|
+
// earlier click-drift bug came from.
|
|
203
|
+
editorBaseTheme,
|
|
204
|
+
// Image-src resolution context for the inline image widget.
|
|
205
|
+
imageContextFacet.of(imageCtx),
|
|
206
|
+
// Image paste / drop pipeline. Pulls bytes off the clipboard
|
|
207
|
+
// or DataTransfer, saves through `insertImageBlob`, inserts
|
|
208
|
+
// `` at the caret.
|
|
209
|
+
imageInsertHandlers,
|
|
210
|
+
// Clipboard interop (#134/#135): rich pastes convert to markdown
|
|
211
|
+
// (image-file pastes stay with the handler above); copies carry
|
|
212
|
+
// markdown + rendered HTML. After imageInsertHandlers so file pastes
|
|
213
|
+
// resolve there first.
|
|
214
|
+
markdownPaste,
|
|
215
|
+
richCopy,
|
|
216
|
+
renderClipboardHtmlFacet.of(
|
|
217
|
+
(markdown2) => (renderClipboardHtmlRef.current ?? (() => null))(markdown2)
|
|
218
|
+
),
|
|
219
|
+
// Host-environment seams. Registered as stable wrappers (reading the
|
|
220
|
+
// latest prop through a ref) only when the host provides the capability;
|
|
221
|
+
// otherwise the facet's browser default applies. See hostFacets.ts.
|
|
222
|
+
...resolveImageSrc ? [
|
|
223
|
+
resolveImageSrcFacet.of(
|
|
224
|
+
(rawSrc, ctx) => (resolveImageSrcRef.current ?? ((s) => s))(rawSrc, ctx)
|
|
225
|
+
)
|
|
226
|
+
] : [],
|
|
227
|
+
...saveImageBytes ? [
|
|
228
|
+
saveImageBytesFacet.of((relPath, bytes) => {
|
|
229
|
+
const fn = saveImageBytesRef.current;
|
|
230
|
+
return fn ? fn(relPath, bytes) : Promise.reject(new Error("no saver"));
|
|
231
|
+
})
|
|
232
|
+
] : [],
|
|
233
|
+
...onOpenExternalUrl ? [
|
|
234
|
+
openExternalUrlFacet.of((url) => {
|
|
235
|
+
openExternalUrlRef.current?.(url);
|
|
236
|
+
})
|
|
237
|
+
] : [],
|
|
238
|
+
...onCommentOnExcerpt ? [
|
|
239
|
+
commentOnExcerptFacet.of((excerpt, anchor) => {
|
|
240
|
+
onCommentOnExcerptRef.current?.(excerpt, anchor);
|
|
241
|
+
})
|
|
242
|
+
] : [],
|
|
243
|
+
// Wikilink resolution facets stay in both modes so Cmd-click
|
|
244
|
+
// can navigate from Raw view too — only the decorating plugin
|
|
245
|
+
// itself is gated by `decorationsEnabled` below.
|
|
246
|
+
wikilinkFromPathFacet.of(filePath),
|
|
247
|
+
wikilinkTargetsFacet.of(linkTargets ?? /* @__PURE__ */ new Set()),
|
|
248
|
+
...onNavigateToLink ? [navigateToFacet.of(onNavigateToLink)] : [],
|
|
249
|
+
// Cursor model: arrow/shift+arrow → next visible source
|
|
250
|
+
// position, skipping hidden markdown syntax in one step.
|
|
251
|
+
cursorModelKeymap,
|
|
252
|
+
// Backspace / Delete: removes visible content; collapses an
|
|
253
|
+
// emptied styled span (no dangling `****`).
|
|
254
|
+
deleteNormalizerKeymap,
|
|
255
|
+
// Cmd+B / Cmd+I / Cmd+E: toggle bold / italic / inline code.
|
|
256
|
+
formatCommandsKeymap,
|
|
257
|
+
// Cmd+1..3 / Cmd+Shift+7..9: heading levels, lists, blockquote.
|
|
258
|
+
blockCommandsKeymap,
|
|
259
|
+
// Click model: Cmd/Ctrl-click on a link opens it; caret
|
|
260
|
+
// placement never lands inside a hidden marker (snap-to-content).
|
|
261
|
+
clickModel,
|
|
262
|
+
// The editor invariant: the syntax tree covers the whole document, not
|
|
263
|
+
// just what the viewport rendered — widgets, affordances and structural
|
|
264
|
+
// commands anywhere in the note are wrong without it.
|
|
265
|
+
parseToEnd,
|
|
266
|
+
EditorView.updateListener.of((update) => {
|
|
267
|
+
if (!update.docChanged) return;
|
|
268
|
+
if (update.transactions.every((tr) => tr.annotation(programmaticSwap))) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (autosaveTimerRef.current !== null) {
|
|
272
|
+
window.clearTimeout(autosaveTimerRef.current);
|
|
273
|
+
}
|
|
274
|
+
autosaveTimerRef.current = window.setTimeout(() => {
|
|
275
|
+
autosaveTimerRef.current = null;
|
|
276
|
+
const body = update.view.state.doc.toString();
|
|
277
|
+
bodyRef.current = body;
|
|
278
|
+
const full = serializeMarkdown({
|
|
279
|
+
frontmatter: frontmatterRef.current,
|
|
280
|
+
body
|
|
281
|
+
});
|
|
282
|
+
const hash = hashString(full);
|
|
283
|
+
if (hash === lastEmittedHashRef.current) return;
|
|
284
|
+
lastEmittedHashRef.current = hash;
|
|
285
|
+
if (currentFileRef.current !== void 0) {
|
|
286
|
+
syncedHashRef.current.set(currentFileRef.current, hash);
|
|
287
|
+
}
|
|
288
|
+
onChangeRef.current(full, []);
|
|
289
|
+
}, AUTOSAVE_DEBOUNCE_MS);
|
|
290
|
+
})
|
|
291
|
+
];
|
|
292
|
+
if (decorationsEnabled) {
|
|
293
|
+
base.push(markdownDecorationsPlugin);
|
|
294
|
+
}
|
|
295
|
+
const merged = mergeExtensions([
|
|
296
|
+
...decorationsEnabled ? [
|
|
297
|
+
wikilinkExtension,
|
|
298
|
+
highlightExtension,
|
|
299
|
+
footnoteExtension,
|
|
300
|
+
mathExtension,
|
|
301
|
+
mermaidExtension,
|
|
302
|
+
tableExtension()
|
|
303
|
+
] : [],
|
|
304
|
+
...hostExtensionsRef.current ?? []
|
|
305
|
+
]);
|
|
306
|
+
base.push(...merged.extensions);
|
|
307
|
+
toolbarContributionsRef.current = merged.toolbar;
|
|
308
|
+
return base;
|
|
309
|
+
}
|
|
310
|
+
const buildExtensionsRef = useRef(buildExtensions);
|
|
311
|
+
useLayoutEffect(function syncBuildExtensionsRef() {
|
|
312
|
+
buildExtensionsRef.current = buildExtensions;
|
|
313
|
+
});
|
|
314
|
+
useLayoutEffect(function mountEditorView() {
|
|
315
|
+
const host = hostRef.current;
|
|
316
|
+
if (!host) return;
|
|
317
|
+
const initial = EditorState.create({
|
|
318
|
+
doc: bodyRef.current,
|
|
319
|
+
extensions: buildExtensionsRef.current()
|
|
320
|
+
});
|
|
321
|
+
if (currentFileRef.current !== void 0) {
|
|
322
|
+
editorStatesRef.current.set(currentFileRef.current, initial);
|
|
323
|
+
syncedHashRef.current.set(currentFileRef.current, lastEmittedHashRef.current);
|
|
324
|
+
}
|
|
325
|
+
const view = new EditorView({ state: initial, parent: host });
|
|
326
|
+
viewRef.current = view;
|
|
327
|
+
setViewForToolbar(view);
|
|
328
|
+
return function teardownEditorView() {
|
|
329
|
+
bodyRef.current = view.state.doc.toString();
|
|
330
|
+
view.destroy();
|
|
331
|
+
viewRef.current = null;
|
|
332
|
+
setViewForToolbar(null);
|
|
333
|
+
};
|
|
334
|
+
}, []);
|
|
335
|
+
useEffect(function syncEditorToActiveFile() {
|
|
336
|
+
const view = viewRef.current;
|
|
337
|
+
if (!view) return;
|
|
338
|
+
const incomingHash = hashString(value);
|
|
339
|
+
const switchingFile = currentFileRef.current !== filePath;
|
|
340
|
+
if (!switchingFile) {
|
|
341
|
+
if (incomingHash === lastEmittedHashRef.current) return;
|
|
342
|
+
const parsed2 = parseFrontmatter(value);
|
|
343
|
+
frontmatterRef.current = parsed2.frontmatter;
|
|
344
|
+
bodyRef.current = parsed2.body;
|
|
345
|
+
lastEmittedHashRef.current = incomingHash;
|
|
346
|
+
view.dispatch({
|
|
347
|
+
changes: { from: 0, to: view.state.doc.length, insert: parsed2.body },
|
|
348
|
+
annotations: programmaticSwap.of(true)
|
|
349
|
+
});
|
|
350
|
+
if (filePath !== void 0) syncedHashRef.current.set(filePath, incomingHash);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const prev = currentFileRef.current;
|
|
354
|
+
if (autosaveTimerRef.current !== null) {
|
|
355
|
+
window.clearTimeout(autosaveTimerRef.current);
|
|
356
|
+
autosaveTimerRef.current = null;
|
|
357
|
+
const outgoingBody = view.state.doc.toString();
|
|
358
|
+
const outgoingFull = serializeMarkdown({
|
|
359
|
+
frontmatter: frontmatterRef.current,
|
|
360
|
+
body: outgoingBody
|
|
361
|
+
});
|
|
362
|
+
const outgoingHash = hashString(outgoingFull);
|
|
363
|
+
if (outgoingHash !== lastEmittedHashRef.current) {
|
|
364
|
+
if (prev !== void 0) syncedHashRef.current.set(prev, outgoingHash);
|
|
365
|
+
onChangeRef.current(outgoingFull, []);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (prev !== void 0) editorStatesRef.current.set(prev, view.state);
|
|
369
|
+
const parsed = parseFrontmatter(value);
|
|
370
|
+
frontmatterRef.current = parsed.frontmatter;
|
|
371
|
+
bodyRef.current = parsed.body;
|
|
372
|
+
lastEmittedHashRef.current = incomingHash;
|
|
373
|
+
currentFileRef.current = filePath;
|
|
374
|
+
const key = filePath ?? "";
|
|
375
|
+
const cached = editorStatesRef.current.get(key);
|
|
376
|
+
const cachedHash = syncedHashRef.current.get(key);
|
|
377
|
+
if (cached && cachedHash === incomingHash) {
|
|
378
|
+
view.setState(cached);
|
|
379
|
+
} else {
|
|
380
|
+
const state = EditorState.create({
|
|
381
|
+
doc: parsed.body,
|
|
382
|
+
extensions: buildExtensionsRef.current()
|
|
383
|
+
});
|
|
384
|
+
editorStatesRef.current.set(key, state);
|
|
385
|
+
syncedHashRef.current.set(key, incomingHash);
|
|
386
|
+
view.setState(state);
|
|
387
|
+
}
|
|
388
|
+
requestAnimationFrame(() => onAfterContentSwapRef.current?.());
|
|
389
|
+
}, [filePath, value]);
|
|
390
|
+
useEffect(function rebuildOnModeChange() {
|
|
391
|
+
const view = viewRef.current;
|
|
392
|
+
if (!view) return;
|
|
393
|
+
if (modeInitializedRef.current === decorationsEnabled) return;
|
|
394
|
+
modeInitializedRef.current = decorationsEnabled;
|
|
395
|
+
const liveBody = view.state.doc.toString();
|
|
396
|
+
editorStatesRef.current.clear();
|
|
397
|
+
syncedHashRef.current.clear();
|
|
398
|
+
const state = EditorState.create({
|
|
399
|
+
doc: liveBody,
|
|
400
|
+
extensions: buildExtensionsRef.current()
|
|
401
|
+
});
|
|
402
|
+
if (currentFileRef.current !== void 0) {
|
|
403
|
+
editorStatesRef.current.set(currentFileRef.current, state);
|
|
404
|
+
syncedHashRef.current.set(currentFileRef.current, lastEmittedHashRef.current);
|
|
405
|
+
}
|
|
406
|
+
view.setState(state);
|
|
407
|
+
}, [decorationsEnabled]);
|
|
408
|
+
const flushPendingToBuffer = useCallback(function flushPendingToBuffer2() {
|
|
409
|
+
const view = viewRef.current;
|
|
410
|
+
if (!view) return;
|
|
411
|
+
if (autosaveTimerRef.current !== null) {
|
|
412
|
+
window.clearTimeout(autosaveTimerRef.current);
|
|
413
|
+
autosaveTimerRef.current = null;
|
|
414
|
+
}
|
|
415
|
+
const body = view.state.doc.toString();
|
|
416
|
+
bodyRef.current = body;
|
|
417
|
+
const full = serializeMarkdown({ frontmatter: frontmatterRef.current, body });
|
|
418
|
+
const hash = hashString(full);
|
|
419
|
+
if (hash === lastEmittedHashRef.current) return;
|
|
420
|
+
lastEmittedHashRef.current = hash;
|
|
421
|
+
onChangeRef.current(full, []);
|
|
422
|
+
}, []);
|
|
423
|
+
useEffect(function registerFlushBridge() {
|
|
424
|
+
onFlushReadyRef.current?.(flushPendingToBuffer);
|
|
425
|
+
return function unregisterFlushBridge() {
|
|
426
|
+
onFlushReadyRef.current?.(null);
|
|
427
|
+
};
|
|
428
|
+
}, [flushPendingToBuffer]);
|
|
429
|
+
useEffect(function cancelPendingAutosaveOnUnmount() {
|
|
430
|
+
return function clearAutosaveTimer() {
|
|
431
|
+
if (autosaveTimerRef.current !== null) {
|
|
432
|
+
window.clearTimeout(autosaveTimerRef.current);
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
}, []);
|
|
436
|
+
useEffect(
|
|
437
|
+
function trackSelectionForCommentBubble() {
|
|
438
|
+
const view = viewForToolbar;
|
|
439
|
+
if (!view) return;
|
|
440
|
+
const refresh = () => {
|
|
441
|
+
const main = view.state.selection.main;
|
|
442
|
+
if (main.empty) {
|
|
443
|
+
setBubbleSelection(null);
|
|
444
|
+
} else {
|
|
445
|
+
setBubbleSelection({
|
|
446
|
+
range: byteRangeOf(view.state, main.from, main.to),
|
|
447
|
+
text: view.state.sliceDoc(main.from, main.to)
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
refresh();
|
|
452
|
+
return onEditorUpdate(view, (update) => {
|
|
453
|
+
if (update.docChanged || update.selectionSet) refresh();
|
|
454
|
+
});
|
|
455
|
+
},
|
|
456
|
+
[viewForToolbar]
|
|
457
|
+
);
|
|
458
|
+
const dismissSelection = useCallback(() => {
|
|
459
|
+
const view = viewRef.current;
|
|
460
|
+
if (!view) return;
|
|
461
|
+
const head = view.state.selection.main.head;
|
|
462
|
+
view.dispatch({ selection: EditorSelection.cursor(head) });
|
|
463
|
+
}, []);
|
|
464
|
+
const toolbarNode = useMemo(
|
|
465
|
+
() => viewForToolbar && toolbar ? toolbar({ view: viewForToolbar, contributions: toolbarContributionsRef.current }) : null,
|
|
466
|
+
[viewForToolbar, toolbar]
|
|
467
|
+
);
|
|
468
|
+
const selectionNode = useMemo(
|
|
469
|
+
() => selectionActions ? selectionActions({ selection: bubbleSelection, dismiss: dismissSelection }) : null,
|
|
470
|
+
[selectionActions, bubbleSelection, dismissSelection]
|
|
471
|
+
);
|
|
472
|
+
return /* @__PURE__ */ jsxs("div", { className: "tiptap-editor cm-editor-host", children: [
|
|
473
|
+
toolbarNode,
|
|
474
|
+
/* @__PURE__ */ jsx("div", { className: "tiptap-editor__scroll cm-editor-host__scroll", ref: hostRef }),
|
|
475
|
+
selectionNode
|
|
476
|
+
] });
|
|
477
|
+
}
|
|
478
|
+
const CodeMirrorMarkdownEditor = memo(CodeMirrorMarkdownEditorInner);
|
|
479
|
+
export {
|
|
480
|
+
CodeMirrorMarkdownEditor
|
|
481
|
+
};
|
|
482
|
+
//# sourceMappingURL=CodeMirrorMarkdownEditor.js.map
|