phormat 0.0.5
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/README.md +102 -0
- package/dist/assets/example-test.svelte +228 -0
- package/dist/debug/JsonDebug.svelte +19 -0
- package/dist/debug/JsonDebug.svelte.d.ts +6 -0
- package/dist/debug/JsonDebugNode.svelte +138 -0
- package/dist/debug/JsonDebugNode.svelte.d.ts +11 -0
- package/dist/demo/documentLifecycle.d.ts +57 -0
- package/dist/demo/documentLifecycle.js +196 -0
- package/dist/demo/index.d.ts +2 -0
- package/dist/demo/index.js +2 -0
- package/dist/editor/BlockEditor.svelte +112 -0
- package/dist/editor/BlockEditor.svelte.d.ts +7 -0
- package/dist/editor/BlockRow.svelte +76 -0
- package/dist/editor/BlockRow.svelte.d.ts +20 -0
- package/dist/editor/Editor.svelte +103 -0
- package/dist/editor/Editor.svelte.d.ts +7 -0
- package/dist/editor/MarkdownEditor.svelte.d.ts +160 -0
- package/dist/editor/MarkdownEditor.svelte.js +1119 -0
- package/dist/editor/NestedRowChrome.svelte +160 -0
- package/dist/editor/NestedRowChrome.svelte.d.ts +20 -0
- package/dist/editor/PhormatEditor.svelte +206 -0
- package/dist/editor/PhormatEditor.svelte.d.ts +26 -0
- package/dist/editor/RawMarkdownPanel.svelte +39 -0
- package/dist/editor/RawMarkdownPanel.svelte.d.ts +6 -0
- package/dist/editor/block-specs/BlockSpecMissing.svelte +12 -0
- package/dist/editor/block-specs/BlockSpecMissing.svelte.d.ts +7 -0
- package/dist/editor/block-specs/blockquote/BlockquoteRenderer.svelte +32 -0
- package/dist/editor/block-specs/blockquote/BlockquoteRenderer.svelte.d.ts +21 -0
- package/dist/editor/block-specs/blockquote/commands.d.ts +2 -0
- package/dist/editor/block-specs/blockquote/commands.js +65 -0
- package/dist/editor/block-specs/blockquote/index.d.ts +6 -0
- package/dist/editor/block-specs/blockquote/index.js +5 -0
- package/dist/editor/block-specs/blockquote/inlineSecondPass.d.ts +6 -0
- package/dist/editor/block-specs/blockquote/inlineSecondPass.js +35 -0
- package/dist/editor/block-specs/blockquote/parse.d.ts +16 -0
- package/dist/editor/block-specs/blockquote/parse.js +188 -0
- package/dist/editor/block-specs/blockquote/reconcile.d.ts +2 -0
- package/dist/editor/block-specs/blockquote/reconcile.js +9 -0
- package/dist/editor/block-specs/blockquote/serialize.d.ts +6 -0
- package/dist/editor/block-specs/blockquote/serialize.js +55 -0
- package/dist/editor/block-specs/blockquote/types.d.ts +20 -0
- package/dist/editor/block-specs/blockquote/types.js +1 -0
- package/dist/editor/block-specs/blockquoteSpec.d.ts +4 -0
- package/dist/editor/block-specs/blockquoteSpec.js +37 -0
- package/dist/editor/block-specs/callout/CalloutRenderer.svelte +38 -0
- package/dist/editor/block-specs/callout/CalloutRenderer.svelte.d.ts +21 -0
- package/dist/editor/block-specs/callout/CalloutTypeIcon.svelte +14 -0
- package/dist/editor/block-specs/callout/CalloutTypeIcon.svelte.d.ts +7 -0
- package/dist/editor/block-specs/callout/commands.d.ts +2 -0
- package/dist/editor/block-specs/callout/commands.js +65 -0
- package/dist/editor/block-specs/callout/icons.d.ts +10 -0
- package/dist/editor/block-specs/callout/icons.js +52 -0
- package/dist/editor/block-specs/callout/index.d.ts +9 -0
- package/dist/editor/block-specs/callout/index.js +7 -0
- package/dist/editor/block-specs/callout/inlineSecondPass.d.ts +6 -0
- package/dist/editor/block-specs/callout/inlineSecondPass.js +9 -0
- package/dist/editor/block-specs/callout/parse.d.ts +9 -0
- package/dist/editor/block-specs/callout/parse.js +83 -0
- package/dist/editor/block-specs/callout/parseBody.d.ts +6 -0
- package/dist/editor/block-specs/callout/parseBody.js +290 -0
- package/dist/editor/block-specs/callout/reconcile.d.ts +2 -0
- package/dist/editor/block-specs/callout/reconcile.js +8 -0
- package/dist/editor/block-specs/callout/serialize.d.ts +5 -0
- package/dist/editor/block-specs/callout/serialize.js +65 -0
- package/dist/editor/block-specs/callout/types.d.ts +7 -0
- package/dist/editor/block-specs/callout/types.js +1 -0
- package/dist/editor/block-specs/calloutSpec.d.ts +2 -0
- package/dist/editor/block-specs/calloutSpec.js +23 -0
- package/dist/editor/block-specs/codeFence/CodeFenceRenderer.svelte +18 -0
- package/dist/editor/block-specs/codeFence/CodeFenceRenderer.svelte.d.ts +21 -0
- package/dist/editor/block-specs/codeFence/commands.d.ts +2 -0
- package/dist/editor/block-specs/codeFence/commands.js +1 -0
- package/dist/editor/block-specs/codeFence/index.d.ts +5 -0
- package/dist/editor/block-specs/codeFence/index.js +4 -0
- package/dist/editor/block-specs/codeFence/inlineSecondPass.d.ts +3 -0
- package/dist/editor/block-specs/codeFence/inlineSecondPass.js +5 -0
- package/dist/editor/block-specs/codeFence/reconcile.d.ts +2 -0
- package/dist/editor/block-specs/codeFence/reconcile.js +5 -0
- package/dist/editor/block-specs/codeFence/serialize.d.ts +2 -0
- package/dist/editor/block-specs/codeFence/serialize.js +8 -0
- package/dist/editor/block-specs/codeFence/types.d.ts +6 -0
- package/dist/editor/block-specs/codeFence/types.js +1 -0
- package/dist/editor/block-specs/codeFenceSpec.d.ts +2 -0
- package/dist/editor/block-specs/codeFenceSpec.js +23 -0
- package/dist/editor/block-specs/columns/ColumnsRenderer.svelte +18 -0
- package/dist/editor/block-specs/columns/ColumnsRenderer.svelte.d.ts +21 -0
- package/dist/editor/block-specs/columns/EditableColumns.svelte +16 -0
- package/dist/editor/block-specs/columns/EditableColumns.svelte.d.ts +4 -0
- package/dist/editor/block-specs/columns/commands.d.ts +2 -0
- package/dist/editor/block-specs/columns/commands.js +1 -0
- package/dist/editor/block-specs/columns/index.d.ts +6 -0
- package/dist/editor/block-specs/columns/index.js +5 -0
- package/dist/editor/block-specs/columns/inlineSecondPass.d.ts +3 -0
- package/dist/editor/block-specs/columns/inlineSecondPass.js +5 -0
- package/dist/editor/block-specs/columns/parse.d.ts +20 -0
- package/dist/editor/block-specs/columns/parse.js +111 -0
- package/dist/editor/block-specs/columns/reconcile.d.ts +2 -0
- package/dist/editor/block-specs/columns/reconcile.js +6 -0
- package/dist/editor/block-specs/columns/serialize.d.ts +2 -0
- package/dist/editor/block-specs/columns/serialize.js +16 -0
- package/dist/editor/block-specs/columns/types.d.ts +4 -0
- package/dist/editor/block-specs/columns/types.js +1 -0
- package/dist/editor/block-specs/columnsSpec.d.ts +2 -0
- package/dist/editor/block-specs/columnsSpec.js +24 -0
- package/dist/editor/block-specs/heading/HeaderRenderer.svelte +30 -0
- package/dist/editor/block-specs/heading/HeaderRenderer.svelte.d.ts +21 -0
- package/dist/editor/block-specs/heading/commands.d.ts +2 -0
- package/dist/editor/block-specs/heading/commands.js +41 -0
- package/dist/editor/block-specs/heading/edit.d.ts +10 -0
- package/dist/editor/block-specs/heading/edit.js +33 -0
- package/dist/editor/block-specs/heading/index.d.ts +7 -0
- package/dist/editor/block-specs/heading/index.js +6 -0
- package/dist/editor/block-specs/heading/inlineSecondPass.d.ts +4 -0
- package/dist/editor/block-specs/heading/inlineSecondPass.js +20 -0
- package/dist/editor/block-specs/heading/parse.d.ts +5 -0
- package/dist/editor/block-specs/heading/parse.js +18 -0
- package/dist/editor/block-specs/heading/reconcile.d.ts +2 -0
- package/dist/editor/block-specs/heading/reconcile.js +8 -0
- package/dist/editor/block-specs/heading/serialize.d.ts +2 -0
- package/dist/editor/block-specs/heading/serialize.js +9 -0
- package/dist/editor/block-specs/heading/types.d.ts +5 -0
- package/dist/editor/block-specs/heading/types.js +1 -0
- package/dist/editor/block-specs/headingSpec.d.ts +2 -0
- package/dist/editor/block-specs/headingSpec.js +28 -0
- package/dist/editor/block-specs/horizontalRule/HorizontalRuleRenderer.svelte +15 -0
- package/dist/editor/block-specs/horizontalRule/HorizontalRuleRenderer.svelte.d.ts +21 -0
- package/dist/editor/block-specs/horizontalRule/commands.d.ts +2 -0
- package/dist/editor/block-specs/horizontalRule/commands.js +1 -0
- package/dist/editor/block-specs/horizontalRule/index.d.ts +6 -0
- package/dist/editor/block-specs/horizontalRule/index.js +5 -0
- package/dist/editor/block-specs/horizontalRule/inlineSecondPass.d.ts +3 -0
- package/dist/editor/block-specs/horizontalRule/inlineSecondPass.js +5 -0
- package/dist/editor/block-specs/horizontalRule/parse.d.ts +2 -0
- package/dist/editor/block-specs/horizontalRule/parse.js +15 -0
- package/dist/editor/block-specs/horizontalRule/reconcile.d.ts +2 -0
- package/dist/editor/block-specs/horizontalRule/reconcile.js +5 -0
- package/dist/editor/block-specs/horizontalRule/serialize.d.ts +2 -0
- package/dist/editor/block-specs/horizontalRule/serialize.js +3 -0
- package/dist/editor/block-specs/horizontalRule/types.d.ts +3 -0
- package/dist/editor/block-specs/horizontalRule/types.js +1 -0
- package/dist/editor/block-specs/horizontalRuleSpec.d.ts +2 -0
- package/dist/editor/block-specs/horizontalRuleSpec.js +24 -0
- package/dist/editor/block-specs/list/ListRenderer.svelte +70 -0
- package/dist/editor/block-specs/list/ListRenderer.svelte.d.ts +21 -0
- package/dist/editor/block-specs/list/commands.d.ts +2 -0
- package/dist/editor/block-specs/list/commands.js +65 -0
- package/dist/editor/block-specs/list/index.d.ts +6 -0
- package/dist/editor/block-specs/list/index.js +5 -0
- package/dist/editor/block-specs/list/inlineSecondPass.d.ts +6 -0
- package/dist/editor/block-specs/list/inlineSecondPass.js +78 -0
- package/dist/editor/block-specs/list/parse.d.ts +11 -0
- package/dist/editor/block-specs/list/parse.js +312 -0
- package/dist/editor/block-specs/list/reconcile.d.ts +2 -0
- package/dist/editor/block-specs/list/reconcile.js +6 -0
- package/dist/editor/block-specs/list/serialize.d.ts +4 -0
- package/dist/editor/block-specs/list/serialize.js +83 -0
- package/dist/editor/block-specs/list/types.d.ts +27 -0
- package/dist/editor/block-specs/list/types.js +1 -0
- package/dist/editor/block-specs/listSpec.d.ts +4 -0
- package/dist/editor/block-specs/listSpec.js +24 -0
- package/dist/editor/block-specs/paragraph/ParagraphRenderer.svelte +22 -0
- package/dist/editor/block-specs/paragraph/ParagraphRenderer.svelte.d.ts +21 -0
- package/dist/editor/block-specs/paragraph/commands.d.ts +2 -0
- package/dist/editor/block-specs/paragraph/commands.js +41 -0
- package/dist/editor/block-specs/paragraph/edit.d.ts +10 -0
- package/dist/editor/block-specs/paragraph/edit.js +69 -0
- package/dist/editor/block-specs/paragraph/index.d.ts +7 -0
- package/dist/editor/block-specs/paragraph/index.js +6 -0
- package/dist/editor/block-specs/paragraph/inlineSecondPass.d.ts +3 -0
- package/dist/editor/block-specs/paragraph/inlineSecondPass.js +25 -0
- package/dist/editor/block-specs/paragraph/parse.d.ts +9 -0
- package/dist/editor/block-specs/paragraph/parse.js +76 -0
- package/dist/editor/block-specs/paragraph/reconcile.d.ts +2 -0
- package/dist/editor/block-specs/paragraph/reconcile.js +9 -0
- package/dist/editor/block-specs/paragraph/serialize.d.ts +4 -0
- package/dist/editor/block-specs/paragraph/serialize.js +39 -0
- package/dist/editor/block-specs/paragraph/types.d.ts +10 -0
- package/dist/editor/block-specs/paragraph/types.js +1 -0
- package/dist/editor/block-specs/paragraphSpec.d.ts +2 -0
- package/dist/editor/block-specs/paragraphSpec.js +24 -0
- package/dist/editor/block-specs/registry.d.ts +10 -0
- package/dist/editor/block-specs/registry.js +34 -0
- package/dist/editor/block-specs/table/TableRenderer.svelte +53 -0
- package/dist/editor/block-specs/table/TableRenderer.svelte.d.ts +21 -0
- package/dist/editor/block-specs/table/commands.d.ts +2 -0
- package/dist/editor/block-specs/table/commands.js +1 -0
- package/dist/editor/block-specs/table/edit.d.ts +10 -0
- package/dist/editor/block-specs/table/edit.js +127 -0
- package/dist/editor/block-specs/table/editCommands.d.ts +18 -0
- package/dist/editor/block-specs/table/editCommands.js +87 -0
- package/dist/editor/block-specs/table/index.d.ts +8 -0
- package/dist/editor/block-specs/table/index.js +6 -0
- package/dist/editor/block-specs/table/inlineSecondPass.d.ts +3 -0
- package/dist/editor/block-specs/table/inlineSecondPass.js +22 -0
- package/dist/editor/block-specs/table/parse.d.ts +17 -0
- package/dist/editor/block-specs/table/parse.js +181 -0
- package/dist/editor/block-specs/table/reconcile.d.ts +2 -0
- package/dist/editor/block-specs/table/reconcile.js +6 -0
- package/dist/editor/block-specs/table/serialize.d.ts +3 -0
- package/dist/editor/block-specs/table/serialize.js +32 -0
- package/dist/editor/block-specs/table/types.d.ts +11 -0
- package/dist/editor/block-specs/table/types.js +1 -0
- package/dist/editor/block-specs/tableSpec.d.ts +2 -0
- package/dist/editor/block-specs/tableSpec.js +25 -0
- package/dist/editor/block-specs/toc/EditableToc.svelte +16 -0
- package/dist/editor/block-specs/toc/EditableToc.svelte.d.ts +4 -0
- package/dist/editor/block-specs/toc/TocRenderer.svelte +22 -0
- package/dist/editor/block-specs/toc/TocRenderer.svelte.d.ts +21 -0
- package/dist/editor/block-specs/toc/commands.d.ts +2 -0
- package/dist/editor/block-specs/toc/commands.js +1 -0
- package/dist/editor/block-specs/toc/index.d.ts +6 -0
- package/dist/editor/block-specs/toc/index.js +5 -0
- package/dist/editor/block-specs/toc/inlineSecondPass.d.ts +3 -0
- package/dist/editor/block-specs/toc/inlineSecondPass.js +5 -0
- package/dist/editor/block-specs/toc/parse.d.ts +10 -0
- package/dist/editor/block-specs/toc/parse.js +43 -0
- package/dist/editor/block-specs/toc/reconcile.d.ts +2 -0
- package/dist/editor/block-specs/toc/reconcile.js +5 -0
- package/dist/editor/block-specs/toc/serialize.d.ts +2 -0
- package/dist/editor/block-specs/toc/serialize.js +6 -0
- package/dist/editor/block-specs/toc/types.d.ts +8 -0
- package/dist/editor/block-specs/toc/types.js +1 -0
- package/dist/editor/block-specs/tocSpec.d.ts +2 -0
- package/dist/editor/block-specs/tocSpec.js +24 -0
- package/dist/editor/block-specs/toggle/ToggleRenderer.svelte +19 -0
- package/dist/editor/block-specs/toggle/ToggleRenderer.svelte.d.ts +21 -0
- package/dist/editor/block-specs/toggle/commands.d.ts +2 -0
- package/dist/editor/block-specs/toggle/commands.js +1 -0
- package/dist/editor/block-specs/toggle/index.d.ts +7 -0
- package/dist/editor/block-specs/toggle/index.js +5 -0
- package/dist/editor/block-specs/toggle/inlineSecondPass.d.ts +3 -0
- package/dist/editor/block-specs/toggle/inlineSecondPass.js +5 -0
- package/dist/editor/block-specs/toggle/parse.d.ts +9 -0
- package/dist/editor/block-specs/toggle/parse.js +78 -0
- package/dist/editor/block-specs/toggle/reconcile.d.ts +2 -0
- package/dist/editor/block-specs/toggle/reconcile.js +6 -0
- package/dist/editor/block-specs/toggle/serialize.d.ts +4 -0
- package/dist/editor/block-specs/toggle/serialize.js +13 -0
- package/dist/editor/block-specs/toggle/types.d.ts +5 -0
- package/dist/editor/block-specs/toggle/types.js +1 -0
- package/dist/editor/block-specs/toggleSpec.d.ts +2 -0
- package/dist/editor/block-specs/toggleSpec.js +24 -0
- package/dist/editor/block-specs/types.d.ts +26 -0
- package/dist/editor/block-specs/types.js +1 -0
- package/dist/editor/blocks/EditableBlockquote.svelte +52 -0
- package/dist/editor/blocks/EditableBlockquote.svelte.d.ts +10 -0
- package/dist/editor/blocks/EditableBlockquoteNodes.svelte +134 -0
- package/dist/editor/blocks/EditableBlockquoteNodes.svelte.d.ts +14 -0
- package/dist/editor/blocks/EditableBlockquoteParagraph.svelte +44 -0
- package/dist/editor/blocks/EditableBlockquoteParagraph.svelte.d.ts +12 -0
- package/dist/editor/blocks/EditableCallout.svelte +182 -0
- package/dist/editor/blocks/EditableCallout.svelte.d.ts +11 -0
- package/dist/editor/blocks/EditableCalloutListItemRow.svelte +169 -0
- package/dist/editor/blocks/EditableCalloutListItemRow.svelte.d.ts +15 -0
- package/dist/editor/blocks/EditableCalloutNodes.svelte +91 -0
- package/dist/editor/blocks/EditableCalloutNodes.svelte.d.ts +13 -0
- package/dist/editor/blocks/EditableCalloutParagraph.svelte +39 -0
- package/dist/editor/blocks/EditableCalloutParagraph.svelte.d.ts +12 -0
- package/dist/editor/blocks/EditableCodeBlock.svelte +43 -0
- package/dist/editor/blocks/EditableCodeBlock.svelte.d.ts +10 -0
- package/dist/editor/blocks/EditableHeading.svelte +161 -0
- package/dist/editor/blocks/EditableHeading.svelte.d.ts +10 -0
- package/dist/editor/blocks/EditableHorizontalRule.svelte +20 -0
- package/dist/editor/blocks/EditableHorizontalRule.svelte.d.ts +10 -0
- package/dist/editor/blocks/EditableInlineSurface.svelte +423 -0
- package/dist/editor/blocks/EditableInlineSurface.svelte.d.ts +26 -0
- package/dist/editor/blocks/EditableList.svelte +77 -0
- package/dist/editor/blocks/EditableList.svelte.d.ts +17 -0
- package/dist/editor/blocks/EditableListItemRow.svelte +231 -0
- package/dist/editor/blocks/EditableListItemRow.svelte.d.ts +19 -0
- package/dist/editor/blocks/EditableParagraph.svelte +208 -0
- package/dist/editor/blocks/EditableParagraph.svelte.d.ts +10 -0
- package/dist/editor/blocks/EditableParagraphNodes.svelte +89 -0
- package/dist/editor/blocks/EditableParagraphNodes.svelte.d.ts +15 -0
- package/dist/editor/blocks/EditableTable.svelte +83 -0
- package/dist/editor/blocks/EditableTable.svelte.d.ts +10 -0
- package/dist/editor/blocks/EditableTableCell.svelte +89 -0
- package/dist/editor/blocks/EditableTableCell.svelte.d.ts +15 -0
- package/dist/editor/blocks/EditableToggle.svelte +94 -0
- package/dist/editor/blocks/EditableToggle.svelte.d.ts +10 -0
- package/dist/editor/commandMenu.d.ts +18 -0
- package/dist/editor/commandMenu.js +83 -0
- package/dist/editor/commandRegistry.d.ts +48 -0
- package/dist/editor/commandRegistry.js +133 -0
- package/dist/editor/context/assetBaseUrl.d.ts +6 -0
- package/dist/editor/context/assetBaseUrl.js +20 -0
- package/dist/editor/dom/editorHistoryKeydown.d.ts +6 -0
- package/dist/editor/dom/editorHistoryKeydown.js +31 -0
- package/dist/editor/dom/plainEnterKeydown.d.ts +12 -0
- package/dist/editor/dom/plainEnterKeydown.js +53 -0
- package/dist/editor/dom/plaintextCaret.d.ts +12 -0
- package/dist/editor/dom/plaintextCaret.js +61 -0
- package/dist/editor/dom/syncDocumentSelectionFocus.d.ts +17 -0
- package/dist/editor/dom/syncDocumentSelectionFocus.js +56 -0
- package/dist/editor/draftPersistence.d.ts +27 -0
- package/dist/editor/draftPersistence.js +83 -0
- package/dist/editor/editorHistoryHandle.d.ts +16 -0
- package/dist/editor/editorHistoryHandle.js +22 -0
- package/dist/editor/inlineChrome/InlineChromeCoordinator.svelte +174 -0
- package/dist/editor/inlineChrome/InlineChromeCoordinator.svelte.d.ts +8 -0
- package/dist/editor/inlineChrome/InlineFormattingToolbar.svelte +181 -0
- package/dist/editor/inlineChrome/InlineFormattingToolbar.svelte.d.ts +3 -0
- package/dist/editor/inlineChrome/inlineChromeActions.d.ts +17 -0
- package/dist/editor/inlineChrome/inlineChromeActions.js +148 -0
- package/dist/editor/inlineChrome/inlineChromeState.svelte.d.ts +23 -0
- package/dist/editor/inlineChrome/inlineChromeState.svelte.js +21 -0
- package/dist/editor/inlineChrome/inlineToolbarIcons.d.ts +14 -0
- package/dist/editor/inlineChrome/inlineToolbarIcons.js +14 -0
- package/dist/editor/inlineChrome/inlineWrapActive.d.ts +3 -0
- package/dist/editor/inlineChrome/inlineWrapActive.js +19 -0
- package/dist/editor/inlineChrome/selectionRect.d.ts +2 -0
- package/dist/editor/inlineChrome/selectionRect.js +23 -0
- package/dist/editor/model/blockEditCommands.d.ts +73 -0
- package/dist/editor/model/blockEditCommands.js +719 -0
- package/dist/editor/model/blockTree.d.ts +39 -0
- package/dist/editor/model/blockTree.js +185 -0
- package/dist/editor/model/blockTreeDrop.d.ts +9 -0
- package/dist/editor/model/blockTreeDrop.js +295 -0
- package/dist/editor/model/blockTreeMutations.d.ts +10 -0
- package/dist/editor/model/blockTreeMutations.js +68 -0
- package/dist/editor/model/calloutEditCommands.d.ts +39 -0
- package/dist/editor/model/calloutEditCommands.js +305 -0
- package/dist/editor/model/documentSelection.d.ts +8 -0
- package/dist/editor/model/documentSelection.js +56 -0
- package/dist/editor/model/documentSelectionFromSource.d.ts +3 -0
- package/dist/editor/model/documentSelectionFromSource.js +45 -0
- package/dist/editor/model/documentToRenderBlocks.d.ts +3 -0
- package/dist/editor/model/documentToRenderBlocks.js +13 -0
- package/dist/editor/model/editorPipeline.bench.d.ts +1 -0
- package/dist/editor/model/editorPipeline.bench.js +27 -0
- package/dist/editor/model/editorTransactions.d.ts +20 -0
- package/dist/editor/model/editorTransactions.js +68 -0
- package/dist/editor/model/emptyParagraph.d.ts +11 -0
- package/dist/editor/model/emptyParagraph.js +25 -0
- package/dist/editor/model/enterCommands.d.ts +16 -0
- package/dist/editor/model/enterCommands.js +288 -0
- package/dist/editor/model/extensionSyntaxWarnings.d.ts +29 -0
- package/dist/editor/model/extensionSyntaxWarnings.js +122 -0
- package/dist/editor/model/findBlockAtSourceOffset.d.ts +3 -0
- package/dist/editor/model/findBlockAtSourceOffset.js +20 -0
- package/dist/editor/model/fixtures/serialization-fidelity/reorder-gaps.svelte +4 -0
- package/dist/editor/model/focusOutcome.d.ts +25 -0
- package/dist/editor/model/focusOutcome.js +1 -0
- package/dist/editor/model/incrementalReparse.d.ts +16 -0
- package/dist/editor/model/incrementalReparse.js +111 -0
- package/dist/editor/model/index.d.ts +22 -0
- package/dist/editor/model/index.js +19 -0
- package/dist/editor/model/inlineDraftCommit.d.ts +17 -0
- package/dist/editor/model/inlineDraftCommit.js +187 -0
- package/dist/editor/model/inlineDraftMerge.d.ts +8 -0
- package/dist/editor/model/inlineDraftMerge.js +81 -0
- package/dist/editor/model/inlineEditCommands.d.ts +28 -0
- package/dist/editor/model/inlineEditCommands.js +581 -0
- package/dist/editor/model/inlinePlain.d.ts +3 -0
- package/dist/editor/model/inlinePlain.js +28 -0
- package/dist/editor/model/inlineSecondPass.d.ts +4 -0
- package/dist/editor/model/inlineSecondPass.js +47 -0
- package/dist/editor/model/line-utils.d.ts +14 -0
- package/dist/editor/model/line-utils.js +38 -0
- package/dist/editor/model/listEditCommands.d.ts +56 -0
- package/dist/editor/model/listEditCommands.js +299 -0
- package/dist/editor/model/nestedContainerTransactions.d.ts +36 -0
- package/dist/editor/model/nestedContainerTransactions.js +336 -0
- package/dist/editor/model/parseMarkdownDocument.d.ts +2 -0
- package/dist/editor/model/parseMarkdownDocument.js +324 -0
- package/dist/editor/model/quoteEditCommands.d.ts +39 -0
- package/dist/editor/model/quoteEditCommands.js +323 -0
- package/dist/editor/model/reconcileBlockIds.d.ts +9 -0
- package/dist/editor/model/reconcileBlockIds.js +297 -0
- package/dist/editor/model/reparseOptions.d.ts +12 -0
- package/dist/editor/model/reparseOptions.js +1 -0
- package/dist/editor/model/resolveEnterPlainSnapshot.d.ts +6 -0
- package/dist/editor/model/resolveEnterPlainSnapshot.js +23 -0
- package/dist/editor/model/richInlines.d.ts +16 -0
- package/dist/editor/model/richInlines.js +494 -0
- package/dist/editor/model/serializeInlineNodes.d.ts +3 -0
- package/dist/editor/model/serializeInlineNodes.js +45 -0
- package/dist/editor/model/serializeMarkdownDocument.d.ts +30 -0
- package/dist/editor/model/serializeMarkdownDocument.js +150 -0
- package/dist/editor/model/structureParseWarnings.d.ts +10 -0
- package/dist/editor/model/structureParseWarnings.js +60 -0
- package/dist/editor/model/syntheticInlineRanges.d.ts +3 -0
- package/dist/editor/model/syntheticInlineRanges.js +36 -0
- package/dist/editor/model/types.d.ts +185 -0
- package/dist/editor/model/types.js +26 -0
- package/dist/editor/plugins/autolinks/AutolinkRenderer.svelte +20 -0
- package/dist/editor/plugins/autolinks/AutolinkRenderer.svelte.d.ts +21 -0
- package/dist/editor/plugins/autolinks/index.d.ts +2 -0
- package/dist/editor/plugins/autolinks/index.js +4 -0
- package/dist/editor/plugins/autolinks/parse-autolinks.d.ts +2 -0
- package/dist/editor/plugins/autolinks/parse-autolinks.js +68 -0
- package/dist/editor/plugins/autolinks/types.d.ts +6 -0
- package/dist/editor/plugins/autolinks/types.js +1 -0
- package/dist/editor/plugins/emphasis/EmphasisRenderer.svelte +15 -0
- package/dist/editor/plugins/emphasis/EmphasisRenderer.svelte.d.ts +21 -0
- package/dist/editor/plugins/emphasis/index.d.ts +2 -0
- package/dist/editor/plugins/emphasis/index.js +4 -0
- package/dist/editor/plugins/emphasis/parse-emphasis.d.ts +2 -0
- package/dist/editor/plugins/emphasis/parse-emphasis.js +188 -0
- package/dist/editor/plugins/emphasis/types.d.ts +24 -0
- package/dist/editor/plugins/emphasis/types.js +1 -0
- package/dist/editor/plugins/escaping/EscapingRenderer.svelte +18 -0
- package/dist/editor/plugins/escaping/EscapingRenderer.svelte.d.ts +21 -0
- package/dist/editor/plugins/escaping/index.d.ts +2 -0
- package/dist/editor/plugins/escaping/index.js +4 -0
- package/dist/editor/plugins/escaping/parse-escaping.d.ts +6 -0
- package/dist/editor/plugins/escaping/parse-escaping.js +26 -0
- package/dist/editor/plugins/escaping/types.d.ts +10 -0
- package/dist/editor/plugins/escaping/types.js +1 -0
- package/dist/editor/plugins/extended-task-list/ExtendedTaskListRenderer.svelte +25 -0
- package/dist/editor/plugins/extended-task-list/ExtendedTaskListRenderer.svelte.d.ts +21 -0
- package/dist/editor/plugins/extended-task-list/index.d.ts +2 -0
- package/dist/editor/plugins/extended-task-list/index.js +4 -0
- package/dist/editor/plugins/extended-task-list/parse-extended-task-list.d.ts +2 -0
- package/dist/editor/plugins/extended-task-list/parse-extended-task-list.js +35 -0
- package/dist/editor/plugins/extended-task-list/types.d.ts +6 -0
- package/dist/editor/plugins/extended-task-list/types.js +1 -0
- package/dist/editor/plugins/highlight/HighlightRenderer.svelte +16 -0
- package/dist/editor/plugins/highlight/HighlightRenderer.svelte.d.ts +21 -0
- package/dist/editor/plugins/highlight/index.d.ts +2 -0
- package/dist/editor/plugins/highlight/index.js +4 -0
- package/dist/editor/plugins/highlight/parse-highlights.d.ts +4 -0
- package/dist/editor/plugins/highlight/parse-highlights.js +49 -0
- package/dist/editor/plugins/highlight/types.d.ts +6 -0
- package/dist/editor/plugins/highlight/types.js +1 -0
- package/dist/editor/plugins/index.d.ts +1 -0
- package/dist/editor/plugins/index.js +1 -0
- package/dist/editor/plugins/links-images/LinksImagesRenderer.svelte +53 -0
- package/dist/editor/plugins/links-images/LinksImagesRenderer.svelte.d.ts +21 -0
- package/dist/editor/plugins/links-images/index.d.ts +2 -0
- package/dist/editor/plugins/links-images/index.js +4 -0
- package/dist/editor/plugins/links-images/parse-image-layout.d.ts +28 -0
- package/dist/editor/plugins/links-images/parse-image-layout.js +147 -0
- package/dist/editor/plugins/links-images/parse-links-images.d.ts +25 -0
- package/dist/editor/plugins/links-images/parse-links-images.js +236 -0
- package/dist/editor/plugins/links-images/resolve-asset-url.d.ts +5 -0
- package/dist/editor/plugins/links-images/resolve-asset-url.js +21 -0
- package/dist/editor/plugins/links-images/types.d.ts +11 -0
- package/dist/editor/plugins/links-images/types.js +1 -0
- package/dist/editor/plugins/mention/MentionRenderer.svelte +18 -0
- package/dist/editor/plugins/mention/MentionRenderer.svelte.d.ts +21 -0
- package/dist/editor/plugins/mention/index.d.ts +2 -0
- package/dist/editor/plugins/mention/index.js +4 -0
- package/dist/editor/plugins/mention/parse-mentions.d.ts +2 -0
- package/dist/editor/plugins/mention/parse-mentions.js +54 -0
- package/dist/editor/plugins/mention/types.d.ts +14 -0
- package/dist/editor/plugins/mention/types.js +1 -0
- package/dist/editor/plugins/raw-text/RawTextRenderer.svelte +19 -0
- package/dist/editor/plugins/raw-text/RawTextRenderer.svelte.d.ts +21 -0
- package/dist/editor/plugins/raw-text/index.d.ts +2 -0
- package/dist/editor/plugins/raw-text/index.js +4 -0
- package/dist/editor/plugins/raw-text/types.d.ts +4 -0
- package/dist/editor/plugins/raw-text/types.js +1 -0
- package/dist/editor/plugins/shared/InlineNodes.svelte +113 -0
- package/dist/editor/plugins/shared/InlineNodes.svelte.d.ts +21 -0
- package/dist/editor/plugins/shared/InlineNodesEdit.svelte +78 -0
- package/dist/editor/plugins/shared/InlineNodesEdit.svelte.d.ts +21 -0
- package/dist/editor/plugins/strikethrough/StrikethroughRenderer.svelte +9 -0
- package/dist/editor/plugins/strikethrough/StrikethroughRenderer.svelte.d.ts +21 -0
- package/dist/editor/plugins/strikethrough/index.d.ts +2 -0
- package/dist/editor/plugins/strikethrough/index.js +4 -0
- package/dist/editor/plugins/strikethrough/parse-strikethrough.d.ts +3 -0
- package/dist/editor/plugins/strikethrough/parse-strikethrough.js +38 -0
- package/dist/editor/plugins/strikethrough/types.d.ts +4 -0
- package/dist/editor/plugins/strikethrough/types.js +1 -0
- package/dist/editor/plugins/synced-block/SyncedBlockRenderer.svelte +16 -0
- package/dist/editor/plugins/synced-block/SyncedBlockRenderer.svelte.d.ts +21 -0
- package/dist/editor/plugins/synced-block/index.d.ts +2 -0
- package/dist/editor/plugins/synced-block/index.js +4 -0
- package/dist/editor/plugins/synced-block/parse-synced-blocks.d.ts +2 -0
- package/dist/editor/plugins/synced-block/parse-synced-blocks.js +15 -0
- package/dist/editor/plugins/synced-block/types.d.ts +4 -0
- package/dist/editor/plugins/synced-block/types.js +1 -0
- package/dist/editor/plugins/types.d.ts +19 -0
- package/dist/editor/plugins/types.js +1 -0
- package/dist/editor/plugins/wiki-link/WikiLinkRenderer.svelte +15 -0
- package/dist/editor/plugins/wiki-link/WikiLinkRenderer.svelte.d.ts +21 -0
- package/dist/editor/plugins/wiki-link/index.d.ts +2 -0
- package/dist/editor/plugins/wiki-link/index.js +4 -0
- package/dist/editor/plugins/wiki-link/parse-wiki-links.d.ts +2 -0
- package/dist/editor/plugins/wiki-link/parse-wiki-links.js +30 -0
- package/dist/editor/plugins/wiki-link/types.d.ts +8 -0
- package/dist/editor/plugins/wiki-link/types.js +1 -0
- package/dist/editor/taskCheckboxStates.d.ts +5 -0
- package/dist/editor/taskCheckboxStates.js +28 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +9 -0
- package/dist/styles/index.css +6 -0
- package/package.json +84 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { EditorBlock, EditorBlockType, EditorDocument } from './types';
|
|
2
|
+
/** Indices into nested {@link EditorBlock.children} from document root downward. */
|
|
3
|
+
export type TreePath = readonly number[];
|
|
4
|
+
export type BlockLocation = {
|
|
5
|
+
block: EditorBlock;
|
|
6
|
+
parent: EditorBlock | null;
|
|
7
|
+
siblings: EditorBlock[];
|
|
8
|
+
index: number;
|
|
9
|
+
/** Index in {@link EditorDocument.blocks} for the root ancestor of this node. */
|
|
10
|
+
topLevelIndex: number;
|
|
11
|
+
path: TreePath;
|
|
12
|
+
};
|
|
13
|
+
export declare function nestingAllowlistFor(parent: EditorBlock | null): ReadonlySet<EditorBlockType> | null;
|
|
14
|
+
export declare function canNestUnder(parent: EditorBlock | null, childType: EditorBlockType): boolean;
|
|
15
|
+
export declare function blockCanMoveSibling(blocks: EditorBlock[], blockId: string, direction: 'up' | 'down'): boolean;
|
|
16
|
+
export declare function blockTreeDepth(blocks: EditorBlock[], blockId: string): number;
|
|
17
|
+
export declare function deepCloneBlock(block: EditorBlock): EditorBlock;
|
|
18
|
+
export declare function deepCloneBlocks(blocks: EditorBlock[]): EditorBlock[];
|
|
19
|
+
export declare function findBlockLocation(blocks: EditorBlock[], blockId: string, parent?: EditorBlock | null, siblings?: EditorBlock[], pathPrefix?: TreePath): BlockLocation | null;
|
|
20
|
+
export declare function findBlockInDocument(doc: EditorDocument, blockId: string): BlockLocation | null;
|
|
21
|
+
/** Relative index from `anchorId` to `focusId` among the same parent's children. */
|
|
22
|
+
export declare function siblingIndexOffset(blocks: EditorBlock[], anchorId: string, focusId: string): number | null;
|
|
23
|
+
export declare function blockAtSiblingOffset(blocks: EditorBlock[], anchorId: string, offset: number): EditorBlock | null;
|
|
24
|
+
/** Contiguous top-level {@link EditorBlock.type} `listItem` run containing `startIndex`. */
|
|
25
|
+
export declare function listRegionBounds(blocks: EditorBlock[], startIndex: number): {
|
|
26
|
+
start: number;
|
|
27
|
+
end: number;
|
|
28
|
+
};
|
|
29
|
+
export declare function listRegionBoundsForBlockId(blocks: EditorBlock[], blockId: string): {
|
|
30
|
+
start: number;
|
|
31
|
+
end: number;
|
|
32
|
+
} | null;
|
|
33
|
+
export declare function sourceRangeForBlockSpan(blocks: EditorBlock[], start: number, end: number, source: string): {
|
|
34
|
+
start: number;
|
|
35
|
+
end: number;
|
|
36
|
+
} | null;
|
|
37
|
+
export declare function normalizeListOrdinalsInItems(items: EditorBlock[]): void;
|
|
38
|
+
export declare function normalizeListOrdinalsForest(blocks: EditorBlock[]): void;
|
|
39
|
+
export declare function blockAtPath(blocks: EditorBlock[], path: TreePath): EditorBlock | null;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
const LIST_ITEM_CHILD_TYPES = new Set([
|
|
2
|
+
'listItem',
|
|
3
|
+
'paragraph',
|
|
4
|
+
'blockquote',
|
|
5
|
+
'codeFence',
|
|
6
|
+
'callout',
|
|
7
|
+
'toggle'
|
|
8
|
+
]);
|
|
9
|
+
const PARAGRAPH_CHILD_TYPES = LIST_ITEM_CHILD_TYPES;
|
|
10
|
+
const BLOCKQUOTE_CHILD_TYPES = new Set([
|
|
11
|
+
'blockquote',
|
|
12
|
+
'listItem',
|
|
13
|
+
'paragraph',
|
|
14
|
+
'codeFence',
|
|
15
|
+
'callout',
|
|
16
|
+
'toggle'
|
|
17
|
+
]);
|
|
18
|
+
const CALLOUT_CHILD_TYPES = BLOCKQUOTE_CHILD_TYPES;
|
|
19
|
+
const ROOT_CHILD_TYPES = new Set([
|
|
20
|
+
'heading',
|
|
21
|
+
'paragraph',
|
|
22
|
+
'codeFence',
|
|
23
|
+
'listItem',
|
|
24
|
+
'blockquote',
|
|
25
|
+
'horizontalRule',
|
|
26
|
+
'table',
|
|
27
|
+
'callout',
|
|
28
|
+
'toggle',
|
|
29
|
+
'columns',
|
|
30
|
+
'toc'
|
|
31
|
+
]);
|
|
32
|
+
export function nestingAllowlistFor(parent) {
|
|
33
|
+
if (parent === null)
|
|
34
|
+
return ROOT_CHILD_TYPES;
|
|
35
|
+
switch (parent.type) {
|
|
36
|
+
case 'listItem':
|
|
37
|
+
return LIST_ITEM_CHILD_TYPES;
|
|
38
|
+
case 'paragraph':
|
|
39
|
+
return PARAGRAPH_CHILD_TYPES;
|
|
40
|
+
case 'blockquote':
|
|
41
|
+
return BLOCKQUOTE_CHILD_TYPES;
|
|
42
|
+
case 'callout':
|
|
43
|
+
return CALLOUT_CHILD_TYPES;
|
|
44
|
+
default:
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function canNestUnder(parent, childType) {
|
|
49
|
+
const allow = nestingAllowlistFor(parent);
|
|
50
|
+
return allow?.has(childType) ?? false;
|
|
51
|
+
}
|
|
52
|
+
export function blockCanMoveSibling(blocks, blockId, direction) {
|
|
53
|
+
const loc = findBlockLocation(blocks, blockId);
|
|
54
|
+
if (!loc)
|
|
55
|
+
return false;
|
|
56
|
+
const newIdx = direction === 'up' ? loc.index - 1 : loc.index + 1;
|
|
57
|
+
return newIdx >= 0 && newIdx < loc.siblings.length;
|
|
58
|
+
}
|
|
59
|
+
export function blockTreeDepth(blocks, blockId) {
|
|
60
|
+
return findBlockLocation(blocks, blockId)?.path.length ?? 0;
|
|
61
|
+
}
|
|
62
|
+
export function deepCloneBlock(block) {
|
|
63
|
+
return {
|
|
64
|
+
...block,
|
|
65
|
+
data: typeof block.data === 'object' && block.data !== null && !Array.isArray(block.data)
|
|
66
|
+
? { ...block.data }
|
|
67
|
+
: block.data,
|
|
68
|
+
inlines: block.inlines?.map((n) => ({ ...n })),
|
|
69
|
+
children: block.children?.map(deepCloneBlock)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export function deepCloneBlocks(blocks) {
|
|
73
|
+
return blocks.map(deepCloneBlock);
|
|
74
|
+
}
|
|
75
|
+
export function findBlockLocation(blocks, blockId, parent = null, siblings = blocks, pathPrefix = []) {
|
|
76
|
+
for (let i = 0; i < siblings.length; i++) {
|
|
77
|
+
const block = siblings[i];
|
|
78
|
+
const path = [...pathPrefix, i];
|
|
79
|
+
const topLevelIndex = path[0] ?? i;
|
|
80
|
+
if (block.id === blockId) {
|
|
81
|
+
return { block, parent, siblings, index: i, topLevelIndex, path };
|
|
82
|
+
}
|
|
83
|
+
if (block.children?.length) {
|
|
84
|
+
const found = findBlockLocation(blocks, blockId, block, block.children, path);
|
|
85
|
+
if (found)
|
|
86
|
+
return found;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
export function findBlockInDocument(doc, blockId) {
|
|
92
|
+
return findBlockLocation(doc.blocks, blockId);
|
|
93
|
+
}
|
|
94
|
+
/** Relative index from `anchorId` to `focusId` among the same parent's children. */
|
|
95
|
+
export function siblingIndexOffset(blocks, anchorId, focusId) {
|
|
96
|
+
const anchor = findBlockLocation(blocks, anchorId);
|
|
97
|
+
const focus = findBlockLocation(blocks, focusId);
|
|
98
|
+
if (!anchor || !focus || anchor.siblings !== focus.siblings)
|
|
99
|
+
return null;
|
|
100
|
+
return focus.index - anchor.index;
|
|
101
|
+
}
|
|
102
|
+
export function blockAtSiblingOffset(blocks, anchorId, offset) {
|
|
103
|
+
const anchor = findBlockLocation(blocks, anchorId);
|
|
104
|
+
if (!anchor)
|
|
105
|
+
return null;
|
|
106
|
+
return anchor.siblings[anchor.index + offset] ?? null;
|
|
107
|
+
}
|
|
108
|
+
/** Contiguous top-level {@link EditorBlock.type} `listItem` run containing `startIndex`. */
|
|
109
|
+
export function listRegionBounds(blocks, startIndex) {
|
|
110
|
+
if (startIndex < 0 || startIndex >= blocks.length || blocks[startIndex]?.type !== 'listItem') {
|
|
111
|
+
return { start: startIndex, end: startIndex };
|
|
112
|
+
}
|
|
113
|
+
let start = startIndex;
|
|
114
|
+
while (start > 0 && blocks[start - 1]?.type === 'listItem')
|
|
115
|
+
start--;
|
|
116
|
+
let end = startIndex + 1;
|
|
117
|
+
while (end < blocks.length && blocks[end]?.type === 'listItem')
|
|
118
|
+
end++;
|
|
119
|
+
return { start, end };
|
|
120
|
+
}
|
|
121
|
+
export function listRegionBoundsForBlockId(blocks, blockId) {
|
|
122
|
+
const loc = findBlockLocation(blocks, blockId);
|
|
123
|
+
if (!loc || loc.parent !== null)
|
|
124
|
+
return null;
|
|
125
|
+
return listRegionBounds(blocks, loc.index);
|
|
126
|
+
}
|
|
127
|
+
export function sourceRangeForBlockSpan(blocks, start, end, source) {
|
|
128
|
+
const first = blocks[start];
|
|
129
|
+
const last = blocks[end - 1];
|
|
130
|
+
if (!first || !last)
|
|
131
|
+
return null;
|
|
132
|
+
if (first.sourceRange.start < 0 || last.sourceRange.end < 0)
|
|
133
|
+
return null;
|
|
134
|
+
return { start: first.sourceRange.start, end: last.sourceRange.end };
|
|
135
|
+
}
|
|
136
|
+
export function normalizeListOrdinalsInItems(items) {
|
|
137
|
+
let n = 1;
|
|
138
|
+
for (const item of items) {
|
|
139
|
+
if (item.type !== 'listItem')
|
|
140
|
+
continue;
|
|
141
|
+
const d = item.data;
|
|
142
|
+
if (d.ordered) {
|
|
143
|
+
item.data = { ...d, ordered: true, ordinalValue: n++ };
|
|
144
|
+
}
|
|
145
|
+
for (const ch of item.children ?? []) {
|
|
146
|
+
if (ch.type === 'listItem')
|
|
147
|
+
normalizeListOrdinalsInItems([ch]);
|
|
148
|
+
else if (ch.children?.length)
|
|
149
|
+
walkBlockTree(ch);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function walkBlockTree(block) {
|
|
154
|
+
if (block.type === 'listItem' && block.children?.length) {
|
|
155
|
+
const listItems = block.children.filter((c) => c.type === 'listItem');
|
|
156
|
+
if (listItems.length)
|
|
157
|
+
normalizeListOrdinalsInItems(block.children);
|
|
158
|
+
}
|
|
159
|
+
for (const ch of block.children ?? [])
|
|
160
|
+
walkBlockTree(ch);
|
|
161
|
+
}
|
|
162
|
+
export function normalizeListOrdinalsForest(blocks) {
|
|
163
|
+
const runs = [];
|
|
164
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
165
|
+
if (blocks[i]?.type === 'listItem') {
|
|
166
|
+
const b = listRegionBounds(blocks, i);
|
|
167
|
+
runs.push(b);
|
|
168
|
+
i = b.end - 1;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
for (const { start, end } of runs) {
|
|
172
|
+
normalizeListOrdinalsInItems(blocks.slice(start, end));
|
|
173
|
+
}
|
|
174
|
+
for (const b of blocks)
|
|
175
|
+
walkBlockTree(b);
|
|
176
|
+
}
|
|
177
|
+
export function blockAtPath(blocks, path) {
|
|
178
|
+
if (path.length === 0)
|
|
179
|
+
return null;
|
|
180
|
+
let node = blocks[path[0]];
|
|
181
|
+
for (let i = 1; i < path.length; i++) {
|
|
182
|
+
node = node?.children?.[path[i]];
|
|
183
|
+
}
|
|
184
|
+
return node ?? null;
|
|
185
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TransactionBuildResult } from './editorTransactions';
|
|
2
|
+
import type { EditorBlock, EditorDocument, EditorOperation } from './types';
|
|
3
|
+
export type TreeDropPlacement = 'before' | 'after' | 'nest' | 'outdent';
|
|
4
|
+
export declare function buildStructuralReplaceOps(source: string, oldBlocks: EditorBlock[], newBlocks: EditorBlock[]): EditorOperation[];
|
|
5
|
+
export declare function applyBlockTreeDrop(blocks: EditorBlock[], draggedId: string, targetId: string, placement: TreeDropPlacement): EditorBlock[] | null;
|
|
6
|
+
export declare function canBlockTreeDrop(blocks: EditorBlock[], draggedId: string, targetId: string, placement: TreeDropPlacement): boolean;
|
|
7
|
+
export declare function blockTreeDropTransaction(source: string, doc: EditorDocument, draggedId: string, targetId: string, placement: TreeDropPlacement): TransactionBuildResult;
|
|
8
|
+
/** Tab / Shift+Tab reparent for any block in the document tree. */
|
|
9
|
+
export declare function tabReparentBlockTransaction(source: string, doc: EditorDocument, blockId: string, shift: boolean): TransactionBuildResult;
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { serializeListRegion } from '../block-specs/list/serialize';
|
|
2
|
+
import { canNestUnder, deepCloneBlocks, findBlockLocation, listRegionBounds, normalizeListOrdinalsForest, sourceRangeForBlockSpan } from './blockTree';
|
|
3
|
+
import { insertSiblingRelative, isDescendantBlock, nestUnderTarget, removeBlockFromTree } from './blockTreeMutations';
|
|
4
|
+
import { moveBlockToIndex, normalizeBlockSliceReplacement } from './blockEditCommands';
|
|
5
|
+
import { serializeEditorBlock, serializeMarkdownDocument } from './serializeMarkdownDocument';
|
|
6
|
+
function topLevelSegments(blocks) {
|
|
7
|
+
const segs = [];
|
|
8
|
+
let i = 0;
|
|
9
|
+
while (i < blocks.length) {
|
|
10
|
+
const b = blocks[i];
|
|
11
|
+
if (b.type === 'listItem') {
|
|
12
|
+
const { start, end } = listRegionBounds(blocks, i);
|
|
13
|
+
segs.push({ startIdx: start, endIdx: end, anchorId: blocks[start].id });
|
|
14
|
+
i = end;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
segs.push({ startIdx: i, endIdx: i + 1, anchorId: b.id });
|
|
18
|
+
i++;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return segs;
|
|
22
|
+
}
|
|
23
|
+
function serializeTopLevelSeg(blocks, seg, source) {
|
|
24
|
+
const { startIdx, endIdx } = seg;
|
|
25
|
+
if (startIdx >= endIdx || startIdx >= blocks.length)
|
|
26
|
+
return null;
|
|
27
|
+
if (blocks[startIdx]?.type === 'listItem') {
|
|
28
|
+
return serializeListRegion(blocks.slice(startIdx, endIdx), source);
|
|
29
|
+
}
|
|
30
|
+
if (endIdx - startIdx !== 1)
|
|
31
|
+
return null;
|
|
32
|
+
const block = blocks[startIdx];
|
|
33
|
+
if (block.sourceRange.synthetic || block.sourceRange.start < 0)
|
|
34
|
+
return null;
|
|
35
|
+
return serializeEditorBlock(block, source);
|
|
36
|
+
}
|
|
37
|
+
function oldSourceEndBeforeSegment(oldBlocks, newBlocks, newSeg, source) {
|
|
38
|
+
if (newSeg.startIdx === 0) {
|
|
39
|
+
const first = oldBlocks[0];
|
|
40
|
+
return first && first.sourceRange.start >= 0 ? first.sourceRange.start : 0;
|
|
41
|
+
}
|
|
42
|
+
for (let i = newSeg.startIdx - 1; i >= 0; i--) {
|
|
43
|
+
const prev = newBlocks[i];
|
|
44
|
+
const oldLoc = findBlockLocation(oldBlocks, prev.id);
|
|
45
|
+
if (!oldLoc)
|
|
46
|
+
continue;
|
|
47
|
+
if (oldLoc.parent !== null) {
|
|
48
|
+
const top = oldBlocks[oldLoc.topLevelIndex];
|
|
49
|
+
if (top?.sourceRange.end >= 0)
|
|
50
|
+
return top.sourceRange.end;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (prev.type === 'listItem') {
|
|
54
|
+
const bounds = listRegionBounds(oldBlocks, oldLoc.index);
|
|
55
|
+
const last = oldBlocks[bounds.end - 1];
|
|
56
|
+
if (last?.sourceRange.end >= 0)
|
|
57
|
+
return last.sourceRange.end;
|
|
58
|
+
}
|
|
59
|
+
else if (oldLoc.block.sourceRange.end >= 0) {
|
|
60
|
+
return oldLoc.block.sourceRange.end;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return source.length;
|
|
64
|
+
}
|
|
65
|
+
function sourceSliceForSegment(source, blocks, seg) {
|
|
66
|
+
const range = sourceRangeForBlockSpan(blocks, seg.startIdx, seg.endIdx, source);
|
|
67
|
+
return range ? source.slice(range.start, range.end) : null;
|
|
68
|
+
}
|
|
69
|
+
function gapBetweenOldSegments(source, oldBlocks, left, right) {
|
|
70
|
+
const leftRange = sourceRangeForBlockSpan(oldBlocks, left.startIdx, left.endIdx, source);
|
|
71
|
+
const rightRange = sourceRangeForBlockSpan(oldBlocks, right.startIdx, right.endIdx, source);
|
|
72
|
+
if (!leftRange || !rightRange)
|
|
73
|
+
return null;
|
|
74
|
+
return source.slice(leftRange.end, rightRange.start);
|
|
75
|
+
}
|
|
76
|
+
function buildWholeDocumentReplaceOp(source, oldBlocks, newBlocks, oldSegs, newSegs) {
|
|
77
|
+
const docRange = sourceRangeForBlockSpan(oldBlocks, 0, oldBlocks.length, source);
|
|
78
|
+
if (!docRange)
|
|
79
|
+
return [];
|
|
80
|
+
const oldByAnchor = new Map(oldSegs.map((seg, idx) => [seg.anchorId, { seg, idx }]));
|
|
81
|
+
let text = '';
|
|
82
|
+
for (let i = 0; i < newSegs.length; i++) {
|
|
83
|
+
const newSeg = newSegs[i];
|
|
84
|
+
const oldMatch = oldByAnchor.get(newSeg.anchorId);
|
|
85
|
+
if (i > 0) {
|
|
86
|
+
const prevOldMatch = oldByAnchor.get(newSegs[i - 1].anchorId);
|
|
87
|
+
const adjacentOldGap = prevOldMatch && oldMatch && oldMatch.idx === prevOldMatch.idx + 1
|
|
88
|
+
? gapBetweenOldSegments(source, oldBlocks, prevOldMatch.seg, oldMatch.seg)
|
|
89
|
+
: null;
|
|
90
|
+
text += adjacentOldGap ?? '\n\n';
|
|
91
|
+
}
|
|
92
|
+
const newText = serializeTopLevelSeg(newBlocks, newSeg, source);
|
|
93
|
+
if (newText === null)
|
|
94
|
+
return [];
|
|
95
|
+
const oldText = oldMatch ? serializeTopLevelSeg(oldBlocks, oldMatch.seg, source) : null;
|
|
96
|
+
const preservedText = oldMatch && oldText === newText
|
|
97
|
+
? sourceSliceForSegment(source, oldBlocks, oldMatch.seg)
|
|
98
|
+
: null;
|
|
99
|
+
text += preservedText ?? newText;
|
|
100
|
+
}
|
|
101
|
+
if (text === source.slice(docRange.start, docRange.end))
|
|
102
|
+
return [];
|
|
103
|
+
return [{ type: 'replaceSlice', range: docRange, text }];
|
|
104
|
+
}
|
|
105
|
+
export function buildStructuralReplaceOps(source, oldBlocks, newBlocks) {
|
|
106
|
+
const oldSegs = topLevelSegments(oldBlocks);
|
|
107
|
+
const newSegs = topLevelSegments(newBlocks);
|
|
108
|
+
const newByAnchor = new Map(newSegs.map((s) => [s.anchorId, s]));
|
|
109
|
+
const oldAnchors = new Set(oldSegs.map((s) => s.anchorId));
|
|
110
|
+
const ops = [];
|
|
111
|
+
for (const oldSeg of oldSegs) {
|
|
112
|
+
const range = sourceRangeForBlockSpan(oldBlocks, oldSeg.startIdx, oldSeg.endIdx, source);
|
|
113
|
+
if (!range)
|
|
114
|
+
continue;
|
|
115
|
+
const newSeg = newByAnchor.get(oldSeg.anchorId);
|
|
116
|
+
if (!newSeg) {
|
|
117
|
+
ops.push({ type: 'replaceSlice', range, text: '' });
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
const oldText = serializeTopLevelSeg(oldBlocks, oldSeg, source);
|
|
121
|
+
const newText = serializeTopLevelSeg(newBlocks, newSeg, source);
|
|
122
|
+
if (oldText === null || newText === null)
|
|
123
|
+
continue;
|
|
124
|
+
if (oldText !== newText) {
|
|
125
|
+
ops.push({ type: 'replaceSlice', range, text: newText });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
for (const newSeg of newSegs) {
|
|
129
|
+
if (oldAnchors.has(newSeg.anchorId))
|
|
130
|
+
continue;
|
|
131
|
+
const newText = serializeTopLevelSeg(newBlocks, newSeg, source);
|
|
132
|
+
if (newText === null)
|
|
133
|
+
continue;
|
|
134
|
+
const insertPos = oldSourceEndBeforeSegment(oldBlocks, newBlocks, newSeg, source);
|
|
135
|
+
if (insertPos === null)
|
|
136
|
+
continue;
|
|
137
|
+
const prefix = insertPos > 0 && newSeg.startIdx > 0 ? '\n\n' : '';
|
|
138
|
+
ops.push({
|
|
139
|
+
type: 'replaceSlice',
|
|
140
|
+
range: { start: insertPos, end: insertPos },
|
|
141
|
+
text: prefix + newText
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (ops.length > 1) {
|
|
145
|
+
return buildWholeDocumentReplaceOp(source, oldBlocks, newBlocks, oldSegs, newSegs);
|
|
146
|
+
}
|
|
147
|
+
ops.sort((a, b) => b.range.start - a.range.start);
|
|
148
|
+
return ops;
|
|
149
|
+
}
|
|
150
|
+
export function applyBlockTreeDrop(blocks, draggedId, targetId, placement) {
|
|
151
|
+
if (draggedId === targetId && placement !== 'nest')
|
|
152
|
+
return null;
|
|
153
|
+
const clone = deepCloneBlocks(blocks);
|
|
154
|
+
const draggedLocBefore = findBlockLocation(clone, draggedId);
|
|
155
|
+
if (!draggedLocBefore)
|
|
156
|
+
return null;
|
|
157
|
+
if (placement === 'outdent' && !draggedLocBefore.parent)
|
|
158
|
+
return null;
|
|
159
|
+
if (placement === 'nest' &&
|
|
160
|
+
(draggedId === targetId || isDescendantBlock(clone, draggedId, targetId))) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
const removed = removeBlockFromTree(clone, draggedId);
|
|
164
|
+
if (!removed)
|
|
165
|
+
return null;
|
|
166
|
+
if (placement === 'outdent') {
|
|
167
|
+
const parentId = draggedLocBefore.parent.id;
|
|
168
|
+
const parentLoc = findBlockLocation(clone, parentId);
|
|
169
|
+
if (!parentLoc)
|
|
170
|
+
return null;
|
|
171
|
+
if (!canNestUnder(parentLoc.parent, removed.type))
|
|
172
|
+
return null;
|
|
173
|
+
parentLoc.siblings.splice(parentLoc.index + 1, 0, removed);
|
|
174
|
+
normalizeListOrdinalsForest(clone);
|
|
175
|
+
return clone;
|
|
176
|
+
}
|
|
177
|
+
const targetLoc = findBlockLocation(clone, targetId);
|
|
178
|
+
if (!targetLoc)
|
|
179
|
+
return null;
|
|
180
|
+
if (placement === 'nest') {
|
|
181
|
+
if (!nestUnderTarget(clone, targetLoc, removed))
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
else if (!canNestUnder(targetLoc.parent, removed.type)) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
insertSiblingRelative(clone, targetLoc, removed, placement);
|
|
189
|
+
}
|
|
190
|
+
normalizeListOrdinalsForest(clone);
|
|
191
|
+
return clone;
|
|
192
|
+
}
|
|
193
|
+
export function canBlockTreeDrop(blocks, draggedId, targetId, placement) {
|
|
194
|
+
return applyBlockTreeDrop(deepCloneBlocks(blocks), draggedId, targetId, placement) !== null;
|
|
195
|
+
}
|
|
196
|
+
export function blockTreeDropTransaction(source, doc, draggedId, targetId, placement) {
|
|
197
|
+
const nextBlocks = applyBlockTreeDrop(doc.blocks, draggedId, targetId, placement);
|
|
198
|
+
if (!nextBlocks)
|
|
199
|
+
return { ok: false, error: 'Block tree drop failed.' };
|
|
200
|
+
if (placement === 'nest' || placement === 'outdent') {
|
|
201
|
+
const draggedLocAfter = findBlockLocation(nextBlocks, draggedId);
|
|
202
|
+
const nextSource = serializeMarkdownDocument({ ...doc, source, blocks: nextBlocks });
|
|
203
|
+
if (nextSource === source) {
|
|
204
|
+
return { ok: false, error: 'Block tree drop made no source changes.' };
|
|
205
|
+
}
|
|
206
|
+
const caret = Math.min(draggedLocAfter?.block.sourceRange.start ?? 0, nextSource.length);
|
|
207
|
+
return {
|
|
208
|
+
ok: true,
|
|
209
|
+
transaction: {
|
|
210
|
+
id: `block-tree-drop:${draggedId}:${placement}:${targetId}`,
|
|
211
|
+
operations: [
|
|
212
|
+
{
|
|
213
|
+
type: 'replaceSlice',
|
|
214
|
+
range: { start: 0, end: source.length },
|
|
215
|
+
text: nextSource
|
|
216
|
+
}
|
|
217
|
+
],
|
|
218
|
+
selection: { anchor: caret, focus: caret }
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
const ops = buildStructuralReplaceOps(source, doc.blocks, nextBlocks);
|
|
223
|
+
if (ops.length === 0) {
|
|
224
|
+
const fromIndex = doc.blocks.findIndex((b) => b.id === draggedId);
|
|
225
|
+
const toIndex = nextBlocks.findIndex((b) => b.id === draggedId);
|
|
226
|
+
const sameTopLevelSet = doc.blocks.length === nextBlocks.length &&
|
|
227
|
+
doc.blocks.every((b) => nextBlocks.some((n) => n.id === b.id));
|
|
228
|
+
if (fromIndex >= 0 &&
|
|
229
|
+
toIndex >= 0 &&
|
|
230
|
+
fromIndex !== toIndex &&
|
|
231
|
+
sameTopLevelSet) {
|
|
232
|
+
const moved = moveBlockToIndex(source, doc, fromIndex, toIndex);
|
|
233
|
+
if (!moved.ok)
|
|
234
|
+
return { ok: false, error: moved.error };
|
|
235
|
+
const range = sourceRangeForBlockSpan(doc.blocks, 0, doc.blocks.length, source);
|
|
236
|
+
if (!range)
|
|
237
|
+
return { ok: false, error: 'Block tree drop has no source span.' };
|
|
238
|
+
const text = normalizeBlockSliceReplacement(source, range.start, range.end, moved.source.slice(range.start, range.end));
|
|
239
|
+
return {
|
|
240
|
+
ok: true,
|
|
241
|
+
transaction: {
|
|
242
|
+
id: `block-tree-drop:${draggedId}:${placement}:${targetId}`,
|
|
243
|
+
operations: [{ type: 'replaceSlice', range, text }],
|
|
244
|
+
selection: moved.selection
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
return { ok: false, error: 'Block tree drop made no source changes.' };
|
|
249
|
+
}
|
|
250
|
+
let caret = doc.blocks[0]?.sourceRange.start ?? 0;
|
|
251
|
+
const caretLoc = findBlockLocation(nextBlocks, draggedId);
|
|
252
|
+
if (caretLoc?.block.sourceRange.start !== undefined && caretLoc.block.sourceRange.start >= 0) {
|
|
253
|
+
caret = caretLoc.block.sourceRange.start;
|
|
254
|
+
}
|
|
255
|
+
// Serialized block text omits the trailing newline that `sourceRange.end` covers; bake the
|
|
256
|
+
// normalization into the operations so the blank-line break after the slice is preserved.
|
|
257
|
+
const normalizedOps = ops.map((op) => op.type === 'replaceSlice'
|
|
258
|
+
? {
|
|
259
|
+
...op,
|
|
260
|
+
text: normalizeBlockSliceReplacement(source, op.range.start, op.range.end, op.text)
|
|
261
|
+
}
|
|
262
|
+
: op);
|
|
263
|
+
let nextSource = source;
|
|
264
|
+
for (const op of [...normalizedOps].sort((a, b) => b.range.start - a.range.start)) {
|
|
265
|
+
if (op.type === 'replaceSlice') {
|
|
266
|
+
nextSource = nextSource.slice(0, op.range.start) + op.text + nextSource.slice(op.range.end);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
caret = Math.min(caret, nextSource.length);
|
|
270
|
+
return {
|
|
271
|
+
ok: true,
|
|
272
|
+
transaction: {
|
|
273
|
+
id: `block-tree-drop:${draggedId}:${placement}:${targetId}`,
|
|
274
|
+
operations: normalizedOps,
|
|
275
|
+
selection: { anchor: caret, focus: caret }
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
/** Tab / Shift+Tab reparent for any block in the document tree. */
|
|
280
|
+
export function tabReparentBlockTransaction(source, doc, blockId, shift) {
|
|
281
|
+
const loc = findBlockLocation(doc.blocks, blockId);
|
|
282
|
+
if (!loc)
|
|
283
|
+
return { ok: false, error: 'Block not found.' };
|
|
284
|
+
if (shift) {
|
|
285
|
+
if (!loc.parent)
|
|
286
|
+
return { ok: false, error: 'Cannot outdent.' };
|
|
287
|
+
return blockTreeDropTransaction(source, doc, blockId, loc.parent.id, 'outdent');
|
|
288
|
+
}
|
|
289
|
+
if (loc.index === 0)
|
|
290
|
+
return { ok: false, error: 'Cannot nest.' };
|
|
291
|
+
const prev = loc.siblings[loc.index - 1];
|
|
292
|
+
if (!prev)
|
|
293
|
+
return { ok: false, error: 'Cannot nest.' };
|
|
294
|
+
return blockTreeDropTransaction(source, doc, blockId, prev.id, 'nest');
|
|
295
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type BlockLocation } from './blockTree';
|
|
2
|
+
import type { EditorBlock } from './types';
|
|
3
|
+
export declare function isDescendantBlock(blocks: EditorBlock[], ancestorId: string, candidateId: string): boolean;
|
|
4
|
+
export declare function removeBlockFromTree(blocks: EditorBlock[], blockId: string): EditorBlock | null;
|
|
5
|
+
/** Promote one level: insert after parent in parent's siblings (Shift+Tab / outdent). */
|
|
6
|
+
export declare function promoteOneLevel(blocks: EditorBlock[], blockId: string): EditorBlock[] | null;
|
|
7
|
+
/** Nest under previous sibling (Tab on listItem). */
|
|
8
|
+
export declare function nestUnderPreviousSibling(blocks: EditorBlock[], blockId: string, canNest?: (parent: EditorBlock, child: EditorBlock) => boolean): EditorBlock[] | null;
|
|
9
|
+
export declare function insertSiblingRelative(blocks: EditorBlock[], targetLoc: BlockLocation, block: EditorBlock, placement: 'before' | 'after'): void;
|
|
10
|
+
export declare function nestUnderTarget(blocks: EditorBlock[], targetLoc: BlockLocation, block: EditorBlock): boolean;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { canNestUnder, deepCloneBlocks, findBlockLocation, normalizeListOrdinalsForest } from './blockTree';
|
|
2
|
+
export function isDescendantBlock(blocks, ancestorId, candidateId) {
|
|
3
|
+
if (ancestorId === candidateId)
|
|
4
|
+
return true;
|
|
5
|
+
const ancestor = findBlockLocation(blocks, ancestorId);
|
|
6
|
+
if (!ancestor?.block.children?.length)
|
|
7
|
+
return false;
|
|
8
|
+
for (const child of ancestor.block.children) {
|
|
9
|
+
if (child.id === candidateId || isDescendantBlock(blocks, child.id, candidateId))
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
export function removeBlockFromTree(blocks, blockId) {
|
|
15
|
+
const loc = findBlockLocation(blocks, blockId);
|
|
16
|
+
if (!loc)
|
|
17
|
+
return null;
|
|
18
|
+
const [removed] = loc.siblings.splice(loc.index, 1);
|
|
19
|
+
return removed ?? null;
|
|
20
|
+
}
|
|
21
|
+
/** Promote one level: insert after parent in parent's siblings (Shift+Tab / outdent). */
|
|
22
|
+
export function promoteOneLevel(blocks, blockId) {
|
|
23
|
+
const clone = deepCloneBlocks(blocks);
|
|
24
|
+
const loc = findBlockLocation(clone, blockId);
|
|
25
|
+
if (!loc?.parent)
|
|
26
|
+
return null;
|
|
27
|
+
const parentLoc = findBlockLocation(clone, loc.parent.id);
|
|
28
|
+
if (!parentLoc)
|
|
29
|
+
return null;
|
|
30
|
+
const removed = removeBlockFromTree(clone, blockId);
|
|
31
|
+
if (!removed)
|
|
32
|
+
return null;
|
|
33
|
+
if (!canNestUnder(parentLoc.parent, removed.type))
|
|
34
|
+
return null;
|
|
35
|
+
parentLoc.siblings.splice(parentLoc.index + 1, 0, removed);
|
|
36
|
+
normalizeListOrdinalsForest(clone);
|
|
37
|
+
return clone;
|
|
38
|
+
}
|
|
39
|
+
/** Nest under previous sibling (Tab on listItem). */
|
|
40
|
+
export function nestUnderPreviousSibling(blocks, blockId, canNest = (parent, child) => canNestUnder(parent, child.type)) {
|
|
41
|
+
const clone = deepCloneBlocks(blocks);
|
|
42
|
+
const loc = findBlockLocation(clone, blockId);
|
|
43
|
+
if (!loc || loc.index === 0)
|
|
44
|
+
return null;
|
|
45
|
+
const removed = removeBlockFromTree(clone, blockId);
|
|
46
|
+
if (!removed)
|
|
47
|
+
return null;
|
|
48
|
+
const prev = loc.siblings[loc.index - 1];
|
|
49
|
+
if (!prev || !canNest(prev, removed))
|
|
50
|
+
return null;
|
|
51
|
+
if (!prev.children)
|
|
52
|
+
prev.children = [];
|
|
53
|
+
prev.children.push(removed);
|
|
54
|
+
normalizeListOrdinalsForest(clone);
|
|
55
|
+
return clone;
|
|
56
|
+
}
|
|
57
|
+
export function insertSiblingRelative(blocks, targetLoc, block, placement) {
|
|
58
|
+
const insertIdx = targetLoc.index + (placement === 'after' ? 1 : 0);
|
|
59
|
+
targetLoc.siblings.splice(insertIdx, 0, block);
|
|
60
|
+
}
|
|
61
|
+
export function nestUnderTarget(blocks, targetLoc, block) {
|
|
62
|
+
if (!canNestUnder(targetLoc.block, block.type))
|
|
63
|
+
return false;
|
|
64
|
+
if (!targetLoc.block.children)
|
|
65
|
+
targetLoc.block.children = [];
|
|
66
|
+
targetLoc.block.children.push(block);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type TreePath } from './blockTree';
|
|
2
|
+
import type { EditorBlock } from './types';
|
|
3
|
+
import type { EditorDocument } from './types';
|
|
4
|
+
import type { TransactionBuildResult } from './editorTransactions';
|
|
5
|
+
export type CalloutPath = TreePath;
|
|
6
|
+
declare const EMPTY_PARAGRAPH_AFTER = "\n\n \n\n";
|
|
7
|
+
export declare function calloutBodySyntheticParagraphId(calloutId: string): string;
|
|
8
|
+
export declare function isCalloutBodySyntheticParagraphId(blockId: string): boolean;
|
|
9
|
+
export declare function makeEmptyCalloutParagraph(): EditorBlock;
|
|
10
|
+
export declare function makeCalloutBodySyntheticParagraph(calloutId: string): EditorBlock;
|
|
11
|
+
/** Write the first empty `> ` body line for an opener-only callout. */
|
|
12
|
+
export declare function ensureCalloutEmptyBodyTransaction(source: string, doc: EditorDocument, calloutBlockIndex: number): TransactionBuildResult;
|
|
13
|
+
export declare function nodeAtCalloutPath(root: EditorBlock, path: CalloutPath): EditorBlock | null;
|
|
14
|
+
/** Path from callout root to any descendant block id (excluding the callout root itself). */
|
|
15
|
+
export declare function findCalloutDescendantPath(root: EditorBlock, blockId: string): CalloutPath | null;
|
|
16
|
+
export declare function calloutParagraphDisplayPlain(block: EditorBlock): string;
|
|
17
|
+
export declare function calloutChildCanMoveSibling(root: EditorBlock, blockId: string, direction: 'up' | 'down'): boolean;
|
|
18
|
+
export declare function calloutMoveSibling(root: EditorBlock, blockId: string, direction: 'up' | 'down'): EditorBlock | null;
|
|
19
|
+
export declare function calloutDeleteChild(root: EditorBlock, blockId: string): EditorBlock | null;
|
|
20
|
+
export declare function calloutDuplicateChild(root: EditorBlock, blockId: string): EditorBlock | null;
|
|
21
|
+
export declare function calloutSiblingIndexOffset(root: EditorBlock, anchorId: string, focusId: string): number | null;
|
|
22
|
+
export declare function siblingFocusIdForCalloutDelete(root: EditorBlock, blockId: string): string | undefined;
|
|
23
|
+
export type CalloutParagraphEnterResult = {
|
|
24
|
+
root: EditorBlock;
|
|
25
|
+
focusBlockId: string;
|
|
26
|
+
exitToParagraph?: false;
|
|
27
|
+
};
|
|
28
|
+
export type CalloutExitResult = {
|
|
29
|
+
root: EditorBlock;
|
|
30
|
+
exitToParagraph: true;
|
|
31
|
+
};
|
|
32
|
+
export declare function calloutParagraphEnterAtPlain(root: EditorBlock, blockId: string, offset: number, plainText: string): CalloutParagraphEnterResult | CalloutExitResult | null;
|
|
33
|
+
export declare function calloutListItemEnterAtPlain(root: EditorBlock, itemId: string, offset: number, plainText: string, source: string): CalloutParagraphEnterResult | CalloutExitResult | null;
|
|
34
|
+
export declare function calloutBlockquoteEnterAtPlain(root: EditorBlock, blockId: string, offset: number, plainText: string, source: string): CalloutParagraphEnterResult | CalloutExitResult | null;
|
|
35
|
+
export declare function calloutExitReplacementMarkdown(calloutMd: string, caretInCallout: number): {
|
|
36
|
+
replacement: string;
|
|
37
|
+
caret: number;
|
|
38
|
+
};
|
|
39
|
+
export { EMPTY_PARAGRAPH_AFTER };
|