@voithos-labs/aragonite 0.10.2 → 0.10.4
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 +6 -21
- package/THIRD-PARTY-NOTICES.md +25 -0
- package/dist/a11y-strings.d.ts +19 -0
- package/dist/a11y-strings.js +19 -0
- package/dist/action-contracts.d.ts +7 -1
- package/dist/ambient/ambient-dom.js +5 -1
- package/dist/block-component.d.ts +14 -0
- package/dist/components/BlockDragHandle.svelte +37 -24
- package/dist/components/BlockHost.svelte +18 -11
- package/dist/components/Editor.svelte +434 -198
- package/dist/components/Editor.svelte.d.ts +1 -1
- package/dist/components/SelectionOverlay.svelte +25 -17
- package/dist/components/SelectionOverlay.svelte.d.ts +1 -1
- package/dist/components/TailInsert.svelte +107 -0
- package/dist/components/TailInsert.svelte.d.ts +17 -0
- package/dist/components/block-content-selector.d.ts +6 -2
- package/dist/components/block-content-selector.js +6 -2
- package/dist/components/blocks/ThematicBreakBlock.svelte +19 -6
- package/dist/components/blocks/ThematicBreakBlock.svelte.d.ts +1 -0
- package/dist/components/blocks/code/CodeBlock.svelte +211 -30
- package/dist/components/blocks/code/CodeBlockRail.svelte +704 -0
- package/dist/components/blocks/code/CodeBlockRail.svelte.d.ts +26 -0
- package/dist/components/blocks/code/code-bootstrap.js +16 -0
- package/dist/components/blocks/code/code-context-actions.d.ts +1 -0
- package/dist/components/blocks/code/code-context-actions.js +24 -0
- package/dist/components/blocks/code/code-fence-exit.d.ts +15 -0
- package/dist/components/blocks/code/code-fence-exit.js +26 -0
- package/dist/components/blocks/code/code-languages.d.ts +6 -0
- package/dist/components/blocks/code/code-languages.js +22 -3
- package/dist/components/blocks/code/code-renderer.js +11 -0
- package/dist/components/blocks/directive/DirectiveContainerBlock.svelte +1 -1
- package/dist/components/blocks/editable-leaf.d.ts +37 -6
- package/dist/components/blocks/editable-leaf.js +248 -30
- package/dist/components/blocks/editable-surface.d.ts +9 -0
- package/dist/components/blocks/editable-surface.js +22 -3
- package/dist/components/blocks/list/ListBlock.svelte +1 -0
- package/dist/components/blocks/list/ListItemBlock.svelte +14 -5
- package/dist/components/blocks/list/ListItemBlock.svelte.d.ts +2 -0
- package/dist/components/blocks/list/task-checkbox.d.ts +2 -0
- package/dist/components/blocks/list/task-checkbox.js +11 -2
- package/dist/components/blocks/surface-wiring.svelte.d.ts +4 -0
- package/dist/components/blocks/surface-wiring.svelte.js +8 -1
- package/dist/components/blocks/table/TableActionMenu.svelte +210 -86
- package/dist/components/blocks/table/TableActionMenu.svelte.d.ts +5 -0
- package/dist/components/blocks/table/TableBlock.svelte +205 -186
- package/dist/components/blocks/table/TableBlock.svelte.d.ts +1 -0
- package/dist/components/blocks/table/TableCellBlock.svelte +87 -22
- package/dist/components/blocks/table/TableRowBlock.svelte +4 -18
- package/dist/components/blocks/table/TableRowBlock.svelte.d.ts +0 -5
- package/dist/components/blocks/table/cell-clipboard.d.ts +10 -0
- package/dist/components/blocks/table/cell-clipboard.js +34 -1
- package/dist/components/blocks/table/cell-keydown-plan.d.ts +1 -1
- package/dist/components/blocks/table/cell-keydown-plan.js +3 -1
- package/dist/components/blocks/table/table-cell-paste.js +2 -1
- package/dist/components/blocks/table/table-menu-model.d.ts +35 -8
- package/dist/components/blocks/table/table-menu-model.js +36 -17
- package/dist/components/blocks/text/TextEditableBlock.svelte +58 -11
- package/dist/components/blocks/text/click-snap-guard.d.ts +3 -0
- package/dist/components/blocks/text/click-snap-guard.js +8 -0
- package/dist/components/blocks/text/delimiter-autopair.d.ts +71 -0
- package/dist/components/blocks/text/delimiter-autopair.js +216 -0
- package/dist/components/blocks/text/edge-policy-dispatch.d.ts +4 -0
- package/dist/components/blocks/text/edge-policy-dispatch.js +89 -20
- package/dist/components/blocks/text/live-selection-edit.d.ts +5 -5
- package/dist/components/blocks/text/live-selection-edit.js +37 -7
- package/dist/components/blocks/text/text-clipboard.js +2 -2
- package/dist/components/blocks/text/text-keydown.d.ts +7 -1
- package/dist/components/blocks/text/text-keydown.js +11 -1
- package/dist/components/blocks/text/text-render.d.ts +1 -1
- package/dist/components/blocks/text/text-render.js +3 -1
- package/dist/components/blocks/text/widget-interaction.d.ts +3 -0
- package/dist/components/blocks/text/widget-interaction.js +181 -37
- package/dist/components/drag-handle.d.ts +41 -0
- package/dist/components/drag-handle.js +134 -0
- package/dist/components/editor-root-focus.d.ts +19 -0
- package/dist/components/editor-root-focus.js +67 -0
- package/dist/components/editor-root-geometry.d.ts +39 -0
- package/dist/components/editor-root-geometry.js +91 -0
- package/dist/components/editor-root-keydown.d.ts +1 -1
- package/dist/components/editor-root-keydown.js +12 -3
- package/dist/components/editor-root-listeners.d.ts +3 -6
- package/dist/components/editor-root-listeners.js +3 -24
- package/dist/components/editor-root-mode-flip.d.ts +36 -0
- package/dist/components/editor-root-mode-flip.js +92 -0
- package/dist/components/image/ImageOverlayHost.svelte +14 -6
- package/dist/components/image/ImageProperties.svelte +512 -70
- package/dist/components/image/ImageProperties.svelte.d.ts +6 -1
- package/dist/components/image/ImageResizeHandles.svelte +67 -34
- package/dist/components/image/image-crop.d.ts +39 -0
- package/dist/components/image/image-crop.js +74 -0
- package/dist/components/image/image-edit-commit.d.ts +1 -0
- package/dist/components/image/image-edit-commit.js +21 -5
- package/dist/components/image/image-source-bytes.js +10 -3
- package/dist/components/image/image-widget-editing.js +1 -0
- package/dist/components/image/widget-dom.js +5 -1
- package/dist/components/link-card/link-card-commit.js +1 -1
- package/dist/components/lrd-map-gate.js +1 -1
- package/dist/components/menu/BlockMenu.svelte +315 -0
- package/dist/components/menu/BlockMenu.svelte.d.ts +34 -0
- package/dist/components/menu/MenuIcon.svelte +153 -0
- package/dist/components/menu/MenuIcon.svelte.d.ts +51 -0
- package/dist/components/menu/SelectionToolbar.svelte +385 -0
- package/dist/components/menu/SelectionToolbar.svelte.d.ts +16 -0
- package/dist/components/menu/clipboard-actions.d.ts +12 -0
- package/dist/components/menu/clipboard-actions.js +42 -0
- package/dist/components/menu/default-context-actions.d.ts +15 -0
- package/dist/components/menu/default-context-actions.js +76 -0
- package/dist/components/menu/flyout-placement.d.ts +6 -0
- package/dist/components/menu/flyout-placement.js +25 -0
- package/dist/core/inline/format-toggle.d.ts +12 -4
- package/dist/core/inline/format-toggle.js +94 -40
- package/dist/core/inline/image-dimensions.d.ts +3 -0
- package/dist/core/inline/image-dimensions.js +46 -10
- package/dist/core/inline/inline-widgets.d.ts +19 -0
- package/dist/core/inline/inline-widgets.js +5 -0
- package/dist/core/inline/scan/brackets.js +1 -0
- package/dist/core/inline/scan/plugin-syntax.d.ts +8 -0
- package/dist/core/inline/scan/plugin-syntax.js +15 -1
- package/dist/core/inline/transparency.js +3 -3
- package/dist/core/inline-render.d.ts +6 -0
- package/dist/core/inline-render.js +32 -0
- package/dist/core/nodes.d.ts +14 -0
- package/dist/cursor/edge-affinity.js +2 -1
- package/dist/cursor/height-oracle.d.ts +2 -3
- package/dist/cursor/height-oracle.js +0 -1
- package/dist/cursor/overlay-remeasure.js +8 -0
- package/dist/cursor/reveal-source.js +7 -2
- package/dist/cursor/scroll-hold.d.ts +10 -0
- package/dist/cursor/scroll-hold.js +22 -0
- package/dist/cursor/scrollport.d.ts +9 -0
- package/dist/cursor/scrollport.js +30 -1
- package/dist/cursor/visual-lines.d.ts +5 -4
- package/dist/cursor/visual-lines.js +56 -11
- package/dist/cursor/widget-edge-snap.d.ts +28 -0
- package/dist/cursor/widget-edge-snap.js +38 -0
- package/dist/cursor/widget-offset.d.ts +9 -0
- package/dist/cursor/widget-offset.js +71 -4
- package/dist/debug/interaction-trace.d.ts +4 -0
- package/dist/debug/interaction-trace.js +15 -0
- package/dist/decorations/decoration-state.svelte.js +1 -1
- package/dist/decorations/reserved-attrs.js +1 -0
- package/dist/editor-actions/ancestry-folds.d.ts +2 -2
- package/dist/editor-actions/ancestry-folds.js +1 -1
- package/dist/editor-actions/block-edit-scope.js +1 -1
- package/dist/editor-actions/commit/text-batch.d.ts +3 -2
- package/dist/editor-actions/commit/text-batch.js +1 -1
- package/dist/editor-actions/commit/undo-controller.js +4 -2
- package/dist/editor-actions/container-edit.js +2 -1
- package/dist/editor-actions/enter-completion.d.ts +2 -0
- package/dist/editor-actions/enter-completion.js +23 -2
- package/dist/editor-actions/focus/focus-dispatch.js +7 -4
- package/dist/editor-actions/focus/focus-landing.d.ts +10 -1
- package/dist/editor-actions/focus/focus-landing.js +20 -6
- package/dist/editor-actions/inline-range-commit.js +1 -1
- package/dist/editor-actions/plugin/container.d.ts +7 -0
- package/dist/editor-actions/plugin/container.js +3 -1
- package/dist/editor-actions/reorder-action.js +19 -10
- package/dist/editor-actions/reorder-drag.js +29 -1
- package/dist/editor-actions/replacement-focus.d.ts +1 -1
- package/dist/editor-actions/replacement-focus.js +1 -1
- package/dist/editor-actions/search-replace.js +1 -1
- package/dist/editor-actions/table-context.d.ts +4 -1
- package/dist/editor-actions/table-context.js +57 -1
- package/dist/editor-events.d.ts +3 -0
- package/dist/editor-keys.d.ts +33 -0
- package/dist/editor-props.d.ts +24 -12
- package/dist/index.d.ts +1 -1
- package/dist/plugin.d.ts +7 -0
- package/dist/plugin.js +16 -0
- package/dist/plugins/latex/BlockMath.svelte +264 -29
- package/dist/plugins/latex/BlockMath.svelte.d.ts +2 -0
- package/dist/plugins/latex/index.d.ts +2 -1
- package/dist/plugins/latex/latex-kind.js +60 -10
- package/dist/plugins/latex/math-completion.js +4 -1
- package/dist/plugins/latex/math-layout.d.ts +15 -0
- package/dist/plugins/latex/math-layout.js +13 -0
- package/dist/plugins/latex/math-source.d.ts +19 -0
- package/dist/plugins/latex/math-source.js +103 -0
- package/dist/plugins/latex/register.d.ts +11 -2
- package/dist/plugins/latex/register.js +3 -1
- package/dist/plugins/latex/renderer.d.ts +3 -3
- package/dist/plugins/latex/renderer.js +13 -6
- package/dist/plugins/mermaid/MermaidBlock.svelte +19 -9
- package/dist/plugins/parrot/ParrotBlock.svelte +3 -1
- package/dist/reactivity/list-windowing.svelte.d.ts +8 -8
- package/dist/reactivity/list-windowing.svelte.js +75 -30
- package/dist/schema/block-completions.d.ts +8 -0
- package/dist/schema/block-completions.js +11 -0
- package/dist/schema/commands.d.ts +9 -5
- package/dist/schema/commands.js +12 -7
- package/dist/schema/context-actions.d.ts +31 -0
- package/dist/schema/context-actions.js +23 -0
- package/dist/schema/fenced-code-raw.js +31 -1
- package/dist/schema/operations.d.ts +8 -1
- package/dist/schema/reserved-chords.js +37 -4
- package/dist/schema/table-cell-raw.d.ts +1 -1
- package/dist/schema/table-cell-raw.js +1 -1
- package/dist/selection/block-hit-test.js +3 -2
- package/dist/selection/char-endpoint-snap.js +1 -1
- package/dist/selection/clipboard-text.js +6 -1
- package/dist/selection/covered-block.d.ts +10 -0
- package/dist/selection/covered-block.js +24 -0
- package/dist/selection/cross-block/dispatch.d.ts +3 -0
- package/dist/selection/cross-block/dispatch.js +13 -1
- package/dist/selection/cross-block/format-range.d.ts +1 -1
- package/dist/selection/cross-block/format-range.js +4 -15
- package/dist/selection/cross-block/format-toggle.js +1 -1
- package/dist/selection/cross-block/keydown.js +3 -29
- package/dist/selection/cross-block/ops.js +1 -1
- package/dist/selection/cross-block/paste.js +31 -35
- package/dist/selection/cross-block/type-replace.d.ts +3 -2
- package/dist/selection/cross-block/type-replace.js +52 -13
- package/dist/selection/dead-space-caret.d.ts +13 -0
- package/dist/selection/dead-space-caret.js +57 -1
- package/dist/selection/drag-pointer.d.ts +26 -2
- package/dist/selection/drag-pointer.js +103 -2
- package/dist/selection/gap-caret.js +1 -1
- package/dist/selection/keyboard-extend.d.ts +3 -2
- package/dist/selection/keyboard-extend.js +4 -3
- package/dist/selection/multi-click.d.ts +42 -0
- package/dist/selection/multi-click.js +203 -0
- package/dist/selection/native-bridge.d.ts +3 -0
- package/dist/selection/native-bridge.js +31 -2
- package/dist/selection/path-lookup.d.ts +10 -2
- package/dist/selection/path-lookup.js +11 -4
- package/dist/selection/pointer-gesture.d.ts +9 -0
- package/dist/selection/pointer-gesture.js +11 -0
- package/dist/selection/primitives.d.ts +7 -0
- package/dist/selection/primitives.js +19 -1
- package/dist/selection/range-delete-ceremony.js +4 -2
- package/dist/selection/range-delete-chrome.js +2 -1
- package/dist/selection/range-delete-table-coverage.js +2 -1
- package/dist/selection/range-delete-table.js +3 -2
- package/dist/selection/range-delete.d.ts +4 -0
- package/dist/selection/range-delete.js +31 -3
- package/dist/selection/selection-drop.d.ts +34 -0
- package/dist/selection/selection-drop.js +253 -0
- package/dist/selection/selection-restore.js +1 -1
- package/dist/selection/selection-state.svelte.d.ts +6 -0
- package/dist/selection/selection-state.svelte.js +36 -1
- package/dist/selection/table-endpoint-snap.js +1 -1
- package/dist/selection/table-rect-extend.js +1 -1
- package/dist/styles/editor-theme.css +75 -31
- package/dist/styles/editor.css +268 -18
- package/dist/testing/container-conformance.js +2 -2
- package/dist/testing/inline-conformance.js +2 -1
- package/dist/tree-operations/blockquote.js +1 -1
- package/dist/tree-operations/chain-rebuild.d.ts +63 -0
- package/dist/tree-operations/chain-rebuild.js +142 -0
- package/dist/tree-operations/children.d.ts +1 -1
- package/dist/tree-operations/children.js +1 -1
- package/dist/tree-operations/cleanup.js +1 -1
- package/dist/tree-operations/content-write.d.ts +50 -0
- package/dist/tree-operations/content-write.js +263 -0
- package/dist/tree-operations/index.d.ts +8 -3
- package/dist/tree-operations/index.js +6 -2
- package/dist/tree-operations/list/exit-replacement.js +1 -1
- package/dist/tree-operations/list/unwrap-merge.js +3 -3
- package/dist/tree-operations/node-ops.d.ts +17 -234
- package/dist/tree-operations/node-ops.js +47 -1113
- package/dist/tree-operations/node-primitives.d.ts +75 -0
- package/dist/tree-operations/node-primitives.js +117 -0
- package/dist/tree-operations/paste/apply.js +1 -1
- package/dist/tree-operations/paste/body-write.d.ts +1 -1
- package/dist/tree-operations/paste/body-write.js +2 -2
- package/dist/tree-operations/paste/container-match.js +4 -2
- package/dist/tree-operations/paste/dispatch.js +2 -1
- package/dist/tree-operations/paste/find-enclosing-list.js +1 -1
- package/dist/tree-operations/paste/focus-target.d.ts +1 -1
- package/dist/tree-operations/paste/list-absorb.js +1 -1
- package/dist/tree-operations/paste/list-break-out.js +1 -1
- package/dist/tree-operations/paste/parent-scope.js +1 -1
- package/dist/tree-operations/paste/paste-replacement.js +1 -1
- package/dist/tree-operations/paste/replace-block-at-parent.d.ts +3 -1
- package/dist/tree-operations/paste/replace-block-at-parent.js +5 -2
- package/dist/tree-operations/paste/replacement-parse.d.ts +17 -0
- package/dist/tree-operations/paste/replacement-parse.js +22 -0
- package/dist/tree-operations/path-mutate.d.ts +1 -1
- package/dist/tree-operations/path-mutate.js +2 -1
- package/dist/tree-operations/reorder-unit.js +1 -1
- package/dist/tree-operations/reorder.d.ts +5 -2
- package/dist/tree-operations/reorder.js +55 -2
- package/dist/tree-operations/settle.d.ts +105 -0
- package/dist/tree-operations/settle.js +660 -0
- package/dist/tree-operations/table-grid-clipboard.d.ts +21 -0
- package/dist/tree-operations/table-grid-clipboard.js +90 -0
- package/dist/tree-operations/unshare.d.ts +15 -77
- package/dist/tree-operations/unshare.js +15 -166
- package/docs/guide/consumer-guide.md +136 -104
- package/docs/guide/plugin-api.md +73 -29
- package/docs/guide/plugin-guide.md +55 -23
- package/package.json +9 -7
- package/dist/components/blocks/code/CodeLanguageChip.svelte +0 -127
- package/dist/components/blocks/code/CodeLanguageChip.svelte.d.ts +0 -14
- package/dist/components/blocks/table/TableGrip.svelte +0 -91
- package/dist/components/blocks/table/TableGrip.svelte.d.ts +0 -8
- package/dist/components/blocks/table/table-drop-target.d.ts +0 -1
- package/dist/components/blocks/table/table-drop-target.js +0 -16
- package/dist/components/blocks/table/table-reorder-drag.d.ts +0 -78
- package/dist/components/blocks/table/table-reorder-drag.js +0 -97
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* No Svelte context or reactivity; inputs are passed in as parameters.
|
|
4
4
|
*/
|
|
5
5
|
import { CURSOR_END, CURSOR_START } from '../../block-component';
|
|
6
|
-
import { consumeStickyLanding } from './focus-landing';
|
|
6
|
+
import { consumeStickyLanding, verticalArrival } from './focus-landing';
|
|
7
7
|
/** Move focus within a container, or delegate upward when out of range. */
|
|
8
8
|
export async function dispatchMoveFocus(refs, innerIndex, position, stickyColumn, parent, scope = {}) {
|
|
9
9
|
const { childCount, options, gapStop } = scope;
|
|
@@ -89,13 +89,16 @@ export function dispatchFocusAtColumn(refs, x, from) {
|
|
|
89
89
|
if (refs.length === 0)
|
|
90
90
|
return;
|
|
91
91
|
const indices = from === 'above' ? refs.map((_, i) => i) : refs.map((_, i) => refs.length - 1 - i);
|
|
92
|
-
//
|
|
93
|
-
//
|
|
92
|
+
// Pass over transparent refs so an entry from above/below lands on the first/last
|
|
93
|
+
// text-bearing child.
|
|
94
94
|
for (const i of indices) {
|
|
95
95
|
const ref = refs[i];
|
|
96
96
|
if (!ref?.focusable)
|
|
97
97
|
continue;
|
|
98
|
-
|
|
98
|
+
const arrival = verticalArrival(ref, from);
|
|
99
|
+
if (arrival === 'entered')
|
|
100
|
+
return;
|
|
101
|
+
if (arrival === 'transparent')
|
|
99
102
|
continue;
|
|
100
103
|
if (ref.focusAtColumn)
|
|
101
104
|
ref.focusAtColumn(x, from);
|
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
* Shared cross-block landing tail for the focus dispatchers. Sticky-X null handling
|
|
3
3
|
* lives here, so `focusAtColumn` receivers always get a finite x.
|
|
4
4
|
*/
|
|
5
|
-
import { type BlockComponent, type FocusPosition } from '../../block-component';
|
|
5
|
+
import { type BlockComponent, type FocusPosition, type StickyColumnDirection } from '../../block-component';
|
|
6
6
|
import type { StickyColumnState } from '../../cursor/sticky-column';
|
|
7
7
|
export declare function consumeStickyLanding(block: BlockComponent, index: number, position: FocusPosition, stickyColumn: StickyColumnState, retryAt: (index: number) => Promise<void> | void): Promise<void>;
|
|
8
|
+
/** What a vertical arrival does at a block: enter its widget, pass over it, or seat a caret. */
|
|
9
|
+
export type VerticalArrival = 'entered' | 'transparent' | 'seat';
|
|
10
|
+
/**
|
|
11
|
+
* The vertical stop rule, asked by both vertical doors: the per-block landing and a container's
|
|
12
|
+
* column entry. A widget-only block carries no column, so it is passed over unless its edge widget
|
|
13
|
+
* takes the arrival, which is a stop of its own and reads alike from either side. `'entered'` means
|
|
14
|
+
* the widget ALREADY took it, so the caller stops rather than repeating the entry.
|
|
15
|
+
*/
|
|
16
|
+
export declare function verticalArrival(block: BlockComponent, from: StickyColumnDirection): VerticalArrival;
|
|
@@ -5,12 +5,15 @@
|
|
|
5
5
|
import { CURSOR_END, CURSOR_START } from '../../block-component';
|
|
6
6
|
export async function consumeStickyLanding(block, index, position, stickyColumn, retryAt) {
|
|
7
7
|
const isStickyMove = typeof position === 'object' && 'stickyColumnFrom' in position;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
if (isStickyMove) {
|
|
9
|
+
const from = position.stickyColumnFrom;
|
|
10
|
+
const arrival = verticalArrival(block, from);
|
|
11
|
+
if (arrival === 'entered')
|
|
12
|
+
return;
|
|
13
|
+
if (arrival === 'transparent') {
|
|
14
|
+
await retryAt(index + (from === 'below' ? -1 : 1));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
14
17
|
}
|
|
15
18
|
// Enter an edge widget rather than dropping a no-op caret at its boundary, so the
|
|
16
19
|
// arrow key produces one visible step.
|
|
@@ -37,3 +40,14 @@ export async function consumeStickyLanding(block, index, position, stickyColumn,
|
|
|
37
40
|
else
|
|
38
41
|
block.focus(CURSOR_END);
|
|
39
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* The vertical stop rule, asked by both vertical doors: the per-block landing and a container's
|
|
45
|
+
* column entry. A widget-only block carries no column, so it is passed over unless its edge widget
|
|
46
|
+
* takes the arrival, which is a stop of its own and reads alike from either side. `'entered'` means
|
|
47
|
+
* the widget ALREADY took it, so the caller stops rather than repeating the entry.
|
|
48
|
+
*/
|
|
49
|
+
export function verticalArrival(block, from) {
|
|
50
|
+
if (!block.isVerticallyTransparent?.())
|
|
51
|
+
return 'seat';
|
|
52
|
+
return block.enterEdgeWidget?.(from === 'above' ? 'start' : 'end') ? 'entered' : 'transparent';
|
|
53
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { docPathFrom } from '../cursor/coordinate-spaces';
|
|
7
7
|
import { expectStateForNode } from '../reactivity/state-registry';
|
|
8
|
-
import { isBlockNode, nodeAt, normalizeOwnRaw, writeOwnRaw } from '../tree-operations/node-
|
|
8
|
+
import { isBlockNode, nodeAt, normalizeOwnRaw, writeOwnRaw } from '../tree-operations/node-primitives';
|
|
9
9
|
import { ensureUnsharedChild, ensureUnsharedPath } from '../tree-operations/unshare';
|
|
10
10
|
export function createInlineRangeCommit(deps) {
|
|
11
11
|
async function commitInlineRange(path, start, end, bytes, caretAfter) {
|
|
@@ -87,6 +87,13 @@ export interface ContainerBlock {
|
|
|
87
87
|
* entry and windowing reveal. False for a modified or non-arrow key: leave it native.
|
|
88
88
|
*/
|
|
89
89
|
moveFocusOut(e: KeyboardEvent): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* The reader's scroll position, captured now. Call before a state flip that swaps this
|
|
92
|
+
* block's view for one of a different height, then await the returned restore: the
|
|
93
|
+
* scrollport is back where it was once the swap has flushed. A reveal in flight outranks
|
|
94
|
+
* it and the restore stands down.
|
|
95
|
+
*/
|
|
96
|
+
captureScrollPosition(): () => Promise<void>;
|
|
90
97
|
}
|
|
91
98
|
/**
|
|
92
99
|
* Collapse-ness has ONE definition: the descriptor's `reservedChrome.isCollapsed`
|
|
@@ -13,6 +13,7 @@ import { eventToChord } from '../../schema/keybindings';
|
|
|
13
13
|
import { isReadingMode } from '../../presentation-mode';
|
|
14
14
|
import { devWarn } from '../../dev-warn';
|
|
15
15
|
import { BLOCK_EDIT_KEY, CONTAINER_EDIT_KEY, EDITOR_DOC_KEY, EDITOR_POLICIES_KEY, EDITOR_SERVICES_KEY, FOCUS_KEY, HISTORY_KEY } from '../../editor-keys';
|
|
16
|
+
import { captureScrollPosition } from '../../cursor/scroll-hold';
|
|
16
17
|
import { emitCommandError } from '../../editor-events';
|
|
17
18
|
import { owningPluginEditor } from '../../schema/plugin-install';
|
|
18
19
|
import { createBlockListState } from '../../reactivity/block-list-state.svelte';
|
|
@@ -130,7 +131,7 @@ export function createContainerBlock(deps) {
|
|
|
130
131
|
const parentFocus = getContext(FOCUS_KEY);
|
|
131
132
|
const parentContainerEdit = getContext(CONTAINER_EDIT_KEY);
|
|
132
133
|
const history = getContext(HISTORY_KEY);
|
|
133
|
-
const { stickyColumn, edgeAffinity, selection, reorder, events: editorEvents, registryView, activePlugins } = getContext(EDITOR_SERVICES_KEY);
|
|
134
|
+
const { stickyColumn, edgeAffinity, selection, reorder, revealAnchor, events: editorEvents, registryView, activePlugins } = getContext(EDITOR_SERVICES_KEY);
|
|
134
135
|
const { keybindingOverrides, presentationMode: getPresentationMode, theme: getTheme } = getContext(EDITOR_POLICIES_KEY);
|
|
135
136
|
const editorDoc = getContext(EDITOR_DOC_KEY);
|
|
136
137
|
const pluginEditor = editorDoc?.pluginEditor;
|
|
@@ -344,6 +345,7 @@ export function createContainerBlock(deps) {
|
|
|
344
345
|
updateOwnMetadata,
|
|
345
346
|
handleKeydown,
|
|
346
347
|
moveFocusOut,
|
|
348
|
+
captureScrollPosition: () => captureScrollPosition(deps.getBoxEl(), () => revealAnchor.get() !== null),
|
|
347
349
|
getPresentationMode,
|
|
348
350
|
getTheme,
|
|
349
351
|
getOptions
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { CURSOR_START } from '../block-component';
|
|
10
10
|
import { reorderChildrenWithTrivia } from '../tree-operations/reorder';
|
|
11
11
|
import { resolveReorderUnit } from '../tree-operations/reorder-unit';
|
|
12
|
-
import { blockNodeAt, nodeAt } from '../tree-operations/node-
|
|
12
|
+
import { blockNodeAt, nodeAt } from '../tree-operations/node-primitives';
|
|
13
13
|
import { renumberOrderedList } from '../tree-operations/list/ordered-markers';
|
|
14
14
|
import { expectStateForNode } from '../reactivity/state-registry';
|
|
15
15
|
import { readCurrentSelection } from '../selection/native-bridge';
|
|
@@ -25,7 +25,7 @@ export function createReorderAction(deps, controller, onReorder) {
|
|
|
25
25
|
function caretOffset() {
|
|
26
26
|
return readCurrentSelection(deps.selectionState, deps.blockRefs)?.focus.offset ?? 0;
|
|
27
27
|
}
|
|
28
|
-
async function commitReorder(unit, to, offset) {
|
|
28
|
+
async function commitReorder(unit, to, offset, focusAfter) {
|
|
29
29
|
let landing = to;
|
|
30
30
|
if (unit.scope === 'document') {
|
|
31
31
|
await controller.commitStructural({
|
|
@@ -36,11 +36,14 @@ export function createReorderAction(deps, controller, onReorder) {
|
|
|
36
36
|
eventPath: docPathFrom([unit.index])
|
|
37
37
|
},
|
|
38
38
|
mutate: (children) => {
|
|
39
|
-
const settled = reorderChildrenWithTrivia(children, unit.index, to, deps.sharing);
|
|
39
|
+
const settled = reorderChildrenWithTrivia(children, unit.index, to, deps.sharing, true);
|
|
40
40
|
landing = settled.landing;
|
|
41
41
|
return settled.change;
|
|
42
42
|
},
|
|
43
|
-
afterTick: () =>
|
|
43
|
+
afterTick: () => {
|
|
44
|
+
if (focusAfter)
|
|
45
|
+
deps.blockRefs[landing]?.focus(CURSOR_START);
|
|
46
|
+
}
|
|
44
47
|
});
|
|
45
48
|
return { landing, total: deps.doc.children.length };
|
|
46
49
|
}
|
|
@@ -69,7 +72,10 @@ export function createReorderAction(deps, controller, onReorder) {
|
|
|
69
72
|
}
|
|
70
73
|
return settled.change;
|
|
71
74
|
},
|
|
72
|
-
afterTick: () =>
|
|
75
|
+
afterTick: () => {
|
|
76
|
+
if (focusAfter)
|
|
77
|
+
state.innerBlockRefs[landing]?.focus(CURSOR_START);
|
|
78
|
+
}
|
|
73
79
|
});
|
|
74
80
|
// Re-resolved, not `parent`: the ceremony's copy-on-write replaced that node, so the one
|
|
75
81
|
// this action resolved still holds the pre-move children.
|
|
@@ -86,19 +92,22 @@ export function createReorderAction(deps, controller, onReorder) {
|
|
|
86
92
|
return null;
|
|
87
93
|
return { unit, to };
|
|
88
94
|
}
|
|
89
|
-
async function run(fromPath, computeTo) {
|
|
95
|
+
async function run(fromPath, computeTo, focusAfter) {
|
|
90
96
|
const target = resolveAndClamp(fromPath, computeTo);
|
|
91
97
|
if (!target)
|
|
92
98
|
return;
|
|
93
99
|
// Drop any cross-block selection so the overlay doesn't fight the move; the
|
|
94
|
-
// commit's afterTick re-places the caret.
|
|
100
|
+
// commit's afterTick re-places the caret when the caller wants it.
|
|
95
101
|
deps.selectionState.collapse();
|
|
96
|
-
const outcome = await commitReorder(target.unit, target.to, caretOffset());
|
|
102
|
+
const outcome = await commitReorder(target.unit, target.to, caretOffset(), focusAfter);
|
|
97
103
|
if (outcome)
|
|
98
104
|
onReorder?.(outcome.landing, outcome.total);
|
|
99
105
|
}
|
|
100
106
|
return {
|
|
101
|
-
|
|
102
|
-
|
|
107
|
+
// A dropped block is not a block you asked to edit: focusing it opens whatever a caret
|
|
108
|
+
// opens there (an equation reveals its source), which is not what a drag asked for.
|
|
109
|
+
// The keyboard nudge is the opposite — the caret must ride the block it is moving.
|
|
110
|
+
moveReorderUnit: (fromPath, toIndex) => run(fromPath, () => toIndex, false),
|
|
111
|
+
nudgeReorderUnit: (fromPath, dir) => run(fromPath, (index) => index + dir, true)
|
|
103
112
|
};
|
|
104
113
|
}
|
|
@@ -144,9 +144,37 @@ function indexOf(host) {
|
|
|
144
144
|
return readBlockPath(host)?.at(-1) ?? null;
|
|
145
145
|
return readBlockPath(host.querySelector('[data-block-path]'))?.at(-2) ?? null;
|
|
146
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* What the block IS, for the kinds whose text does not read as a label: a table's cells run
|
|
149
|
+
* together into `IngredientAmountWater35 L`, an equation reads as its own source. Prose keeps
|
|
150
|
+
* its first words, which is the best label it could have.
|
|
151
|
+
*/
|
|
152
|
+
const KIND_LABELS = {
|
|
153
|
+
table: 'Table',
|
|
154
|
+
mathBlock: 'Equation',
|
|
155
|
+
fencedCode: 'Code',
|
|
156
|
+
mermaid: 'Diagram',
|
|
157
|
+
thematicBreak: 'Divider',
|
|
158
|
+
details: 'Details',
|
|
159
|
+
image: 'Image'
|
|
160
|
+
};
|
|
147
161
|
function ghostLabel(host) {
|
|
162
|
+
const kind = host.dataset.blockKind ?? '';
|
|
163
|
+
if (kind === 'table')
|
|
164
|
+
return tableLabel(host);
|
|
165
|
+
const named = KIND_LABELS[kind];
|
|
166
|
+
if (named)
|
|
167
|
+
return named;
|
|
148
168
|
const text = (host.textContent ?? '').trim().replace(/\s+/g, ' ');
|
|
149
169
|
if (!text)
|
|
150
|
-
return '
|
|
170
|
+
return host.querySelector('[data-image-widget]') ? 'Image' : 'Block';
|
|
151
171
|
return text.length > 40 ? text.slice(0, 40) + '…' : text;
|
|
152
172
|
}
|
|
173
|
+
/** Body rows × columns: the shape is what tells one table from another at a glance. */
|
|
174
|
+
function tableLabel(host) {
|
|
175
|
+
const rows = host.querySelectorAll('.table-row').length;
|
|
176
|
+
const cols = host.querySelector('.table-row')?.childElementCount ?? 0;
|
|
177
|
+
if (rows === 0 || cols === 0)
|
|
178
|
+
return 'Table';
|
|
179
|
+
return `Table · ${rows} × ${cols}`;
|
|
180
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* probe that picks structural-vs-typing, and the post-commit caret restore.
|
|
4
4
|
*/
|
|
5
5
|
import { updateNodeContent } from '../tree-operations';
|
|
6
|
-
import { type SettledContent } from '../tree-operations/
|
|
6
|
+
import { type SettledContent } from '../tree-operations/content-write';
|
|
7
7
|
import { type AnyBlockKind } from '../core/nodes';
|
|
8
8
|
import type { NodeView } from '../core/node-views';
|
|
9
9
|
import type { StructuralChange } from '../tree-operations/structural-change';
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* probe that picks structural-vs-typing, and the post-commit caret restore.
|
|
4
4
|
*/
|
|
5
5
|
import { updateNodeContent } from '../tree-operations';
|
|
6
|
-
import { settledCaretTarget } from '../tree-operations/
|
|
6
|
+
import { settledCaretTarget } from '../tree-operations/content-write';
|
|
7
7
|
import { makeBlockNode } from '../core/nodes';
|
|
8
8
|
import { readBlockPath } from '../selection/path-lookup';
|
|
9
9
|
// ── Reparse probe ────────────────────────────────────────────────────────────
|
|
@@ -2,7 +2,7 @@ import { parse } from '../core/parser';
|
|
|
2
2
|
import { cloneNode } from '../tree-operations/clone';
|
|
3
3
|
import { spliceMany } from '../tree-operations/splice-many';
|
|
4
4
|
import { getBlockKindDescriptor } from '../schema/block-kind-descriptor';
|
|
5
|
-
import { normalizeBodyWrite, normalizeReplacementTrivia, writeOwnRaw } from '../tree-operations/node-
|
|
5
|
+
import { normalizeBodyWrite, normalizeReplacementTrivia, writeOwnRaw } from '../tree-operations/node-primitives';
|
|
6
6
|
import { rebuildAncestryRaw } from '../schema/container-raw';
|
|
7
7
|
import { replacePreservingFirst, stampStructuralChange } from '../tree-operations/structural-change';
|
|
8
8
|
import { applyRangesToText } from '../search/replace';
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* live here.
|
|
5
5
|
*/
|
|
6
6
|
import type { CellPosition, ContainerEditActions, TableContext } from '../action-contracts';
|
|
7
|
+
import type { GrammarView } from '../schema/block-openers';
|
|
7
8
|
import type { NodeView } from '../core/node-views';
|
|
8
9
|
import type { UndoController } from './deps';
|
|
9
10
|
import type { BlockListState } from '../reactivity/block-list-state.svelte';
|
|
@@ -29,6 +30,8 @@ export interface TableMutationsContextDeps {
|
|
|
29
30
|
controller: UndoController;
|
|
30
31
|
focusCell: (rowIdx: number, colIdx: number, position: CellPosition) => void;
|
|
31
32
|
announceReorder: (message: string) => void;
|
|
33
|
+
/** The instance grammar the cell byte-write door threads (absent: the global one). */
|
|
34
|
+
grammar?: GrammarView;
|
|
32
35
|
}
|
|
33
|
-
export type TableMutationsContext = Pick<TableContext, 'insertRowAbove' | 'insertRowBelow' | 'insertColumnLeft' | 'insertColumnRight' | 'deleteRow' | 'deleteColumn' | 'reorderRowTo' | 'moveRowUp' | 'moveRowDown' | 'reorderColumnTo' | 'moveColumnLeft' | 'moveColumnRight' | 'cycleAlignment' | 'setColumnAlignment'>;
|
|
36
|
+
export type TableMutationsContext = Pick<TableContext, 'insertRowAbove' | 'insertRowBelow' | 'insertColumnLeft' | 'insertColumnRight' | 'deleteRow' | 'deleteColumn' | 'reorderRowTo' | 'moveRowUp' | 'moveRowDown' | 'reorderColumnTo' | 'moveColumnLeft' | 'moveColumnRight' | 'cycleAlignment' | 'setColumnAlignment' | 'pasteGrid'>;
|
|
34
37
|
export declare function createTableMutationsContext(deps: TableMutationsContextDeps): TableMutationsContext;
|
|
@@ -8,8 +8,9 @@ import { extendDocPath, docPathFrom } from '../cursor/coordinate-spaces';
|
|
|
8
8
|
import { getStateForNode } from '../reactivity/state-registry';
|
|
9
9
|
import { assertInvariant } from '../assert';
|
|
10
10
|
import { columnAligned, COLUMN_ALIGNMENT_CLEARED, DELETED_COLUMN, DELETED_ROW, INSERTED_COLUMN, INSERTED_ROW, movedColumnToPosition, movedRowToPosition } from '../a11y-strings';
|
|
11
|
-
import { ensureUnsharedChildren } from '../tree-operations/unshare';
|
|
11
|
+
import { ensureUnsharedChildren, ensureUnsharedSubtree } from '../tree-operations/unshare';
|
|
12
12
|
import { rebuildTableRowRaw, rebuildTableRaw } from '../schema/container-rebuilders';
|
|
13
|
+
import { writeOwnRaw } from '../tree-operations/node-primitives';
|
|
13
14
|
import { reorderChildren } from '../tree-operations/reorder';
|
|
14
15
|
import { insertEmptyRow, insertEmptyColumn, deleteRow as mutDeleteRow, deleteColumn as mutDeleteColumn, moveColumn as mutMoveColumn, cycleAlignment as mutCycleAlignment, setAlignment as mutSetAlignment, canDeleteRow, canDeleteColumn } from '../tree-operations/table-mutations';
|
|
15
16
|
/**
|
|
@@ -105,6 +106,60 @@ export function createTableMutationsContext(deps) {
|
|
|
105
106
|
afterTick: opts.afterTick
|
|
106
107
|
});
|
|
107
108
|
}
|
|
109
|
+
// Grown at the bottom and the right only, so each scope's change is one contiguous insert:
|
|
110
|
+
// rows for the table, cells for every mounted row. Cell texts go through the cell kind's own
|
|
111
|
+
// raw rule in place, and the table raw is rebuilt once, delimiter line included.
|
|
112
|
+
async function pasteGrid(origin, grid) {
|
|
113
|
+
const { myPath, controller, focusCell } = deps;
|
|
114
|
+
const rows = grid.length;
|
|
115
|
+
let cols = 0;
|
|
116
|
+
for (const line of grid)
|
|
117
|
+
cols = Math.max(cols, line.length);
|
|
118
|
+
if (rows === 0 || cols === 0)
|
|
119
|
+
return;
|
|
120
|
+
const { scopes, rowIndices } = mountedColumnScopes();
|
|
121
|
+
await controller.commitMultiScope({
|
|
122
|
+
scopes,
|
|
123
|
+
snapshot: { path: docPathFrom(myPath), offset: 0 },
|
|
124
|
+
mutate: ([tableScope, ...rowScopes]) => {
|
|
125
|
+
// Subtree, not children: the cell writes below land at depth two, and a row's
|
|
126
|
+
// cells stay shared with the undo snapshot when only the rows are unshared —
|
|
127
|
+
// the write would go through it and undo would restore the pasted bytes.
|
|
128
|
+
ensureUnsharedSubtree(tableScope.node, tableScope.sharing);
|
|
129
|
+
assertInvariant('column-scope-alignment', () => rowScopes.every((s, i) => s.node === tableScope.node.children?.[rowIndices[i]])
|
|
130
|
+
? null
|
|
131
|
+
: {
|
|
132
|
+
code: 'column-scope-alignment',
|
|
133
|
+
message: 'pasteGrid: row scopes misaligned with owned table children'
|
|
134
|
+
});
|
|
135
|
+
const table = tableScope.node;
|
|
136
|
+
const oldRows = table.children?.length ?? 0;
|
|
137
|
+
const oldCols = metadataOf(table, 'table').columnCount;
|
|
138
|
+
const needRows = origin.rowIdx + rows;
|
|
139
|
+
const needCols = origin.colIdx + cols;
|
|
140
|
+
for (let r = oldRows; r < needRows; r++)
|
|
141
|
+
insertEmptyRow(table, r - 1, 'below');
|
|
142
|
+
for (let c = oldCols; c < needCols; c++)
|
|
143
|
+
insertEmptyColumn(table, c - 1, 'right');
|
|
144
|
+
grid.forEach((line, r) => {
|
|
145
|
+
const cells = table.children[origin.rowIdx + r].children;
|
|
146
|
+
line.forEach((text, c) => writeOwnRaw(cells[origin.colIdx + c], text, deps.grammar));
|
|
147
|
+
});
|
|
148
|
+
rebuildTableRaw(table);
|
|
149
|
+
const addedRows = needRows - oldRows;
|
|
150
|
+
const addedCols = needCols - oldCols;
|
|
151
|
+
const tableChange = addedRows > 0 ? { op: 'insert', at: oldRows, count: addedRows } : { op: 'noop' };
|
|
152
|
+
const rowChange = addedCols > 0 ? { op: 'insert', at: oldCols, count: addedCols } : { op: 'noop' };
|
|
153
|
+
return [tableChange, ...rowScopes.map(() => rowChange)];
|
|
154
|
+
},
|
|
155
|
+
op: {
|
|
156
|
+
kind: 'tablePasteGrid',
|
|
157
|
+
detail: { rowIdx: origin.rowIdx, colIdx: origin.colIdx, rows, cols },
|
|
158
|
+
eventPath: docPathFrom(myPath)
|
|
159
|
+
},
|
|
160
|
+
afterTick: () => focusCell(origin.rowIdx + rows - 1, origin.colIdx + cols - 1, 'end')
|
|
161
|
+
});
|
|
162
|
+
}
|
|
108
163
|
async function insertColumn(colIdx, side) {
|
|
109
164
|
const { focusCell, focusedCell } = deps;
|
|
110
165
|
const insertAt = side === 'left' ? colIdx : colIdx + 1;
|
|
@@ -187,6 +242,7 @@ export function createTableMutationsContext(deps) {
|
|
|
187
242
|
return {
|
|
188
243
|
insertRowAbove: (rowIdx) => insertRow(rowIdx, 'above'),
|
|
189
244
|
insertRowBelow: (rowIdx) => insertRow(rowIdx, 'below'),
|
|
245
|
+
pasteGrid,
|
|
190
246
|
insertColumnLeft: (colIdx) => insertColumn(colIdx, 'left'),
|
|
191
247
|
insertColumnRight: (colIdx) => insertColumn(colIdx, 'right'),
|
|
192
248
|
reorderRowTo,
|
package/dist/editor-events.d.ts
CHANGED
|
@@ -54,6 +54,9 @@ export interface EditorEventMap {
|
|
|
54
54
|
/** The theme name after a `theme` prop change (never fired at mount), for a plugin
|
|
55
55
|
* that paints its own colors and so cannot pick the change up from CSS. */
|
|
56
56
|
themeChange: string;
|
|
57
|
+
/** `true` when an editor-owned menu (right-click, insert `+`) opens, `false` when it closes,
|
|
58
|
+
* so host chrome over the selection can step aside rather than stack on it. */
|
|
59
|
+
menuChange: boolean;
|
|
57
60
|
}
|
|
58
61
|
export interface EditorEvents {
|
|
59
62
|
on<K extends keyof EditorEventMap>(event: K, handler: (payload: EditorEventMap[K]) => void): () => void;
|
package/dist/editor-keys.d.ts
CHANGED
|
@@ -45,6 +45,35 @@ export interface PastedImage {
|
|
|
45
45
|
/** Host import hook for pasted images: resolves to the markdown to insert, or null
|
|
46
46
|
* to skip that image. Called once per image file, in clipboard order. */
|
|
47
47
|
export type PasteImageHook = (image: PastedImage) => Promise<string | null>;
|
|
48
|
+
/** What a code block hands its host when the run affordance is pressed. */
|
|
49
|
+
export interface CodeRunRequest {
|
|
50
|
+
/** The fence body alone — opener and closer lines excluded. */
|
|
51
|
+
code: string;
|
|
52
|
+
/** The opener's full info string, untrimmed of trailing attributes (`py {1-3}`). */
|
|
53
|
+
info: string;
|
|
54
|
+
/** Child indices from the document root to this block. */
|
|
55
|
+
path: number[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Host hook for executing a code block. The editor runs nothing itself: installing this is
|
|
59
|
+
* what puts the run affordance on the block's rail, and the host owns everything after —
|
|
60
|
+
* the engine, the result, and where output goes. Absent, no run affordance renders.
|
|
61
|
+
*/
|
|
62
|
+
export type RunCodeHook = (request: CodeRunRequest) => void;
|
|
63
|
+
/** One entry in a code block's overflow menu. `run` is called with the menu already closed. */
|
|
64
|
+
export interface CodeMenuItem {
|
|
65
|
+
id: string;
|
|
66
|
+
label: string;
|
|
67
|
+
run: () => void;
|
|
68
|
+
/** Renders dimmed and refuses activation. */
|
|
69
|
+
disabled?: boolean;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Host hook for the code block's overflow menu, consulted each time the menu opens so the
|
|
73
|
+
* items can read live state. Absent — or returning nothing — renders no overflow affordance:
|
|
74
|
+
* the editor has no app-level actions of its own to put there.
|
|
75
|
+
*/
|
|
76
|
+
export type CodeMenuItemsHook = (request: CodeRunRequest) => readonly CodeMenuItem[];
|
|
48
77
|
export type PresentationModeGetter = () => PresentationMode;
|
|
49
78
|
/** The editor's theme name, as reflected to `data-editor-theme`. An open string:
|
|
50
79
|
* built-ins are `'dark'`/`'light'`, and a consumer may name its own. */
|
|
@@ -150,6 +179,10 @@ export interface EditorPolicies {
|
|
|
150
179
|
/** Set-once host import hook for image-bearing pastes. Required-nullable: a mount must
|
|
151
180
|
* answer, and `undefined` deliberately leaves the paste on the text/plain path. */
|
|
152
181
|
onPasteImage: PasteImageHook | undefined;
|
|
182
|
+
/** Set-once host execution hook; its presence is what renders the run affordance. */
|
|
183
|
+
onRunCode: RunCodeHook | undefined;
|
|
184
|
+
/** Set-once host menu hook; its presence is what renders the overflow affordance. */
|
|
185
|
+
codeMenuItems: CodeMenuItemsHook | undefined;
|
|
153
186
|
/** Resolved image URLs that failed to load this session. One Set per instance, so a
|
|
154
187
|
* failed load never suppresses another editor's broken-state recompute
|
|
155
188
|
* (`components/image/widget-dom.ts`). */
|
package/dist/editor-props.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { Snippet } from 'svelte';
|
|
6
6
|
import type { AnyBlockKind } from './core/nodes';
|
|
7
|
-
import type { PasteImageHook, ResolveImageUrl, ResolveLinkUrl } from './editor-keys';
|
|
7
|
+
import type { CodeMenuItemsHook, PasteImageHook, ResolveImageUrl, ResolveLinkUrl, RunCodeHook } from './editor-keys';
|
|
8
8
|
import type { ImageLoadPolicy } from './core/inline-render';
|
|
9
9
|
import type { PresentationMode } from './presentation-mode';
|
|
10
10
|
import type { KeybindingOverride } from './schema/keybinding-overrides';
|
|
@@ -27,16 +27,29 @@ export interface EditorProps {
|
|
|
27
27
|
* in order and the markdown returned is inserted at the caret; `null` skips it.
|
|
28
28
|
* Installing it takes the WHOLE paste — the clipboard's `text/plain` is not pasted. */
|
|
29
29
|
onPasteImage?: PasteImageHook;
|
|
30
|
+
/** Execution hook for code blocks, set once at mount. The editor runs nothing itself:
|
|
31
|
+
* installing this is what puts the run affordance on a code block's rail, and the host
|
|
32
|
+
* owns the engine, the result, and where output goes. Absent, no run affordance renders. */
|
|
33
|
+
onRunCode?: RunCodeHook;
|
|
34
|
+
/** Overflow-menu hook for code blocks, set once at mount and consulted each time a menu
|
|
35
|
+
* opens so items can read live state. Absent, or returning nothing, renders no overflow
|
|
36
|
+
* affordance — the editor has no app-level actions of its own to offer there. */
|
|
37
|
+
codeMenuItems?: CodeMenuItemsHook;
|
|
30
38
|
/** Host chrome rendered INSIDE the editor's scroll container, above the first block
|
|
31
39
|
* (a title, properties panel, tag row). It scrolls away with the document rather than
|
|
32
40
|
* pinning, which is what lets the editor keep its own scrollport and windowing. */
|
|
33
41
|
header?: Snippet;
|
|
34
|
-
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
42
|
+
/** The block drag handle (default on; reading mode never shows it). A hover reveals it;
|
|
43
|
+
* touch, which has none, shows it outright. Only the blocks a reader picks up whole carry
|
|
44
|
+
* one — code, tables, equations, diagrams, pictures, list items, dividers, cards — never
|
|
45
|
+
* prose (paragraph, heading, quote, note). `false` removes them, except on a picture,
|
|
46
|
+
* whose grip is the only pointer road to move it. Keyboard reorder (Alt+Arrow) is always
|
|
47
|
+
* available, as is the table's right-click cell menu. */
|
|
38
48
|
blockDragHandles?: boolean;
|
|
39
49
|
searchBar?: boolean;
|
|
50
|
+
/** The editor's own formatting popover beside a prose selection (default on; reading mode
|
|
51
|
+
* never shows it). A host with its own bar over `runCommand` passes false. */
|
|
52
|
+
selectionToolbar?: boolean;
|
|
40
53
|
/** Where the editor's own find/replace bar renders. Default (absent) keeps it pinned inside
|
|
41
54
|
* the editor root; an element relocates the SAME bar into it, theme scope included, so
|
|
42
55
|
* host-scroll embeds can put it in a pane's chrome instead of mid-page. Read live, and
|
|
@@ -102,14 +115,13 @@ export interface EditorInstance {
|
|
|
102
115
|
*/
|
|
103
116
|
insertMarkdown(md: string): boolean;
|
|
104
117
|
/**
|
|
105
|
-
* Run a command by id at the focused surface,
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* on an unknown id, in reading mode, with nothing focused, and on the link editor over a range.
|
|
118
|
+
* Run a command by id at the focused surface, or across a painted range where the id has a
|
|
119
|
+
* cross-block arm (a format toggle marks every block it touches, a table by its cells). False,
|
|
120
|
+
* and nothing mutates, on an unknown id, in reading mode, with nothing focused, and on the link
|
|
121
|
+
* editor over a range. `arg` reaches the arm as a keybinding's argument would (`heading.cycle`
|
|
122
|
+
* takes the level, 0 for plain text); an arm that takes none ignores it.
|
|
111
123
|
*/
|
|
112
|
-
runCommand(commandId: string): boolean;
|
|
124
|
+
runCommand(commandId: string, arg?: unknown): boolean;
|
|
113
125
|
/**
|
|
114
126
|
* Whether `runCommand(id)` would reach that command's arm right now, asked at the seam that
|
|
115
127
|
* would run it, so a host can grey a toolbar button out instead of hiding the affordance.
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { default as Editor } from './components/Editor.svelte';
|
|
|
2
2
|
export type { EditorProps, EditorInstance } from './editor-props';
|
|
3
3
|
export type { EditorDiagnostics, InteractionTraceEntry } from './editor-props';
|
|
4
4
|
export type { BlockComponent } from './block-component';
|
|
5
|
-
export type { ResolveImageUrl, ResolveLinkUrl, PastedImage, PasteImageHook } from './editor-keys';
|
|
5
|
+
export type { ResolveImageUrl, ResolveLinkUrl, PastedImage, PasteImageHook, CodeRunRequest, RunCodeHook, CodeMenuItem, CodeMenuItemsHook } from './editor-keys';
|
|
6
6
|
export type { ImageLoadPolicy } from './core/inline-render';
|
|
7
7
|
export type { PresentationMode } from './presentation-mode';
|
|
8
8
|
export type { SearchState, SearchOptions } from './search/search-state.svelte';
|
package/dist/plugin.d.ts
CHANGED
|
@@ -29,9 +29,15 @@ export type { OuterBlockScan } from './schema/block-openers';
|
|
|
29
29
|
export { OPENER_PRIORITIES } from './schema/opener-priorities';
|
|
30
30
|
export { registerBlockCompleter } from './schema/block-completions';
|
|
31
31
|
export type { BlockCompleter, CompletionResult } from './schema/block-completions';
|
|
32
|
+
export { registerLanguage, listLanguages, getLanguageAliases } from './components/blocks/code/code-languages';
|
|
33
|
+
export type { LanguageGrammar } from './components/blocks/code/code-languages';
|
|
34
|
+
export { tokenizeBody as highlightCode } from './components/blocks/code/code-renderer';
|
|
35
|
+
export type { LanguageFn } from 'highlight.js';
|
|
32
36
|
export type { CommandId } from './schema/commands';
|
|
33
37
|
export type { KeyBinding } from './schema/keybindings';
|
|
34
38
|
export { registerBlockCommand } from './schema/block-commands';
|
|
39
|
+
export { registerBlockContextActions } from './schema/context-actions';
|
|
40
|
+
export type { BlockContextAction, BlockActionContext, BlockContextActionProvider } from './schema/context-actions';
|
|
35
41
|
export type { BlockCommandContext, BlockCommandHandler } from './schema/block-commands';
|
|
36
42
|
export type { PluginCommandId, AnyCommandId } from './schema/command-id';
|
|
37
43
|
export { registerGlobalCommand } from './schema/global-commands';
|
|
@@ -97,6 +103,7 @@ export { caretOffsetAtPoint } from './cursor/point-offset';
|
|
|
97
103
|
export type { CaretTarget } from './schema/block-kind-descriptor';
|
|
98
104
|
export { CURSOR_END } from './block-component';
|
|
99
105
|
export type { CursorEnd } from './block-component';
|
|
106
|
+
export { POINTER_GESTURE_ATTR } from './selection/pointer-gesture';
|
|
100
107
|
export type { EditorSelection, SelectionPoint } from './selection/primitives';
|
|
101
108
|
export { SELECTION_END } from './block-component';
|
|
102
109
|
export type { SelectionEnd } from './block-component';
|
package/dist/plugin.js
CHANGED
|
@@ -38,9 +38,21 @@ export { OPENER_PRIORITIES } from './schema/opener-priorities';
|
|
|
38
38
|
// never type into existence: a completer reads one typed line and answers the lines that
|
|
39
39
|
// complete it, plus where the caret seats inside the mint.
|
|
40
40
|
export { registerBlockCompleter } from './schema/block-completions';
|
|
41
|
+
// ── Code-block languages (pre-freeze) ────────────────────────────────────────
|
|
42
|
+
// The registry behind fenced-code highlighting. The editor bootstraps a curated set (every
|
|
43
|
+
// grammar is bundle weight for every consumer), so a host needing more registers them itself,
|
|
44
|
+
// BEFORE mounting an editor: a block on screen re-tokenizes only when its bytes next change.
|
|
45
|
+
// An unregistered language is not an error — the fence still round-trips, just untokenized.
|
|
46
|
+
// `listLanguages` lists each language once; `getLanguageAliases` holds the other spellings.
|
|
47
|
+
export { registerLanguage, listLanguages, getLanguageAliases } from './components/blocks/code/code-languages';
|
|
48
|
+
// The code block's own tokenizer, for a plugin whose source surface wants the same highlighting
|
|
49
|
+
// (block math paints its LaTeX with it). Text-preserving: the fragment's textContent is `body`.
|
|
50
|
+
export { tokenizeBody as highlightCode } from './components/blocks/code/code-renderer';
|
|
41
51
|
// ── Command mint (pre-freeze) ────────────────────────────────────────────────
|
|
42
52
|
// A (kind, name) block-command mints a PluginCommandId; AnyCommandId spans built-in and minted.
|
|
43
53
|
export { registerBlockCommand } from './schema/block-commands';
|
|
54
|
+
// The block context menu: a kind's right-click actions, empty unless something registers them.
|
|
55
|
+
export { registerBlockContextActions } from './schema/context-actions';
|
|
44
56
|
// A global command is process-wide but runs against the dispatching instance's EditorContext.
|
|
45
57
|
export { registerGlobalCommand } from './schema/global-commands';
|
|
46
58
|
// ── Parse / serialize helpers (pre-freeze) ───────────────────────────────────
|
|
@@ -153,4 +165,8 @@ export { registerPasteTransform } from './tree-operations/paste/paste-transforms
|
|
|
153
165
|
// names one), and the sentinel for "wherever this leaf ends".
|
|
154
166
|
export { caretOffsetAtPoint } from './cursor/point-offset';
|
|
155
167
|
export { CURSOR_END } from './block-component';
|
|
168
|
+
// ── Pointer gestures (pre-freeze) ────────────────────────────────────────────
|
|
169
|
+
// Put this attribute on an element whose drags are your widget's own (a pan, a brush) and the
|
|
170
|
+
// editor's pointer arms leave a press inside it alone: no block range, no click ladder.
|
|
171
|
+
export { POINTER_GESTURE_ATTR } from './selection/pointer-gesture';
|
|
156
172
|
export { SELECTION_END } from './block-component';
|