@latentic/live-markdown 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -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 +15 -0
- package/dist/codemirror/math/mathWidget.js +36 -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 +35 -880
- package/dist/index.js +128 -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
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import "../../chunk-V6TY7KAL.js";
|
|
2
|
+
import { findClusterBreak } from "@codemirror/state";
|
|
3
|
+
import { markdownDecorationsPlugin } from "../core/plugin.js";
|
|
4
|
+
import { tableField } from "../table/tableField.js";
|
|
5
|
+
function containingAtomic(view, p) {
|
|
6
|
+
let found = null;
|
|
7
|
+
const scan = (set) => {
|
|
8
|
+
if (found || !set) return;
|
|
9
|
+
set.between(p, p, (from, to) => {
|
|
10
|
+
if (from < p && p < to) {
|
|
11
|
+
found = { from, to };
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
scan(view.plugin(markdownDecorationsPlugin)?.atomic);
|
|
17
|
+
scan(view.state.field(tableField, false));
|
|
18
|
+
return found;
|
|
19
|
+
}
|
|
20
|
+
function tableEdgeAt(view, p, dir) {
|
|
21
|
+
let found = null;
|
|
22
|
+
view.state.field(tableField, false)?.between(p, p, (from, to) => {
|
|
23
|
+
if (dir === "backward" ? to === p : from === p) {
|
|
24
|
+
found = { from, to };
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return found;
|
|
29
|
+
}
|
|
30
|
+
function atomicTouching(view, p, side) {
|
|
31
|
+
let found = null;
|
|
32
|
+
const scan = (set) => {
|
|
33
|
+
if (found || !set) return;
|
|
34
|
+
set.between(p, p, (from, to) => {
|
|
35
|
+
if (from === to) return;
|
|
36
|
+
if (side === "before" ? to === p : from === p) {
|
|
37
|
+
found = { from, to };
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
scan(view.plugin(markdownDecorationsPlugin)?.atomic);
|
|
43
|
+
scan(view.state.field(tableField, false));
|
|
44
|
+
return found;
|
|
45
|
+
}
|
|
46
|
+
function visibleCharBefore(view, pos) {
|
|
47
|
+
let e = pos;
|
|
48
|
+
for (; ; ) {
|
|
49
|
+
const range = containingAtomic(view, e) ?? atomicTouching(view, e, "before");
|
|
50
|
+
if (!range) break;
|
|
51
|
+
e = range.from;
|
|
52
|
+
}
|
|
53
|
+
if (e <= 0) return null;
|
|
54
|
+
const line = view.state.doc.lineAt(e);
|
|
55
|
+
if (e === line.from) return { from: e - 1, to: e };
|
|
56
|
+
return { from: line.from + findClusterBreak(line.text, e - line.from, false), to: e };
|
|
57
|
+
}
|
|
58
|
+
function visibleCharAfter(view, pos) {
|
|
59
|
+
const docLen = view.state.doc.length;
|
|
60
|
+
let s = pos;
|
|
61
|
+
for (; ; ) {
|
|
62
|
+
const range = containingAtomic(view, s) ?? atomicTouching(view, s, "after");
|
|
63
|
+
if (!range) break;
|
|
64
|
+
s = range.to;
|
|
65
|
+
}
|
|
66
|
+
if (s >= docLen) return null;
|
|
67
|
+
const line = view.state.doc.lineAt(s);
|
|
68
|
+
if (s === line.to) return { from: s, to: s + 1 };
|
|
69
|
+
return { from: s, to: line.from + findClusterBreak(line.text, s - line.from, true) };
|
|
70
|
+
}
|
|
71
|
+
function previousVisiblePosition(view, pos) {
|
|
72
|
+
if (pos <= 0) return 0;
|
|
73
|
+
let p = pos - 1;
|
|
74
|
+
while (p > 0) {
|
|
75
|
+
const range = containingAtomic(view, p) ?? tableEdgeAt(view, p, "backward");
|
|
76
|
+
if (range) p = range.from - 1;
|
|
77
|
+
else return p;
|
|
78
|
+
}
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
function nextVisiblePosition(view, pos) {
|
|
82
|
+
const docLen = view.state.doc.length;
|
|
83
|
+
if (pos >= docLen) return docLen;
|
|
84
|
+
let p = pos + 1;
|
|
85
|
+
while (p < docLen) {
|
|
86
|
+
const range = containingAtomic(view, p) ?? tableEdgeAt(view, p, "forward");
|
|
87
|
+
if (range) p = range.to + 1;
|
|
88
|
+
else return p;
|
|
89
|
+
}
|
|
90
|
+
return docLen;
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
nextVisiblePosition,
|
|
94
|
+
previousVisiblePosition,
|
|
95
|
+
visibleCharAfter,
|
|
96
|
+
visibleCharBefore
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=visiblePosition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/codemirror/interaction/visiblePosition.ts"],"sourcesContent":["/**\n * Visible-position navigation across hidden, atomic ranges.\n *\n * In Rich Edit Mode the caret may never land *inside* an atomic range — a\n * hidden inline marker (`**`, `[`, `` ` ``, …) or a whole table's `| … |` block\n * source. These helpers return the next / previous position that sits outside\n * every atomic range, so the arrow keys and the delete normalizer step *over* a\n * table the same way they step over an inline marker instead of walking into\n * its hidden source.\n *\n * Two atomic sources are consulted together: the decoration plugin's inline\n * ranges and the table field's block ranges. (The table also registers with\n * CM6's `EditorView.atomicRanges` facet, but that only governs CM6's *default*\n * commands — our `Prec.high` arrow/delete handlers run instead, so they have to\n * consult the table themselves or they march straight through the grid source.)\n *\n * \"Inside\" is strict: a position at a range's `from` or `to` is a boundary the\n * caret may rest on, not inside it.\n */\n\nimport { findClusterBreak } from \"@codemirror/state\";\nimport { type EditorView } from \"@codemirror/view\";\n\nimport { markdownDecorationsPlugin } from \"../core/plugin\";\nimport { tableField } from \"../table/tableField\";\n\ntype RangeQueryable = {\n between(from: number, to: number, f: (from: number, to: number) => void | false): void;\n};\n\n/** The atomic range strictly containing `p` (inline marker or table), or null. */\nfunction containingAtomic(view: EditorView, p: number): { from: number; to: number } | null {\n let found: { from: number; to: number } | null = null;\n const scan = (set: RangeQueryable | null | undefined): void => {\n if (found || !set) return;\n set.between(p, p, (from, to) => {\n if (from < p && p < to) {\n found = { from, to };\n return false;\n }\n });\n };\n scan(view.plugin(markdownDecorationsPlugin)?.atomic);\n scan(view.state.field(tableField, false));\n return found;\n}\n\n/**\n * A table whose far edge sits exactly at `p` in the direction of travel — its\n * `to` when stepping backward, its `from` when stepping forward. Block widgets\n * paint position `to` on the blank line just past the table (and `from` on the\n * line just before), so resting the caret there looks identical to the adjacent\n * line — a press that seems to do nothing. Treat the edge like the inside of the\n * table and step over the whole grid, so the caret moves through it in one key.\n */\nfunction tableEdgeAt(\n view: EditorView,\n p: number,\n dir: \"backward\" | \"forward\",\n): { from: number; to: number } | null {\n let found: { from: number; to: number } | null = null;\n view.state.field(tableField, false)?.between(p, p, (from, to) => {\n if (dir === \"backward\" ? to === p : from === p) {\n found = { from, to };\n return false;\n }\n });\n return found;\n}\n\n/** The atomic range whose far edge sits exactly at `p` on the given side —\n * the trailing edge when looking backward, the leading edge when forward. */\nfunction atomicTouching(\n view: EditorView,\n p: number,\n side: \"before\" | \"after\",\n): { from: number; to: number } | null {\n let found: { from: number; to: number } | null = null;\n const scan = (set: RangeQueryable | null | undefined): void => {\n if (found || !set) return;\n set.between(p, p, (from, to) => {\n if (from === to) return; // zero-length ranges aren't skippable content\n if (side === \"before\" ? to === p : from === p) {\n found = { from, to };\n return false;\n }\n });\n };\n scan(view.plugin(markdownDecorationsPlugin)?.atomic);\n scan(view.state.field(tableField, false));\n return found;\n}\n\n/**\n * The visible grapheme immediately before/after `pos` as a deletable source\n * range, skipping any hidden markers between it and the caret — or null at the\n * document edge. Unlike {@link previousVisiblePosition} (a caret MOTION stop),\n * this never folds a marker into the range: deleting it removes exactly one\n * visible character, so `**Compose**` backspaced from either side of its\n * hidden closing `**` becomes `**Compos**`, never raw `**Compos`. A newline\n * counts as the adjacent char — callers treat that as a line-join.\n */\nexport function visibleCharBefore(\n view: EditorView,\n pos: number,\n): { from: number; to: number } | null {\n let e = pos;\n for (;;) {\n const range = containingAtomic(view, e) ?? atomicTouching(view, e, \"before\");\n if (!range) break;\n e = range.from;\n }\n if (e <= 0) return null;\n const line = view.state.doc.lineAt(e);\n if (e === line.from) return { from: e - 1, to: e };\n return { from: line.from + findClusterBreak(line.text, e - line.from, false), to: e };\n}\n\nexport function visibleCharAfter(\n view: EditorView,\n pos: number,\n): { from: number; to: number } | null {\n const docLen = view.state.doc.length;\n let s = pos;\n for (;;) {\n const range = containingAtomic(view, s) ?? atomicTouching(view, s, \"after\");\n if (!range) break;\n s = range.to;\n }\n if (s >= docLen) return null;\n const line = view.state.doc.lineAt(s);\n if (s === line.to) return { from: s, to: s + 1 };\n return { from: s, to: line.from + findClusterBreak(line.text, s - line.from, true) };\n}\n\nexport function previousVisiblePosition(view: EditorView, pos: number): number {\n if (pos <= 0) return 0;\n let p = pos - 1;\n while (p > 0) {\n const range = containingAtomic(view, p) ?? tableEdgeAt(view, p, \"backward\");\n if (range) p = range.from - 1;\n else return p;\n }\n return 0;\n}\n\nexport function nextVisiblePosition(view: EditorView, pos: number): number {\n const docLen = view.state.doc.length;\n if (pos >= docLen) return docLen;\n let p = pos + 1;\n while (p < docLen) {\n const range = containingAtomic(view, p) ?? tableEdgeAt(view, p, \"forward\");\n if (range) p = range.to + 1;\n else return p;\n }\n return docLen;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { WidgetType, EditorView } from '@codemirror/view';
|
|
2
|
+
import { NodeRule } from '../core/paint.js';
|
|
3
|
+
import '@codemirror/state';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Bullet widget — a real DOM element CM6 places where the hidden
|
|
7
|
+
* `ListMark` (`-` / `*` / `1.`) used to be.
|
|
8
|
+
*
|
|
9
|
+
* Why a widget and not a CSS `::before`:
|
|
10
|
+
* * `::before` is a pseudo-element. It paints in the right spot
|
|
11
|
+
* but is NOT part of CM6's line metric (the requestMeasure
|
|
12
|
+
* cycle reads `offsetTop` / `getBoundingClientRect` on real
|
|
13
|
+
* elements and lines, not pseudo siblings). With `::before` the
|
|
14
|
+
* bullet drifts visually as font size or padding changes, and
|
|
15
|
+
* click coordinates on the bullet column return the wrong byte.
|
|
16
|
+
* * A `WidgetType` rendered via `Decoration.replace({widget})`
|
|
17
|
+
* becomes a real `<span>` in the line — its width, height, and
|
|
18
|
+
* baseline participate in measurement. Click→byte is exact;
|
|
19
|
+
* scroll alignment is exact.
|
|
20
|
+
*
|
|
21
|
+
* Same pattern Zettlr uses for its `BulletWidget` (see
|
|
22
|
+
* `markdown-editor/renderers/render-emphasis.ts`).
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
declare class BulletWidget extends WidgetType {
|
|
26
|
+
/**
|
|
27
|
+
* Eq returns true if two widgets are interchangeable — when CM6
|
|
28
|
+
* reuses the existing DOM instead of replacing it. Bullets are
|
|
29
|
+
* stateless so any two bullet widgets are equivalent.
|
|
30
|
+
*/
|
|
31
|
+
eq(_other: BulletWidget): boolean;
|
|
32
|
+
toDOM(_view: EditorView): HTMLElement;
|
|
33
|
+
/**
|
|
34
|
+
* Widgets can swallow input events; we don't want our bullet to.
|
|
35
|
+
* `ignoreEvent` returning `false` lets the click pass through to
|
|
36
|
+
* the editor, so clicking on the bullet column lands the caret at
|
|
37
|
+
* the start of the list item content.
|
|
38
|
+
*/
|
|
39
|
+
ignoreEvent(): boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Ordered-list marker widget — the counterpart of {@link BulletWidget} for
|
|
43
|
+
* `OrderedList` items. An ordered item's hidden `ListMark` is its number
|
|
44
|
+
* (`1.`, `2.`, …), so unlike a bullet (which swaps `-` for `•`) this renders the
|
|
45
|
+
* marker's own text — otherwise a numbered list would render as bullets.
|
|
46
|
+
*/
|
|
47
|
+
declare class OrderedMarkerWidget extends WidgetType {
|
|
48
|
+
private readonly marker;
|
|
49
|
+
constructor(marker: string);
|
|
50
|
+
/** Carries its number, so CM6 only rebuilds the DOM when the number changes. */
|
|
51
|
+
eq(other: OrderedMarkerWidget): boolean;
|
|
52
|
+
toDOM(_view: EditorView): HTMLElement;
|
|
53
|
+
ignoreEvent(): boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A `-`/`*`/`+`/`1.` list mark → bullet, its number, or (for a task item)
|
|
57
|
+
* nothing beside the checkbox.
|
|
58
|
+
*/
|
|
59
|
+
declare const listMarkRule: NodeRule;
|
|
60
|
+
|
|
61
|
+
export { BulletWidget, OrderedMarkerWidget, listMarkRule };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__publicField
|
|
3
|
+
} from "../../chunk-V6TY7KAL.js";
|
|
4
|
+
import { Decoration, WidgetType } from "@codemirror/view";
|
|
5
|
+
import { none } from "../core/paint.js";
|
|
6
|
+
class BulletWidget extends WidgetType {
|
|
7
|
+
/**
|
|
8
|
+
* Eq returns true if two widgets are interchangeable — when CM6
|
|
9
|
+
* reuses the existing DOM instead of replacing it. Bullets are
|
|
10
|
+
* stateless so any two bullet widgets are equivalent.
|
|
11
|
+
*/
|
|
12
|
+
eq(_other) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
toDOM(_view) {
|
|
16
|
+
const el = document.createElement("span");
|
|
17
|
+
el.className = "cm-bullet-widget";
|
|
18
|
+
el.textContent = "\u2022";
|
|
19
|
+
return el;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Widgets can swallow input events; we don't want our bullet to.
|
|
23
|
+
* `ignoreEvent` returning `false` lets the click pass through to
|
|
24
|
+
* the editor, so clicking on the bullet column lands the caret at
|
|
25
|
+
* the start of the list item content.
|
|
26
|
+
*/
|
|
27
|
+
ignoreEvent() {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
class OrderedMarkerWidget extends WidgetType {
|
|
32
|
+
constructor(marker) {
|
|
33
|
+
super();
|
|
34
|
+
__publicField(this, "marker", marker);
|
|
35
|
+
}
|
|
36
|
+
/** Carries its number, so CM6 only rebuilds the DOM when the number changes. */
|
|
37
|
+
eq(other) {
|
|
38
|
+
return other.marker === this.marker;
|
|
39
|
+
}
|
|
40
|
+
toDOM(_view) {
|
|
41
|
+
const el = document.createElement("span");
|
|
42
|
+
el.className = "cm-bullet-widget cm-ordered-marker";
|
|
43
|
+
el.textContent = this.marker;
|
|
44
|
+
return el;
|
|
45
|
+
}
|
|
46
|
+
ignoreEvent() {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const BULLET_REPLACE = Decoration.replace({ widget: new BulletWidget() });
|
|
51
|
+
const listMarkRule = (ctx) => {
|
|
52
|
+
if (ctx.state.doc.sliceString(ctx.to, ctx.to + 1) !== " ") {
|
|
53
|
+
return none;
|
|
54
|
+
}
|
|
55
|
+
const atomicTo = ctx.to + 1;
|
|
56
|
+
const listItem = ctx.node.parent;
|
|
57
|
+
if (listItem?.getChild("Task")) {
|
|
58
|
+
return { paint: "hide", atomicTo };
|
|
59
|
+
}
|
|
60
|
+
const list = listItem?.parent;
|
|
61
|
+
if (list?.name === "OrderedList") {
|
|
62
|
+
const state = ctx.state;
|
|
63
|
+
const delimiter = state.sliceDoc(ctx.from, ctx.to).replace(/^\d+/, "") || ".";
|
|
64
|
+
const firstMark = list.firstChild?.getChild("ListMark");
|
|
65
|
+
const start = firstMark ? Number.parseInt(state.sliceDoc(firstMark.from, firstMark.to), 10) : 1;
|
|
66
|
+
let offset = 0;
|
|
67
|
+
for (let sibling = listItem?.prevSibling; sibling; sibling = sibling.prevSibling) {
|
|
68
|
+
if (sibling.name === "ListItem") offset += 1;
|
|
69
|
+
}
|
|
70
|
+
const ordinal = (Number.isNaN(start) ? 1 : start) + offset;
|
|
71
|
+
return {
|
|
72
|
+
paint: "widget",
|
|
73
|
+
deco: Decoration.replace({ widget: new OrderedMarkerWidget(`${ordinal}${delimiter}`) }),
|
|
74
|
+
atomicTo
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return { paint: "widget", deco: BULLET_REPLACE, atomicTo };
|
|
78
|
+
};
|
|
79
|
+
export {
|
|
80
|
+
BulletWidget,
|
|
81
|
+
OrderedMarkerWidget,
|
|
82
|
+
listMarkRule
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=bulletWidget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/codemirror/list/bulletWidget.ts"],"sourcesContent":["/**\n * Bullet widget — a real DOM element CM6 places where the hidden\n * `ListMark` (`-` / `*` / `1.`) used to be.\n *\n * Why a widget and not a CSS `::before`:\n * * `::before` is a pseudo-element. It paints in the right spot\n * but is NOT part of CM6's line metric (the requestMeasure\n * cycle reads `offsetTop` / `getBoundingClientRect` on real\n * elements and lines, not pseudo siblings). With `::before` the\n * bullet drifts visually as font size or padding changes, and\n * click coordinates on the bullet column return the wrong byte.\n * * A `WidgetType` rendered via `Decoration.replace({widget})`\n * becomes a real `<span>` in the line — its width, height, and\n * baseline participate in measurement. Click→byte is exact;\n * scroll alignment is exact.\n *\n * Same pattern Zettlr uses for its `BulletWidget` (see\n * `markdown-editor/renderers/render-emphasis.ts`).\n */\n\nimport { Decoration, WidgetType, type EditorView } from \"@codemirror/view\";\n\nimport { type NodeRule, type Paint, none } from \"../core/paint\";\n\nexport class BulletWidget extends WidgetType {\n /**\n * Eq returns true if two widgets are interchangeable — when CM6\n * reuses the existing DOM instead of replacing it. Bullets are\n * stateless so any two bullet widgets are equivalent.\n */\n override eq(_other: BulletWidget): boolean {\n return true;\n }\n\n override toDOM(_view: EditorView): HTMLElement {\n const el = document.createElement(\"span\");\n el.className = \"cm-bullet-widget\";\n el.textContent = \"•\";\n return el;\n }\n\n /**\n * Widgets can swallow input events; we don't want our bullet to.\n * `ignoreEvent` returning `false` lets the click pass through to\n * the editor, so clicking on the bullet column lands the caret at\n * the start of the list item content.\n */\n override ignoreEvent(): boolean {\n return false;\n }\n}\n\n/**\n * Ordered-list marker widget — the counterpart of {@link BulletWidget} for\n * `OrderedList` items. An ordered item's hidden `ListMark` is its number\n * (`1.`, `2.`, …), so unlike a bullet (which swaps `-` for `•`) this renders the\n * marker's own text — otherwise a numbered list would render as bullets.\n */\nexport class OrderedMarkerWidget extends WidgetType {\n constructor(private readonly marker: string) {\n super();\n }\n\n /** Carries its number, so CM6 only rebuilds the DOM when the number changes. */\n override eq(other: OrderedMarkerWidget): boolean {\n return other.marker === this.marker;\n }\n\n override toDOM(_view: EditorView): HTMLElement {\n const el = document.createElement(\"span\");\n el.className = \"cm-bullet-widget cm-ordered-marker\";\n el.textContent = this.marker;\n return el;\n }\n\n override ignoreEvent(): boolean {\n return false;\n }\n}\n\n/* ---------------- The ListMark rule ---------------- */\n\n\n\nconst BULLET_REPLACE = Decoration.replace({ widget: new BulletWidget() });\n\n/**\n * A `-`/`*`/`+`/`1.` list mark → bullet, its number, or (for a task item)\n * nothing beside the checkbox.\n */\nexport const listMarkRule: NodeRule = (ctx): Paint => {\n // A marker renders only once it's COMPLETE — followed by a space. A lone\n // `-` at the end of a line is text the user is still typing; rendering it\n // as a bullet mid-type is the surprise we avoid (CommonMark does count it\n // as an empty item).\n if (ctx.state.doc.sliceString(ctx.to, ctx.to + 1) !== \" \") {\n return none;\n }\n const atomicTo = ctx.to + 1;\n const listItem = ctx.node.parent;\n // A task item's checkbox IS its marker (`ListItem` → `ListMark` + `Task`):\n // hide the list mark rather than drawing a bullet next to the checkbox.\n if (listItem?.getChild(\"Task\")) {\n return { paint: \"hide\", atomicTo };\n }\n // An ordered item renders its number, never a `•`. Renumber on display\n // (CommonMark): start at the first item's number and increment by position,\n // so `1. 1. 1.` shows as `1. 2. 3.`. The source delimiter (`.`/`)`) is kept.\n const list = listItem?.parent;\n if (list?.name === \"OrderedList\") {\n const state = ctx.state;\n const delimiter = state.sliceDoc(ctx.from, ctx.to).replace(/^\\d+/, \"\") || \".\";\n const firstMark = list.firstChild?.getChild(\"ListMark\");\n const start = firstMark\n ? Number.parseInt(state.sliceDoc(firstMark.from, firstMark.to), 10)\n : 1;\n let offset = 0;\n for (let sibling = listItem?.prevSibling; sibling; sibling = sibling.prevSibling) {\n if (sibling.name === \"ListItem\") offset += 1;\n }\n const ordinal = (Number.isNaN(start) ? 1 : start) + offset;\n return {\n paint: \"widget\",\n deco: Decoration.replace({ widget: new OrderedMarkerWidget(`${ordinal}${delimiter}`) }),\n atomicTo,\n };\n }\n return { paint: \"widget\", deco: BULLET_REPLACE, atomicTo };\n};\n"],"mappings":";;;AAoBA,SAAS,YAAY,kBAAmC;AAExD,SAAoC,YAAY;AAEzC,MAAM,qBAAqB,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlC,GAAG,QAA+B;AACzC,WAAO;AAAA,EACT;AAAA,EAES,MAAM,OAAgC;AAC7C,UAAM,KAAK,SAAS,cAAc,MAAM;AACxC,OAAG,YAAY;AACf,OAAG,cAAc;AACjB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQS,cAAuB;AAC9B,WAAO;AAAA,EACT;AACF;AAQO,MAAM,4BAA4B,WAAW;AAAA,EAClD,YAA6B,QAAgB;AAC3C,UAAM;AADqB;AAAA,EAE7B;AAAA;AAAA,EAGS,GAAG,OAAqC;AAC/C,WAAO,MAAM,WAAW,KAAK;AAAA,EAC/B;AAAA,EAES,MAAM,OAAgC;AAC7C,UAAM,KAAK,SAAS,cAAc,MAAM;AACxC,OAAG,YAAY;AACf,OAAG,cAAc,KAAK;AACtB,WAAO;AAAA,EACT;AAAA,EAES,cAAuB;AAC9B,WAAO;AAAA,EACT;AACF;AAMA,MAAM,iBAAiB,WAAW,QAAQ,EAAE,QAAQ,IAAI,aAAa,EAAE,CAAC;AAMjE,MAAM,eAAyB,CAAC,QAAe;AAKpD,MAAI,IAAI,MAAM,IAAI,YAAY,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK;AACzD,WAAO;AAAA,EACT;AACA,QAAM,WAAW,IAAI,KAAK;AAC1B,QAAM,WAAW,IAAI,KAAK;AAG1B,MAAI,UAAU,SAAS,MAAM,GAAG;AAC9B,WAAO,EAAE,OAAO,QAAQ,SAAS;AAAA,EACnC;AAIA,QAAM,OAAO,UAAU;AACvB,MAAI,MAAM,SAAS,eAAe;AAChC,UAAM,QAAQ,IAAI;AAClB,UAAM,YAAY,MAAM,SAAS,IAAI,MAAM,IAAI,EAAE,EAAE,QAAQ,QAAQ,EAAE,KAAK;AAC1E,UAAM,YAAY,KAAK,YAAY,SAAS,UAAU;AACtD,UAAM,QAAQ,YACV,OAAO,SAAS,MAAM,SAAS,UAAU,MAAM,UAAU,EAAE,GAAG,EAAE,IAChE;AACJ,QAAI,SAAS;AACb,aAAS,UAAU,UAAU,aAAa,SAAS,UAAU,QAAQ,aAAa;AAChF,UAAI,QAAQ,SAAS,WAAY,WAAU;AAAA,IAC7C;AACA,UAAM,WAAW,OAAO,MAAM,KAAK,IAAI,IAAI,SAAS;AACpD,WAAO;AAAA,MACL,OAAO;AAAA,MACP,MAAM,WAAW,QAAQ,EAAE,QAAQ,IAAI,oBAAoB,GAAG,OAAO,GAAG,SAAS,EAAE,EAAE,CAAC;AAAA,MACtF;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,OAAO,UAAU,MAAM,gBAAgB,SAAS;AAC3D;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/codemirror/list/index.ts"],"sourcesContent":["/**\n * Lists and tasks: Enter continuation, Tab/Shift-Tab indent, and the\n * bullet / number / checkbox widgets that render the markers.\n */\nexport * from \"./listContinuation\";\nexport * from \"./listIndent\";\n"],"mappings":"AAIA,cAAc;AACd,cAAc;","names":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as _codemirror_state from '@codemirror/state';
|
|
2
|
+
import { Command } from '@codemirror/view';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Tight list continuation on Enter.
|
|
6
|
+
*
|
|
7
|
+
* `@codemirror/lang-markdown`'s stock `insertNewlineContinueMarkup` continues a
|
|
8
|
+
* list when you press Enter, but for any list it considers "non-tight" (loose —
|
|
9
|
+
* because a blank line crept in, or a paragraph lazily continues below the
|
|
10
|
+
* list) it PREPENDS a blank line on every Enter. To the user that reads as the
|
|
11
|
+
* caret "skipping a line": you wanted a new bullet on the very next line and
|
|
12
|
+
* got a gap instead. People editing a rich bullet list expect Enter to always
|
|
13
|
+
* drop the next bullet tight against the current one.
|
|
14
|
+
*
|
|
15
|
+
* This command handles two cases: Enter at the END of a NON-EMPTY, non-task
|
|
16
|
+
* bullet/ordered item — inserting a plain `\n<indent><marker> ` with no blank
|
|
17
|
+
* line, always tight — and Enter at a TASK item's content start, splitting it
|
|
18
|
+
* into an empty unchecked box above and the original item below (#95). Empty
|
|
19
|
+
* items (exit-the-list), task continuation at line end, code blocks,
|
|
20
|
+
* blockquotes, other mid-line splits, and every non-list case return `false`
|
|
21
|
+
* and fall through to the stock markdown / default Enter handlers, so their
|
|
22
|
+
* existing behavior is untouched. Bound at `Prec.highest` so it runs before
|
|
23
|
+
* the markdown keymap's Enter.
|
|
24
|
+
*/
|
|
25
|
+
declare const tightListContinuation: Command;
|
|
26
|
+
declare const tightListKeymap: _codemirror_state.Extension;
|
|
27
|
+
|
|
28
|
+
export { tightListContinuation, tightListKeymap };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import "../../chunk-V6TY7KAL.js";
|
|
2
|
+
import { EditorSelection, Prec } from "@codemirror/state";
|
|
3
|
+
import { keymap } from "@codemirror/view";
|
|
4
|
+
import { lineStructure } from "../core/lineStructure.js";
|
|
5
|
+
import { treeAt } from "../core/treeAt.js";
|
|
6
|
+
const tightListContinuation = (view) => {
|
|
7
|
+
const { state } = view;
|
|
8
|
+
const { main } = state.selection;
|
|
9
|
+
if (!main.empty) return false;
|
|
10
|
+
const line = state.doc.lineAt(main.head);
|
|
11
|
+
const info = lineStructure(state, line);
|
|
12
|
+
if (info.list?.task && !info.inCode && main.head === info.list.markTo && info.list.markTo < line.to) {
|
|
13
|
+
const mark = state.sliceDoc(info.list.markFrom, info.list.markTo);
|
|
14
|
+
const indent2 = state.sliceDoc(line.from, info.list.markFrom);
|
|
15
|
+
const insert2 = `${state.lineBreak}${indent2}${mark}`;
|
|
16
|
+
view.dispatch({
|
|
17
|
+
changes: [
|
|
18
|
+
// Same length as `mark` — the caret math below relies on that.
|
|
19
|
+
{ from: info.list.markFrom, to: info.list.markTo, insert: mark.replace(/\[[xX]\]/, "[ ]") },
|
|
20
|
+
{ from: main.head, insert: insert2 }
|
|
21
|
+
],
|
|
22
|
+
selection: EditorSelection.cursor(main.head + insert2.length),
|
|
23
|
+
scrollIntoView: true,
|
|
24
|
+
userEvent: "input"
|
|
25
|
+
});
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
if (main.head !== line.to) return false;
|
|
29
|
+
const match = /^(\s*)([-*+]|\d+[.)])\s+(\S.*)$/.exec(line.text);
|
|
30
|
+
if (!match) return false;
|
|
31
|
+
const [, indent, marker, content] = match;
|
|
32
|
+
if (/^\[[ xX]\]/.test(content)) return false;
|
|
33
|
+
let inList = false;
|
|
34
|
+
const cursor = treeAt(state, main.head).resolveInner(main.head, -1).cursor();
|
|
35
|
+
do {
|
|
36
|
+
const name = cursor.name;
|
|
37
|
+
if (name === "ListItem" || name === "BulletList" || name === "OrderedList") {
|
|
38
|
+
inList = true;
|
|
39
|
+
}
|
|
40
|
+
if (/Code/.test(name)) return false;
|
|
41
|
+
} while (cursor.parent());
|
|
42
|
+
if (!inList) return false;
|
|
43
|
+
const ordered = /^(\d+)([.)])$/.exec(marker);
|
|
44
|
+
const nextMarker = ordered ? `${parseInt(ordered[1], 10) + 1}${ordered[2]}` : marker;
|
|
45
|
+
const insert = `${state.lineBreak}${indent}${nextMarker} `;
|
|
46
|
+
view.dispatch({
|
|
47
|
+
changes: { from: main.head, insert },
|
|
48
|
+
selection: EditorSelection.cursor(main.head + insert.length),
|
|
49
|
+
scrollIntoView: true,
|
|
50
|
+
userEvent: "input"
|
|
51
|
+
});
|
|
52
|
+
return true;
|
|
53
|
+
};
|
|
54
|
+
const tightListKeymap = Prec.highest(
|
|
55
|
+
keymap.of([{ key: "Enter", run: tightListContinuation }])
|
|
56
|
+
);
|
|
57
|
+
export {
|
|
58
|
+
tightListContinuation,
|
|
59
|
+
tightListKeymap
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=listContinuation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/codemirror/list/listContinuation.ts"],"sourcesContent":["import { EditorSelection, Prec } from \"@codemirror/state\";\nimport { keymap, type Command } from \"@codemirror/view\";\n\nimport { lineStructure } from \"../core/lineStructure\";\nimport { treeAt } from \"../core/treeAt\";\n\n/**\n * Tight list continuation on Enter.\n *\n * `@codemirror/lang-markdown`'s stock `insertNewlineContinueMarkup` continues a\n * list when you press Enter, but for any list it considers \"non-tight\" (loose —\n * because a blank line crept in, or a paragraph lazily continues below the\n * list) it PREPENDS a blank line on every Enter. To the user that reads as the\n * caret \"skipping a line\": you wanted a new bullet on the very next line and\n * got a gap instead. People editing a rich bullet list expect Enter to always\n * drop the next bullet tight against the current one.\n *\n * This command handles two cases: Enter at the END of a NON-EMPTY, non-task\n * bullet/ordered item — inserting a plain `\\n<indent><marker> ` with no blank\n * line, always tight — and Enter at a TASK item's content start, splitting it\n * into an empty unchecked box above and the original item below (#95). Empty\n * items (exit-the-list), task continuation at line end, code blocks,\n * blockquotes, other mid-line splits, and every non-list case return `false`\n * and fall through to the stock markdown / default Enter handlers, so their\n * existing behavior is untouched. Bound at `Prec.highest` so it runs before\n * the markdown keymap's Enter.\n */\nexport const tightListContinuation: Command = (view) => {\n const { state } = view;\n const { main } = state.selection;\n if (!main.empty) return false;\n const line = state.doc.lineAt(main.head);\n\n // Task-item split at the content start (#95). The stock handler leaves the\n // remaining empty item spelled `- [ ]` — WITHOUT the trailing space — and\n // the grammar reads that as a bullet whose text is a literal `[ ]`, so the\n // checkbox markdown shows raw. Emit the split ourselves: the current line\n // keeps an empty UNCHECKED box (`- [ ] `, space intact), the text moves to\n // a new item that keeps the original marker and checked state.\n const info = lineStructure(state, line);\n if (\n info.list?.task &&\n !info.inCode &&\n main.head === info.list.markTo &&\n info.list.markTo < line.to\n ) {\n const mark = state.sliceDoc(info.list.markFrom, info.list.markTo);\n const indent = state.sliceDoc(line.from, info.list.markFrom);\n const insert = `${state.lineBreak}${indent}${mark}`;\n view.dispatch({\n changes: [\n // Same length as `mark` — the caret math below relies on that.\n { from: info.list.markFrom, to: info.list.markTo, insert: mark.replace(/\\[[xX]\\]/, \"[ ]\") },\n { from: main.head, insert },\n ],\n selection: EditorSelection.cursor(main.head + insert.length),\n scrollIntoView: true,\n userEvent: \"input\",\n });\n return true;\n }\n\n // Only when continuing from the very end of the line — not splitting mid-item.\n if (main.head !== line.to) return false;\n\n const match = /^(\\s*)([-*+]|\\d+[.)])\\s+(\\S.*)$/.exec(line.text);\n if (!match) return false; // empty item or not a list line → let the stock handler decide\n const [, indent, marker, content] = match;\n if (/^\\[[ xX]\\]/.test(content)) return false; // task item → stock handler keeps the checkbox\n\n // Confirm we're genuinely inside a list and NOT a code block (a `- x` line\n // inside a fenced block matches the regex but must not be auto-continued).\n let inList = false;\n const cursor = treeAt(state, main.head).resolveInner(main.head, -1).cursor();\n do {\n const name = cursor.name;\n if (name === \"ListItem\" || name === \"BulletList\" || name === \"OrderedList\") {\n inList = true;\n }\n if (/Code/.test(name)) return false;\n } while (cursor.parent());\n if (!inList) return false;\n\n const ordered = /^(\\d+)([.)])$/.exec(marker);\n const nextMarker = ordered ? `${parseInt(ordered[1], 10) + 1}${ordered[2]}` : marker;\n const insert = `${state.lineBreak}${indent}${nextMarker} `;\n view.dispatch({\n changes: { from: main.head, insert },\n selection: EditorSelection.cursor(main.head + insert.length),\n scrollIntoView: true,\n userEvent: \"input\",\n });\n return true;\n};\n\nexport const tightListKeymap = Prec.highest(\n keymap.of([{ key: \"Enter\", run: tightListContinuation }]),\n);\n"],"mappings":";AAAA,SAAS,iBAAiB,YAAY;AACtC,SAAS,cAA4B;AAErC,SAAS,qBAAqB;AAC9B,SAAS,cAAc;AAuBhB,MAAM,wBAAiC,CAAC,SAAS;AACtD,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,EAAE,KAAK,IAAI,MAAM;AACvB,MAAI,CAAC,KAAK,MAAO,QAAO;AACxB,QAAM,OAAO,MAAM,IAAI,OAAO,KAAK,IAAI;AAQvC,QAAM,OAAO,cAAc,OAAO,IAAI;AACtC,MACE,KAAK,MAAM,QACX,CAAC,KAAK,UACN,KAAK,SAAS,KAAK,KAAK,UACxB,KAAK,KAAK,SAAS,KAAK,IACxB;AACA,UAAM,OAAO,MAAM,SAAS,KAAK,KAAK,UAAU,KAAK,KAAK,MAAM;AAChE,UAAMA,UAAS,MAAM,SAAS,KAAK,MAAM,KAAK,KAAK,QAAQ;AAC3D,UAAMC,UAAS,GAAG,MAAM,SAAS,GAAGD,OAAM,GAAG,IAAI;AACjD,SAAK,SAAS;AAAA,MACZ,SAAS;AAAA;AAAA,QAEP,EAAE,MAAM,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,QAAQ,QAAQ,KAAK,QAAQ,YAAY,KAAK,EAAE;AAAA,QAC1F,EAAE,MAAM,KAAK,MAAM,QAAAC,QAAO;AAAA,MAC5B;AAAA,MACA,WAAW,gBAAgB,OAAO,KAAK,OAAOA,QAAO,MAAM;AAAA,MAC3D,gBAAgB;AAAA,MAChB,WAAW;AAAA,IACb,CAAC;AACD,WAAO;AAAA,EACT;AAGA,MAAI,KAAK,SAAS,KAAK,GAAI,QAAO;AAElC,QAAM,QAAQ,kCAAkC,KAAK,KAAK,IAAI;AAC9D,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,CAAC,EAAE,QAAQ,QAAQ,OAAO,IAAI;AACpC,MAAI,aAAa,KAAK,OAAO,EAAG,QAAO;AAIvC,MAAI,SAAS;AACb,QAAM,SAAS,OAAO,OAAO,KAAK,IAAI,EAAE,aAAa,KAAK,MAAM,EAAE,EAAE,OAAO;AAC3E,KAAG;AACD,UAAM,OAAO,OAAO;AACpB,QAAI,SAAS,cAAc,SAAS,gBAAgB,SAAS,eAAe;AAC1E,eAAS;AAAA,IACX;AACA,QAAI,OAAO,KAAK,IAAI,EAAG,QAAO;AAAA,EAChC,SAAS,OAAO,OAAO;AACvB,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,UAAU,gBAAgB,KAAK,MAAM;AAC3C,QAAM,aAAa,UAAU,GAAG,SAAS,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC,KAAK;AAC9E,QAAM,SAAS,GAAG,MAAM,SAAS,GAAG,MAAM,GAAG,UAAU;AACvD,OAAK,SAAS;AAAA,IACZ,SAAS,EAAE,MAAM,KAAK,MAAM,OAAO;AAAA,IACnC,WAAW,gBAAgB,OAAO,KAAK,OAAO,OAAO,MAAM;AAAA,IAC3D,gBAAgB;AAAA,IAChB,WAAW;AAAA,EACb,CAAC;AACD,SAAO;AACT;AAEO,MAAM,kBAAkB,KAAK;AAAA,EAClC,OAAO,GAAG,CAAC,EAAE,KAAK,SAAS,KAAK,sBAAsB,CAAC,CAAC;AAC1D;","names":["indent","insert"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as _codemirror_state from '@codemirror/state';
|
|
2
|
+
import { Command } from '@codemirror/view';
|
|
3
|
+
|
|
4
|
+
declare const indentListItem: Command;
|
|
5
|
+
declare const outdentListItem: Command;
|
|
6
|
+
declare const listIndentKeymap: _codemirror_state.Extension;
|
|
7
|
+
|
|
8
|
+
export { indentListItem, listIndentKeymap, outdentListItem };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import "../../chunk-V6TY7KAL.js";
|
|
2
|
+
import { Prec } from "@codemirror/state";
|
|
3
|
+
import { keymap } from "@codemirror/view";
|
|
4
|
+
import { treeAt } from "../core/treeAt.js";
|
|
5
|
+
const LIST_LINE = /^(\s*)([-*+] |\d+[.)] )/;
|
|
6
|
+
function listMarker(text) {
|
|
7
|
+
const m = LIST_LINE.exec(text);
|
|
8
|
+
if (!m) return null;
|
|
9
|
+
return { indent: m[1].length, markerWidth: m[2].length, ordered: /\d/.test(m[2]) };
|
|
10
|
+
}
|
|
11
|
+
function inListContext(state, pos) {
|
|
12
|
+
if (!listMarker(state.doc.lineAt(pos).text)) return false;
|
|
13
|
+
const cursor = treeAt(state, pos).resolveInner(pos, -1).cursor();
|
|
14
|
+
do {
|
|
15
|
+
if (/Code/.test(cursor.name)) return false;
|
|
16
|
+
} while (cursor.parent());
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
function nestingParent(state, lineNo, indent) {
|
|
20
|
+
for (let n = lineNo - 1; n >= 1; n--) {
|
|
21
|
+
const text = state.doc.line(n).text;
|
|
22
|
+
if (text.trim() === "") continue;
|
|
23
|
+
const info = listMarker(text);
|
|
24
|
+
if (!info) return null;
|
|
25
|
+
if (info.indent === indent) return info;
|
|
26
|
+
if (info.indent < indent) return null;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
function outdentTarget(state, lineNo, indent) {
|
|
31
|
+
for (let n = lineNo - 1; n >= 1; n--) {
|
|
32
|
+
const text = state.doc.line(n).text;
|
|
33
|
+
if (text.trim() === "") continue;
|
|
34
|
+
const info = listMarker(text);
|
|
35
|
+
if (!info) return null;
|
|
36
|
+
if (info.indent < indent) return info;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
function changeForLine(state, lineNo, dir) {
|
|
41
|
+
const line = state.doc.line(lineNo);
|
|
42
|
+
const info = listMarker(line.text);
|
|
43
|
+
if (!info) return null;
|
|
44
|
+
if (dir === "indent") {
|
|
45
|
+
const parent = nestingParent(state, lineNo, info.indent);
|
|
46
|
+
if (!parent) return null;
|
|
47
|
+
const newIndent2 = parent.indent + parent.markerWidth;
|
|
48
|
+
if (newIndent2 <= info.indent) return null;
|
|
49
|
+
if (info.ordered) {
|
|
50
|
+
const digits = /^\d+/.exec(line.text.slice(info.indent))?.[0] ?? "";
|
|
51
|
+
return {
|
|
52
|
+
from: line.from,
|
|
53
|
+
to: line.from + info.indent + digits.length,
|
|
54
|
+
insert: " ".repeat(newIndent2) + "1"
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return { from: line.from, insert: " ".repeat(newIndent2 - info.indent) };
|
|
58
|
+
}
|
|
59
|
+
if (info.indent === 0) return null;
|
|
60
|
+
const newIndent = outdentTarget(state, lineNo, info.indent)?.indent ?? 0;
|
|
61
|
+
return { from: line.from, to: line.from + (info.indent - newIndent), insert: "" };
|
|
62
|
+
}
|
|
63
|
+
function changeListIndent(view, dir) {
|
|
64
|
+
const { state } = view;
|
|
65
|
+
const range = state.selection.main;
|
|
66
|
+
if (!inListContext(state, range.from)) return false;
|
|
67
|
+
const changes = [];
|
|
68
|
+
const firstLine = state.doc.lineAt(range.from).number;
|
|
69
|
+
const lastLine = state.doc.lineAt(range.to).number;
|
|
70
|
+
for (let n = firstLine; n <= lastLine; n++) {
|
|
71
|
+
const change = changeForLine(state, n, dir);
|
|
72
|
+
if (change) changes.push(change);
|
|
73
|
+
}
|
|
74
|
+
if (changes.length === 0) return true;
|
|
75
|
+
view.dispatch({
|
|
76
|
+
changes,
|
|
77
|
+
scrollIntoView: true,
|
|
78
|
+
userEvent: dir === "indent" ? "input.indent" : "delete.dedent"
|
|
79
|
+
});
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
const indentListItem = (view) => changeListIndent(view, "indent");
|
|
83
|
+
const outdentListItem = (view) => changeListIndent(view, "outdent");
|
|
84
|
+
const listIndentKeymap = Prec.highest(
|
|
85
|
+
keymap.of([
|
|
86
|
+
{ key: "Tab", run: indentListItem },
|
|
87
|
+
{ key: "Shift-Tab", run: outdentListItem }
|
|
88
|
+
])
|
|
89
|
+
);
|
|
90
|
+
export {
|
|
91
|
+
indentListItem,
|
|
92
|
+
listIndentKeymap,
|
|
93
|
+
outdentListItem
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=listIndent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/codemirror/list/listIndent.ts"],"sourcesContent":["/**\n * List indent / outdent on Tab / Shift-Tab.\n *\n * Tab nests the current list item one level under its preceding sibling;\n * Shift-Tab promotes it one level. The step is the *parent's marker width*\n * (3 columns under `1. `, 2 under `- `), never a fixed unit — that's what lets\n * CommonMark parse the result as a real sublist; a naive two-space indent\n * mis-nests ordered items. A freshly nested ordered item is renumbered to `1`\n * so its sublist renders from one (the decoration plugin renumbers the rest by\n * position).\n *\n * Both commands are gated on the caret sitting in a list line, so anywhere else\n * — prose, a fenced code block — they return false and Tab keeps its normal\n * behaviour rather than hijacking focus or inserting a stray indent.\n */\n\nimport { type ChangeSpec, type EditorState, Prec } from \"@codemirror/state\";\nimport { type Command, EditorView, keymap } from \"@codemirror/view\";\nimport { treeAt } from \"../core/treeAt\";\n\ninterface ListMarker {\n /** Leading-space count. */\n indent: number;\n /** Marker plus its one trailing space: `- ` → 2, `12. ` → 4. */\n markerWidth: number;\n ordered: boolean;\n}\n\nconst LIST_LINE = /^(\\s*)([-*+] |\\d+[.)] )/;\n\nfunction listMarker(text: string): ListMarker | null {\n const m = LIST_LINE.exec(text);\n if (!m) return null;\n return { indent: m[1].length, markerWidth: m[2].length, ordered: /\\d/.test(m[2]) };\n}\n\n/** A list line, but not one that's actually inside a fenced code block. */\nfunction inListContext(state: EditorState, pos: number): boolean {\n if (!listMarker(state.doc.lineAt(pos).text)) return false;\n const cursor = treeAt(state, pos).resolveInner(pos, -1).cursor();\n do {\n if (/Code/.test(cursor.name)) return false;\n } while (cursor.parent());\n return true;\n}\n\n/** The preceding sibling to nest under, or null when this is the first item at\n * its level (nothing above to nest under) or the list breaks above. Blank\n * lines — a loose list — are stepped over. */\nfunction nestingParent(state: EditorState, lineNo: number, indent: number): ListMarker | null {\n for (let n = lineNo - 1; n >= 1; n--) {\n const text = state.doc.line(n).text;\n if (text.trim() === \"\") continue;\n const info = listMarker(text);\n if (!info) return null;\n if (info.indent === indent) return info;\n if (info.indent < indent) return null;\n }\n return null;\n}\n\n/** The nearest shallower list line; its indent is where an outdent lands. Null\n * → outdent all the way to column 0. */\nfunction outdentTarget(state: EditorState, lineNo: number, indent: number): ListMarker | null {\n for (let n = lineNo - 1; n >= 1; n--) {\n const text = state.doc.line(n).text;\n if (text.trim() === \"\") continue;\n const info = listMarker(text);\n if (!info) return null;\n if (info.indent < indent) return info;\n }\n return null;\n}\n\nfunction changeForLine(\n state: EditorState,\n lineNo: number,\n dir: \"indent\" | \"outdent\",\n): ChangeSpec | null {\n const line = state.doc.line(lineNo);\n const info = listMarker(line.text);\n if (!info) return null;\n\n if (dir === \"indent\") {\n const parent = nestingParent(state, lineNo, info.indent);\n if (!parent) return null; // first item at its level — can't nest\n const newIndent = parent.indent + parent.markerWidth;\n if (newIndent <= info.indent) return null;\n if (info.ordered) {\n // Rewrite the indent and the leading number together so the new sublist\n // starts at `1`; the plugin renumbers any siblings by position.\n const digits = /^\\d+/.exec(line.text.slice(info.indent))?.[0] ?? \"\";\n return {\n from: line.from,\n to: line.from + info.indent + digits.length,\n insert: \" \".repeat(newIndent) + \"1\",\n };\n }\n return { from: line.from, insert: \" \".repeat(newIndent - info.indent) };\n }\n\n if (info.indent === 0) return null; // top level — nothing to outdent\n const newIndent = outdentTarget(state, lineNo, info.indent)?.indent ?? 0;\n return { from: line.from, to: line.from + (info.indent - newIndent), insert: \"\" };\n}\n\nfunction changeListIndent(view: EditorView, dir: \"indent\" | \"outdent\"): boolean {\n const { state } = view;\n const range = state.selection.main;\n if (!inListContext(state, range.from)) return false;\n\n const changes: ChangeSpec[] = [];\n const firstLine = state.doc.lineAt(range.from).number;\n const lastLine = state.doc.lineAt(range.to).number;\n for (let n = firstLine; n <= lastLine; n++) {\n const change = changeForLine(state, n, dir);\n if (change) changes.push(change);\n }\n // Still consume Tab inside a list when nothing moves (first item, or top-level\n // outdent), so it never drops a literal tab into the list.\n if (changes.length === 0) return true;\n\n view.dispatch({\n changes,\n scrollIntoView: true,\n userEvent: dir === \"indent\" ? \"input.indent\" : \"delete.dedent\",\n });\n return true;\n}\n\nexport const indentListItem: Command = (view) => changeListIndent(view, \"indent\");\nexport const outdentListItem: Command = (view) => changeListIndent(view, \"outdent\");\n\nexport const listIndentKeymap = Prec.highest(\n keymap.of([\n { key: \"Tab\", run: indentListItem },\n { key: \"Shift-Tab\", run: outdentListItem },\n ]),\n);\n"],"mappings":"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","names":["newIndent"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { WidgetType, EditorView } from '@codemirror/view';
|
|
2
|
+
import { NodeRule } from '../core/paint.js';
|
|
3
|
+
import '@codemirror/state';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Task checkbox widget — renders `[ ]` / `[x]` as a real interactive
|
|
7
|
+
* `<input type="checkbox">`. Clicking toggles the source.
|
|
8
|
+
*
|
|
9
|
+
* Per spec section 16.4: source `- [ ] Task` becomes a visible
|
|
10
|
+
* `☐ Task` with a real checkbox. Toggling persists as source change
|
|
11
|
+
* (`[ ]` ↔ `[x]`).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
declare class TaskCheckboxWidget extends WidgetType {
|
|
15
|
+
readonly checked: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Source position of the marker's first character (`[`). Used at
|
|
18
|
+
* click time to dispatch the toggling change. Included in `eq()`
|
|
19
|
+
* so CM6 doesn't reuse a widget whose `from` has drifted under
|
|
20
|
+
* us — if the document was edited above the task item, the
|
|
21
|
+
* dispatched range must be the *current* source position, not a
|
|
22
|
+
* stale one.
|
|
23
|
+
*/
|
|
24
|
+
readonly from: number;
|
|
25
|
+
constructor(checked: boolean,
|
|
26
|
+
/**
|
|
27
|
+
* Source position of the marker's first character (`[`). Used at
|
|
28
|
+
* click time to dispatch the toggling change. Included in `eq()`
|
|
29
|
+
* so CM6 doesn't reuse a widget whose `from` has drifted under
|
|
30
|
+
* us — if the document was edited above the task item, the
|
|
31
|
+
* dispatched range must be the *current* source position, not a
|
|
32
|
+
* stale one.
|
|
33
|
+
*/
|
|
34
|
+
from: number);
|
|
35
|
+
eq(other: TaskCheckboxWidget): boolean;
|
|
36
|
+
toDOM(view: EditorView): HTMLElement;
|
|
37
|
+
ignoreEvent(): boolean;
|
|
38
|
+
}
|
|
39
|
+
/** `[ ]` / `[x]` → a real checkbox widget, checked state from the source. */
|
|
40
|
+
declare const taskMarkerRule: NodeRule;
|
|
41
|
+
|
|
42
|
+
export { TaskCheckboxWidget, taskMarkerRule };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__publicField
|
|
3
|
+
} from "../../chunk-V6TY7KAL.js";
|
|
4
|
+
import { Decoration, WidgetType } from "@codemirror/view";
|
|
5
|
+
class TaskCheckboxWidget extends WidgetType {
|
|
6
|
+
constructor(checked, from) {
|
|
7
|
+
super();
|
|
8
|
+
__publicField(this, "checked", checked);
|
|
9
|
+
__publicField(this, "from", from);
|
|
10
|
+
}
|
|
11
|
+
eq(other) {
|
|
12
|
+
return other.checked === this.checked && other.from === this.from;
|
|
13
|
+
}
|
|
14
|
+
toDOM(view) {
|
|
15
|
+
const input = document.createElement("input");
|
|
16
|
+
input.type = "checkbox";
|
|
17
|
+
input.checked = this.checked;
|
|
18
|
+
input.className = "cm-task-checkbox";
|
|
19
|
+
input.addEventListener("mousedown", (e) => e.stopPropagation());
|
|
20
|
+
input.addEventListener("click", (e) => {
|
|
21
|
+
e.stopPropagation();
|
|
22
|
+
const newMarker = this.checked ? "[ ]" : "[x]";
|
|
23
|
+
view.dispatch({
|
|
24
|
+
changes: { from: this.from, to: this.from + 3, insert: newMarker },
|
|
25
|
+
userEvent: "input.format.task"
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
return input;
|
|
29
|
+
}
|
|
30
|
+
ignoreEvent() {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const taskMarkerRule = (ctx) => {
|
|
35
|
+
const checked = /\[[xX]\]/.test(ctx.state.sliceDoc(ctx.from, ctx.to));
|
|
36
|
+
const spaceFollows = ctx.state.doc.sliceString(ctx.to, ctx.to + 1) === " ";
|
|
37
|
+
return {
|
|
38
|
+
paint: "widget",
|
|
39
|
+
deco: Decoration.replace({ widget: new TaskCheckboxWidget(checked, ctx.from) }),
|
|
40
|
+
...spaceFollows ? { atomicTo: ctx.to + 1 } : {}
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export {
|
|
44
|
+
TaskCheckboxWidget,
|
|
45
|
+
taskMarkerRule
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=taskCheckboxWidget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/codemirror/list/taskCheckboxWidget.ts"],"sourcesContent":["/**\n * Task checkbox widget — renders `[ ]` / `[x]` as a real interactive\n * `<input type=\"checkbox\">`. Clicking toggles the source.\n *\n * Per spec section 16.4: source `- [ ] Task` becomes a visible\n * `☐ Task` with a real checkbox. Toggling persists as source change\n * (`[ ]` ↔ `[x]`).\n */\n\nimport { Decoration, EditorView, WidgetType } from \"@codemirror/view\";\n\nimport { type NodeRule, type Paint } from \"../core/paint\";\n\nexport class TaskCheckboxWidget extends WidgetType {\n constructor(\n readonly checked: boolean,\n /**\n * Source position of the marker's first character (`[`). Used at\n * click time to dispatch the toggling change. Included in `eq()`\n * so CM6 doesn't reuse a widget whose `from` has drifted under\n * us — if the document was edited above the task item, the\n * dispatched range must be the *current* source position, not a\n * stale one.\n */\n readonly from: number,\n ) {\n super();\n }\n\n override eq(other: TaskCheckboxWidget): boolean {\n return other.checked === this.checked && other.from === this.from;\n }\n\n override toDOM(view: EditorView): HTMLElement {\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.checked = this.checked;\n input.className = \"cm-task-checkbox\";\n // Stop propagation so clicking the checkbox doesn't also place\n // the caret at the marker position.\n input.addEventListener(\"mousedown\", (e) => e.stopPropagation());\n input.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n const newMarker = this.checked ? \"[ ]\" : \"[x]\";\n view.dispatch({\n changes: { from: this.from, to: this.from + 3, insert: newMarker },\n userEvent: \"input.format.task\",\n });\n });\n return input;\n }\n\n override ignoreEvent(): boolean {\n return false;\n }\n}\n\n/* ---------------- The TaskMarker rule ---------------- */\n\n\n\n/** `[ ]` / `[x]` → a real checkbox widget, checked state from the source. */\nexport const taskMarkerRule: NodeRule = (ctx): Paint => {\n const checked = /\\[[xX]\\]/.test(ctx.state.sliceDoc(ctx.from, ctx.to));\n const spaceFollows = ctx.state.doc.sliceString(ctx.to, ctx.to + 1) === \" \";\n return {\n paint: \"widget\",\n deco: Decoration.replace({ widget: new TaskCheckboxWidget(checked, ctx.from) }),\n ...(spaceFollows ? { atomicTo: ctx.to + 1 } : {}),\n };\n};\n"],"mappings":";;;AASA,SAAS,YAAwB,kBAAkB;AAI5C,MAAM,2BAA2B,WAAW;AAAA,EACjD,YACW,SASA,MACT;AACA,UAAM;AAXG;AASA;AAAA,EAGX;AAAA,EAES,GAAG,OAAoC;AAC9C,WAAO,MAAM,YAAY,KAAK,WAAW,MAAM,SAAS,KAAK;AAAA,EAC/D;AAAA,EAES,MAAM,MAA+B;AAC5C,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,OAAO;AACb,UAAM,UAAU,KAAK;AACrB,UAAM,YAAY;AAGlB,UAAM,iBAAiB,aAAa,CAAC,MAAM,EAAE,gBAAgB,CAAC;AAC9D,UAAM,iBAAiB,SAAS,CAAC,MAAM;AACrC,QAAE,gBAAgB;AAClB,YAAM,YAAY,KAAK,UAAU,QAAQ;AACzC,WAAK,SAAS;AAAA,QACZ,SAAS,EAAE,MAAM,KAAK,MAAM,IAAI,KAAK,OAAO,GAAG,QAAQ,UAAU;AAAA,QACjE,WAAW;AAAA,MACb,CAAC;AAAA,IACH,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAES,cAAuB;AAC9B,WAAO;AAAA,EACT;AACF;AAOO,MAAM,iBAA2B,CAAC,QAAe;AACtD,QAAM,UAAU,WAAW,KAAK,IAAI,MAAM,SAAS,IAAI,MAAM,IAAI,EAAE,CAAC;AACpE,QAAM,eAAe,IAAI,MAAM,IAAI,YAAY,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM;AACvE,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM,WAAW,QAAQ,EAAE,QAAQ,IAAI,mBAAmB,SAAS,IAAI,IAAI,EAAE,CAAC;AAAA,IAC9E,GAAI,eAAe,EAAE,UAAU,IAAI,KAAK,EAAE,IAAI,CAAC;AAAA,EACjD;AACF;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/codemirror/math/index.ts"],"sourcesContent":["/** Math: `$…$` / `$$…$$` rendered with KaTeX. */\nexport * from \"./mathPlugin\";\n"],"mappings":"AACA,cAAc;","names":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { StateField } from '@codemirror/state';
|
|
2
|
+
import { DecorationSet } from '@codemirror/view';
|
|
3
|
+
|
|
4
|
+
declare const INLINE_MATH_RE: RegExp;
|
|
5
|
+
declare const mathPlugin: StateField<{
|
|
6
|
+
decorations: DecorationSet;
|
|
7
|
+
atomic: DecorationSet;
|
|
8
|
+
}>;
|
|
9
|
+
|
|
10
|
+
export { INLINE_MATH_RE, mathPlugin };
|