@voithos-labs/aragonite 0.10.3 → 0.10.7
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 +2 -2
- package/dist/a11y-strings.d.ts +12 -5
- package/dist/a11y-strings.js +61 -5
- package/dist/action-contracts.d.ts +242 -155
- package/dist/action-contracts.js +2 -2
- package/dist/active-editor.d.ts +3 -3
- package/dist/active-editor.js +8 -9
- package/dist/ambient/ambient-dom.d.ts +2 -5
- package/dist/ambient/ambient-dom.js +16 -62
- package/dist/assert.js +6 -5
- package/dist/block-component.d.ts +135 -109
- package/dist/block-component.js +30 -22
- package/dist/block-id.d.ts +6 -10
- package/dist/block-id.js +25 -14
- package/dist/bounded-memo.d.ts +5 -5
- package/dist/bounded-memo.js +6 -6
- package/dist/components/BlockDragHandle.svelte +13 -20
- package/dist/components/BlockHost.svelte +56 -134
- package/dist/components/BlockList.svelte +22 -19
- package/dist/components/DecorationOverlay.svelte +9 -10
- package/dist/components/DecorationOverlay.svelte.d.ts +2 -2
- package/dist/components/Editor.svelte +619 -1089
- package/dist/components/Editor.svelte.d.ts +9 -20
- package/dist/components/GapCaret.svelte +26 -59
- package/dist/components/SelectionOverlay.svelte +36 -67
- package/dist/components/SelectionOverlay.svelte.d.ts +6 -4
- package/dist/components/TailInsert.svelte +8 -55
- package/dist/components/TailInsert.svelte.d.ts +4 -6
- package/dist/components/block-content-selector.d.ts +11 -11
- package/dist/components/block-content-selector.js +11 -11
- package/dist/components/block-el-lookup.d.ts +6 -0
- package/dist/components/block-el-lookup.js +27 -0
- package/dist/components/blocks/BlockquoteBlock.svelte +3 -3
- package/dist/components/blocks/ThematicBreakBlock.svelte +22 -63
- package/dist/components/blocks/ThematicBreakBlock.svelte.d.ts +0 -2
- package/dist/components/blocks/code/CodeBlock.svelte +255 -276
- package/dist/components/blocks/code/CodeBlock.svelte.d.ts +2 -3
- package/dist/components/blocks/code/CodeBlockRail.svelte +103 -100
- package/dist/components/blocks/code/CodeBlockRail.svelte.d.ts +9 -4
- package/dist/components/blocks/code/code-beforeinput.d.ts +1 -1
- package/dist/components/blocks/code/code-bootstrap.d.ts +3 -5
- package/dist/components/blocks/code/code-bootstrap.js +35 -28
- package/dist/components/blocks/code/code-context-actions.js +5 -4
- package/dist/components/blocks/code/code-enter.js +2 -2
- package/dist/components/blocks/code/code-fence-boundary.d.ts +29 -46
- package/dist/components/blocks/code/code-fence-boundary.js +40 -66
- package/dist/components/blocks/code/code-fence-exit.d.ts +6 -11
- package/dist/components/blocks/code/code-fence-exit.js +24 -25
- package/dist/components/blocks/code/code-indent.d.ts +2 -2
- package/dist/components/blocks/code/code-indent.js +4 -7
- package/dist/components/blocks/code/code-languages.d.ts +16 -12
- package/dist/components/blocks/code/code-languages.js +58 -32
- package/dist/components/blocks/code/code-paste-surface.d.ts +3 -2
- package/dist/components/blocks/code/code-paste-surface.js +9 -18
- package/dist/components/blocks/code/code-renderer.d.ts +21 -5
- package/dist/components/blocks/code/code-renderer.js +90 -125
- package/dist/components/blocks/directive/DirectiveContainerBlock.svelte +5 -8
- package/dist/components/blocks/directive/activate-directives.d.ts +4 -4
- package/dist/components/blocks/directive/activate-directives.js +18 -13
- package/dist/components/blocks/editable-leaf.d.ts +50 -74
- package/dist/components/blocks/editable-leaf.js +144 -202
- package/dist/components/blocks/editable-surface.d.ts +96 -100
- package/dist/components/blocks/editable-surface.js +101 -109
- package/dist/components/blocks/list/ListBlock.svelte +46 -90
- package/dist/components/blocks/list/ListItemBlock.svelte +99 -144
- package/dist/components/blocks/list/ListItemBlock.svelte.d.ts +3 -0
- package/dist/components/blocks/list/task-checkbox.d.ts +5 -2
- package/dist/components/blocks/list/task-checkbox.js +12 -7
- package/dist/components/blocks/plain-text-backend.d.ts +4 -20
- package/dist/components/blocks/plain-text-backend.js +9 -43
- package/dist/components/blocks/surface-wiring.svelte.d.ts +8 -9
- package/dist/components/blocks/surface-wiring.svelte.js +15 -34
- package/dist/components/blocks/table/TableActionMenu.svelte +19 -18
- package/dist/components/blocks/table/TableActionMenu.svelte.d.ts +3 -1
- package/dist/components/blocks/table/TableBlock.svelte +100 -165
- package/dist/components/blocks/table/TableBlock.svelte.d.ts +3 -3
- package/dist/components/blocks/table/TableCellBlock.svelte +307 -385
- package/dist/components/blocks/table/TableCellBlock.svelte.d.ts +1 -0
- package/dist/components/blocks/table/TableRowBlock.svelte +60 -104
- package/dist/components/blocks/table/TableRowBlock.svelte.d.ts +0 -1
- package/dist/components/blocks/table/cell-keydown-plan.d.ts +4 -9
- package/dist/components/blocks/table/cell-keydown-plan.js +8 -12
- package/dist/components/blocks/table/cell-pointer.d.ts +18 -23
- package/dist/components/blocks/table/cell-pointer.js +49 -71
- package/dist/components/blocks/table/cell-render.d.ts +24 -29
- package/dist/components/blocks/table/cell-render.js +29 -31
- package/dist/components/blocks/table/selected-cells.d.ts +7 -7
- package/dist/components/blocks/table/selected-cells.js +9 -13
- package/dist/components/blocks/table/table-caret-at-point.d.ts +4 -4
- package/dist/components/blocks/table/table-caret-at-point.js +5 -5
- package/dist/components/blocks/table/table-cell-paste.d.ts +5 -11
- package/dist/components/blocks/table/table-cell-paste.js +27 -43
- package/dist/components/blocks/table/table-drag-hit-test.js +2 -1
- package/dist/components/blocks/table/table-menu-model.d.ts +4 -8
- package/dist/components/blocks/table/table-menu-model.js +6 -10
- package/dist/components/blocks/table/table-navigation.js +2 -2
- package/dist/components/blocks/text/TextEditableBlock.svelte +392 -310
- package/dist/components/blocks/text/TextEditableBlock.svelte.d.ts +2 -1
- package/dist/components/blocks/text/auto-pair-record.d.ts +23 -0
- package/dist/components/blocks/text/auto-pair-record.js +51 -0
- package/dist/components/blocks/text/click-snap-guard.d.ts +9 -4
- package/dist/components/blocks/text/click-snap-guard.js +16 -5
- package/dist/components/blocks/text/composition-seat.d.ts +17 -14
- package/dist/components/blocks/text/composition-seat.js +11 -11
- package/dist/components/blocks/text/construct-edge-delete.d.ts +20 -20
- package/dist/components/blocks/text/construct-edge-delete.js +50 -65
- package/dist/components/blocks/text/construct-reveal.d.ts +16 -21
- package/dist/components/blocks/text/construct-reveal.js +13 -14
- package/dist/components/blocks/text/delimiter-autopair.d.ts +51 -34
- package/dist/components/blocks/text/delimiter-autopair.js +87 -103
- package/dist/components/blocks/text/edge-policy-dispatch.d.ts +44 -46
- package/dist/components/blocks/text/edge-policy-dispatch.js +164 -180
- package/dist/components/blocks/text/edge-seat.d.ts +17 -26
- package/dist/components/blocks/text/edge-seat.js +43 -70
- package/dist/components/blocks/text/link-at-point.d.ts +9 -9
- package/dist/components/blocks/text/link-at-point.js +12 -15
- package/dist/components/blocks/text/live-join-seam.d.ts +6 -9
- package/dist/components/blocks/text/live-join-seam.js +75 -112
- package/dist/components/blocks/text/live-selection-edit.d.ts +14 -43
- package/dist/components/blocks/text/live-selection-edit.js +32 -105
- package/dist/components/blocks/text/live-split-rebalance.d.ts +9 -13
- package/dist/components/blocks/text/live-split-rebalance.js +50 -67
- package/dist/components/blocks/text/marker-completion.d.ts +7 -12
- package/dist/components/blocks/text/marker-completion.js +17 -10
- package/dist/components/blocks/text/pending-mark-insert.d.ts +11 -18
- package/dist/components/blocks/text/pending-mark-insert.js +30 -49
- package/dist/components/blocks/text/screen-diff.d.ts +5 -15
- package/dist/components/blocks/text/screen-diff.js +5 -19
- package/dist/components/blocks/text/text-clipboard.d.ts +23 -32
- package/dist/components/blocks/text/text-clipboard.js +27 -32
- package/dist/components/blocks/text/text-keydown.d.ts +20 -30
- package/dist/components/blocks/text/text-keydown.js +54 -51
- package/dist/components/blocks/text/text-render.d.ts +25 -35
- package/dist/components/blocks/text/text-render.js +82 -61
- package/dist/components/blocks/text/widget-adjacency.d.ts +9 -9
- package/dist/components/blocks/text/widget-adjacency.js +17 -17
- package/dist/components/blocks/text/widget-interaction.d.ts +67 -43
- package/dist/components/blocks/text/widget-interaction.js +243 -208
- package/dist/components/blocks/widget-portal.d.ts +20 -29
- package/dist/components/blocks/widget-portal.js +16 -14
- package/dist/components/built-in-blocks.d.ts +3 -4
- package/dist/components/built-in-blocks.js +17 -18
- package/dist/components/drag-handle.d.ts +13 -30
- package/dist/components/drag-handle.js +25 -63
- package/dist/components/editor-built-ins.d.ts +1 -0
- package/dist/components/editor-built-ins.js +16 -0
- package/dist/components/editor-root-clipboard.d.ts +6 -6
- package/dist/components/editor-root-clipboard.js +16 -27
- package/dist/components/editor-root-document-swap.d.ts +49 -0
- package/dist/components/editor-root-document-swap.js +54 -0
- package/dist/components/editor-root-focus.d.ts +5 -4
- package/dist/components/editor-root-focus.js +51 -22
- package/dist/components/editor-root-focused-surface.d.ts +35 -0
- package/dist/components/editor-root-focused-surface.js +65 -0
- package/dist/components/editor-root-geometry.d.ts +15 -24
- package/dist/components/editor-root-geometry.js +27 -31
- package/dist/components/editor-root-gestures.d.ts +39 -0
- package/dist/components/editor-root-gestures.js +189 -0
- package/dist/components/editor-root-keydown.d.ts +10 -25
- package/dist/components/editor-root-keydown.js +19 -43
- package/dist/components/editor-root-listeners.d.ts +22 -31
- package/dist/components/editor-root-listeners.js +49 -46
- package/dist/components/editor-root-menus.d.ts +51 -0
- package/dist/components/editor-root-menus.js +147 -0
- package/dist/components/editor-root-mode-flip.d.ts +16 -11
- package/dist/components/editor-root-mode-flip.js +36 -34
- package/dist/components/editor-root-scroll-host.d.ts +22 -0
- package/dist/components/editor-root-scroll-host.js +34 -0
- package/dist/components/editor-root-test-surface.d.ts +48 -0
- package/dist/components/editor-root-test-surface.js +6 -0
- package/dist/components/image/ImageOverlayHost.svelte +44 -35
- package/dist/components/image/ImageOverlayHost.svelte.d.ts +5 -6
- package/dist/components/image/ImageProperties.svelte +37 -41
- package/dist/components/image/ImageProperties.svelte.d.ts +9 -4
- package/dist/components/image/ImageResizeHandles.svelte +26 -30
- package/dist/components/image/image-crop.d.ts +5 -11
- package/dist/components/image/image-crop.js +5 -11
- package/dist/components/image/image-edit-commit.d.ts +19 -16
- package/dist/components/image/image-edit-commit.js +74 -38
- package/dist/components/image/image-resize.d.ts +2 -5
- package/dist/components/image/image-resize.js +3 -6
- package/dist/components/image/image-widget-editing.d.ts +3 -3
- package/dist/components/image/image-widget-editing.js +9 -9
- package/dist/components/image/widget-dom.d.ts +2 -3
- package/dist/components/image/widget-dom.js +19 -24
- package/dist/components/image/widget-selection-state.svelte.d.ts +10 -11
- package/dist/components/image/widget-selection-state.svelte.js +26 -19
- package/dist/components/kind-cue.svelte.d.ts +21 -0
- package/dist/components/kind-cue.svelte.js +35 -0
- package/dist/components/link-card/LinkCard.svelte +115 -64
- package/dist/components/link-card/LinkCard.svelte.d.ts +7 -5
- package/dist/components/link-card/LinkCardHost.svelte +42 -33
- package/dist/components/link-card/LinkCardHost.svelte.d.ts +10 -8
- package/dist/components/link-card/link-card-commit.d.ts +16 -19
- package/dist/components/link-card/link-card-commit.js +21 -30
- package/dist/components/link-card/link-card-entry.d.ts +13 -23
- package/dist/components/link-card/link-card-entry.js +16 -24
- package/dist/components/link-card/link-card-state.svelte.d.ts +17 -21
- package/dist/components/link-card/link-card-state.svelte.js +2 -2
- package/dist/components/lrd-map-gate.d.ts +4 -11
- package/dist/components/lrd-map-gate.js +5 -11
- package/dist/components/menu/BlockMenu.svelte +20 -81
- package/dist/components/menu/BlockMenu.svelte.d.ts +11 -9
- package/dist/components/menu/InlineMenuHost.svelte +191 -0
- package/dist/components/menu/InlineMenuHost.svelte.d.ts +13 -0
- package/dist/components/menu/MenuIcon.svelte +3 -103
- package/dist/components/menu/MenuIcon.svelte.d.ts +2 -44
- package/dist/components/menu/SelectionToolbar.svelte +380 -0
- package/dist/components/menu/SelectionToolbar.svelte.d.ts +14 -0
- package/dist/components/menu/clipboard-actions.d.ts +3 -4
- package/dist/components/menu/clipboard-actions.js +3 -4
- package/dist/components/menu/default-context-actions.d.ts +4 -13
- package/dist/components/menu/default-context-actions.js +49 -67
- package/dist/components/menu/flyout-placement.d.ts +2 -2
- package/dist/components/menu/flyout-placement.js +2 -2
- package/dist/components/menu/menu-presence.svelte.d.ts +12 -0
- package/dist/components/menu/menu-presence.svelte.js +19 -0
- package/dist/components/paste-image-arm.d.ts +6 -11
- package/dist/components/paste-image-arm.js +11 -18
- package/dist/components/portal.d.ts +2 -5
- package/dist/components/portal.js +4 -7
- package/dist/core/directive/activate.d.ts +4 -5
- package/dist/core/directive/activate.js +8 -9
- package/dist/core/directive/container-opener.js +13 -12
- package/dist/core/directive/grammar.d.ts +2 -5
- package/dist/core/directive/grammar.js +10 -10
- package/dist/core/directive/kinds.d.ts +4 -7
- package/dist/core/directive/kinds.js +14 -16
- package/dist/core/directive/registry.d.ts +12 -9
- package/dist/core/directive/registry.js +19 -20
- package/dist/core/directive/text-recognizer.d.ts +3 -2
- package/dist/core/directive/text-recognizer.js +5 -9
- package/dist/core/escapable.d.ts +1 -5
- package/dist/core/escapable.js +1 -5
- package/dist/core/inline/backticks.d.ts +3 -4
- package/dist/core/inline/backticks.js +3 -4
- package/dist/core/inline/character-refs.js +2 -1
- package/dist/core/inline/destination-bytes.d.ts +6 -3
- package/dist/core/inline/destination-bytes.js +50 -8
- package/dist/core/inline/entity-widget.d.ts +4 -3
- package/dist/core/inline/entity-widget.js +6 -6
- package/dist/core/inline/format-toggle.d.ts +22 -28
- package/dist/core/inline/format-toggle.js +97 -129
- package/dist/core/inline/html-entities.d.ts +2 -3
- package/dist/core/inline/html-entities.js +2 -3
- package/dist/core/inline/html-tag-grammar.js +6 -2
- package/dist/core/inline/image-dimensions.d.ts +2 -0
- package/dist/core/inline/image-dimensions.js +19 -2
- package/dist/core/inline/image-source-bytes.d.ts +11 -0
- package/dist/core/inline/image-source-bytes.js +71 -0
- package/dist/core/inline/index.d.ts +28 -21
- package/dist/core/inline/index.js +56 -34
- package/dist/core/inline/inline-cache.d.ts +12 -15
- package/dist/core/inline/inline-cache.js +11 -14
- package/dist/core/inline/inline-widgets.d.ts +55 -68
- package/dist/core/inline/inline-widgets.js +55 -58
- package/dist/core/inline/link-destination.d.ts +31 -0
- package/dist/core/inline/link-destination.js +129 -0
- package/dist/core/inline/link-reference-resolver.d.ts +8 -6
- package/dist/core/inline/link-reference-resolver.js +10 -6
- package/dist/core/inline/link-source-bytes.d.ts +31 -0
- package/dist/{components/blocks/text → core/inline}/link-source-bytes.js +43 -54
- package/dist/core/inline/live-edit/read-back.d.ts +29 -0
- package/dist/core/inline/live-edit/read-back.js +50 -0
- package/dist/core/inline/picture.d.ts +10 -0
- package/dist/core/inline/picture.js +40 -0
- package/dist/core/inline/scan/autolinks.d.ts +7 -8
- package/dist/core/inline/scan/autolinks.js +80 -59
- package/dist/core/inline/scan/brackets.d.ts +2 -2
- package/dist/core/inline/scan/brackets.js +6 -103
- package/dist/core/inline/scan/code-spans.d.ts +4 -0
- package/dist/core/inline/scan/code-spans.js +8 -0
- package/dist/core/inline/scan/emphasis.js +10 -14
- package/dist/core/inline/scan/index.d.ts +3 -1
- package/dist/core/inline/scan/index.js +32 -33
- package/dist/core/inline/scan/plugin-syntax.d.ts +28 -36
- package/dist/core/inline/scan/plugin-syntax.js +75 -89
- package/dist/core/inline/scan/scan-state.d.ts +2 -0
- package/dist/core/inline/scan/scan-state.js +1 -0
- package/dist/core/inline/scan/simple-nodes.d.ts +2 -5
- package/dist/core/inline/scan/simple-nodes.js +2 -5
- package/dist/core/inline/scan/triggers.d.ts +17 -0
- package/dist/core/inline/scan/triggers.js +26 -0
- package/dist/core/inline/scan/url.js +8 -10
- package/dist/core/inline/transparency.d.ts +2 -1
- package/dist/core/inline/transparency.js +33 -17
- package/dist/core/inline/visibility.d.ts +30 -49
- package/dist/core/inline/visibility.js +31 -49
- package/dist/core/inline/walk.d.ts +4 -10
- package/dist/core/inline/walk.js +4 -10
- package/dist/core/inline-render.d.ts +22 -27
- package/dist/core/inline-render.js +51 -60
- package/dist/core/lines.d.ts +67 -26
- package/dist/core/lines.js +164 -33
- package/dist/core/metadata-parity.d.ts +9 -0
- package/dist/core/metadata-parity.js +25 -0
- package/dist/core/node-views.d.ts +7 -6
- package/dist/core/node-views.js +5 -5
- package/dist/core/nodes.d.ts +34 -44
- package/dist/core/nodes.js +4 -12
- package/dist/core/parser.d.ts +27 -34
- package/dist/core/parser.js +53 -67
- package/dist/core/parsers/blockquote.d.ts +5 -8
- package/dist/core/parsers/blockquote.js +11 -10
- package/dist/core/parsers/built-in-openers.d.ts +2 -5
- package/dist/core/parsers/built-in-openers.js +5 -8
- package/dist/core/parsers/fence-syntax.d.ts +36 -7
- package/dist/core/parsers/fence-syntax.js +61 -11
- package/dist/core/parsers/fenced-code.d.ts +16 -0
- package/dist/core/parsers/fenced-code.js +16 -15
- package/dist/core/parsers/heading.d.ts +19 -2
- package/dist/core/parsers/heading.js +50 -2
- package/dist/core/parsers/html-block.d.ts +3 -6
- package/dist/core/parsers/html-block.js +10 -11
- package/dist/core/parsers/indented-code.d.ts +1 -1
- package/dist/core/parsers/indented-code.js +2 -8
- package/dist/core/parsers/link-reference.d.ts +5 -3
- package/dist/core/parsers/link-reference.js +116 -120
- package/dist/core/parsers/list.d.ts +12 -5
- package/dist/core/parsers/list.js +53 -36
- package/dist/core/parsers/paragraph.d.ts +3 -3
- package/dist/core/parsers/paragraph.js +14 -5
- package/dist/core/parsers/table-completion.d.ts +2 -5
- package/dist/core/parsers/table-completion.js +7 -10
- package/dist/core/parsers/table.d.ts +8 -8
- package/dist/core/parsers/table.js +23 -26
- package/dist/core/parsers/thematic-break.js +15 -14
- package/dist/core/paths.d.ts +13 -0
- package/dist/core/paths.js +31 -0
- package/dist/core/terminator-escalation.d.ts +0 -7
- package/dist/core/terminator-escalation.js +5 -8
- package/dist/core/url-policy.d.ts +2 -5
- package/dist/core/url-policy.js +8 -12
- package/dist/cursor/caret-memory.d.ts +34 -0
- package/dist/cursor/caret-memory.js +82 -0
- package/dist/cursor/coordinate-spaces.d.ts +26 -19
- package/dist/cursor/coordinate-spaces.js +32 -20
- package/dist/cursor/dom-walk.d.ts +7 -13
- package/dist/cursor/dom-walk.js +7 -13
- package/dist/cursor/edge-affinity.d.ts +7 -35
- package/dist/cursor/edge-affinity.js +13 -44
- package/dist/cursor/focused-caret.d.ts +6 -8
- package/dist/cursor/focused-caret.js +7 -16
- package/dist/cursor/height-model.d.ts +3 -3
- package/dist/cursor/height-model.js +5 -5
- package/dist/cursor/height-oracle.d.ts +10 -7
- package/dist/cursor/height-oracle.js +26 -75
- package/dist/cursor/observe-resize.d.ts +13 -0
- package/dist/cursor/observe-resize.js +43 -0
- package/dist/cursor/overlay-rects.d.ts +2 -5
- package/dist/cursor/overlay-rects.js +2 -5
- package/dist/cursor/overlay-remeasure.d.ts +6 -7
- package/dist/cursor/overlay-remeasure.js +10 -14
- package/dist/cursor/pending-marks.d.ts +7 -9
- package/dist/cursor/pending-marks.js +6 -27
- package/dist/cursor/point-offset.d.ts +16 -10
- package/dist/cursor/point-offset.js +60 -25
- package/dist/cursor/reveal-source.d.ts +7 -11
- package/dist/cursor/reveal-source.js +10 -18
- package/dist/cursor/scroll-ancestors.d.ts +9 -20
- package/dist/cursor/scroll-ancestors.js +14 -26
- package/dist/cursor/scroll-owner.d.ts +92 -0
- package/dist/cursor/scroll-owner.js +283 -0
- package/dist/cursor/scrollport.d.ts +16 -8
- package/dist/cursor/scrollport.js +28 -5
- package/dist/cursor/sticky-column.d.ts +6 -29
- package/dist/cursor/sticky-column.js +6 -49
- package/dist/cursor/sticky-measure.d.ts +14 -9
- package/dist/cursor/sticky-measure.js +99 -49
- package/dist/cursor/surface-backend.d.ts +41 -0
- package/dist/cursor/surface-backend.js +78 -0
- package/dist/cursor/typography-estimates.d.ts +3 -3
- package/dist/cursor/typography-estimates.js +3 -3
- package/dist/cursor/visual-lines.d.ts +25 -13
- package/dist/cursor/visual-lines.js +72 -28
- package/dist/cursor/widget-edge-snap.d.ts +23 -0
- package/dist/cursor/widget-edge-snap.js +39 -0
- package/dist/cursor/widget-offset.d.ts +111 -102
- package/dist/cursor/widget-offset.js +352 -177
- package/dist/debug/diagnostics-report.d.ts +6 -6
- package/dist/debug/diagnostics-report.js +5 -5
- package/dist/debug/dump-tree.js +2 -2
- package/dist/debug/editor-diagnostics.d.ts +15 -0
- package/dist/debug/editor-diagnostics.js +33 -0
- package/dist/debug/inspect.d.ts +2 -2
- package/dist/debug/inspect.js +4 -4
- package/dist/debug/interaction-trace.d.ts +14 -15
- package/dist/debug/interaction-trace.js +19 -20
- package/dist/debug/operations-log.d.ts +1 -1
- package/dist/debug/operations-log.js +1 -1
- package/dist/decorations/buckets.d.ts +6 -12
- package/dist/decorations/buckets.js +4 -11
- package/dist/decorations/decoration-state.svelte.d.ts +2 -3
- package/dist/decorations/decoration-state.svelte.js +24 -26
- package/dist/decorations/island-dom.d.ts +10 -18
- package/dist/decorations/island-dom.js +25 -50
- package/dist/decorations/reserved-attrs.d.ts +6 -8
- package/dist/decorations/reserved-attrs.js +31 -17
- package/dist/decorations/types.d.ts +6 -7
- package/dist/decorations/types.js +2 -1
- package/dist/decorations/use-block-decorations.svelte.d.ts +19 -0
- package/dist/decorations/use-block-decorations.svelte.js +71 -0
- package/dist/decorations/widget-dom.d.ts +3 -3
- package/dist/decorations/widget-dom.js +5 -5
- package/dist/dev-warn.d.ts +5 -2
- package/dist/dev-warn.js +16 -4
- package/dist/editor-actions/ancestry-folds.d.ts +9 -14
- package/dist/editor-actions/ancestry-folds.js +13 -18
- package/dist/editor-actions/block-edit-core.d.ts +49 -22
- package/dist/editor-actions/block-edit-core.js +279 -151
- package/dist/editor-actions/block-edit-scope.d.ts +63 -50
- package/dist/editor-actions/block-edit-scope.js +100 -48
- package/dist/editor-actions/block-edit.d.ts +2 -3
- package/dist/editor-actions/block-edit.js +14 -90
- package/dist/editor-actions/commit/history.d.ts +4 -4
- package/dist/editor-actions/commit/history.js +33 -34
- package/dist/editor-actions/commit/reading-write-gate.d.ts +18 -0
- package/dist/editor-actions/commit/reading-write-gate.js +56 -0
- package/dist/editor-actions/commit/text-batch.d.ts +7 -11
- package/dist/editor-actions/commit/text-batch.js +6 -7
- package/dist/editor-actions/commit/undo-controller.d.ts +6 -4
- package/dist/editor-actions/commit/undo-controller.js +346 -216
- package/dist/editor-actions/container-block-component.d.ts +32 -51
- package/dist/editor-actions/container-block-component.js +66 -92
- package/dist/editor-actions/container-edit.d.ts +4 -2
- package/dist/editor-actions/container-edit.js +14 -44
- package/dist/editor-actions/container-exit-overrides.d.ts +6 -4
- package/dist/editor-actions/container-exit-overrides.js +19 -21
- package/dist/editor-actions/deps.d.ts +25 -32
- package/dist/editor-actions/enter-completion.d.ts +12 -15
- package/dist/editor-actions/enter-completion.js +49 -51
- package/dist/editor-actions/focus/focus-dispatch.d.ts +24 -25
- package/dist/editor-actions/focus/focus-dispatch.js +33 -52
- package/dist/editor-actions/focus/focus-landing.d.ts +11 -5
- package/dist/editor-actions/focus/focus-landing.js +29 -14
- package/dist/editor-actions/focus/focus.d.ts +3 -2
- package/dist/editor-actions/focus/focus.js +42 -59
- package/dist/editor-actions/index.d.ts +4 -3
- package/dist/editor-actions/index.js +5 -4
- package/dist/editor-actions/inline-range-commit.d.ts +18 -16
- package/dist/editor-actions/inline-range-commit.js +45 -54
- package/dist/editor-actions/leaf-write.d.ts +11 -0
- package/dist/editor-actions/leaf-write.js +102 -0
- package/dist/editor-actions/list-context.d.ts +9 -10
- package/dist/editor-actions/list-context.js +115 -110
- package/dist/editor-actions/list-overrides.d.ts +13 -5
- package/dist/editor-actions/list-overrides.js +36 -12
- package/dist/editor-actions/merge-fallback.d.ts +10 -16
- package/dist/editor-actions/merge-fallback.js +11 -22
- package/dist/editor-actions/nested/container-actions.d.ts +37 -0
- package/dist/editor-actions/nested/container-actions.js +42 -0
- package/dist/editor-actions/nested/emptied-container.d.ts +5 -0
- package/dist/editor-actions/nested/emptied-container.js +5 -0
- package/dist/editor-actions/nested/nested-actions.d.ts +22 -25
- package/dist/editor-actions/nested/nested-actions.js +17 -15
- package/dist/editor-actions/nested/nested-block-edit.d.ts +3 -4
- package/dist/editor-actions/nested/nested-block-edit.js +40 -134
- package/dist/editor-actions/nested/nested-focus.d.ts +2 -3
- package/dist/editor-actions/nested/nested-focus.js +33 -21
- package/dist/editor-actions/paste-coordinator.d.ts +3 -2
- package/dist/editor-actions/paste-coordinator.js +17 -13
- package/dist/editor-actions/plugin/chrome-leaf.d.ts +11 -9
- package/dist/editor-actions/plugin/chrome-leaf.js +14 -13
- package/dist/editor-actions/plugin/container.d.ts +55 -76
- package/dist/editor-actions/plugin/container.js +105 -186
- package/dist/editor-actions/plugin/directive-container.d.ts +4 -4
- package/dist/editor-actions/plugin/directive-container.js +7 -8
- package/dist/editor-actions/reorder-action.d.ts +7 -12
- package/dist/editor-actions/reorder-action.js +32 -48
- package/dist/editor-actions/reorder-drag.d.ts +12 -8
- package/dist/editor-actions/reorder-drag.js +45 -41
- package/dist/editor-actions/replacement-focus.d.ts +13 -21
- package/dist/editor-actions/replacement-focus.js +32 -33
- package/dist/editor-actions/search-replace.js +71 -67
- package/dist/editor-actions/stored-caret.d.ts +7 -0
- package/dist/editor-actions/stored-caret.js +10 -0
- package/dist/editor-actions/table-context.d.ts +9 -11
- package/dist/editor-actions/table-context.js +70 -93
- package/dist/editor-actions/unwrap-strategies.d.ts +4 -5
- package/dist/editor-actions/unwrap-strategies.js +52 -63
- package/dist/editor-actions/whole-block-focus-surface.d.ts +19 -28
- package/dist/editor-actions/whole-block-focus-surface.js +43 -53
- package/dist/editor-events.d.ts +25 -29
- package/dist/editor-events.js +17 -28
- package/dist/editor-keys.d.ts +96 -104
- package/dist/editor-keys.js +11 -24
- package/dist/editor-props.d.ts +91 -71
- package/dist/editor-rects.d.ts +23 -34
- package/dist/editor-rects.js +9 -77
- package/dist/env.d.ts +6 -4
- package/dist/env.js +8 -4
- package/dist/index.d.ts +6 -2
- package/dist/index.js +5 -2
- package/dist/inline-menu/inline-menu-session.d.ts +37 -0
- package/dist/inline-menu/inline-menu-session.js +98 -0
- package/dist/inline-menu/inline-menu-state.svelte.d.ts +63 -0
- package/dist/inline-menu/inline-menu-state.svelte.js +409 -0
- package/dist/inline-menu/types.d.ts +77 -0
- package/dist/inline-menu/types.js +7 -0
- package/dist/invariants/child-id-parity.d.ts +23 -0
- package/dist/invariants/child-id-parity.js +39 -0
- package/dist/invariants/commit-paths.d.ts +4 -4
- package/dist/invariants/commit-paths.js +4 -4
- package/dist/invariants/commit-scope.d.ts +4 -4
- package/dist/invariants/commit-scope.js +9 -8
- package/dist/invariants/context-keys.d.ts +2 -5
- package/dist/invariants/context-keys.js +3 -6
- package/dist/invariants/descriptor.d.ts +2 -6
- package/dist/invariants/descriptor.js +2 -6
- package/dist/invariants/inline-transitions.d.ts +9 -16
- package/dist/invariants/inline-transitions.js +10 -18
- package/dist/invariants/install.d.ts +18 -27
- package/dist/invariants/install.js +29 -30
- package/dist/invariants/keeps-a-block.d.ts +7 -0
- package/dist/invariants/keeps-a-block.js +14 -0
- package/dist/invariants/landable-caret.d.ts +5 -7
- package/dist/invariants/landable-caret.js +8 -11
- package/dist/invariants/landing-focus-scroll.d.ts +7 -0
- package/dist/invariants/landing-focus-scroll.js +13 -0
- package/dist/invariants/landing-value.d.ts +13 -0
- package/dist/invariants/landing-value.js +27 -0
- package/dist/invariants/marker-css-parity.d.ts +5 -6
- package/dist/invariants/marker-css-parity.js +11 -12
- package/dist/invariants/measures-in-own-list.d.ts +6 -0
- package/dist/invariants/measures-in-own-list.js +13 -0
- package/dist/invariants/node-shape.d.ts +18 -37
- package/dist/invariants/node-shape.js +123 -79
- package/dist/invariants/open-tail.d.ts +7 -0
- package/dist/invariants/open-tail.js +45 -0
- package/dist/invariants/placement-ends-widget.d.ts +8 -0
- package/dist/invariants/placement-ends-widget.js +13 -0
- package/dist/invariants/registry.d.ts +27 -66
- package/dist/invariants/registry.js +61 -137
- package/dist/invariants/render-fidelity.d.ts +4 -4
- package/dist/invariants/render-fidelity.js +5 -5
- package/dist/invariants/selection-endpoints.d.ts +6 -7
- package/dist/invariants/selection-endpoints.js +18 -16
- package/dist/invariants/single-node-sink.d.ts +4 -5
- package/dist/invariants/single-node-sink.js +4 -5
- package/dist/invariants/snapshot-integrity.d.ts +5 -6
- package/dist/invariants/snapshot-integrity.js +1 -1
- package/dist/invariants/structural-descriptor.d.ts +6 -15
- package/dist/invariants/structural-descriptor.js +6 -15
- package/dist/menu-icons.d.ts +47 -0
- package/dist/menu-icons.js +113 -0
- package/dist/perf/instruments.d.ts +20 -5
- package/dist/perf/instruments.js +35 -15
- package/dist/perf/use-mount-gauge.svelte.js +4 -4
- package/dist/plugin.d.ts +38 -8
- package/dist/plugin.js +102 -74
- package/dist/plugins/admonitions/AdmonitionBlock.svelte +14 -11
- package/dist/plugins/admonitions/admonition-kind.js +12 -10
- package/dist/plugins/admonitions/convert-document.d.ts +5 -5
- package/dist/plugins/admonitions/convert-document.js +8 -7
- package/dist/plugins/admonitions/gh-alert.d.ts +8 -1
- package/dist/plugins/admonitions/gh-alert.js +21 -22
- package/dist/plugins/admonitions/github-alert-kind.d.ts +5 -7
- package/dist/plugins/admonitions/github-alert-kind.js +28 -37
- package/dist/plugins/admonitions/index.js +2 -2
- package/dist/plugins/admonitions/kinds.d.ts +1 -1
- package/dist/plugins/admonitions/register.js +11 -2
- package/dist/plugins/details/DetailsBlock.svelte +20 -20
- package/dist/plugins/details/details-disclosure.svelte.d.ts +5 -6
- package/dist/plugins/details/details-disclosure.svelte.js +6 -7
- package/dist/plugins/details/details-kind.d.ts +6 -7
- package/dist/plugins/details/details-kind.js +44 -59
- package/dist/plugins/emoji/emoji-recognizer.d.ts +4 -7
- package/dist/plugins/emoji/emoji-recognizer.js +7 -14
- package/dist/plugins/footnotes/FootnoteDefinition.svelte +33 -16
- package/dist/plugins/footnotes/FootnoteReference.svelte +39 -19
- package/dist/plugins/footnotes/constants.d.ts +2 -0
- package/dist/plugins/footnotes/constants.js +3 -0
- package/dist/plugins/footnotes/footnote-definition.d.ts +8 -6
- package/dist/plugins/footnotes/footnote-definition.js +69 -45
- package/dist/plugins/footnotes/footnote-lookup.d.ts +3 -3
- package/dist/plugins/footnotes/footnote-lookup.js +14 -26
- package/dist/plugins/footnotes/footnote-numbering.d.ts +11 -11
- package/dist/plugins/footnotes/footnote-numbering.js +22 -31
- package/dist/plugins/footnotes/footnote-reference.d.ts +4 -4
- package/dist/plugins/footnotes/footnote-reference.js +8 -13
- package/dist/plugins/footnotes/index.js +2 -3
- package/dist/plugins/highlight-occurrences/highlight-occurrences-plugin.d.ts +5 -8
- package/dist/plugins/highlight-occurrences/highlight-occurrences-plugin.js +8 -3
- package/dist/plugins/highlight-occurrences/occurrence-source.d.ts +10 -12
- package/dist/plugins/highlight-occurrences/occurrence-source.js +21 -18
- package/dist/plugins/highlight-occurrences/occurrences.d.ts +11 -11
- package/dist/plugins/highlight-occurrences/occurrences.js +14 -36
- package/dist/plugins/highlight-occurrences/word-char.d.ts +1 -0
- package/dist/plugins/highlight-occurrences/word-char.js +4 -0
- package/dist/plugins/latex/BlockMath.svelte +58 -75
- package/dist/plugins/latex/BlockMath.svelte.d.ts +2 -4
- package/dist/plugins/latex/MathInline.svelte +10 -9
- package/dist/plugins/latex/flanking.d.ts +1 -0
- package/dist/plugins/latex/flanking.js +3 -0
- package/dist/plugins/latex/index.d.ts +1 -1
- package/dist/plugins/latex/latex-kind.d.ts +4 -4
- package/dist/plugins/latex/latex-kind.js +113 -85
- package/dist/plugins/latex/math-completion.d.ts +1 -1
- package/dist/plugins/latex/math-completion.js +5 -8
- package/dist/plugins/latex/math-layout.d.ts +2 -8
- package/dist/plugins/latex/math-layout.js +0 -9
- package/dist/plugins/latex/math-renderer.d.ts +17 -20
- package/dist/plugins/latex/math-renderer.js +21 -38
- package/dist/plugins/latex/math-source.d.ts +4 -8
- package/dist/plugins/latex/math-source.js +36 -75
- package/dist/plugins/latex/register.d.ts +10 -11
- package/dist/plugins/latex/register.js +24 -10
- package/dist/plugins/latex/renderer.d.ts +9 -10
- package/dist/plugins/latex/renderer.js +9 -24
- package/dist/plugins/mermaid/MermaidBlock.svelte +63 -47
- package/dist/plugins/mermaid/index.js +1 -1
- package/dist/plugins/mermaid/mermaid-kind.d.ts +4 -7
- package/dist/plugins/mermaid/mermaid-kind.js +30 -47
- package/dist/plugins/mermaid/mermaid-renderer.d.ts +9 -16
- package/dist/plugins/mermaid/mermaid-renderer.js +12 -31
- package/dist/plugins/mermaid/register.d.ts +3 -3
- package/dist/plugins/mermaid/register.js +5 -5
- package/dist/plugins/mermaid/renderer.d.ts +5 -5
- package/dist/plugins/mermaid/renderer.js +8 -11
- package/dist/plugins/parrot/ParrotBlock.svelte +18 -7
- package/dist/plugins/parrot/ParrotBlock.svelte.d.ts +2 -2
- package/dist/plugins/parrot/parrot-plugin.js +3 -3
- package/dist/plugins/slash-commands/filter.d.ts +23 -0
- package/dist/plugins/slash-commands/filter.js +31 -0
- package/dist/plugins/slash-commands/index.d.ts +2 -0
- package/dist/plugins/slash-commands/index.js +2 -0
- package/dist/plugins/slash-commands/slash-commands-plugin.d.ts +12 -0
- package/dist/plugins/slash-commands/slash-commands-plugin.js +40 -0
- package/dist/plugins/slash-commands/slash-source.d.ts +36 -0
- package/dist/plugins/slash-commands/slash-source.js +108 -0
- package/dist/plugins/toc/TocBlock.svelte +23 -22
- package/dist/plugins/toc/TocBlock.svelte.d.ts +2 -3
- package/dist/plugins/toc/heading-outline.d.ts +7 -12
- package/dist/plugins/toc/heading-outline.js +22 -36
- package/dist/plugins/toc/navigation-queue.d.ts +2 -4
- package/dist/plugins/toc/toc-plugin.d.ts +5 -5
- package/dist/plugins/toc/toc-plugin.js +20 -13
- package/dist/presentation-mode.d.ts +15 -23
- package/dist/presentation-mode.js +19 -25
- package/dist/reactivity/block-list-state.svelte.d.ts +9 -11
- package/dist/reactivity/block-list-state.svelte.js +8 -9
- package/dist/reactivity/block-window.svelte.d.ts +12 -6
- package/dist/reactivity/block-window.svelte.js +44 -17
- package/dist/reactivity/child-list.d.ts +34 -0
- package/dist/reactivity/child-list.js +48 -0
- package/dist/reactivity/content-version.svelte.d.ts +4 -7
- package/dist/reactivity/content-version.svelte.js +3 -5
- package/dist/reactivity/hold-across.d.ts +39 -0
- package/dist/reactivity/hold-across.js +57 -0
- package/dist/reactivity/layout-state.svelte.d.ts +27 -0
- package/dist/reactivity/layout-state.svelte.js +51 -0
- package/dist/reactivity/list-tree.d.ts +39 -0
- package/dist/reactivity/list-tree.js +132 -0
- package/dist/reactivity/list-windowing.svelte.d.ts +50 -71
- package/dist/reactivity/list-windowing.svelte.js +143 -292
- package/dist/reactivity/measure-batch.d.ts +6 -8
- package/dist/reactivity/measure-batch.js +5 -6
- package/dist/reactivity/publish-ref.svelte.d.ts +16 -41
- package/dist/reactivity/publish-ref.svelte.js +21 -85
- package/dist/reactivity/scope-geometry.d.ts +6 -13
- package/dist/reactivity/scope-geometry.js +7 -14
- package/dist/reactivity/state-registry.d.ts +5 -5
- package/dist/reactivity/state-registry.js +11 -15
- package/dist/reactivity/use-container-windowing.svelte.d.ts +13 -26
- package/dist/reactivity/use-container-windowing.svelte.js +64 -74
- package/dist/reactivity/use-measured-child.svelte.d.ts +10 -0
- package/dist/reactivity/use-measured-child.svelte.js +41 -0
- package/dist/reactivity/use-window-floor.svelte.d.ts +2 -0
- package/dist/reactivity/use-window-floor.svelte.js +27 -0
- package/dist/reactivity/window-slice.d.ts +4 -4
- package/dist/reactivity/window-slice.js +0 -2
- package/dist/renderer-slot.d.ts +48 -0
- package/dist/renderer-slot.js +85 -0
- package/dist/scan-index.d.ts +4 -4
- package/dist/scan-index.js +4 -4
- package/dist/schema/block-commands.d.ts +69 -54
- package/dist/schema/block-commands.js +91 -104
- package/dist/schema/block-completions.d.ts +16 -19
- package/dist/schema/block-completions.js +25 -32
- package/dist/schema/block-component-registry.d.ts +13 -14
- package/dist/schema/block-component-registry.js +19 -17
- package/dist/schema/block-kind-descriptor.d.ts +234 -168
- package/dist/schema/block-kind-descriptor.js +151 -66
- package/dist/schema/block-openers.d.ts +48 -39
- package/dist/schema/block-openers.js +73 -83
- package/dist/schema/built-in-descriptors.d.ts +3 -5
- package/dist/schema/built-in-descriptors.js +96 -80
- package/dist/schema/child-spans.d.ts +12 -10
- package/dist/schema/child-spans.js +68 -34
- package/dist/schema/closure.d.ts +18 -16
- package/dist/schema/closure.js +24 -14
- package/dist/schema/command-id.d.ts +6 -8
- package/dist/schema/command-id.js +20 -25
- package/dist/schema/commands.d.ts +79 -81
- package/dist/schema/commands.js +156 -116
- package/dist/schema/container-raw.d.ts +51 -11
- package/dist/schema/container-raw.js +143 -14
- package/dist/schema/container-rebuilders.d.ts +17 -15
- package/dist/schema/container-rebuilders.js +30 -22
- package/dist/schema/context-actions.d.ts +25 -13
- package/dist/schema/context-actions.js +32 -17
- package/dist/schema/define-plugin-block.d.ts +8 -6
- package/dist/schema/define-plugin-block.js +6 -4
- package/dist/schema/fenced-code-raw.d.ts +30 -17
- package/dist/schema/fenced-code-raw.js +155 -107
- package/dist/schema/global-commands.d.ts +6 -6
- package/dist/schema/global-commands.js +14 -22
- package/dist/schema/height-estimates.d.ts +31 -0
- package/dist/schema/height-estimates.js +64 -0
- package/dist/schema/inline-construct-policy.d.ts +42 -55
- package/dist/schema/inline-construct-policy.js +36 -35
- package/dist/schema/insert-catalogue.d.ts +30 -0
- package/dist/schema/insert-catalogue.js +95 -0
- package/dist/schema/keybinding-overrides.d.ts +9 -11
- package/dist/schema/keybinding-overrides.js +1 -1
- package/dist/schema/keybindings.d.ts +15 -7
- package/dist/schema/keybindings.js +21 -9
- package/dist/schema/merge-rules.d.ts +5 -7
- package/dist/schema/merge-rules.js +7 -9
- package/dist/schema/opener-priorities.d.ts +4 -4
- package/dist/schema/opener-priorities.js +4 -4
- package/dist/schema/operations.d.ts +9 -11
- package/dist/schema/operations.js +3 -3
- package/dist/schema/page-role.d.ts +14 -0
- package/dist/schema/page-role.js +19 -0
- package/dist/schema/plugin-activation.d.ts +4 -6
- package/dist/schema/plugin-activation.js +12 -10
- package/dist/schema/plugin-editor-context.d.ts +25 -10
- package/dist/schema/plugin-editor-context.js +40 -9
- package/dist/schema/plugin-install.d.ts +49 -17
- package/dist/schema/plugin-install.js +51 -25
- package/dist/schema/plugin-kind.d.ts +12 -8
- package/dist/schema/plugin-kind.js +35 -42
- package/dist/schema/plugin-name.js +3 -3
- package/dist/schema/plugin-registry.d.ts +54 -0
- package/dist/schema/plugin-registry.js +70 -0
- package/dist/schema/reading.d.ts +23 -0
- package/dist/schema/reading.js +7 -0
- package/dist/schema/register-once.d.ts +3 -5
- package/dist/schema/register-once.js +7 -16
- package/dist/schema/registration-checks.d.ts +12 -16
- package/dist/schema/registration-checks.js +35 -51
- package/dist/schema/registration-pairs.d.ts +54 -0
- package/dist/schema/registration-pairs.js +48 -0
- package/dist/schema/registration-pending.d.ts +8 -12
- package/dist/schema/registration-pending.js +9 -9
- package/dist/schema/registry-reset.d.ts +8 -4
- package/dist/schema/registry-reset.js +13 -26
- package/dist/schema/registry-view.d.ts +25 -13
- package/dist/schema/registry-view.js +26 -20
- package/dist/schema/reserved-chords.d.ts +9 -10
- package/dist/schema/reserved-chords.js +73 -78
- package/dist/schema/reserved-chrome.d.ts +12 -11
- package/dist/schema/reserved-chrome.js +15 -11
- package/dist/schema/setext-raw.d.ts +13 -0
- package/dist/schema/setext-raw.js +33 -0
- package/dist/schema/stored-as.d.ts +20 -0
- package/dist/schema/stored-as.js +6 -0
- package/dist/schema/table-cell-raw.d.ts +18 -7
- package/dist/schema/table-cell-raw.js +28 -7
- package/dist/schema/whole-block-unit.d.ts +5 -4
- package/dist/schema/whole-block-unit.js +5 -4
- package/dist/search/document-scan.d.ts +3 -3
- package/dist/search/document-scan.js +2 -2
- package/dist/search/matcher.d.ts +1 -1
- package/dist/search/regex-executor.d.ts +5 -6
- package/dist/search/regex-executor.js +6 -8
- package/dist/search/replace.d.ts +2 -5
- package/dist/search/replace.js +2 -5
- package/dist/search/search-state.svelte.d.ts +5 -5
- package/dist/search/search-state.svelte.js +12 -16
- package/dist/selection/autoscroll.d.ts +6 -9
- package/dist/selection/block-hit-test.d.ts +16 -24
- package/dist/selection/block-hit-test.js +29 -22
- package/dist/selection/caret-doors.d.ts +15 -14
- package/dist/selection/caret-doors.js +37 -26
- package/dist/selection/caret-landing.d.ts +62 -0
- package/dist/selection/caret-landing.js +157 -0
- package/dist/selection/caret-restore.d.ts +17 -10
- package/dist/selection/caret-restore.js +10 -22
- package/dist/selection/caret-target.d.ts +30 -0
- package/dist/selection/caret-target.js +84 -0
- package/dist/selection/char-endpoint-snap.d.ts +6 -10
- package/dist/selection/char-endpoint-snap.js +8 -14
- package/dist/selection/clipboard-text.d.ts +5 -12
- package/dist/selection/clipboard-text.js +69 -172
- package/dist/selection/covered-block.d.ts +6 -8
- package/dist/selection/covered-block.js +8 -19
- package/dist/selection/cross-block/clipboard.d.ts +3 -2
- package/dist/selection/cross-block/clipboard.js +13 -4
- package/dist/selection/cross-block/dispatch.d.ts +47 -43
- package/dist/selection/cross-block/dispatch.js +12 -23
- package/dist/selection/cross-block/format-range.d.ts +18 -21
- package/dist/selection/cross-block/format-range.js +104 -103
- package/dist/selection/cross-block/format-toggle.d.ts +10 -15
- package/dist/selection/cross-block/format-toggle.js +28 -33
- package/dist/selection/cross-block/keydown.d.ts +4 -4
- package/dist/selection/cross-block/keydown.js +93 -152
- package/dist/selection/cross-block/ops.d.ts +19 -34
- package/dist/selection/cross-block/ops.js +110 -95
- package/dist/selection/cross-block/paste.d.ts +2 -3
- package/dist/selection/cross-block/paste.js +61 -104
- package/dist/selection/cross-block/pointer.d.ts +17 -15
- package/dist/selection/cross-block/pointer.js +74 -25
- package/dist/selection/cross-block/type-replace.d.ts +4 -6
- package/dist/selection/cross-block/type-replace.js +53 -146
- package/dist/selection/dead-space-caret.d.ts +20 -28
- package/dist/selection/dead-space-caret.js +79 -87
- package/dist/selection/drag-pointer.d.ts +22 -5
- package/dist/selection/drag-pointer.js +63 -31
- package/dist/selection/gap-caret.d.ts +17 -28
- package/dist/selection/gap-caret.js +14 -26
- package/dist/selection/grid-selection.d.ts +12 -0
- package/dist/selection/grid-selection.js +22 -0
- package/dist/selection/keyboard-extend.d.ts +27 -39
- package/dist/selection/keyboard-extend.js +94 -116
- package/dist/selection/multi-click.d.ts +37 -0
- package/dist/selection/multi-click.js +197 -0
- package/dist/selection/native-bridge.d.ts +30 -37
- package/dist/selection/native-bridge.js +80 -100
- package/dist/selection/nearest-block.d.ts +17 -12
- package/dist/selection/nearest-block.js +37 -18
- package/dist/selection/path-lookup.d.ts +31 -14
- package/dist/selection/path-lookup.js +110 -20
- package/dist/selection/path-math.d.ts +9 -11
- package/dist/selection/path-math.js +5 -7
- package/dist/selection/pointer-gesture.d.ts +9 -0
- package/dist/selection/pointer-gesture.js +11 -0
- package/dist/selection/pointer-session.d.ts +10 -16
- package/dist/selection/pointer-session.js +6 -7
- package/dist/selection/primitives.d.ts +64 -33
- package/dist/selection/primitives.js +61 -53
- package/dist/selection/range-coverage.d.ts +94 -0
- package/dist/selection/range-coverage.js +365 -0
- package/dist/selection/range-delete-ceremony.d.ts +28 -74
- package/dist/selection/range-delete-ceremony.js +100 -141
- package/dist/selection/range-delete-chrome.d.ts +20 -33
- package/dist/selection/range-delete-chrome.js +53 -78
- package/dist/selection/range-delete-table-coverage.d.ts +11 -25
- package/dist/selection/range-delete-table-coverage.js +42 -112
- package/dist/selection/range-delete-table.d.ts +14 -12
- package/dist/selection/range-delete-table.js +106 -310
- package/dist/selection/range-delete.d.ts +18 -19
- package/dist/selection/range-delete.js +83 -123
- package/dist/selection/round-trip-restore.d.ts +18 -0
- package/dist/selection/round-trip-restore.js +19 -0
- package/dist/selection/selection-announcer.d.ts +17 -0
- package/dist/selection/selection-announcer.js +25 -0
- package/dist/selection/selection-description.d.ts +4 -3
- package/dist/selection/selection-description.js +5 -4
- package/dist/selection/selection-drop.d.ts +52 -0
- package/dist/selection/selection-drop.js +317 -0
- package/dist/selection/selection-restore.d.ts +20 -33
- package/dist/selection/selection-restore.js +21 -44
- package/dist/selection/selection-state.svelte.d.ts +50 -42
- package/dist/selection/selection-state.svelte.js +144 -98
- package/dist/selection/shared-keydown.d.ts +22 -27
- package/dist/selection/shared-keydown.js +25 -45
- package/dist/selection/table-endpoint-snap.d.ts +17 -41
- package/dist/selection/table-endpoint-snap.js +54 -80
- package/dist/selection/table-rect-extend.d.ts +3 -6
- package/dist/selection/table-rect-extend.js +19 -14
- package/dist/styles/editor-theme.css +75 -53
- package/dist/styles/editor.css +248 -139
- package/dist/testing/conformance-core.d.ts +50 -18
- package/dist/testing/conformance-core.js +88 -50
- package/dist/testing/container-conformance.d.ts +48 -84
- package/dist/testing/container-conformance.js +159 -285
- package/dist/testing/headless-actions.d.ts +34 -19
- package/dist/testing/headless-actions.js +116 -65
- package/dist/testing/headless-block-list.svelte.d.ts +16 -0
- package/dist/testing/headless-block-list.svelte.js +22 -0
- package/dist/testing/inline-conformance.d.ts +15 -22
- package/dist/testing/inline-conformance.js +131 -148
- package/dist/testing/kind-conformance.d.ts +19 -24
- package/dist/testing/kind-conformance.js +204 -117
- package/dist/testing/kit-reading.d.ts +7 -0
- package/dist/testing/kit-reading.js +16 -0
- package/dist/testing/mount-dom-stubs.d.ts +4 -5
- package/dist/testing/mount-dom-stubs.js +8 -5
- package/dist/testing/parse-convergence.d.ts +10 -10
- package/dist/testing/parse-convergence.js +14 -49
- package/dist/testing.d.ts +13 -9
- package/dist/testing.js +28 -38
- package/dist/tree-operations/blockquote.d.ts +8 -14
- package/dist/tree-operations/blockquote.js +25 -45
- package/dist/tree-operations/chain-rebuild.d.ts +34 -25
- package/dist/tree-operations/chain-rebuild.js +115 -52
- package/dist/tree-operations/children.d.ts +5 -9
- package/dist/tree-operations/children.js +7 -11
- package/dist/tree-operations/cleanup.d.ts +6 -7
- package/dist/tree-operations/cleanup.js +14 -11
- package/dist/tree-operations/clone.js +5 -4
- package/dist/tree-operations/container-lift.d.ts +10 -5
- package/dist/tree-operations/container-lift.js +20 -14
- package/dist/tree-operations/container-offsets.d.ts +22 -0
- package/dist/tree-operations/container-offsets.js +89 -0
- package/dist/tree-operations/content-write.d.ts +52 -29
- package/dist/tree-operations/content-write.js +155 -110
- package/dist/tree-operations/index.d.ts +4 -4
- package/dist/tree-operations/index.js +4 -4
- package/dist/tree-operations/keep-one-block.d.ts +10 -0
- package/dist/tree-operations/keep-one-block.js +19 -0
- package/dist/tree-operations/leaf-range.d.ts +33 -0
- package/dist/tree-operations/leaf-range.js +67 -0
- package/dist/tree-operations/list/empty-check.d.ts +2 -3
- package/dist/tree-operations/list/empty-check.js +4 -4
- package/dist/tree-operations/list/exit-replacement.d.ts +4 -6
- package/dist/tree-operations/list/exit-replacement.js +4 -9
- package/dist/tree-operations/list/item-partition.d.ts +2 -2
- package/dist/tree-operations/list/item-partition.js +2 -2
- package/dist/tree-operations/list/list-builders.d.ts +18 -16
- package/dist/tree-operations/list/list-builders.js +59 -30
- package/dist/tree-operations/list/ordered-markers.d.ts +7 -16
- package/dist/tree-operations/list/ordered-markers.js +7 -16
- package/dist/tree-operations/list/reconcile-task.d.ts +16 -7
- package/dist/tree-operations/list/reconcile-task.js +80 -23
- package/dist/tree-operations/list/sublist-separator.d.ts +7 -7
- package/dist/tree-operations/list/sublist-separator.js +20 -27
- package/dist/tree-operations/list/task-paragraph.d.ts +25 -0
- package/dist/tree-operations/list/task-paragraph.js +54 -0
- package/dist/tree-operations/list/unwrap-merge.d.ts +8 -16
- package/dist/tree-operations/list/unwrap-merge.js +44 -79
- package/dist/tree-operations/node-ops.d.ts +30 -52
- package/dist/tree-operations/node-ops.js +152 -218
- package/dist/tree-operations/node-primitives.d.ts +44 -31
- package/dist/tree-operations/node-primitives.js +84 -60
- package/dist/tree-operations/open-tail.d.ts +25 -0
- package/dist/tree-operations/open-tail.js +100 -0
- package/dist/tree-operations/parse-block.d.ts +15 -2
- package/dist/tree-operations/parse-block.js +19 -4
- package/dist/tree-operations/paste/apply.d.ts +7 -8
- package/dist/tree-operations/paste/apply.js +33 -63
- package/dist/tree-operations/paste/body-write.d.ts +8 -6
- package/dist/tree-operations/paste/body-write.js +13 -14
- package/dist/tree-operations/paste/container-match.d.ts +7 -10
- package/dist/tree-operations/paste/container-match.js +76 -58
- package/dist/tree-operations/paste/container-paste.d.ts +3 -3
- package/dist/tree-operations/paste/container-paste.js +3 -3
- package/dist/tree-operations/paste/dispatch.d.ts +26 -29
- package/dist/tree-operations/paste/dispatch.js +68 -53
- package/dist/tree-operations/paste/focus-target.d.ts +11 -14
- package/dist/tree-operations/paste/focus-target.js +13 -18
- package/dist/tree-operations/paste/hooks.d.ts +7 -12
- package/dist/tree-operations/paste/hooks.js +49 -46
- package/dist/tree-operations/paste/line-ending.d.ts +11 -0
- package/dist/tree-operations/paste/line-ending.js +32 -0
- package/dist/tree-operations/paste/list-absorb.d.ts +8 -11
- package/dist/tree-operations/paste/list-absorb.js +17 -19
- package/dist/tree-operations/paste/list-break-out.d.ts +12 -11
- package/dist/tree-operations/paste/list-break-out.js +24 -32
- package/dist/tree-operations/paste/parent-scope.d.ts +8 -12
- package/dist/tree-operations/paste/parent-scope.js +9 -16
- package/dist/tree-operations/paste/paste-deps.d.ts +14 -9
- package/dist/tree-operations/paste/paste-replacement.d.ts +20 -3
- package/dist/tree-operations/paste/paste-replacement.js +73 -42
- package/dist/tree-operations/paste/paste-transforms.d.ts +5 -7
- package/dist/tree-operations/paste/paste-transforms.js +18 -27
- package/dist/tree-operations/paste/replacement-parse.d.ts +19 -0
- package/dist/tree-operations/paste/replacement-parse.js +24 -0
- package/dist/tree-operations/paste/strategy.d.ts +1 -1
- package/dist/tree-operations/paste/strategy.js +1 -1
- package/dist/tree-operations/paste/table-slice.js +15 -10
- package/dist/tree-operations/paste-surfaces.d.ts +18 -29
- package/dist/tree-operations/paste-surfaces.js +14 -10
- package/dist/tree-operations/path-mutate.d.ts +7 -8
- package/dist/tree-operations/path-mutate.js +4 -4
- package/dist/tree-operations/reorder-unit.d.ts +4 -5
- package/dist/tree-operations/reorder-unit.js +5 -6
- package/dist/tree-operations/reorder.d.ts +7 -9
- package/dist/tree-operations/reorder.js +39 -40
- package/dist/tree-operations/settle.d.ts +42 -53
- package/dist/tree-operations/settle.js +241 -162
- package/dist/tree-operations/sharing.d.ts +5 -5
- package/dist/tree-operations/splice-many.d.ts +5 -5
- package/dist/tree-operations/splice-many.js +5 -5
- package/dist/tree-operations/stored-as.d.ts +13 -0
- package/dist/tree-operations/stored-as.js +48 -0
- package/dist/tree-operations/structural-change.d.ts +11 -15
- package/dist/tree-operations/structural-change.js +10 -14
- package/dist/tree-operations/structural-suffix.d.ts +22 -0
- package/dist/tree-operations/structural-suffix.js +61 -0
- package/dist/tree-operations/sub-table-copy.d.ts +7 -0
- package/dist/tree-operations/sub-table-copy.js +40 -36
- package/dist/tree-operations/table-grid-clipboard.d.ts +2 -7
- package/dist/tree-operations/table-grid-clipboard.js +11 -36
- package/dist/tree-operations/table-mutations.d.ts +7 -3
- package/dist/tree-operations/table-mutations.js +45 -9
- package/dist/tree-operations/unshare.d.ts +11 -15
- package/dist/tree-operations/unshare.js +15 -17
- package/dist/undo/manager.js +1 -1
- package/dist/undo/types.d.ts +2 -2
- package/docs/guide/consumer-guide.md +329 -205
- package/docs/guide/directives.md +7 -7
- package/docs/guide/plugin-api.md +267 -183
- package/docs/guide/plugin-guide.md +341 -235
- package/docs/guide/plugin-testing.md +96 -82
- package/package.json +17 -21
- package/dist/ambient/ambient-cursor.d.ts +0 -41
- package/dist/ambient/ambient-cursor.js +0 -120
- package/dist/components/blocks/code/code-paste.d.ts +0 -24
- package/dist/components/blocks/code/code-paste.js +0 -21
- package/dist/components/blocks/table/cell-clipboard.d.ts +0 -33
- package/dist/components/blocks/table/cell-clipboard.js +0 -67
- package/dist/components/blocks/text/hidden-suffix.d.ts +0 -10
- package/dist/components/blocks/text/hidden-suffix.js +0 -15
- package/dist/components/blocks/text/link-source-bytes.d.ts +0 -37
- package/dist/components/image/image-source-bytes.d.ts +0 -15
- package/dist/components/image/image-source-bytes.js +0 -80
- package/dist/cursor/content-offsets.d.ts +0 -29
- package/dist/cursor/content-offsets.js +0 -151
- package/dist/cursor/reveal-anchor.d.ts +0 -30
- package/dist/cursor/reveal-anchor.js +0 -31
- package/dist/invariants/split-landing.d.ts +0 -8
- package/dist/invariants/split-landing.js +0 -15
- package/dist/selection/double-click-trim.d.ts +0 -17
- package/dist/selection/double-click-trim.js +0 -57
- package/dist/tree-operations/list/terminator.d.ts +0 -17
- package/dist/tree-operations/list/terminator.js +0 -60
- package/dist/tree-operations/paste/replace-block-at-parent.d.ts +0 -29
- package/dist/tree-operations/paste/replace-block-at-parent.js +0 -75
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getContext, tick, untrack } from 'svelte';
|
|
3
3
|
import { CURSOR_START, type AmbientPrefix, type BlockComponent } from '../../../block-component';
|
|
4
|
+
import { readBlocks } from '../../../core/parser';
|
|
5
|
+
import { ambientHoldsTaskBox } from '../list/task-checkbox';
|
|
6
|
+
import { shownKind } from '../../../core/parsers/heading';
|
|
4
7
|
import type { DocumentView, NodeView } from '../../../core/node-views';
|
|
5
8
|
import type { EditorRects } from '../../../editor-rects';
|
|
6
9
|
import { enterLinkCardAtCaret, linkCardTargetAt } from '../../link-card/link-card-entry';
|
|
@@ -15,13 +18,17 @@
|
|
|
15
18
|
} from '../../../editor-keys';
|
|
16
19
|
import type { IndexedDecoration } from '../../../decorations/buckets';
|
|
17
20
|
import type { ReplaceDecoration, WidgetDecoration } from '../../../decorations/types';
|
|
18
|
-
import { getContentRange, isProseKind } from '../../../core/inline';
|
|
21
|
+
import { getContentRange, isProseKind, structuralSuffix } from '../../../core/inline';
|
|
19
22
|
import { devWarn } from '../../../dev-warn';
|
|
20
23
|
import { resolvedInlineContent } from '../../../core/inline/inline-cache';
|
|
21
|
-
import type { LinkReferenceResolver } from '../../../core/inline/link-reference-resolver';
|
|
22
24
|
import { isInlineWidget } from '../../../core/inline/inline-widgets';
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
+
import {
|
|
26
|
+
documentLineEnding,
|
|
27
|
+
trimTrailingLineEnding,
|
|
28
|
+
trailingLineEnding
|
|
29
|
+
} from '../../../core/lines';
|
|
30
|
+
import { caretIsInTextContent, seatIsInTextContent } from './click-snap-guard';
|
|
31
|
+
import { caretSeatInElement } from '../../../cursor/point-offset';
|
|
25
32
|
import { FALLBACK_CONTENT_WIDTH } from '../../../cursor/typography-estimates';
|
|
26
33
|
import {
|
|
27
34
|
createInlineFormatActiveMemo,
|
|
@@ -44,14 +51,15 @@
|
|
|
44
51
|
import { createTextClipboard } from './text-clipboard';
|
|
45
52
|
import { createTextRender } from './text-render';
|
|
46
53
|
import { createWidgetInteraction } from './widget-interaction';
|
|
47
|
-
import { createEdgePolicyDispatch
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
54
|
+
import { createEdgePolicyDispatch } from './edge-policy-dispatch';
|
|
55
|
+
import { keepsKindAt } from '../../../core/inline/live-edit/read-back';
|
|
56
|
+
import { storedAsAt } from '../../../tree-operations/stored-as';
|
|
57
|
+
import { applyLiveRangeEdit } from './live-selection-edit';
|
|
58
|
+
import { replaceRangeInLeaf } from '../../../tree-operations/leaf-range';
|
|
50
59
|
import { applyDelimiterAutoPair } from './delimiter-autopair';
|
|
51
60
|
import { createCompositionSeat } from './composition-seat';
|
|
52
61
|
import { createConstructReveal } from './construct-reveal';
|
|
53
62
|
import { assertInvariant } from '../../../assert';
|
|
54
|
-
import { paintsFocusedMarkers } from '../../../presentation-mode';
|
|
55
63
|
import { widgetElByStart } from './widget-adjacency';
|
|
56
64
|
import {
|
|
57
65
|
caretLandableBounds,
|
|
@@ -59,29 +67,24 @@
|
|
|
59
67
|
handleSharedBeforeInput
|
|
60
68
|
} from '../../../selection/shared-keydown';
|
|
61
69
|
import {
|
|
70
|
+
editableSurfaceAttributes,
|
|
62
71
|
createEditableSurface,
|
|
63
72
|
consumePendingRestore,
|
|
64
73
|
withKeydownVerdict
|
|
65
74
|
} from '../editable-surface';
|
|
66
75
|
import { wireSurfaceContexts, useParkFocusOnUnmount } from '../surface-wiring.svelte';
|
|
67
76
|
import {
|
|
68
|
-
domTextOffsetAtNode,
|
|
69
77
|
landableStartAbutsIsland,
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
markerPrefixOf,
|
|
79
|
+
rawOffsetAt,
|
|
80
|
+
rawTextOfContent,
|
|
72
81
|
revealsNoMarkers,
|
|
73
82
|
screenVisibilityOf,
|
|
74
|
-
|
|
83
|
+
rawSelectionFocus
|
|
75
84
|
} from '../../../cursor/widget-offset';
|
|
76
|
-
import {
|
|
77
|
-
import {
|
|
78
|
-
asRawOffset,
|
|
79
|
-
toClampedRawOffset,
|
|
80
|
-
toDomTextOffset
|
|
81
|
-
} from '../../../cursor/coordinate-spaces';
|
|
82
|
-
import { createAmbientCursorIO } from '../../../ambient/ambient-cursor';
|
|
85
|
+
import { asRawOffset } from '../../../cursor/coordinate-spaces';
|
|
86
|
+
import { createSurfaceBackend } from '../../../cursor/surface-backend';
|
|
83
87
|
import { type CommandId } from '../../../schema/commands';
|
|
84
|
-
import { reorderRunCommand } from '../../../editor-actions/reorder-action';
|
|
85
88
|
import { planTypedCompletion } from '../../../editor-actions/enter-completion';
|
|
86
89
|
import {
|
|
87
90
|
perfEnabled,
|
|
@@ -107,19 +110,18 @@
|
|
|
107
110
|
myPath?: number[];
|
|
108
111
|
blockClass?: string;
|
|
109
112
|
ambientPrefix?: AmbientPrefix;
|
|
110
|
-
// Accepted
|
|
111
|
-
//
|
|
113
|
+
// Accepted so the props match `BlockComponentProps`: this block reads the document
|
|
114
|
+
// from its own context, and binding here would shadow the global `document`.
|
|
112
115
|
document?: DocumentView;
|
|
113
|
-
//
|
|
114
|
-
// widgets whose own gesture jumps elsewhere in the document.
|
|
116
|
+
// Passed on to inline widgets whose own gesture jumps elsewhere in the document.
|
|
115
117
|
rects?: EditorRects;
|
|
116
118
|
} = $props();
|
|
117
119
|
|
|
118
120
|
const ambientPrefixText = $derived(
|
|
119
121
|
typeof ambientPrefix === 'string' ? ambientPrefix : ambientPrefix.text
|
|
120
122
|
);
|
|
121
|
-
// The hanging indent is the prefix
|
|
122
|
-
// prefix
|
|
123
|
+
// The hanging indent is how wide the prefix draws: its text width by default, or what a
|
|
124
|
+
// prefix that draws itself, such as the task checkbox, declares.
|
|
123
125
|
const ambientIndent = $derived(
|
|
124
126
|
(typeof ambientPrefix === 'string' ? undefined : ambientPrefix.indent) ??
|
|
125
127
|
`${ambientPrefixText.length}ch`
|
|
@@ -131,46 +133,52 @@
|
|
|
131
133
|
focusActions,
|
|
132
134
|
controller,
|
|
133
135
|
pasteCoordinator,
|
|
134
|
-
|
|
135
|
-
edgeAffinity,
|
|
136
|
+
caretMemory,
|
|
136
137
|
selection,
|
|
137
138
|
getDoc,
|
|
138
139
|
getEditorRoot,
|
|
139
|
-
grammar,
|
|
140
140
|
activePlugins,
|
|
141
141
|
events: editorEvents,
|
|
142
|
-
|
|
142
|
+
reading
|
|
143
143
|
} = wiring.deps;
|
|
144
|
+
const { grammar } = reading;
|
|
145
|
+
// A block with no line ending of its own is the document's last line; a write gives it the
|
|
146
|
+
// document's.
|
|
147
|
+
const documentEnding = () => documentLineEnding(getDoc());
|
|
148
|
+
const blockEnding = () => trailingLineEnding(node.raw, documentEnding());
|
|
149
|
+
// Made per gesture, never derived: a derived value would subscribe the block to the tree.
|
|
150
|
+
const storedAs = () => storedAsAt(getDoc(), myPath, reading);
|
|
144
151
|
// Present inside a list item, whose ListItemBlock owns Tab-as-indent.
|
|
145
152
|
const listContext = getContext(LIST_CONTEXT_KEY);
|
|
146
153
|
const {
|
|
147
|
-
|
|
148
|
-
pendingMarks,
|
|
154
|
+
autoPairs,
|
|
149
155
|
widgetSelection,
|
|
150
156
|
linkCard,
|
|
151
|
-
|
|
157
|
+
inlineMenuCombobox,
|
|
158
|
+
decorations: decorationEngine,
|
|
159
|
+
kindCue
|
|
152
160
|
} = getContext<EditorServices>(EDITOR_SERVICES_KEY);
|
|
161
|
+
const ownPairs = autoPairs.forBlock();
|
|
162
|
+
|
|
153
163
|
const {
|
|
154
164
|
resolveImageUrl,
|
|
155
165
|
resolveLinkUrl,
|
|
156
166
|
imageLoadPolicy,
|
|
157
167
|
brokenImageUrls: brokenUrlCache,
|
|
158
|
-
presentationMode: getPresentationMode,
|
|
159
168
|
theme: getTheme,
|
|
160
169
|
onPasteImage
|
|
161
170
|
} = getContext<EditorPolicies>(EDITOR_POLICIES_KEY);
|
|
162
171
|
const { contentVersion: getContentVersion } = getContext<EditorDoc>(EDITOR_DOC_KEY);
|
|
163
|
-
const
|
|
164
|
-
const
|
|
172
|
+
const readOnly = $derived(reading.mode() === 'reading');
|
|
173
|
+
const combobox = $derived(inlineMenuCombobox(myPath));
|
|
165
174
|
|
|
166
|
-
/**
|
|
167
|
-
*
|
|
175
|
+
/** What the link card is asked about here, the same shape a table cell passes: `range` is the
|
|
176
|
+
* live selection both when the chord runs and when the pressed state is read. */
|
|
168
177
|
const linkCardQuery = (contentEl: HTMLElement, range: { start: number; end: number } | null) => ({
|
|
169
178
|
contentEl,
|
|
170
179
|
block: node,
|
|
171
180
|
path: myPath,
|
|
172
|
-
|
|
173
|
-
mode: presentationMode,
|
|
181
|
+
reading,
|
|
174
182
|
selection: range,
|
|
175
183
|
crossBlockRange: selection.isCrossBlock
|
|
176
184
|
});
|
|
@@ -182,84 +190,85 @@
|
|
|
182
190
|
});
|
|
183
191
|
}
|
|
184
192
|
};
|
|
185
|
-
// A constant
|
|
193
|
+
// A shared constant keeps an empty decoration list out of the render key.
|
|
186
194
|
const NO_ISLANDS: IndexedDecoration<WidgetDecoration | ReplaceDecoration>[] = [];
|
|
187
195
|
let el: HTMLDivElement | undefined = $state();
|
|
188
196
|
let composing = $state(false);
|
|
189
|
-
// A
|
|
190
|
-
// the per-keystroke CST commit and the block commits once
|
|
197
|
+
// A widget's shown source lives only in the DOM, so `onInput` and IME `compositionend`
|
|
198
|
+
// skip the per-keystroke CST commit and the block commits once when it is hidden.
|
|
191
199
|
let revealing = $state(false);
|
|
192
200
|
/** Cursor offset to restore after the next $effect render. Null = don't touch cursor. */
|
|
193
201
|
let pendingCursorOffset = $state<number | null>(null);
|
|
194
|
-
//
|
|
195
|
-
|
|
196
|
-
// Survives the click→keydown gap when Chromium clears the caret at CE=false-adjacent
|
|
197
|
-
// positions. Reactive so the snap-caret overlay sees changes.
|
|
202
|
+
// Survives the click-to-keydown gap when Chromium clears the caret beside a non-editable
|
|
203
|
+
// widget. Reactive so the snap-caret overlay sees changes.
|
|
198
204
|
let lastSnapTargetOffset = $state<number | null>(null);
|
|
205
|
+
/** Counted up on every `armSnapTarget` call, so setting the offset already held still repaints:
|
|
206
|
+
* Svelte coalesces a null-then-same-value write into no change at all. */
|
|
207
|
+
let snapEpoch = $state(0);
|
|
208
|
+
|
|
209
|
+
function armSnapTarget(offset: number | null): void {
|
|
210
|
+
lastSnapTargetOffset = offset;
|
|
211
|
+
snapEpoch++;
|
|
212
|
+
}
|
|
213
|
+
// Beside a non-editable widget Chromium paints a taller caret for the length of the press.
|
|
214
|
+
// Reactive, so the synthetic caret can hide it as the press lands rather than after the click.
|
|
215
|
+
let pressSeatedBesideIsland = $state(false);
|
|
216
|
+
let pressPending = false;
|
|
199
217
|
|
|
200
|
-
//
|
|
201
|
-
// which gesture set the restore; the render effect
|
|
218
|
+
// The one place a pending cursor is written, tagged so the interaction trace names
|
|
219
|
+
// which gesture set the restore; the render effect reads and clears it.
|
|
202
220
|
function setPendingCursorOffset(offset: number | null, source: string): void {
|
|
203
221
|
tracePendingCursorSet(source, offset);
|
|
204
222
|
pendingCursorOffset = offset;
|
|
205
223
|
}
|
|
206
224
|
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
const cursor = createAmbientCursorIO({
|
|
225
|
+
const cursor = createSurfaceBackend({
|
|
210
226
|
getEl: () => el ?? null,
|
|
211
|
-
getAmbientLength: () => ambientLength,
|
|
212
227
|
getSnapTarget: () => lastSnapTargetOffset
|
|
213
228
|
});
|
|
214
229
|
|
|
215
230
|
const editableSurface = createEditableSurface({
|
|
216
231
|
...wiring.deps,
|
|
217
232
|
getEl: () => el ?? null,
|
|
218
|
-
getAmbientLength: () => ambientLength,
|
|
219
233
|
isInputSuppressed: () => revealing,
|
|
220
|
-
backend:
|
|
221
|
-
getRaw: () => cursor.getRaw(),
|
|
222
|
-
setRaw: (offset) => cursor.setRaw(offset),
|
|
223
|
-
buildRange: (start, end) =>
|
|
224
|
-
createRangeAtDomTextOffsets(
|
|
225
|
-
el!,
|
|
226
|
-
toDomTextOffset(start, ambientLength),
|
|
227
|
-
toDomTextOffset(end, ambientLength)
|
|
228
|
-
)
|
|
229
|
-
},
|
|
234
|
+
backend: cursor,
|
|
230
235
|
getMyPath: () => myPath,
|
|
231
236
|
getIndex: () => index,
|
|
232
237
|
getComposing: () => composing,
|
|
233
238
|
setComposing: (value) => {
|
|
234
239
|
composing = value;
|
|
235
240
|
},
|
|
236
|
-
getPreEditOffset: () => preEditOffset,
|
|
237
|
-
setPreEditOffset: (offset) => {
|
|
238
|
-
preEditOffset = offset;
|
|
239
|
-
},
|
|
240
241
|
setPendingCursor: (offset) => setPendingCursorOffset(offset, 'surface'),
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
getTextLen: () => liveDisplayLength(),
|
|
242
|
+
getFocusOffset: () => (el ? rawSelectionFocus(el) : null),
|
|
243
|
+
getTextLen: () => caretReach(),
|
|
244
244
|
readText: () => readRawText(),
|
|
245
245
|
relocateComposedText: (after, composedAt) => compositionSeat.relocate(after, composedAt),
|
|
246
246
|
commitInput: (text, preEdit, saved) => {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
247
|
+
// Typed text is the one write whose kind change the block names (`kind-cue.svelte.ts`).
|
|
248
|
+
const before = shownKind(node);
|
|
249
|
+
const write = blockEdit.updateBlockContent(
|
|
250
|
+
index,
|
|
251
|
+
text + blockEnding(),
|
|
252
|
+
'authored',
|
|
253
|
+
preEdit,
|
|
254
|
+
saved
|
|
255
|
+
);
|
|
256
|
+
void kindCue.afterTypedWrite(write, myPath, before);
|
|
257
|
+
return write.admitted ? write.caret : null;
|
|
252
258
|
},
|
|
253
259
|
inputPrelude: () => {
|
|
254
260
|
markKeystrokeStart();
|
|
255
|
-
|
|
256
|
-
}
|
|
261
|
+
armSnapTarget(null);
|
|
262
|
+
},
|
|
263
|
+
handleBeforeInput: onBeforeInput
|
|
257
264
|
});
|
|
258
265
|
|
|
259
266
|
const crossBlock = editableSurface.crossBlock;
|
|
260
267
|
const sharedCtx = editableSurface.sharedCtx;
|
|
261
268
|
|
|
262
269
|
const widgetInteraction = createWidgetInteraction({
|
|
270
|
+
getLineEnding: documentEnding,
|
|
271
|
+
storedAs,
|
|
263
272
|
get node() {
|
|
264
273
|
return node;
|
|
265
274
|
},
|
|
@@ -270,14 +279,13 @@
|
|
|
270
279
|
return myPath;
|
|
271
280
|
},
|
|
272
281
|
getEl: () => el ?? null,
|
|
273
|
-
getAmbientLength: () => ambientLength,
|
|
274
282
|
getEditorContentWidth: () => getEditorRoot()?.clientWidth ?? FALLBACK_CONTENT_WIDTH,
|
|
275
283
|
cursor,
|
|
276
284
|
widgetSelection,
|
|
277
285
|
blockEdit,
|
|
278
286
|
focusActions,
|
|
279
287
|
setSnapTarget: (offset) => {
|
|
280
|
-
|
|
288
|
+
armSnapTarget(offset);
|
|
281
289
|
},
|
|
282
290
|
setPendingCursor: (offset) => setPendingCursorOffset(offset, 'widget'),
|
|
283
291
|
readRawText: () => readRawText(),
|
|
@@ -285,15 +293,15 @@
|
|
|
285
293
|
revealing = value;
|
|
286
294
|
},
|
|
287
295
|
isCrossBlock: () => selection.isCrossBlock,
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
return linkRef;
|
|
296
|
+
get reading() {
|
|
297
|
+
return reading;
|
|
291
298
|
}
|
|
292
299
|
});
|
|
293
300
|
|
|
294
|
-
// After widgetInteraction
|
|
301
|
+
// After `widgetInteraction`, because a clipboard edit hides a shown source before it
|
|
295
302
|
// touches the CST.
|
|
296
303
|
const clipboardHandlers = createTextClipboard({
|
|
304
|
+
storedAs,
|
|
297
305
|
get node() {
|
|
298
306
|
return node;
|
|
299
307
|
},
|
|
@@ -307,11 +315,9 @@
|
|
|
307
315
|
caret: editableSurface.caret,
|
|
308
316
|
crossBlock,
|
|
309
317
|
selection,
|
|
310
|
-
|
|
311
|
-
edgeAffinity,
|
|
318
|
+
caretMemory,
|
|
312
319
|
blockEdit,
|
|
313
320
|
pasteCoordinator,
|
|
314
|
-
grammar,
|
|
315
321
|
activePlugins,
|
|
316
322
|
getDoc,
|
|
317
323
|
widgetSelection,
|
|
@@ -321,31 +327,28 @@
|
|
|
321
327
|
isReadOnly: () => readOnly,
|
|
322
328
|
foldRevealBeforeMutation: () => widgetInteraction.foldRevealBeforeMutation(),
|
|
323
329
|
isRevealing: () => widgetInteraction.isRevealing(),
|
|
324
|
-
getPresentationMode: () => presentationMode,
|
|
325
|
-
getAmbientPrefix: () => ambientPrefixText,
|
|
326
330
|
readRevealedText: () => readRawText(),
|
|
327
|
-
get
|
|
328
|
-
return
|
|
331
|
+
get reading() {
|
|
332
|
+
return reading;
|
|
329
333
|
}
|
|
330
334
|
});
|
|
331
335
|
|
|
332
|
-
// preview-inline
|
|
336
|
+
// Showing markers in preview-inline mode: CSS classes only, no keys intercepted.
|
|
333
337
|
const constructReveal = createConstructReveal({
|
|
334
338
|
get node() {
|
|
335
339
|
return node;
|
|
336
340
|
},
|
|
337
|
-
get
|
|
338
|
-
return
|
|
341
|
+
get reading() {
|
|
342
|
+
return reading;
|
|
339
343
|
},
|
|
340
344
|
getEl: () => el ?? null,
|
|
341
|
-
getAmbientLength: () => ambientLength,
|
|
342
|
-
getPresentationMode: () => presentationMode,
|
|
343
345
|
isCrossBlock: () => selection.isCrossBlock
|
|
344
346
|
});
|
|
345
347
|
|
|
346
|
-
//
|
|
348
|
+
// Every caret-edge key goes through this one dispatch (G4.12); entering a widget stays in
|
|
347
349
|
// `widgetInteraction.enterWidget`.
|
|
348
350
|
const edgeDispatch = createEdgePolicyDispatch({
|
|
351
|
+
getLineEnding: documentEnding,
|
|
349
352
|
get node() {
|
|
350
353
|
return node;
|
|
351
354
|
},
|
|
@@ -355,51 +358,45 @@
|
|
|
355
358
|
get containerParent() {
|
|
356
359
|
return blockNodeAt(getDoc(), myPath.slice(0, -1));
|
|
357
360
|
},
|
|
358
|
-
get
|
|
359
|
-
return
|
|
361
|
+
get reading() {
|
|
362
|
+
return reading;
|
|
360
363
|
},
|
|
361
364
|
getEl: () => el ?? null,
|
|
362
|
-
|
|
363
|
-
getAmbientPrefix: () => ambientPrefixText,
|
|
365
|
+
storedAs,
|
|
364
366
|
hasIslands: () =>
|
|
365
367
|
decorationEngine ? decorationEngine.islandsForPath(myPath).length > 0 : false,
|
|
366
368
|
getRawSelection: () => cursor.getRawSelection(),
|
|
367
369
|
blockEdit,
|
|
368
370
|
setPendingCursor: (offset, source) => setPendingCursorOffset(offset, source),
|
|
369
371
|
setSnapTarget: (offset) => {
|
|
370
|
-
|
|
372
|
+
armSnapTarget(offset);
|
|
371
373
|
},
|
|
372
374
|
isRevealing: () => widgetInteraction.isRevealing(),
|
|
373
375
|
enterWidget: (widget, fromTrailingEdge) =>
|
|
374
376
|
widgetInteraction.enterWidget(widget, fromTrailingEdge),
|
|
375
377
|
isReading: () => readOnly,
|
|
376
|
-
getEdgeAffinity:
|
|
377
|
-
noteOutside:
|
|
378
|
-
pendingMarks,
|
|
379
|
-
|
|
378
|
+
getEdgeAffinity: caretMemory.side,
|
|
379
|
+
noteOutside: caretMemory.noteExtreme,
|
|
380
|
+
pendingMarks: caretMemory.pendingMarks,
|
|
381
|
+
ownPairs
|
|
380
382
|
});
|
|
381
383
|
|
|
382
|
-
// The same
|
|
384
|
+
// The same placement rules the keydown dispatch uses, for the one insertion it cannot reach.
|
|
383
385
|
const compositionSeat = createCompositionSeat({
|
|
384
386
|
getDisplayText: () => getDisplayText(),
|
|
385
|
-
getInlines: () => resolvedInlineContent(node,
|
|
386
|
-
|
|
387
|
+
getInlines: () => resolvedInlineContent(node, reading),
|
|
388
|
+
reading,
|
|
389
|
+
getAffinity: caretMemory.side,
|
|
387
390
|
getScreen: () => screenVisibilityOf(el ?? null),
|
|
388
|
-
consumePendingMarks:
|
|
389
|
-
restorePendingMarks:
|
|
391
|
+
consumePendingMarks: caretMemory.pendingMarks.consume,
|
|
392
|
+
restorePendingMarks: caretMemory.pendingMarks.restore,
|
|
390
393
|
getRawSelection: () => cursor.getRawSelection(),
|
|
391
|
-
// The
|
|
392
|
-
//
|
|
394
|
+
// The in-leaf range replace `handleLiveSelectionEdit` uses, in the displayed bytes this
|
|
395
|
+
// returns (`commitInput` re-appends the trailing line ending).
|
|
393
396
|
resolveRangeEdit: (range, typed) => {
|
|
394
|
-
const edit =
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
typed,
|
|
398
|
-
presentationMode,
|
|
399
|
-
linkRef,
|
|
400
|
-
ambientPrefixText
|
|
401
|
-
);
|
|
402
|
-
return edit && { raw: trimTrailingLineEnding(edit.raw), caret: edit.caret };
|
|
397
|
+
const edit = replaceRangeInLeaf(node, range, typed, storedAs());
|
|
398
|
+
if (edit.matchesBrowserEdit) return null;
|
|
399
|
+
return { raw: trimTrailingLineEnding(edit.raw), caret: edit.caret };
|
|
403
400
|
}
|
|
404
401
|
});
|
|
405
402
|
|
|
@@ -422,19 +419,11 @@
|
|
|
422
419
|
get imageLoadPolicy() {
|
|
423
420
|
return imageLoadPolicy();
|
|
424
421
|
},
|
|
425
|
-
|
|
426
|
-
return presentationMode;
|
|
427
|
-
},
|
|
422
|
+
reading,
|
|
428
423
|
getTheme,
|
|
429
424
|
getDocument: () => getDoc(),
|
|
430
425
|
getContentVersion,
|
|
431
426
|
navigateTo: (path) => rects?.navigateTo(path) ?? Promise.resolve(false),
|
|
432
|
-
get linkResolver(): LinkReferenceResolver | undefined {
|
|
433
|
-
return linkRef?.current;
|
|
434
|
-
},
|
|
435
|
-
get linkStamp(): string {
|
|
436
|
-
return String(linkRef?.epoch ?? 0);
|
|
437
|
-
},
|
|
438
427
|
get islands() {
|
|
439
428
|
return decorationEngine ? decorationEngine.islandsForPath(myPath) : NO_ISLANDS;
|
|
440
429
|
},
|
|
@@ -473,31 +462,29 @@
|
|
|
473
462
|
widgetInteraction.snapClickToWidgetEdge(clientX, clientY);
|
|
474
463
|
}
|
|
475
464
|
|
|
476
|
-
/** The
|
|
477
|
-
*
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
return
|
|
465
|
+
/** The length the caret counts against: the DOM's while a source is shown, since the CST has
|
|
466
|
+
* not seen that edit. */
|
|
467
|
+
function caretReach(): number {
|
|
468
|
+
if (widgetInteraction.isRevealing()) return readRawText().length;
|
|
469
|
+
return getDisplayText().length;
|
|
481
470
|
}
|
|
482
471
|
|
|
483
|
-
/** The offsets a caret can reach here,
|
|
484
|
-
*
|
|
485
|
-
* moves in to what the DOM can land rather than testing 0 / length. */
|
|
472
|
+
/** The offsets a caret can reach here, as the arrow exits read them: a mode that draws no marker
|
|
473
|
+
* puts the block's own marker bytes out of reach, so 0 and the length are wrong there. */
|
|
486
474
|
function caretBounds(): { start: number; end: number } {
|
|
487
|
-
return el ? caretLandableBounds(sharedCtx, el) : { start: 0, end:
|
|
475
|
+
return el ? caretLandableBounds(sharedCtx, el) : { start: 0, end: caretReach() };
|
|
488
476
|
}
|
|
489
477
|
|
|
490
|
-
/** The structural bytes this
|
|
491
|
-
* that
|
|
478
|
+
/** The structural bytes this key gives up before any merge: a declared kind's, in a mode
|
|
479
|
+
* that draws none of them. Null everywhere else, and the merge below takes the key. */
|
|
492
480
|
function demoteBeforeMerge(offset: number): TextEditResult | null {
|
|
493
481
|
if (!el || !revealsNoMarkers(el)) return null;
|
|
494
482
|
if (tryGetBlockKindDescriptor(node.kind)?.contentStartBackspace !== 'demote-first') return null;
|
|
495
483
|
return demoteToParagraph(node.raw, getContentRange(node), offset);
|
|
496
484
|
}
|
|
497
485
|
|
|
498
|
-
/**
|
|
499
|
-
*
|
|
500
|
-
* and is valid only after one. `offset`/`selected` are closed over: the fold moves them. */
|
|
486
|
+
/** Split so hiding a shown source fits between the halves: `applies` reads only the DOM, and
|
|
487
|
+
* `perform` reads `node.raw`, valid only after the source is hidden. */
|
|
501
488
|
function blockCommand(
|
|
502
489
|
id: CommandId,
|
|
503
490
|
arg: unknown,
|
|
@@ -512,9 +499,20 @@
|
|
|
512
499
|
return always(() => blockEdit.descendToBody(index));
|
|
513
500
|
case 'block.hardBreak':
|
|
514
501
|
return always(() => {
|
|
515
|
-
const { newRaw, caretOffset } = insertHardBreak(
|
|
516
|
-
|
|
517
|
-
|
|
502
|
+
const { newRaw, caretOffset } = insertHardBreak(
|
|
503
|
+
node.raw,
|
|
504
|
+
offset,
|
|
505
|
+
documentEnding(),
|
|
506
|
+
getContentRange(node)
|
|
507
|
+
);
|
|
508
|
+
const write = blockEdit.updateBlockContent(
|
|
509
|
+
index,
|
|
510
|
+
newRaw,
|
|
511
|
+
'authored',
|
|
512
|
+
offset,
|
|
513
|
+
caretOffset
|
|
514
|
+
);
|
|
515
|
+
if (write.admitted) setPendingCursorOffset(write.caret, 'hard-break');
|
|
518
516
|
});
|
|
519
517
|
case 'block.insertTab':
|
|
520
518
|
return {
|
|
@@ -523,65 +521,78 @@
|
|
|
523
521
|
// A literal tab, because the browser default moves focus out of the editor.
|
|
524
522
|
perform: () => {
|
|
525
523
|
const { newRaw, caretOffset } = insertLiteralTab(node.raw, offset);
|
|
526
|
-
|
|
527
|
-
|
|
524
|
+
// The key types its own character, so its kind change is named as typing's is.
|
|
525
|
+
const before = shownKind(node);
|
|
526
|
+
const write = blockEdit.updateBlockContent(
|
|
527
|
+
index,
|
|
528
|
+
newRaw,
|
|
529
|
+
'authored',
|
|
530
|
+
offset,
|
|
531
|
+
caretOffset
|
|
532
|
+
);
|
|
533
|
+
void kindCue.afterTypedWrite(write, myPath, before);
|
|
534
|
+
if (write.admitted) setPendingCursorOffset(write.caret, 'insert-tab');
|
|
528
535
|
}
|
|
529
536
|
};
|
|
530
537
|
case 'block.mergePrev':
|
|
531
538
|
return {
|
|
532
|
-
// At
|
|
533
|
-
//
|
|
534
|
-
applies: () => offset <= caretBounds().start &&
|
|
539
|
+
// At or before, not equal: a caret can still be placed at an offset the DOM
|
|
540
|
+
// traversal moves forward, and a strict test would make the key do nothing.
|
|
541
|
+
applies: () => offset <= caretBounds().start && cursor.getRawSelection() === null,
|
|
535
542
|
perform: () => {
|
|
536
543
|
const demoted = demoteBeforeMerge(offset);
|
|
537
544
|
if (!demoted) return void blockEdit.mergeWithPrevious(index);
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
545
|
+
const write = blockEdit.updateBlockContent(
|
|
546
|
+
index,
|
|
547
|
+
demoted.newRaw,
|
|
548
|
+
'literal',
|
|
549
|
+
offset,
|
|
550
|
+
demoted.caretOffset
|
|
542
551
|
);
|
|
543
|
-
setPendingCursorOffset(
|
|
552
|
+
if (write.admitted) setPendingCursorOffset(write.caret, 'demote');
|
|
544
553
|
}
|
|
545
554
|
};
|
|
546
555
|
case 'block.mergeNext':
|
|
547
556
|
return {
|
|
548
|
-
|
|
549
|
-
// without surfacing it (live-mode.md § 4.5). The keydown dispatch consumes that press; this is
|
|
550
|
-
// the same rule for the callers that never pass through it.
|
|
551
|
-
applies: () =>
|
|
552
|
-
offset >= caretBounds().end &&
|
|
553
|
-
!hasSelectionHelper() &&
|
|
554
|
-
!hidesStructuralSuffix(el ?? null, node, liveDisplayLength()),
|
|
557
|
+
applies: () => offset >= caretBounds().end && cursor.getRawSelection() === null,
|
|
555
558
|
perform: () => void blockEdit.mergeWithNext(index)
|
|
556
559
|
};
|
|
557
560
|
case 'link.openCard':
|
|
558
|
-
// Consumed
|
|
559
|
-
//
|
|
560
|
-
// default the host was told not to expect (Ctrl+K kills to end of line here).
|
|
561
|
+
// Consumed whether or not a card opens: `reservedChords()` reports Mod+K as the editor's,
|
|
562
|
+
// and the browser default (Ctrl+K kills a line) would surprise the host.
|
|
561
563
|
return always(enterLinkCard);
|
|
562
564
|
case 'heading.cycle':
|
|
563
565
|
return {
|
|
564
|
-
// A heading marks
|
|
566
|
+
// A heading marks prose. The raw-editable kinds bind this keymap too, and there
|
|
565
567
|
// an ATX prefix is content: it would destroy a link reference definition.
|
|
566
568
|
applies: () => isProseKind(node.kind),
|
|
567
569
|
perform: () => {
|
|
568
|
-
// `arg`
|
|
569
|
-
//
|
|
570
|
-
// back to the strip behavior.
|
|
570
|
+
// `arg` comes untrusted from the keybinding channel, and an out-of-range level
|
|
571
|
+
// would throw inside `repeat`, so it falls back to stripping the heading.
|
|
571
572
|
const level = typeof arg === 'number' && arg >= 0 && arg <= 6 ? arg : 0;
|
|
572
573
|
const cycled = cycleHeading(node.raw, getContentRange(node), level, offset);
|
|
573
574
|
if (!cycled) return;
|
|
574
|
-
|
|
575
|
-
|
|
575
|
+
// Text after a task box is the to-do's own text, so a written `# ` would stay
|
|
576
|
+
// text there; replacing the block makes the heading and gives the box up.
|
|
577
|
+
if (ambientHoldsTaskBox(ambientPrefix)) {
|
|
578
|
+
const heading = readBlocks(cycled.newRaw, { grammar, scope: 'fragment' }).children;
|
|
579
|
+
const focus = { replacementIndex: 0, offset: cycled.caretOffset };
|
|
580
|
+
void blockEdit.replaceBlock(index, heading, focus, { snapshotOffset: offset });
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
const write = blockEdit.updateBlockContent(
|
|
584
|
+
index,
|
|
585
|
+
cycled.newRaw,
|
|
586
|
+
'literal',
|
|
587
|
+
offset,
|
|
588
|
+
cycled.caretOffset
|
|
589
|
+
);
|
|
590
|
+
if (write.admitted) setPendingCursorOffset(write.caret, 'heading-cycle');
|
|
576
591
|
}
|
|
577
592
|
};
|
|
578
|
-
case 'block.moveUp':
|
|
579
|
-
case 'block.moveDown':
|
|
580
|
-
// Through `always`, not a bare opener line: every perform here rides the reveal fold.
|
|
581
|
-
return always(() => void reorderRunCommand(id, reorder, () => myPath));
|
|
582
593
|
default: {
|
|
583
|
-
// The format chords
|
|
584
|
-
// command that toggles it, so a new markable kind
|
|
594
|
+
// The format chords come from the policy table: a construct that declares a mark names
|
|
595
|
+
// the command that toggles it, so a new markable kind needs no branch here.
|
|
585
596
|
const marked = inlineMarkForCommand(id);
|
|
586
597
|
return marked === null
|
|
587
598
|
? null
|
|
@@ -591,53 +602,53 @@
|
|
|
591
602
|
}
|
|
592
603
|
|
|
593
604
|
export function runCommand(id: CommandId, arg?: unknown): boolean {
|
|
594
|
-
// Read live:
|
|
595
|
-
// `preEditOffset` would be stale here.
|
|
605
|
+
// Read live: a command dispatched from another block arrives with no input event here.
|
|
596
606
|
const offset = cursor.getRaw() ?? 0;
|
|
597
607
|
const command = blockCommand(id, arg, offset, cursor.getRawSelection());
|
|
598
608
|
if (!command || !command.applies()) return false;
|
|
599
|
-
|
|
600
|
-
performBlockCommand(id, command.perform);
|
|
601
|
-
return true;
|
|
602
|
-
}
|
|
603
|
-
// A live reveal holds this block's bytes in ephemeral DOM, so every `perform` would
|
|
604
|
-
// splice the pre-reveal source: fold, settle, then act. The fold is handed the user's
|
|
605
|
-
// offset, valid because the committed text IS the DOM text it was measured against.
|
|
606
|
-
const fold = widgetInteraction.foldRevealBeforeMutation(offset);
|
|
607
|
-
void (fold?.settled ?? tick()).then(() => performBlockCommand(id, command.perform));
|
|
609
|
+
afterSourceCommit(() => performBlockCommand(id, command.perform), offset);
|
|
608
610
|
return true;
|
|
609
611
|
}
|
|
610
612
|
|
|
613
|
+
// A shown source holds this block's edit in the DOM only, so a command waits for it to be
|
|
614
|
+
// written; the user's offset stays valid, since the written text is the DOM text.
|
|
615
|
+
export function afterSourceCommit(run: () => void, offset = cursor.getRaw() ?? 0): void {
|
|
616
|
+
if (!widgetInteraction.isRevealing()) return run();
|
|
617
|
+
const fold = widgetInteraction.foldRevealBeforeMutation(offset);
|
|
618
|
+
void (fold?.settled ?? tick()).then(run);
|
|
619
|
+
}
|
|
620
|
+
|
|
611
621
|
// A toolbar asks once per button on every selection change, so the buttons share the parse.
|
|
612
622
|
const formatActive = createInlineFormatActiveMemo();
|
|
613
623
|
|
|
614
|
-
//
|
|
615
|
-
// and for the card the same construct its own entry resolves.
|
|
624
|
+
// Whether a button shows as pressed: the same displayed text, content and selection the
|
|
625
|
+
// toggle itself uses, and for the card the same construct its own entry resolves.
|
|
616
626
|
export function isCommandActive(id: CommandId): boolean {
|
|
617
627
|
const marked = inlineMarkForCommand(id);
|
|
618
628
|
if (!marked) {
|
|
619
|
-
//
|
|
629
|
+
// The link card is the one pressed state no mark policy answers.
|
|
620
630
|
if (id !== 'link.openCard' || !el) return false;
|
|
621
631
|
return linkCardTargetAt(linkCardQuery(el, cursor.getRawSelection())) !== null;
|
|
622
632
|
}
|
|
623
633
|
const caret = cursor.getRaw() ?? 0;
|
|
624
634
|
const selection = cursor.getRawSelection() ?? { start: caret, end: caret };
|
|
625
635
|
return formatActive(
|
|
626
|
-
{ display: getDisplayText(), content: getContentRange(node), selection },
|
|
636
|
+
{ display: getDisplayText(), content: getContentRange(node), selection, reading },
|
|
627
637
|
marked.kind
|
|
628
638
|
);
|
|
629
639
|
}
|
|
630
640
|
|
|
631
|
-
//
|
|
632
|
-
//
|
|
633
|
-
// TODO(#35): funnel the fold at every mutation entry path, not just the command arms.
|
|
641
|
+
// A command never writes while a source is shown, so a failure means a `runCommand` branch
|
|
642
|
+
// skipped hiding it (G1.26). TODO: hide a shown source at the other entry paths that write.
|
|
634
643
|
function performBlockCommand(id: CommandId, perform: () => void): void {
|
|
635
644
|
assertInvariant('reveal-transition', () =>
|
|
636
645
|
widgetInteraction.isRevealing()
|
|
637
646
|
? { code: 'command-during-reveal', message: `${id} mutated the block with a reveal open` }
|
|
638
647
|
: null
|
|
639
648
|
);
|
|
640
|
-
|
|
649
|
+
// A command is not typing: its bytes are their own undo step, so one Ctrl+Z undoes the
|
|
650
|
+
// command alone rather than the burst of typing around it.
|
|
651
|
+
controller.isolateUndoEntry(perform);
|
|
641
652
|
}
|
|
642
653
|
|
|
643
654
|
void ({
|
|
@@ -652,7 +663,8 @@
|
|
|
652
663
|
claimRootClipboard,
|
|
653
664
|
insertMarkdown,
|
|
654
665
|
snapCaretToPoint,
|
|
655
|
-
runCommand
|
|
666
|
+
runCommand,
|
|
667
|
+
afterSourceCommit
|
|
656
668
|
} satisfies BlockComponent);
|
|
657
669
|
|
|
658
670
|
// ── Content sync ──────────────────────────────────────────────────────
|
|
@@ -670,8 +682,8 @@
|
|
|
670
682
|
}
|
|
671
683
|
|
|
672
684
|
const t0 = perfEnabled() ? performance.now() : 0;
|
|
673
|
-
// With a
|
|
674
|
-
//
|
|
685
|
+
// With a restore pending, the code below overwrites the selection, so the render's
|
|
686
|
+
// own caret capture would be wasted.
|
|
675
687
|
textRender.render({
|
|
676
688
|
forceRebuild: pendingCursorOffset !== null,
|
|
677
689
|
carryCaret: pendingCursorOffset === null
|
|
@@ -679,18 +691,17 @@
|
|
|
679
691
|
if (perfEnabled()) recordBlockRender(performance.now() - t0, myPath);
|
|
680
692
|
|
|
681
693
|
if (pendingCursorOffset !== null) {
|
|
682
|
-
//
|
|
683
|
-
//
|
|
684
|
-
// The clear runs regardless, so a skipped restore is dropped, never re-armed.
|
|
694
|
+
// Restored only while this block has focus: a commit on blur also sets a pending offset,
|
|
695
|
+
// and restoring it would pull the selection back. Cleared either way.
|
|
685
696
|
const applied = consumePendingRestore(el ?? null, pendingCursorOffset, (offset) => {
|
|
686
|
-
if (!widgetInteraction.revealInterior(offset))
|
|
697
|
+
if (!widgetInteraction.revealInterior(offset))
|
|
698
|
+
cursor.setRaw(asRawOffset(offset), { clamp: 'exact' });
|
|
687
699
|
});
|
|
688
700
|
tracePendingCursorConsume(pendingCursorOffset, applied);
|
|
689
701
|
pendingCursorOffset = null;
|
|
690
702
|
}
|
|
691
|
-
// A rebuild
|
|
692
|
-
//
|
|
693
|
-
// because the caret chain must never join this effect's dependencies.
|
|
703
|
+
// A rebuild makes spans with no marker class, so the shown markers are re-applied before paint.
|
|
704
|
+
// Untracked, so the caret's reads never join this effect's dependencies.
|
|
694
705
|
untrack(() => {
|
|
695
706
|
if (!composing) constructReveal.update(true);
|
|
696
707
|
});
|
|
@@ -699,30 +710,50 @@
|
|
|
699
710
|
|
|
700
711
|
useParkFocusOnUnmount(() => el ?? null, getEditorRoot);
|
|
701
712
|
|
|
702
|
-
//
|
|
703
|
-
//
|
|
713
|
+
// Only clears: the snap target means "the click meant this", and only `snapClickToWidgetEdge`
|
|
714
|
+
// sets it.
|
|
704
715
|
function clearSnapTargetIfMoved(root: HTMLElement): void {
|
|
705
716
|
if (lastSnapTargetOffset === null) return;
|
|
706
717
|
const sel = window.getSelection();
|
|
718
|
+
// With no range there is nothing to compare the snap target against, and this function only
|
|
719
|
+
// clears: the gestures that move the caret elsewhere clear it through their own handlers.
|
|
707
720
|
if (!sel || sel.rangeCount === 0) return;
|
|
708
721
|
const range = sel.getRangeAt(0);
|
|
709
722
|
if (!root.contains(range.startContainer)) {
|
|
710
|
-
|
|
723
|
+
armSnapTarget(null);
|
|
711
724
|
return;
|
|
712
725
|
}
|
|
713
|
-
const
|
|
714
|
-
|
|
715
|
-
if (off !== lastSnapTargetOffset) lastSnapTargetOffset = null;
|
|
726
|
+
const off = rawOffsetAt(root, range.startContainer, range.startOffset);
|
|
727
|
+
if (off !== lastSnapTargetOffset) armSnapTarget(null);
|
|
716
728
|
}
|
|
717
729
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
730
|
+
/** Whether the press left the browser's caret at an element-level offset in this block, the
|
|
731
|
+
* position Chromium paints at the line box's height rather than at the text's. */
|
|
732
|
+
function notePressSeat(root: HTMLElement): void {
|
|
733
|
+
if (!pressPending) return;
|
|
734
|
+
const sel = window.getSelection();
|
|
735
|
+
const seated =
|
|
736
|
+
!!sel &&
|
|
737
|
+
sel.isCollapsed &&
|
|
738
|
+
sel.rangeCount > 0 &&
|
|
739
|
+
root.contains(sel.getRangeAt(0).startContainer) &&
|
|
740
|
+
!caretIsInTextContent(root, sel);
|
|
741
|
+
if (seated !== pressSeatedBesideIsland) pressSeatedBesideIsland = seated;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
function endPress(): void {
|
|
745
|
+
pressPending = false;
|
|
746
|
+
if (pressSeatedBesideIsland) pressSeatedBesideIsland = false;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// The snap target is cleared even during composition, since an IME caret move invalidates it;
|
|
750
|
+
// the source and marker updates skip composition as `onInput` does.
|
|
721
751
|
$effect(() => {
|
|
722
752
|
const root = el;
|
|
723
753
|
if (!root) return;
|
|
724
754
|
const handler = () => {
|
|
725
755
|
clearSnapTargetIfMoved(root);
|
|
756
|
+
notePressSeat(root);
|
|
726
757
|
if (composing) return;
|
|
727
758
|
widgetInteraction.foldRevealIfSelectionEscaped();
|
|
728
759
|
constructReveal.update();
|
|
@@ -733,46 +764,68 @@
|
|
|
733
764
|
|
|
734
765
|
$effect(() => {
|
|
735
766
|
if (!el) return;
|
|
767
|
+
// Read so that setting the offset already held still repaints and clears the other blocks.
|
|
768
|
+
void snapEpoch;
|
|
736
769
|
for (const w of el.querySelectorAll('.md-snap-after, .md-snap-before')) {
|
|
737
770
|
w.classList.remove('md-snap-after', 'md-snap-before');
|
|
738
771
|
}
|
|
739
|
-
//
|
|
740
|
-
//
|
|
741
|
-
// whether it painted, so darkening the native one is the only guarantee available.
|
|
772
|
+
// Chromium draws its caret unreliably beside a non-editable widget and nothing can ask
|
|
773
|
+
// whether it did, so the editor hides it and draws its own.
|
|
742
774
|
el.classList.remove('md-snap-caret-active');
|
|
743
|
-
|
|
775
|
+
// Hidden from the press, not from the click, so a press beside a widget does not show the
|
|
776
|
+
// browser's caret first and the synthetic one after it.
|
|
777
|
+
if (pressSeatedBesideIsland) el.classList.add('md-snap-caret-active');
|
|
778
|
+
// A cross-block range owns the caret's position wherever its endpoints landed, so no block
|
|
779
|
+
// paints one of its own under it, however the range was entered.
|
|
780
|
+
if (lastSnapTargetOffset === null || selection.isCrossBlock) return;
|
|
744
781
|
const off = lastSnapTargetOffset;
|
|
745
|
-
for (const inline of resolvedInlineContent(node,
|
|
746
|
-
if (!isInlineWidget(inline, node.raw)) continue;
|
|
782
|
+
for (const inline of resolvedInlineContent(node, reading)) {
|
|
783
|
+
if (!isInlineWidget(inline, node.raw, grammar)) continue;
|
|
747
784
|
if (inline.end !== off && inline.start !== off) continue;
|
|
748
785
|
const widget = widgetElByStart(el, inline.start);
|
|
749
786
|
if (widget) {
|
|
787
|
+
sweepOtherBlocksSnap();
|
|
750
788
|
widget.classList.add(inline.end === off ? 'md-snap-after' : 'md-snap-before');
|
|
751
789
|
el.classList.add('md-snap-caret-active');
|
|
790
|
+
// One caret is one position, so one widget in the document carries the paint (G1.39).
|
|
791
|
+
assertInvariant('snap-caret-unique', () => {
|
|
792
|
+
const root = getEditorRoot();
|
|
793
|
+
const painted = root?.querySelectorAll('.md-snap-after, .md-snap-before').length ?? 1;
|
|
794
|
+
return painted > 1
|
|
795
|
+
? {
|
|
796
|
+
code: 'snap-caret-not-unique',
|
|
797
|
+
message: `${painted} synthetic carets painted at once; one caret is one position`
|
|
798
|
+
}
|
|
799
|
+
: null;
|
|
800
|
+
});
|
|
752
801
|
}
|
|
753
802
|
return;
|
|
754
803
|
}
|
|
755
804
|
});
|
|
756
805
|
|
|
806
|
+
/** A block painting its synthetic caret clears every other block's: one that unmounts with the
|
|
807
|
+
* caret inside never hears the change that clears its own. */
|
|
808
|
+
function sweepOtherBlocksSnap(): void {
|
|
809
|
+
const root = getEditorRoot();
|
|
810
|
+
if (!root || !el) return;
|
|
811
|
+
for (const stale of root.querySelectorAll('.md-snap-after, .md-snap-before')) {
|
|
812
|
+
if (!el.contains(stale)) stale.classList.remove('md-snap-after', 'md-snap-before');
|
|
813
|
+
}
|
|
814
|
+
for (const block of root.querySelectorAll('.md-snap-caret-active')) {
|
|
815
|
+
if (block !== el) block.classList.remove('md-snap-caret-active');
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
757
819
|
// ── Event Handlers ──────────────────────────────────────────────────
|
|
758
820
|
|
|
759
821
|
const onInput = editableSurface.onInput;
|
|
760
822
|
|
|
761
|
-
// Walk children rather than reading textContent, so stray text nodes Chromium inserts
|
|
762
|
-
// around the marker span don't pollute the raw.
|
|
763
823
|
function readRawText(): string {
|
|
764
|
-
|
|
765
|
-
const ambient = ambientLength > 0 ? ambientSpanOf(el) : null;
|
|
766
|
-
let out = '';
|
|
767
|
-
for (const child of Array.from(el.childNodes)) {
|
|
768
|
-
if (child === ambient) continue;
|
|
769
|
-
out += rawTextOfNode(child, node.raw);
|
|
770
|
-
}
|
|
771
|
-
return out;
|
|
824
|
+
return el ? rawTextOfContent(el, node.raw, structuralSuffix(node)) : '';
|
|
772
825
|
}
|
|
773
826
|
|
|
774
|
-
// Captured before the
|
|
775
|
-
//
|
|
827
|
+
// Captured before the shared handler: its cross-block half clears the arrival side, and the
|
|
828
|
+
// first `input` during the composition resets that side to the typed one.
|
|
776
829
|
function onCompositionStart(): void {
|
|
777
830
|
compositionSeat.noteStart();
|
|
778
831
|
editableSurface.onCompositionStart();
|
|
@@ -786,75 +839,72 @@
|
|
|
786
839
|
async function onKeyDown(e: KeyboardEvent): Promise<void> {
|
|
787
840
|
if (composing || editableSurface.isDetached()) return;
|
|
788
841
|
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
// Reveal-only backstop, before any default runs: rapid arrows outrun the async
|
|
792
|
-
// selectionchange reveal, and a step against folded markers skips their bytes.
|
|
842
|
+
// Shows markers only, before any default runs: fast arrows outrun the async
|
|
843
|
+
// `selectionchange` update, and a step against still-hidden markers skips their bytes.
|
|
793
844
|
constructReveal.prepareForKeydown(e);
|
|
794
845
|
|
|
795
|
-
// Escape cancels a
|
|
796
|
-
// source
|
|
846
|
+
// Escape cancels a shown source back to its rendered form; every other key edits the
|
|
847
|
+
// source in the DOM or reaches the commands below, which hide it before writing.
|
|
797
848
|
if ((await widgetInteraction.handleRevealingKeydown(e)) || editableSurface.isDetached()) return;
|
|
798
849
|
|
|
799
|
-
// Before handleSharedKeydown
|
|
800
|
-
// ArrowLeft
|
|
801
|
-
// isn't there.
|
|
850
|
+
// Before `handleSharedKeydown`: selecting cleared the browser range, so the shared
|
|
851
|
+
// ArrowLeft branch would read offset 0.
|
|
802
852
|
if ((await widgetInteraction.handleSelectedWidgetKeydown(e)) || editableSurface.isDetached())
|
|
803
853
|
return;
|
|
804
854
|
|
|
805
|
-
// The
|
|
855
|
+
// The browser default, with `user-select: none` on the widget, collapses the selection
|
|
806
856
|
// instead of stepping past it.
|
|
807
857
|
if (widgetInteraction.handleShiftArrowIntoWidget(e)) return;
|
|
808
858
|
|
|
809
859
|
if ((await handleSharedKeydown(e, sharedCtx)) || editableSurface.isDetached()) return;
|
|
810
860
|
|
|
811
|
-
// Every caret-edge construct
|
|
812
|
-
//
|
|
861
|
+
// Every caret-edge construct goes through this one dispatch, keeping contenteditable
|
|
862
|
+
// from corrupting the atomic bytes each stands for.
|
|
813
863
|
if (edgeDispatch.handleKeydown(e, cursor.getRaw())) return;
|
|
814
864
|
|
|
815
|
-
//
|
|
816
|
-
//
|
|
817
|
-
// not a raw-0 DOM write: the landable clamp applies.
|
|
865
|
+
// The browser's Home lands before the marker span or past a leading widget. `CURSOR_START`
|
|
866
|
+
// rather than offset 0, so the clamp still applies.
|
|
818
867
|
if (
|
|
819
868
|
e.key === 'Home' &&
|
|
820
869
|
!e.shiftKey &&
|
|
821
870
|
el &&
|
|
822
|
-
(
|
|
871
|
+
(markerPrefixOf(el) !== null || landableStartAbutsIsland(el))
|
|
823
872
|
) {
|
|
824
873
|
e.preventDefault();
|
|
825
874
|
focus(CURSOR_START);
|
|
826
875
|
return;
|
|
827
876
|
}
|
|
828
877
|
|
|
829
|
-
|
|
878
|
+
const target = { kind: node.kind, runCommand, getPath: () => myPath, afterSourceCommit };
|
|
879
|
+
if (wiring.dispatchChord(e, target)) return;
|
|
830
880
|
}
|
|
831
881
|
|
|
832
882
|
const onKeyDownTraced = withKeydownVerdict(onKeyDown);
|
|
833
883
|
|
|
834
|
-
/**
|
|
835
|
-
*
|
|
836
|
-
* write the runs the range crossed literally, so the edit goes through the join seam instead.
|
|
837
|
-
* Declines wherever that seam has nothing to clean, leaving the engine its grapheme and IME
|
|
838
|
-
* behavior.
|
|
839
|
-
*/
|
|
884
|
+
/** A range edit in a mode that draws no delimiter goes through the join rules, since the browser
|
|
885
|
+
* would leave the crossed markers behind. Elsewhere the browser keeps its own edit. */
|
|
840
886
|
function handleLiveSelectionEdit(e: InputEvent): boolean {
|
|
841
887
|
return applyLiveRangeEdit(
|
|
842
888
|
e,
|
|
843
889
|
node,
|
|
844
890
|
cursor,
|
|
845
|
-
|
|
846
|
-
linkRef,
|
|
847
|
-
ambientPrefixText,
|
|
891
|
+
storedAs(),
|
|
848
892
|
widgetInteraction.isRevealing,
|
|
849
893
|
(edit) => {
|
|
850
|
-
|
|
851
|
-
|
|
894
|
+
const write = blockEdit.updateBlockContent(
|
|
895
|
+
index,
|
|
896
|
+
edit.raw,
|
|
897
|
+
'authored',
|
|
898
|
+
edit.range.start,
|
|
899
|
+
edit.caret
|
|
900
|
+
);
|
|
901
|
+
if (write.admitted) setPendingCursorOffset(write.caret, 'live-selection-edit');
|
|
852
902
|
}
|
|
853
903
|
);
|
|
854
904
|
}
|
|
855
905
|
|
|
856
|
-
// The write takes the
|
|
857
|
-
// inside the pair.
|
|
906
|
+
// The write takes the same path as the range edit above, so the block repaints once with the
|
|
907
|
+
// caret inside the pair. While a source is shown the caret counts into the DOM text instead.
|
|
858
908
|
function handleDelimiterAutoPair(e: InputEvent): boolean {
|
|
859
909
|
return applyDelimiterAutoPair(e, {
|
|
860
910
|
text: () => (widgetInteraction.isRevealing() ? readRawText() : getDisplayText()),
|
|
@@ -863,15 +913,18 @@
|
|
|
863
913
|
hasSelection: () => cursor.getRawSelection() !== null,
|
|
864
914
|
isRevealing: widgetInteraction.isRevealing,
|
|
865
915
|
foldReveal: () => widgetInteraction.foldRevealBeforeMutation(),
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
916
|
+
setCaret: (offset) => cursor.setRaw(asRawOffset(offset), { clamp: 'exact' }),
|
|
917
|
+
seatOutside: caretMemory.noteExtreme,
|
|
918
|
+
completesLine: (caret) =>
|
|
919
|
+
planTypedCompletion(node, caret, grammar, documentEnding()) !== null,
|
|
920
|
+
// Each auto-pair caller asks this itself until the caret-edge key table gives it one caller.
|
|
921
|
+
keepsKind: (line) => keepsKindAt(node, line, storedAs()),
|
|
922
|
+
reading,
|
|
923
|
+
ownPairs,
|
|
871
924
|
write: (text, caretBefore, caretAfter) => {
|
|
872
|
-
const raw = text +
|
|
873
|
-
|
|
874
|
-
setPendingCursorOffset(
|
|
925
|
+
const raw = text + blockEnding();
|
|
926
|
+
const write = blockEdit.updateBlockContent(index, raw, 'authored', caretBefore, caretAfter);
|
|
927
|
+
if (write.admitted) setPendingCursorOffset(write.caret, 'delimiter-autopair');
|
|
875
928
|
}
|
|
876
929
|
});
|
|
877
930
|
}
|
|
@@ -880,111 +933,140 @@
|
|
|
880
933
|
if (await handleSharedBeforeInput(e, sharedCtx)) return;
|
|
881
934
|
if (handleLiveSelectionEdit(e)) return;
|
|
882
935
|
if (handleDelimiterAutoPair(e)) return;
|
|
883
|
-
//
|
|
936
|
+
// An `insertLineBreak` from a soft keyboard or IME got past `onKeyDown`: consume it, since
|
|
937
|
+
// Shift+Enter is what makes a hard break.
|
|
884
938
|
if (e.inputType === 'insertLineBreak') {
|
|
885
939
|
e.preventDefault();
|
|
886
940
|
return;
|
|
887
941
|
}
|
|
888
942
|
}
|
|
889
943
|
|
|
890
|
-
//
|
|
891
|
-
//
|
|
892
|
-
// load-bearing: a column-aligned click on another visual line must not reveal.
|
|
944
|
+
// `onClick` snaps from the press point to the nearest widget edge. Y is kept too: a click at
|
|
945
|
+
// the same column on another visual line must not open a source.
|
|
893
946
|
let lastClickClientX: number | null = null;
|
|
894
947
|
let lastClickClientY: number | null = null;
|
|
895
948
|
|
|
949
|
+
/** The browser starts no drag from a non-editable inline widget, so the editor paints the range
|
|
950
|
+
* itself from the widget's edge on the press's side. */
|
|
951
|
+
function islandPress(e: PointerEvent): { paintSameBlock: boolean; anchorOffset?: number } {
|
|
952
|
+
if (!el || e.button !== 0 || e.shiftKey) return { paintSameBlock: false };
|
|
953
|
+
const anchorOffset = widgetInteraction.islandDragAnchor(e.clientX, e.clientY);
|
|
954
|
+
if (anchorOffset === null) return { paintSameBlock: false };
|
|
955
|
+
return { paintSameBlock: true, anchorOffset };
|
|
956
|
+
}
|
|
957
|
+
|
|
896
958
|
function onPointerDown(e: PointerEvent): void {
|
|
897
|
-
if (crossBlock.handlePointerDown(e)) return;
|
|
959
|
+
if (crossBlock.handlePointerDown(e, islandPress(e))) return;
|
|
898
960
|
lastClickClientX = e.clientX;
|
|
899
961
|
lastClickClientY = e.clientY;
|
|
900
|
-
|
|
901
|
-
//
|
|
902
|
-
|
|
962
|
+
armSnapTarget(null);
|
|
963
|
+
// Only a primary press ends in a click; a context-menu press would keep the caret hidden.
|
|
964
|
+
pressPending = e.button === 0;
|
|
965
|
+
// Read now, not at the `selectionchange` that follows: that event can arrive after a frame
|
|
966
|
+
// has already painted the native caret. Level with a line, where a padding press lands.
|
|
967
|
+
const seat = pressPending && el ? caretSeatInElement(el, e.clientX, e.clientY) : null;
|
|
968
|
+
pressSeatedBesideIsland =
|
|
969
|
+
!!seat && !!el && el.contains(seat.node) && !seatIsInTextContent(el, seat.node);
|
|
970
|
+
// A click on a widget that can show its source is this editor's gesture: cancelling the
|
|
971
|
+
// browser's caret default leaves that code as the only writer of the selection.
|
|
903
972
|
if (widgetInteraction.isPointOnRevealWidget(e.clientX, e.clientY)) e.preventDefault();
|
|
904
973
|
}
|
|
905
974
|
|
|
906
975
|
function onBlur(e: FocusEvent): void {
|
|
907
976
|
if (el && e.relatedTarget && el.contains(e.relatedTarget as Node)) return;
|
|
908
|
-
//
|
|
977
|
+
// Save an edit to a shown source before the caret is gone.
|
|
909
978
|
widgetInteraction.commitRevealOnBlur();
|
|
910
|
-
|
|
979
|
+
armSnapTarget(null);
|
|
980
|
+
endPress();
|
|
911
981
|
demoteEmptyHeadingOnBlur();
|
|
912
982
|
}
|
|
913
983
|
|
|
914
984
|
function demoteEmptyHeadingOnBlur(): void {
|
|
915
985
|
if (readOnly || node.kind !== 'heading' || editableSurface.isDetached()) return;
|
|
916
986
|
const demoted = demoteEmptyAtxHeading(node.raw, getContentRange(node));
|
|
917
|
-
if (demoted) void blockEdit.updateBlockContent(index, demoted.newRaw, 0);
|
|
987
|
+
if (demoted) void blockEdit.updateBlockContent(index, demoted.newRaw, 'literal', 0);
|
|
918
988
|
}
|
|
919
989
|
|
|
920
990
|
function onClick(e: MouseEvent): void {
|
|
921
991
|
// An inline widget's own handler runs first, and a jump it starts can unmount this
|
|
922
|
-
//
|
|
992
|
+
// block before the click reaches it; nothing below applies to a block that is gone.
|
|
923
993
|
if (!el) return;
|
|
924
994
|
const x = lastClickClientX;
|
|
925
995
|
const y = lastClickClientY;
|
|
926
996
|
lastClickClientX = null;
|
|
927
997
|
lastClickClientY = null;
|
|
928
|
-
cursor.
|
|
998
|
+
cursor.clampOutOfMarkerPrefix();
|
|
929
999
|
widgetInteraction.snapClickToWidgetEdge(x, y, {
|
|
930
1000
|
modified: e.ctrlKey || e.metaKey,
|
|
931
|
-
clickCount: e.detail
|
|
1001
|
+
clickCount: e.detail,
|
|
1002
|
+
// A release that travelled ends a drag rather than a click: showing the source there
|
|
1003
|
+
// would unmount the widget the drag just painted a range across.
|
|
1004
|
+
moved:
|
|
1005
|
+
x !== null && y !== null && (Math.abs(e.clientX - x) > 3 || Math.abs(e.clientY - y) > 3)
|
|
932
1006
|
});
|
|
1007
|
+
// The click has decided: from here the snap target hides the browser's caret, or nothing does.
|
|
1008
|
+
endPress();
|
|
933
1009
|
}
|
|
934
1010
|
|
|
935
1011
|
// ── Formatting shortcuts ────────────────────────────────────────────
|
|
936
1012
|
|
|
937
|
-
// `range`
|
|
938
|
-
//
|
|
939
|
-
// nothing to toggle. A collapsed range is the caret contract, not a bail.
|
|
1013
|
+
// `range` was read before the command ran and must not be read again: hiding a shown source
|
|
1014
|
+
// collapses the live selection.
|
|
940
1015
|
function toggleFormat(format: InlineMarkKind, range: { start: number; end: number }): void {
|
|
941
1016
|
if (!el) return;
|
|
942
1017
|
|
|
943
|
-
//
|
|
944
|
-
//
|
|
945
|
-
|
|
946
|
-
// block the caret is in, so they show the pair and take the byte path.
|
|
947
|
-
if (!paintsFocusedMarkers(presentationMode) && range.start === range.end) {
|
|
1018
|
+
// Where the markers stay hidden, an empty `****` would be invisible bytes, so the mark waits
|
|
1019
|
+
// for the next insertion (`docs/design/live-mode.md` § 4.3).
|
|
1020
|
+
if (reading.hidesDelimitersAtCaret() && range.start === range.end) {
|
|
948
1021
|
// The insertion that spends the mark starts its own undo entry, so it is never
|
|
949
|
-
//
|
|
1022
|
+
// merged into the burst the chord interrupted.
|
|
950
1023
|
controller.flushDebouncedCheckpoint();
|
|
951
|
-
pendingMarks.toggle(format);
|
|
1024
|
+
caretMemory.pendingMarks.toggle(format);
|
|
952
1025
|
return;
|
|
953
1026
|
}
|
|
954
1027
|
|
|
955
1028
|
const toggled = toggleInlineFormat(
|
|
956
|
-
{
|
|
957
|
-
|
|
958
|
-
|
|
1029
|
+
{
|
|
1030
|
+
display: getDisplayText(),
|
|
1031
|
+
content: getContentRange(node),
|
|
1032
|
+
selection: range,
|
|
1033
|
+
reading
|
|
1034
|
+
},
|
|
1035
|
+
format
|
|
959
1036
|
);
|
|
960
1037
|
if (!toggled) return;
|
|
961
1038
|
const { newDisplay, newSelStart, newSelEnd } = toggled;
|
|
962
1039
|
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
1040
|
+
const write = blockEdit.updateBlockContent(
|
|
1041
|
+
index,
|
|
1042
|
+
newDisplay + blockEnding(),
|
|
1043
|
+
'literal',
|
|
1044
|
+
range.start,
|
|
1045
|
+
newSelStart
|
|
966
1046
|
);
|
|
1047
|
+
if (!write.admitted) return;
|
|
967
1048
|
|
|
968
1049
|
tick().then(() => {
|
|
969
|
-
setSelection(
|
|
1050
|
+
setSelection(write.caret, write.storedOffset(newSelEnd));
|
|
970
1051
|
});
|
|
971
1052
|
}
|
|
972
1053
|
</script>
|
|
973
1054
|
|
|
974
|
-
<!-- Reading mode
|
|
975
|
-
|
|
1055
|
+
<!-- Reading mode turns contenteditable off, ruling out every browser edit; tabindex keeps focus
|
|
1056
|
+
and arrow traversal. Both roles the spread sets are interactive, which the compiler cannot see. -->
|
|
1057
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
976
1058
|
<div
|
|
977
1059
|
bind:this={el}
|
|
978
1060
|
tabindex="0"
|
|
979
1061
|
class="text-editable-block {blockClass}"
|
|
980
1062
|
contenteditable={readOnly ? 'false' : 'true'}
|
|
981
1063
|
aria-readonly={readOnly ? 'true' : undefined}
|
|
982
|
-
|
|
983
|
-
style:text-indent={ambientPrefixText ?
|
|
1064
|
+
{...editableSurfaceAttributes(node, combobox)}
|
|
1065
|
+
style:text-indent={ambientPrefixText ? `calc(-1 * ${ambientIndent})` : null}
|
|
984
1066
|
style:padding-left={ambientPrefixText ? ambientIndent : null}
|
|
985
1067
|
oninput={onInput}
|
|
986
1068
|
onkeydown={onKeyDownTraced}
|
|
987
|
-
onbeforeinput={onBeforeInput}
|
|
1069
|
+
onbeforeinput={editableSurface.onBeforeInput}
|
|
988
1070
|
oncopy={clipboardHandlers.onCopy}
|
|
989
1071
|
oncut={clipboardHandlers.onCut}
|
|
990
1072
|
onpaste={clipboardHandlers.onPaste}
|