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 } from './types';
|
|
2
|
+
/** Child indices from a blockquote node downward (not including the top-level block index). */
|
|
3
|
+
export type QuotePath = readonly number[];
|
|
4
|
+
export declare function blockquoteDisplayPlain(block: EditorBlock, source: string): string;
|
|
5
|
+
/** @deprecated Use {@link blockquoteDisplayPlain} — same plain text the edit surface shows. */
|
|
6
|
+
export declare function blockquoteBodyPlain(block: EditorBlock, source: string): string;
|
|
7
|
+
export declare function setBlockquoteBodyPlain(block: EditorBlock, plain: string): void;
|
|
8
|
+
export declare function nodeAtQuotePath(root: EditorBlock, path: QuotePath): EditorBlock | null;
|
|
9
|
+
export declare function findQuoteBlockPath(root: EditorBlock, blockId: string): QuotePath | null;
|
|
10
|
+
/** Relative child index from `anchorId` to `focusId` under the same blockquote parent. */
|
|
11
|
+
export declare function quoteSiblingIndexOffset(root: EditorBlock, anchorId: string, focusId: string): number | null;
|
|
12
|
+
export declare function blockquoteAtSiblingOffset(root: EditorBlock, anchorId: string, offset: number): EditorBlock | null;
|
|
13
|
+
/** @deprecated Use {@link findQuoteBlockPath}. */
|
|
14
|
+
export declare function findQuoteParagraphPath(root: EditorBlock, paragraphId: string): QuotePath | null;
|
|
15
|
+
export declare function quoteMoveSibling(root: EditorBlock, path: QuotePath, direction: 'up' | 'down'): EditorBlock | null;
|
|
16
|
+
export declare function quoteDeleteBlock(root: EditorBlock, path: QuotePath): EditorBlock | null;
|
|
17
|
+
export declare function quoteDuplicateBlock(root: EditorBlock, path: QuotePath): EditorBlock | null;
|
|
18
|
+
export declare function quoteBlockCanMoveSibling(root: EditorBlock, path: QuotePath, direction: 'up' | 'down'): boolean;
|
|
19
|
+
/** @deprecated */
|
|
20
|
+
export declare function quoteDeleteParagraph(root: EditorBlock, path: QuotePath): EditorBlock | null;
|
|
21
|
+
/** @deprecated */
|
|
22
|
+
export declare function quoteDuplicateParagraph(root: EditorBlock, path: QuotePath): EditorBlock | null;
|
|
23
|
+
/** @deprecated */
|
|
24
|
+
export declare function quoteParagraphCanMoveSibling(root: EditorBlock, path: QuotePath, direction: 'up' | 'down'): boolean;
|
|
25
|
+
/** @deprecated */
|
|
26
|
+
export declare function quoteReorderParagraph(root: EditorBlock, quotePath: QuotePath, fromIndex: number, toIndex: number): EditorBlock | null;
|
|
27
|
+
export declare function quoteBlockIndices(quote: EditorBlock): number[];
|
|
28
|
+
export type QuoteEnterResult = {
|
|
29
|
+
root: EditorBlock;
|
|
30
|
+
focusBlockId: string;
|
|
31
|
+
exitToParagraph?: false;
|
|
32
|
+
};
|
|
33
|
+
export type QuoteExitResult = {
|
|
34
|
+
root: EditorBlock;
|
|
35
|
+
exitToParagraph: true;
|
|
36
|
+
};
|
|
37
|
+
export declare function quoteEnterAtPlain(root: EditorBlock, quotePath: QuotePath, offset: number, plainText: string, source: string): QuoteEnterResult | QuoteExitResult | null;
|
|
38
|
+
/** @deprecated */
|
|
39
|
+
export declare function quoteParagraphIndices(quote: EditorBlock): number[];
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { cloneInlineNodeDeep, inlineTextNode } from './inlineEditCommands';
|
|
2
|
+
import { deepCloneBlock } from './blockTree';
|
|
3
|
+
import { inlineNodesToPlainText } from './inlinePlain';
|
|
4
|
+
function syntheticRange() {
|
|
5
|
+
return { start: -1, end: -1, startLine: -1, endLine: -1, synthetic: true };
|
|
6
|
+
}
|
|
7
|
+
export function blockquoteDisplayPlain(block, source) {
|
|
8
|
+
if (block.type !== 'blockquote')
|
|
9
|
+
return '';
|
|
10
|
+
if (block.inlines?.length)
|
|
11
|
+
return inlineNodesToPlainText(block.inlines);
|
|
12
|
+
if (block.sourceRange.start >= 0 && !block.sourceRange.synthetic) {
|
|
13
|
+
const slice = source.slice(block.sourceRange.start, block.sourceRange.end);
|
|
14
|
+
const firstLine = slice.split('\n')[0] ?? '';
|
|
15
|
+
const m = firstLine.match(/^\s*(?:>\s*)+(.*)$/);
|
|
16
|
+
return (m ? m[1] : firstLine).trimEnd();
|
|
17
|
+
}
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
/** @deprecated Use {@link blockquoteDisplayPlain} — same plain text the edit surface shows. */
|
|
21
|
+
export function blockquoteBodyPlain(block, source) {
|
|
22
|
+
return blockquoteDisplayPlain(block, source);
|
|
23
|
+
}
|
|
24
|
+
export function setBlockquoteBodyPlain(block, plain) {
|
|
25
|
+
block.inlines = plain.length > 0 ? [inlineTextNode(plain)] : [];
|
|
26
|
+
}
|
|
27
|
+
export function nodeAtQuotePath(root, path) {
|
|
28
|
+
let n = root;
|
|
29
|
+
for (const i of path) {
|
|
30
|
+
const ch = n.children?.[i];
|
|
31
|
+
if (!ch)
|
|
32
|
+
return null;
|
|
33
|
+
n = ch;
|
|
34
|
+
}
|
|
35
|
+
return n;
|
|
36
|
+
}
|
|
37
|
+
export function findQuoteBlockPath(root, blockId) {
|
|
38
|
+
if (root.type === 'blockquote' && root.id === blockId)
|
|
39
|
+
return [];
|
|
40
|
+
function walk(node, prefix) {
|
|
41
|
+
for (let i = 0; i < (node.children?.length ?? 0); i++) {
|
|
42
|
+
const ch = node.children[i];
|
|
43
|
+
const p = [...prefix, i];
|
|
44
|
+
if (ch.id === blockId && ch.type === 'blockquote')
|
|
45
|
+
return p;
|
|
46
|
+
if (ch.type === 'blockquote') {
|
|
47
|
+
const found = walk(ch, p);
|
|
48
|
+
if (found)
|
|
49
|
+
return found;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
if (root.type !== 'blockquote')
|
|
55
|
+
return null;
|
|
56
|
+
return walk(root, []);
|
|
57
|
+
}
|
|
58
|
+
/** Relative child index from `anchorId` to `focusId` under the same blockquote parent. */
|
|
59
|
+
export function quoteSiblingIndexOffset(root, anchorId, focusId) {
|
|
60
|
+
const anchorPath = findQuoteBlockPath(root, anchorId);
|
|
61
|
+
const focusPath = findQuoteBlockPath(root, focusId);
|
|
62
|
+
if (!anchorPath || !focusPath || anchorPath.length !== focusPath.length)
|
|
63
|
+
return null;
|
|
64
|
+
for (let i = 0; i < anchorPath.length - 1; i++) {
|
|
65
|
+
if (anchorPath[i] !== focusPath[i])
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
return focusPath[focusPath.length - 1] - anchorPath[anchorPath.length - 1];
|
|
69
|
+
}
|
|
70
|
+
export function blockquoteAtSiblingOffset(root, anchorId, offset) {
|
|
71
|
+
const anchorPath = findQuoteBlockPath(root, anchorId);
|
|
72
|
+
if (!anchorPath)
|
|
73
|
+
return null;
|
|
74
|
+
const parentPath = anchorPath.slice(0, -1);
|
|
75
|
+
const parent = parentPath.length === 0 ? root : nodeAtQuotePath(root, parentPath);
|
|
76
|
+
const idx = anchorPath[anchorPath.length - 1] + offset;
|
|
77
|
+
return parent?.children?.[idx] ?? null;
|
|
78
|
+
}
|
|
79
|
+
/** @deprecated Use {@link findQuoteBlockPath}. */
|
|
80
|
+
export function findQuoteParagraphPath(root, paragraphId) {
|
|
81
|
+
return findQuoteBlockPath(root, paragraphId);
|
|
82
|
+
}
|
|
83
|
+
function parentAtPath(root, path) {
|
|
84
|
+
if (path.length === 0)
|
|
85
|
+
return root.type === 'blockquote' ? root : null;
|
|
86
|
+
const parentPath = path.slice(0, -1);
|
|
87
|
+
const parent = nodeAtQuotePath(root, parentPath);
|
|
88
|
+
return parent ?? root;
|
|
89
|
+
}
|
|
90
|
+
export function quoteMoveSibling(root, path, direction) {
|
|
91
|
+
if (path.length === 0)
|
|
92
|
+
return null;
|
|
93
|
+
const parent = parentAtPath(root, path);
|
|
94
|
+
const node = nodeAtQuotePath(root, path);
|
|
95
|
+
if (!parent || !node)
|
|
96
|
+
return null;
|
|
97
|
+
const idx = path[path.length - 1];
|
|
98
|
+
const newIdx = direction === 'up' ? idx - 1 : idx + 1;
|
|
99
|
+
const chs = parent.children ?? [];
|
|
100
|
+
if (newIdx < 0 || newIdx >= chs.length)
|
|
101
|
+
return null;
|
|
102
|
+
const clone = deepCloneBlock(root);
|
|
103
|
+
const liveParent = nodeAtQuotePath(clone, path.slice(0, -1));
|
|
104
|
+
if (!liveParent)
|
|
105
|
+
return null;
|
|
106
|
+
const kids = [...(liveParent.children ?? [])];
|
|
107
|
+
const [removed] = kids.splice(idx, 1);
|
|
108
|
+
if (!removed)
|
|
109
|
+
return null;
|
|
110
|
+
kids.splice(newIdx, 0, removed);
|
|
111
|
+
liveParent.children = kids;
|
|
112
|
+
return clone;
|
|
113
|
+
}
|
|
114
|
+
export function quoteDeleteBlock(root, path) {
|
|
115
|
+
const node = nodeAtQuotePath(root, path);
|
|
116
|
+
if (!node)
|
|
117
|
+
return null;
|
|
118
|
+
if (path.length === 0)
|
|
119
|
+
return null;
|
|
120
|
+
const clone = deepCloneBlock(root);
|
|
121
|
+
const parent = nodeAtQuotePath(clone, path.slice(0, -1));
|
|
122
|
+
if (!parent)
|
|
123
|
+
return null;
|
|
124
|
+
const idx = path[path.length - 1];
|
|
125
|
+
parent.children = (parent.children ?? []).filter((_, i) => i !== idx);
|
|
126
|
+
return clone;
|
|
127
|
+
}
|
|
128
|
+
export function quoteDuplicateBlock(root, path) {
|
|
129
|
+
const node = nodeAtQuotePath(root, path);
|
|
130
|
+
if (!node || node.type !== 'blockquote')
|
|
131
|
+
return null;
|
|
132
|
+
const clone = deepCloneBlock(root);
|
|
133
|
+
const parent = path.length === 0 ? null : nodeAtQuotePath(clone, path.slice(0, -1));
|
|
134
|
+
const src = nodeAtQuotePath(clone, path);
|
|
135
|
+
if (!src || src.type !== 'blockquote')
|
|
136
|
+
return null;
|
|
137
|
+
const dup = deepCloneBlock(src);
|
|
138
|
+
dup.id = crypto.randomUUID();
|
|
139
|
+
function reId(n) {
|
|
140
|
+
n.id = crypto.randomUUID();
|
|
141
|
+
for (const ch of n.children ?? [])
|
|
142
|
+
reId(ch);
|
|
143
|
+
}
|
|
144
|
+
reId(dup);
|
|
145
|
+
if (path.length === 0)
|
|
146
|
+
return dup;
|
|
147
|
+
if (!parent)
|
|
148
|
+
return null;
|
|
149
|
+
const idx = path[path.length - 1];
|
|
150
|
+
const kids = [...(parent.children ?? [])];
|
|
151
|
+
kids.splice(idx + 1, 0, dup);
|
|
152
|
+
parent.children = kids;
|
|
153
|
+
return clone;
|
|
154
|
+
}
|
|
155
|
+
export function quoteBlockCanMoveSibling(root, path, direction) {
|
|
156
|
+
if (path.length === 0)
|
|
157
|
+
return false;
|
|
158
|
+
const parent = parentAtPath(root, path);
|
|
159
|
+
const idx = path[path.length - 1];
|
|
160
|
+
const newIdx = direction === 'up' ? idx - 1 : idx + 1;
|
|
161
|
+
const chs = parent?.children ?? [];
|
|
162
|
+
return newIdx >= 0 && newIdx < chs.length;
|
|
163
|
+
}
|
|
164
|
+
/** @deprecated */
|
|
165
|
+
export function quoteDeleteParagraph(root, path) {
|
|
166
|
+
return quoteDeleteBlock(root, path);
|
|
167
|
+
}
|
|
168
|
+
/** @deprecated */
|
|
169
|
+
export function quoteDuplicateParagraph(root, path) {
|
|
170
|
+
return quoteDuplicateBlock(root, path);
|
|
171
|
+
}
|
|
172
|
+
/** @deprecated */
|
|
173
|
+
export function quoteParagraphCanMoveSibling(root, path, direction) {
|
|
174
|
+
return quoteBlockCanMoveSibling(root, path, direction);
|
|
175
|
+
}
|
|
176
|
+
/** @deprecated */
|
|
177
|
+
export function quoteReorderParagraph(root, quotePath, fromIndex, toIndex) {
|
|
178
|
+
const quote = nodeAtQuotePath(root, quotePath);
|
|
179
|
+
if (!quote || quote.type !== 'blockquote')
|
|
180
|
+
return null;
|
|
181
|
+
const chs = quote.children ?? [];
|
|
182
|
+
if (fromIndex === toIndex || fromIndex < 0 || toIndex < 0)
|
|
183
|
+
return null;
|
|
184
|
+
if (fromIndex >= chs.length || toIndex >= chs.length)
|
|
185
|
+
return null;
|
|
186
|
+
const clone = deepCloneBlock(root);
|
|
187
|
+
const liveQuote = nodeAtQuotePath(clone, quotePath);
|
|
188
|
+
if (!liveQuote)
|
|
189
|
+
return null;
|
|
190
|
+
const kids = [...(liveQuote.children ?? [])];
|
|
191
|
+
const [removed] = kids.splice(fromIndex, 1);
|
|
192
|
+
if (!removed)
|
|
193
|
+
return null;
|
|
194
|
+
kids.splice(toIndex, 0, removed);
|
|
195
|
+
liveQuote.children = kids;
|
|
196
|
+
return clone;
|
|
197
|
+
}
|
|
198
|
+
export function quoteBlockIndices(quote) {
|
|
199
|
+
const out = [];
|
|
200
|
+
const chs = quote.children ?? [];
|
|
201
|
+
for (let i = 0; i < chs.length; i++) {
|
|
202
|
+
if (chs[i]?.type === 'blockquote')
|
|
203
|
+
out.push(i);
|
|
204
|
+
}
|
|
205
|
+
return out;
|
|
206
|
+
}
|
|
207
|
+
function makeEmptyBlockquote() {
|
|
208
|
+
return {
|
|
209
|
+
type: 'blockquote',
|
|
210
|
+
id: crypto.randomUUID(),
|
|
211
|
+
sourceRange: syntheticRange(),
|
|
212
|
+
data: {},
|
|
213
|
+
children: [],
|
|
214
|
+
inlines: []
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function quoteSiblingContext(root, path) {
|
|
218
|
+
const node = nodeAtQuotePath(root, path);
|
|
219
|
+
if (!node || node.type !== 'blockquote')
|
|
220
|
+
return null;
|
|
221
|
+
if (path.length === 0) {
|
|
222
|
+
if (!root.children)
|
|
223
|
+
root.children = [];
|
|
224
|
+
return { parent: root, siblings: root.children, index: -1, node: root, pathLength: 0 };
|
|
225
|
+
}
|
|
226
|
+
const parentPath = path.slice(0, -1);
|
|
227
|
+
const parent = nodeAtQuotePath(root, parentPath);
|
|
228
|
+
if (!parent)
|
|
229
|
+
return null;
|
|
230
|
+
if (!parent.children)
|
|
231
|
+
parent.children = [];
|
|
232
|
+
const index = path[path.length - 1];
|
|
233
|
+
return { parent, siblings: parent.children, index, node, pathLength: path.length };
|
|
234
|
+
}
|
|
235
|
+
function shouldExitEmptyQuote(ctx, source) {
|
|
236
|
+
const body = blockquoteDisplayPlain(ctx.node, source);
|
|
237
|
+
if (body.length > 0)
|
|
238
|
+
return false;
|
|
239
|
+
if (ctx.index > 0) {
|
|
240
|
+
const prev = ctx.siblings[ctx.index - 1];
|
|
241
|
+
return prev?.type === 'blockquote' && blockquoteBodyPlain(prev, source).length === 0;
|
|
242
|
+
}
|
|
243
|
+
if (ctx.index === 0 && ctx.pathLength > 0) {
|
|
244
|
+
return ctx.parent.type === 'blockquote' && blockquoteBodyPlain(ctx.parent, source).length === 0;
|
|
245
|
+
}
|
|
246
|
+
if (ctx.pathLength === 0) {
|
|
247
|
+
const kids = ctx.siblings;
|
|
248
|
+
const last = kids[kids.length - 1];
|
|
249
|
+
return last?.type === 'blockquote' && blockquoteBodyPlain(last, source).length === 0;
|
|
250
|
+
}
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
export function quoteEnterAtPlain(root, quotePath, offset, plainText, source) {
|
|
254
|
+
if (root.type !== 'blockquote')
|
|
255
|
+
return null;
|
|
256
|
+
const clone = deepCloneBlock(root);
|
|
257
|
+
const ctxRaw = quoteSiblingContext(clone, quotePath);
|
|
258
|
+
if (!ctxRaw)
|
|
259
|
+
return null;
|
|
260
|
+
const ctx = ctxRaw;
|
|
261
|
+
const body = plainText;
|
|
262
|
+
if (body.length === 0) {
|
|
263
|
+
if (shouldExitEmptyQuote(ctx, source)) {
|
|
264
|
+
if (ctx.pathLength === 0) {
|
|
265
|
+
setBlockquoteBodyPlain(ctx.node, '');
|
|
266
|
+
while (ctx.siblings.length > 0) {
|
|
267
|
+
const last = ctx.siblings[ctx.siblings.length - 1];
|
|
268
|
+
if (last?.type !== 'blockquote' || blockquoteBodyPlain(last, source).length > 0)
|
|
269
|
+
break;
|
|
270
|
+
ctx.siblings.pop();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
ctx.siblings.splice(ctx.index, 1);
|
|
275
|
+
}
|
|
276
|
+
return { root: clone, exitToParagraph: true };
|
|
277
|
+
}
|
|
278
|
+
const newQuote = makeEmptyBlockquote();
|
|
279
|
+
if (ctx.pathLength === 0) {
|
|
280
|
+
ctx.siblings.push(newQuote);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
ctx.siblings.splice(ctx.index + 1, 0, newQuote);
|
|
284
|
+
}
|
|
285
|
+
return { root: clone, focusBlockId: newQuote.id };
|
|
286
|
+
}
|
|
287
|
+
if (offset <= 0) {
|
|
288
|
+
const newQuote = makeEmptyBlockquote();
|
|
289
|
+
if (ctx.pathLength === 0) {
|
|
290
|
+
ctx.siblings.unshift(newQuote);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
ctx.siblings.splice(ctx.index, 0, newQuote);
|
|
294
|
+
}
|
|
295
|
+
return { root: clone, focusBlockId: newQuote.id };
|
|
296
|
+
}
|
|
297
|
+
if (offset >= body.length) {
|
|
298
|
+
const newQuote = makeEmptyBlockquote();
|
|
299
|
+
if (ctx.pathLength === 0) {
|
|
300
|
+
ctx.siblings.push(newQuote);
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
ctx.siblings.splice(ctx.index + 1, 0, newQuote);
|
|
304
|
+
}
|
|
305
|
+
return { root: clone, focusBlockId: newQuote.id };
|
|
306
|
+
}
|
|
307
|
+
const left = body.slice(0, offset);
|
|
308
|
+
const right = body.slice(offset);
|
|
309
|
+
setBlockquoteBodyPlain(ctx.node, left);
|
|
310
|
+
const newQuote = makeEmptyBlockquote();
|
|
311
|
+
setBlockquoteBodyPlain(newQuote, right);
|
|
312
|
+
if (ctx.pathLength === 0) {
|
|
313
|
+
ctx.siblings.unshift(newQuote);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
ctx.siblings.splice(ctx.index + 1, 0, newQuote);
|
|
317
|
+
}
|
|
318
|
+
return { root: clone, focusBlockId: newQuote.id };
|
|
319
|
+
}
|
|
320
|
+
/** @deprecated */
|
|
321
|
+
export function quoteParagraphIndices(quote) {
|
|
322
|
+
return quoteBlockIndices(quote);
|
|
323
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EditorBlock } from './types';
|
|
2
|
+
/** Plain-text identity for matching block bodies. */
|
|
3
|
+
export declare function blockIdentityFingerprint(block: EditorBlock): string;
|
|
4
|
+
/**
|
|
5
|
+
* Reassigns stable session IDs to parsed blocks by matching the previous frame.
|
|
6
|
+
* Recurses into matched pairs' `children` so nested list items / blockquote children
|
|
7
|
+
* keep stable IDs across reparses. Synthetic blocks keep their existing `id` (editor-assigned).
|
|
8
|
+
*/
|
|
9
|
+
export declare function reconcileBlockIds(prev: EditorBlock[], next: EditorBlock[]): EditorBlock[];
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { blockquoteReconcileFingerprint } from '../block-specs/blockquote/reconcile';
|
|
2
|
+
import { calloutReconcileFingerprint } from '../block-specs/callout/reconcile';
|
|
3
|
+
import { codeFenceReconcileFingerprint } from '../block-specs/codeFence/reconcile';
|
|
4
|
+
import { columnsReconcileFingerprint } from '../block-specs/columns/reconcile';
|
|
5
|
+
import { headingReconcileFingerprint } from '../block-specs/heading/reconcile';
|
|
6
|
+
import { horizontalRuleReconcileFingerprint } from '../block-specs/horizontalRule/reconcile';
|
|
7
|
+
import { listItemReconcileFingerprint } from '../block-specs/list/reconcile';
|
|
8
|
+
import { paragraphReconcileFingerprint } from '../block-specs/paragraph/reconcile';
|
|
9
|
+
import { tableReconcileFingerprint } from '../block-specs/table/reconcile';
|
|
10
|
+
import { tocReconcileFingerprint } from '../block-specs/toc/reconcile';
|
|
11
|
+
import { toggleReconcileFingerprint } from '../block-specs/toggle/reconcile';
|
|
12
|
+
function newSessionId() {
|
|
13
|
+
return crypto.randomUUID();
|
|
14
|
+
}
|
|
15
|
+
/** Plain-text identity for matching block bodies. */
|
|
16
|
+
export function blockIdentityFingerprint(block) {
|
|
17
|
+
if (block.type === 'paragraph') {
|
|
18
|
+
return paragraphReconcileFingerprint(block);
|
|
19
|
+
}
|
|
20
|
+
if (block.type === 'heading') {
|
|
21
|
+
return headingReconcileFingerprint(block);
|
|
22
|
+
}
|
|
23
|
+
if (block.type === 'listItem') {
|
|
24
|
+
return listItemReconcileFingerprint(block);
|
|
25
|
+
}
|
|
26
|
+
if (block.type === 'blockquote') {
|
|
27
|
+
return blockquoteReconcileFingerprint(block, blockIdentityFingerprint);
|
|
28
|
+
}
|
|
29
|
+
if (block.type === 'table') {
|
|
30
|
+
return tableReconcileFingerprint(block);
|
|
31
|
+
}
|
|
32
|
+
if (block.type === 'callout') {
|
|
33
|
+
return calloutReconcileFingerprint(block, blockIdentityFingerprint);
|
|
34
|
+
}
|
|
35
|
+
if (block.type === 'toggle') {
|
|
36
|
+
return toggleReconcileFingerprint(block);
|
|
37
|
+
}
|
|
38
|
+
if (block.type === 'codeFence') {
|
|
39
|
+
return codeFenceReconcileFingerprint(block);
|
|
40
|
+
}
|
|
41
|
+
if (block.type === 'horizontalRule') {
|
|
42
|
+
return horizontalRuleReconcileFingerprint(block);
|
|
43
|
+
}
|
|
44
|
+
if (block.type === 'columns') {
|
|
45
|
+
return columnsReconcileFingerprint(block);
|
|
46
|
+
}
|
|
47
|
+
if (block.type === 'toc') {
|
|
48
|
+
return tocReconcileFingerprint(block);
|
|
49
|
+
}
|
|
50
|
+
return `${block.type}:${block.sourceRange.startLine}:${block.sourceRange.endLine}`;
|
|
51
|
+
}
|
|
52
|
+
function realRange(block) {
|
|
53
|
+
return !block.sourceRange.synthetic && block.sourceRange.start >= 0;
|
|
54
|
+
}
|
|
55
|
+
/** Shared prefix length — cheap stand-in for similarity while typing. */
|
|
56
|
+
function prefixOverlap(a, b) {
|
|
57
|
+
let n = 0;
|
|
58
|
+
const max = Math.min(a.length, b.length);
|
|
59
|
+
while (n < max && a.charCodeAt(n) === b.charCodeAt(n))
|
|
60
|
+
n++;
|
|
61
|
+
return n;
|
|
62
|
+
}
|
|
63
|
+
function scorePair(prev, next, prevIndex, nextIndex) {
|
|
64
|
+
if (prev.type !== next.type)
|
|
65
|
+
return -1;
|
|
66
|
+
const fpPrev = blockIdentityFingerprint(prev);
|
|
67
|
+
const fpNext = blockIdentityFingerprint(next);
|
|
68
|
+
const pref = prefixOverlap(fpPrev, fpNext);
|
|
69
|
+
const indexBonus = 50 - Math.min(50, Math.abs(prevIndex - nextIndex) * 5);
|
|
70
|
+
return pref + indexBonus + (fpPrev === fpNext ? 200 : 0);
|
|
71
|
+
}
|
|
72
|
+
function collectRealListItems(blocks) {
|
|
73
|
+
const out = [];
|
|
74
|
+
function walk(block) {
|
|
75
|
+
if (block.type === 'listItem' && realRange(block))
|
|
76
|
+
out.push(block);
|
|
77
|
+
for (const child of block.children ?? [])
|
|
78
|
+
walk(child);
|
|
79
|
+
}
|
|
80
|
+
for (const block of blocks)
|
|
81
|
+
walk(block);
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
function collectListItems(blocks) {
|
|
85
|
+
const out = [];
|
|
86
|
+
function walk(block) {
|
|
87
|
+
if (block.type === 'listItem')
|
|
88
|
+
out.push(block);
|
|
89
|
+
for (const child of block.children ?? [])
|
|
90
|
+
walk(child);
|
|
91
|
+
}
|
|
92
|
+
for (const block of blocks)
|
|
93
|
+
walk(block);
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
function collectAllIds(blocks) {
|
|
97
|
+
const out = new Set();
|
|
98
|
+
function walk(block) {
|
|
99
|
+
out.add(block.id);
|
|
100
|
+
for (const child of block.children ?? [])
|
|
101
|
+
walk(child);
|
|
102
|
+
}
|
|
103
|
+
for (const block of blocks)
|
|
104
|
+
walk(block);
|
|
105
|
+
return out;
|
|
106
|
+
}
|
|
107
|
+
/** Assign fresh UUIDs to every block in the subtree (used for unmatched / fresh nested children). */
|
|
108
|
+
function assignFreshIdsRecursive(block) {
|
|
109
|
+
if (realRange(block)) {
|
|
110
|
+
block.id = newSessionId();
|
|
111
|
+
}
|
|
112
|
+
if (block.children) {
|
|
113
|
+
for (const c of block.children)
|
|
114
|
+
assignFreshIdsRecursive(c);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Reassigns stable session IDs to parsed blocks by matching the previous frame.
|
|
119
|
+
* Recurses into matched pairs' `children` so nested list items / blockquote children
|
|
120
|
+
* keep stable IDs across reparses. Synthetic blocks keep their existing `id` (editor-assigned).
|
|
121
|
+
*/
|
|
122
|
+
export function reconcileBlockIds(prev, next) {
|
|
123
|
+
const out = next.map((b) => cloneBlock(b));
|
|
124
|
+
const prevReal = prev.filter((p) => realRange(p));
|
|
125
|
+
const realNextIndices = [];
|
|
126
|
+
for (let i = 0; i < out.length; i++) {
|
|
127
|
+
if (realRange(out[i]))
|
|
128
|
+
realNextIndices.push(i);
|
|
129
|
+
}
|
|
130
|
+
if (realNextIndices.length === 0) {
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
133
|
+
if (prevReal.length === 0) {
|
|
134
|
+
for (const i of realNextIndices) {
|
|
135
|
+
assignFreshIdsRecursive(out[i]);
|
|
136
|
+
}
|
|
137
|
+
return out;
|
|
138
|
+
}
|
|
139
|
+
const usedPrev = new Set();
|
|
140
|
+
const matchedPrevByNextIdx = new Map();
|
|
141
|
+
// Phase 1: exact source start + type
|
|
142
|
+
for (const i of realNextIndices) {
|
|
143
|
+
const nb = out[i];
|
|
144
|
+
if (!realRange(nb))
|
|
145
|
+
continue;
|
|
146
|
+
for (let pj = 0; pj < prevReal.length; pj++) {
|
|
147
|
+
if (usedPrev.has(pj))
|
|
148
|
+
continue;
|
|
149
|
+
const pb = prevReal[pj];
|
|
150
|
+
if (pb.type !== nb.type)
|
|
151
|
+
continue;
|
|
152
|
+
if (pb.sourceRange.start !== nb.sourceRange.start)
|
|
153
|
+
continue;
|
|
154
|
+
out[i].id = pb.id;
|
|
155
|
+
usedPrev.add(pj);
|
|
156
|
+
matchedPrevByNextIdx.set(i, pb);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Phase 1b: empty list demotion preserves row identity across listItem -> paragraph.
|
|
161
|
+
for (const i of realNextIndices) {
|
|
162
|
+
if (matchedPrevByNextIdx.has(i))
|
|
163
|
+
continue;
|
|
164
|
+
const nb = out[i];
|
|
165
|
+
if (!realRange(nb) || nb.type !== 'paragraph')
|
|
166
|
+
continue;
|
|
167
|
+
for (let pj = 0; pj < prevReal.length; pj++) {
|
|
168
|
+
if (usedPrev.has(pj))
|
|
169
|
+
continue;
|
|
170
|
+
const pb = prevReal[pj];
|
|
171
|
+
if (pb.type !== 'listItem')
|
|
172
|
+
continue;
|
|
173
|
+
if (pb.sourceRange.start !== nb.sourceRange.start)
|
|
174
|
+
continue;
|
|
175
|
+
out[i].id = pb.id;
|
|
176
|
+
usedPrev.add(pj);
|
|
177
|
+
matchedPrevByNextIdx.set(i, pb);
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Phase 1c: demotion that splits a list run shifts source offsets (blank lines
|
|
182
|
+
// inserted around the demoted row), so the exact-start match in Phase 1b misses.
|
|
183
|
+
// Empty-list demotion only fires on an empty body, and the demoted paragraph
|
|
184
|
+
// serializes with a whitespace placeholder, so match the nearest unmatched
|
|
185
|
+
// empty-bodied prev listItem to keep the row's reconciled id (post-split focus).
|
|
186
|
+
for (const i of realNextIndices) {
|
|
187
|
+
if (matchedPrevByNextIdx.has(i))
|
|
188
|
+
continue;
|
|
189
|
+
const nb = out[i];
|
|
190
|
+
if (!realRange(nb) || nb.type !== 'paragraph')
|
|
191
|
+
continue;
|
|
192
|
+
if (blockIdentityFingerprint(nb).trim().length > 0)
|
|
193
|
+
continue;
|
|
194
|
+
let bestPj = -1;
|
|
195
|
+
let bestDistance = Infinity;
|
|
196
|
+
for (let pj = 0; pj < prevReal.length; pj++) {
|
|
197
|
+
if (usedPrev.has(pj))
|
|
198
|
+
continue;
|
|
199
|
+
const pb = prevReal[pj];
|
|
200
|
+
if (pb.type !== 'listItem')
|
|
201
|
+
continue;
|
|
202
|
+
if (blockIdentityFingerprint(pb).trim().length > 0)
|
|
203
|
+
continue;
|
|
204
|
+
const distance = Math.abs(pb.sourceRange.start - nb.sourceRange.start);
|
|
205
|
+
if (distance < bestDistance) {
|
|
206
|
+
bestDistance = distance;
|
|
207
|
+
bestPj = pj;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (bestPj >= 0) {
|
|
211
|
+
out[i].id = prevReal[bestPj].id;
|
|
212
|
+
usedPrev.add(bestPj);
|
|
213
|
+
matchedPrevByNextIdx.set(i, prevReal[bestPj]);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Phase 2: greedy score
|
|
217
|
+
for (const i of realNextIndices) {
|
|
218
|
+
if (matchedPrevByNextIdx.has(i))
|
|
219
|
+
continue;
|
|
220
|
+
const nb = out[i];
|
|
221
|
+
let bestPj = -1;
|
|
222
|
+
let bestScore = -1;
|
|
223
|
+
for (let pj = 0; pj < prevReal.length; pj++) {
|
|
224
|
+
if (usedPrev.has(pj))
|
|
225
|
+
continue;
|
|
226
|
+
const origPrevIdx = prev.indexOf(prevReal[pj]);
|
|
227
|
+
const s = scorePair(prevReal[pj], nb, origPrevIdx, i);
|
|
228
|
+
if (s > bestScore) {
|
|
229
|
+
bestScore = s;
|
|
230
|
+
bestPj = pj;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (bestPj >= 0 && bestScore >= 55) {
|
|
234
|
+
out[i].id = prevReal[bestPj].id;
|
|
235
|
+
usedPrev.add(bestPj);
|
|
236
|
+
matchedPrevByNextIdx.set(i, prevReal[bestPj]);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
for (const i of realNextIndices) {
|
|
240
|
+
const nb = out[i];
|
|
241
|
+
const pb = matchedPrevByNextIdx.get(i);
|
|
242
|
+
if (!pb) {
|
|
243
|
+
assignFreshIdsRecursive(nb);
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (nb.children && nb.children.length > 0) {
|
|
247
|
+
const reconciledChildren = reconcileBlockIds(pb.children ?? [], nb.children);
|
|
248
|
+
nb.children = reconciledChildren;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
reconcileMovedListItemIds(prev, out);
|
|
252
|
+
return out;
|
|
253
|
+
}
|
|
254
|
+
function reconcileMovedListItemIds(prev, next) {
|
|
255
|
+
const prevItems = collectRealListItems(prev);
|
|
256
|
+
if (prevItems.length === 0)
|
|
257
|
+
return;
|
|
258
|
+
const prevIds = new Set(prevItems.map((item) => item.id));
|
|
259
|
+
// A prev list-item id is off-limits if it is already carried by *any* next block,
|
|
260
|
+
// not just a next list item: empty-list demotion (Phase 1c) can assign a former
|
|
261
|
+
// list-item id to the demoted paragraph, and reusing it here would duplicate the key.
|
|
262
|
+
const usedPrevIds = new Set();
|
|
263
|
+
for (const id of collectAllIds(next)) {
|
|
264
|
+
if (prevIds.has(id))
|
|
265
|
+
usedPrevIds.add(id);
|
|
266
|
+
}
|
|
267
|
+
const nextItems = collectListItems(next);
|
|
268
|
+
for (let nextIndex = 0; nextIndex < nextItems.length; nextIndex++) {
|
|
269
|
+
const nextItem = nextItems[nextIndex];
|
|
270
|
+
if (prevIds.has(nextItem.id))
|
|
271
|
+
continue;
|
|
272
|
+
let best = null;
|
|
273
|
+
let bestScore = -1;
|
|
274
|
+
for (let prevIndex = 0; prevIndex < prevItems.length; prevIndex++) {
|
|
275
|
+
const prevItem = prevItems[prevIndex];
|
|
276
|
+
if (usedPrevIds.has(prevItem.id))
|
|
277
|
+
continue;
|
|
278
|
+
const score = scorePair(prevItem, nextItem, prevIndex, nextIndex);
|
|
279
|
+
if (score > bestScore) {
|
|
280
|
+
best = prevItem;
|
|
281
|
+
bestScore = score;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (best && bestScore >= 55) {
|
|
285
|
+
nextItem.id = best.id;
|
|
286
|
+
usedPrevIds.add(best.id);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/** Shallow clone with a fresh `children` array (children themselves are reused; ids are mutated in place via `cloneBlock` recursion). */
|
|
291
|
+
function cloneBlock(block) {
|
|
292
|
+
const out = { ...block };
|
|
293
|
+
if (block.children) {
|
|
294
|
+
out.children = block.children.map(cloneBlock);
|
|
295
|
+
}
|
|
296
|
+
return out;
|
|
297
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EditorBlockType } from './types';
|
|
2
|
+
/** How {@link MarkdownEditor} chooses full vs incremental reparse. */
|
|
3
|
+
export type ReparseKind = 'full' | 'inlineDraftCommit';
|
|
4
|
+
export type InlineDraftCommitBlockType = Extract<EditorBlockType, 'paragraph' | 'heading' | 'table'>;
|
|
5
|
+
export type ReparseOptions = {
|
|
6
|
+
kind: 'full';
|
|
7
|
+
} | {
|
|
8
|
+
kind: 'inlineDraftCommit';
|
|
9
|
+
blockIndex: number;
|
|
10
|
+
expectedType: InlineDraftCommitBlockType;
|
|
11
|
+
};
|
|
12
|
+
export declare const FULL_REPARSE: ReparseOptions;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const FULL_REPARSE = { kind: 'full' };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { EditorBlock } from './types';
|
|
2
|
+
/** Map live DOM plain + caret into model display-plain coordinates for Enter. */
|
|
3
|
+
export declare function resolveEnterPlainSnapshot(block: EditorBlock, plainText: string, plainOffset: number, kind: 'paragraph' | 'heading'): {
|
|
4
|
+
plain: string;
|
|
5
|
+
offset: number;
|
|
6
|
+
};
|