@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
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* horizontal extension clamps at the column edges, since a rectangle has no sideways exit.
|
|
6
6
|
*/
|
|
7
7
|
import { metadataOf } from '../core/nodes';
|
|
8
|
-
import { isBlockNode, nodeAt } from '../tree-operations/node-
|
|
8
|
+
import { isBlockNode, nodeAt } from '../tree-operations/node-primitives';
|
|
9
9
|
import { cellRowCol } from '../cursor/coordinate-spaces';
|
|
10
10
|
import { pathsEqual } from './path-math';
|
|
11
11
|
/**
|
|
@@ -9,40 +9,51 @@
|
|
|
9
9
|
/* ── Host-chrome tier: the consumer's vocabulary, defaults behind the class ── */
|
|
10
10
|
|
|
11
11
|
:where(.aragonite-editor-theme) {
|
|
12
|
+
/* Two faces, because they answer different questions. `--font-editor` is the SURFACE
|
|
13
|
+
face — prose, headings, markers — and a host may legitimately set it proportional.
|
|
14
|
+
`--font-code` is what must stay monospace whatever that choice is: code blocks, code
|
|
15
|
+
spans, raw HTML, revealed source. Defaulted to the same stack, so a consumer that
|
|
16
|
+
never names the second one sees exactly what it saw before. */
|
|
12
17
|
--font-editor: 'Cascadia Code', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
|
|
18
|
+
--font-code: 'Cascadia Code', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
|
|
19
|
+
/* The menus' and popovers' face: the host's own UI font where it names one. */
|
|
20
|
+
--font-ui: 'Inter', system-ui, sans-serif;
|
|
13
21
|
/* Type-scale root: headings, code and markers are all `em`-relative, so one override
|
|
14
22
|
scales the surface. A themed host sets it on any ancestor instead. */
|
|
15
23
|
--editor-font-size: 1rem;
|
|
16
24
|
|
|
17
25
|
/* Corner radii by role: small controls (buttons, inputs, chips) and elevated surfaces
|
|
18
26
|
(overlays, popovers). Chrome whose corner is neither keeps its own literal. */
|
|
19
|
-
--radius-ui:
|
|
27
|
+
--radius-ui: 4px;
|
|
20
28
|
--radius-surface: 8px;
|
|
21
29
|
|
|
22
|
-
|
|
23
|
-
--color-
|
|
24
|
-
--color-
|
|
25
|
-
--color-
|
|
26
|
-
--color-
|
|
27
|
-
--color-
|
|
28
|
-
|
|
29
|
-
--color-
|
|
30
|
+
/* The page ground, which the menus and the image toolbar paint on. */
|
|
31
|
+
--color-bg: #2c2c2a;
|
|
32
|
+
--color-surface: #1a1a19;
|
|
33
|
+
--color-text-secondary: #cfcfca;
|
|
34
|
+
--color-text-primary: #e8e8e5;
|
|
35
|
+
--color-border: #3e3e3b;
|
|
36
|
+
--color-ui-muted: #8f8f89;
|
|
37
|
+
--color-ui-dulled: #a3a39d;
|
|
38
|
+
--color-accent: #567b67;
|
|
30
39
|
/* Base the selection, search-match and reorder washes derive from, so one declaration
|
|
31
|
-
moves all of them; the washes themselves stay editor-owned.
|
|
32
|
-
|
|
33
|
-
--color-
|
|
40
|
+
moves all of them; the washes themselves stay editor-owned. Tracking the accent means
|
|
41
|
+
a host that recolors one recolors all four. */
|
|
42
|
+
--color-selection: var(--color-accent, #567b67);
|
|
43
|
+
--color-error: #ff5f57;
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
:where(.aragonite-editor-theme)[data-editor-theme='light'] {
|
|
37
|
-
--color-
|
|
38
|
-
--color-
|
|
39
|
-
--color-text-
|
|
40
|
-
--color-
|
|
41
|
-
--color-
|
|
42
|
-
--color-ui-
|
|
43
|
-
--color-
|
|
44
|
-
--color-
|
|
45
|
-
--color-
|
|
47
|
+
--color-bg: #dfddd7;
|
|
48
|
+
--color-surface: #efeee9;
|
|
49
|
+
--color-text-secondary: #4a4a45;
|
|
50
|
+
--color-text-primary: #2a2a27;
|
|
51
|
+
--color-border: #c9c7c0;
|
|
52
|
+
--color-ui-muted: #83837b;
|
|
53
|
+
--color-ui-dulled: #71716a;
|
|
54
|
+
--color-accent: #567b67;
|
|
55
|
+
--color-selection: var(--color-accent, #567b67);
|
|
56
|
+
--color-error: #d03025;
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
/* ── Editor-owned tier: defaults on `.editor`, so they hold with or without the class ── */
|
|
@@ -58,6 +69,10 @@
|
|
|
58
69
|
--color-bg-secondary, which is measured against the base bg. */
|
|
59
70
|
--color-ui-faint: rgba(255, 255, 255, 0.07);
|
|
60
71
|
|
|
72
|
+
/* One radius for a picture, the crop frame that clips it and the selection ring on the
|
|
73
|
+
overlay above it: half the surface radius, enough to soften a photo without a card look. */
|
|
74
|
+
--md-image-radius: 4px;
|
|
75
|
+
|
|
61
76
|
/* Markdown syntax override points, deliberately neutral so the default rendering carries no
|
|
62
77
|
extra palette. Mode-independent: the chrome tokens they chain to carry the light/dark
|
|
63
78
|
split. */
|
|
@@ -69,7 +84,10 @@
|
|
|
69
84
|
--syntax-code: currentColor;
|
|
70
85
|
--syntax-comment: currentColor;
|
|
71
86
|
--syntax-list: currentColor;
|
|
72
|
-
|
|
87
|
+
/* The rendered rule's colour, and its ONLY consumer. A divider separates rather than
|
|
88
|
+
announces, so it defaults to the border token; mid-grey at this weight competed with
|
|
89
|
+
the text either side. A host that wants a louder rule still names this token. */
|
|
90
|
+
--syntax-separator: var(--color-border, #3e3e3b);
|
|
73
91
|
--syntax-task: currentColor;
|
|
74
92
|
--syntax-task-done: rgba(128, 128, 128, 0.7);
|
|
75
93
|
|
|
@@ -98,8 +116,8 @@
|
|
|
98
116
|
/* Presentational tokens (mode-independent). */
|
|
99
117
|
/* Washes over the host-declarable selection base, alpha apart, so a host that names one
|
|
100
118
|
base moves the selection, the search matches and the reorder chrome together. */
|
|
101
|
-
--selection-overlay-bg:
|
|
102
|
-
--search-match-bg:
|
|
119
|
+
--selection-overlay-bg: rgba(100, 150, 255, 0.3);
|
|
120
|
+
--search-match-bg: rgba(100, 150, 255, 0.22);
|
|
103
121
|
/* Painted on top of the match text, so it must keep an alpha channel or it hides it. */
|
|
104
122
|
--search-match-active-bg: rgba(216, 166, 87, 0.55);
|
|
105
123
|
--md-ref-label-color: rgba(128, 128, 128, 0.45);
|
|
@@ -111,38 +129,64 @@
|
|
|
111
129
|
--md-reorder-indicator: var(--color-selection, #6496ff);
|
|
112
130
|
/* Wash on the container being reordered within during a nested drag. Tinted with the reorder
|
|
113
131
|
accent, not neutral grey, so the shift stays perceptible for low-contrast vision. */
|
|
114
|
-
--reorder-scope-bg:
|
|
132
|
+
--reorder-scope-bg: rgba(100, 150, 255, 0.14);
|
|
115
133
|
--syntax-marker-dim: 0.65;
|
|
116
134
|
|
|
135
|
+
/* Menu/popout elevation, per mode: a shadow tuned for a near-black surface is invisible
|
|
136
|
+
over a white one. Editor-owned rather than host-family, since a host palette names
|
|
137
|
+
colors, not elevation. */
|
|
138
|
+
--menu-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.35);
|
|
139
|
+
/* The rest of the host app's menu family, so a menu here is the host's menu to the pixel. */
|
|
140
|
+
--menu-item-hover: rgba(255, 255, 255, 0.07);
|
|
141
|
+
--menu-search-divider: rgba(255, 255, 255, 0.08);
|
|
142
|
+
--menu-scrollbar-thumb: rgba(255, 255, 255, 0.18);
|
|
143
|
+
--menu-scrollbar-thumb-hover: rgba(255, 255, 255, 0.3);
|
|
144
|
+
|
|
117
145
|
/* Placeholder tint behind off-window content (VR-8), so a spacer that outruns the
|
|
118
146
|
window recompute reads as "loading" rather than a white tear. */
|
|
119
147
|
--vr-spacer-bg: rgba(255, 255, 255, 0.025);
|
|
120
148
|
}
|
|
121
149
|
|
|
150
|
+
/* The washes follow a host's `--color-selection` where the engine can mix; the static values
|
|
151
|
+
above are the same tints of the default base, for engines without `color-mix` (WebKit before
|
|
152
|
+
Safari 16.2). */
|
|
153
|
+
@supports (color: color-mix(in srgb, red, blue)) {
|
|
154
|
+
:where(.editor, .aragonite-editor-theme) {
|
|
155
|
+
--selection-overlay-bg: color-mix(in srgb, var(--color-selection, #6496ff) 30%, transparent);
|
|
156
|
+
--search-match-bg: color-mix(in srgb, var(--color-selection, #6496ff) 22%, transparent);
|
|
157
|
+
--reorder-scope-bg: color-mix(in srgb, var(--color-selection, #6496ff) 14%, transparent);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
122
161
|
:where(.editor, .aragonite-editor-theme)[data-editor-theme='light'] {
|
|
123
|
-
--color-bg-secondary: rgba(0, 0, 0, 0.
|
|
162
|
+
--color-bg-secondary: rgba(0, 0, 0, 0.035);
|
|
124
163
|
--color-bg-elevated: #f5f6f8;
|
|
125
164
|
--color-bg-muted: #eaeaea;
|
|
126
165
|
--color-text-muted: #57606a;
|
|
127
166
|
--color-ui-faint: rgba(0, 0, 0, 0.06);
|
|
167
|
+
--menu-shadow: 0 8px 24px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.06);
|
|
168
|
+
--menu-item-hover: rgba(0, 0, 0, 0.05);
|
|
169
|
+
--menu-search-divider: rgba(0, 0, 0, 0.07);
|
|
170
|
+
--menu-scrollbar-thumb: rgba(0, 0, 0, 0.2);
|
|
171
|
+
--menu-scrollbar-thumb-hover: rgba(0, 0, 0, 0.32);
|
|
128
172
|
|
|
129
173
|
/* --syntax-* tokens are mode-independent — no light overrides. */
|
|
130
174
|
|
|
131
175
|
/* Code block syntax highlighting — GitHub Light-inspired palette */
|
|
132
|
-
--code-tok-keyword: #
|
|
176
|
+
--code-tok-keyword: #c1202b;
|
|
133
177
|
--code-tok-string: #0a3069;
|
|
134
178
|
--code-tok-number: #0550ae;
|
|
135
179
|
--code-tok-literal: #0550ae;
|
|
136
|
-
--code-tok-comment: #
|
|
180
|
+
--code-tok-comment: #5c646d;
|
|
137
181
|
--code-tok-type: #953800;
|
|
138
|
-
--code-tok-function: #
|
|
139
|
-
--code-tok-operator: #
|
|
182
|
+
--code-tok-function: #7447c6;
|
|
183
|
+
--code-tok-operator: #c1202b;
|
|
140
184
|
--code-tok-meta: #953800;
|
|
141
185
|
--code-tok-attr: #116329;
|
|
142
186
|
--code-tok-regexp: #116329;
|
|
143
187
|
--code-tok-symbol: #0550ae;
|
|
144
188
|
--code-tok-added: #116329;
|
|
145
|
-
--code-tok-removed: #
|
|
189
|
+
--code-tok-removed: #c1202b;
|
|
146
190
|
--code-tok-heading: #0550ae;
|
|
147
191
|
--code-tok-link: #0550ae;
|
|
148
192
|
|
package/dist/styles/editor.css
CHANGED
|
@@ -168,6 +168,28 @@
|
|
|
168
168
|
max-width: 100%;
|
|
169
169
|
height: auto;
|
|
170
170
|
display: block;
|
|
171
|
+
border-radius: var(--md-image-radius);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* A cropped image: the widget is the frame (width and aspect set inline from the `|WxH` hint,
|
|
175
|
+
capped to the column) and the image pans inside it, sized and offset by `image-crop.ts`. */
|
|
176
|
+
:where(.editor) .md-image-widget.md-image-cropped {
|
|
177
|
+
overflow: hidden;
|
|
178
|
+
max-width: 100%;
|
|
179
|
+
/* The frame clips the picture, so the rounding belongs to it. `clip-path` alongside
|
|
180
|
+
`overflow`, because a rounded overflow clip is the one Chromium drops when the picture
|
|
181
|
+
inside gets its own compositing layer, and a crop is exactly when that happens. */
|
|
182
|
+
border-radius: var(--md-image-radius);
|
|
183
|
+
clip-path: inset(0 round var(--md-image-radius));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* The picture keeps its own radius rather than going square inside the frame: at zoom 1 it sits
|
|
187
|
+
exactly on the frame, so the two corners coincide, and above 1 its corners are outside the
|
|
188
|
+
frame entirely. Either way the crop cannot come out with harder corners than the plain image. */
|
|
189
|
+
:where(.editor) .md-image-widget.md-image-cropped img {
|
|
190
|
+
position: absolute;
|
|
191
|
+
max-width: none;
|
|
192
|
+
object-fit: cover;
|
|
171
193
|
}
|
|
172
194
|
|
|
173
195
|
/* Image-bearing list-item / blockquote paragraph: the ambient marker sits at the image's
|
|
@@ -249,6 +271,12 @@
|
|
|
249
271
|
pointer-events: none;
|
|
250
272
|
}
|
|
251
273
|
|
|
274
|
+
/* The tint IS the widget's selection paint: native `::selection` on the text inside it (a KaTeX
|
|
275
|
+
box is text) would stack a second wash on the same pixels. */
|
|
276
|
+
:where(.editor) [data-inline-widget].md-widget-selected ::selection {
|
|
277
|
+
background: transparent;
|
|
278
|
+
}
|
|
279
|
+
|
|
252
280
|
/* Synthetic caret on the snap-target edge — Chromium doesn't reliably render
|
|
253
281
|
the live caret adjacent to a contenteditable=false neighbor. */
|
|
254
282
|
:where(.editor) [data-inline-widget].md-snap-after::before,
|
|
@@ -263,12 +291,14 @@
|
|
|
263
291
|
pointer-events: none;
|
|
264
292
|
}
|
|
265
293
|
|
|
294
|
+
/* Clear of the widget's own edge: against a picture, a caret drawn tight to the frame reads as
|
|
295
|
+
part of the border rather than as a caret waiting for the next character. */
|
|
266
296
|
:where(.editor) [data-inline-widget].md-snap-after::before {
|
|
267
|
-
right: -
|
|
297
|
+
right: -4px;
|
|
268
298
|
}
|
|
269
299
|
|
|
270
300
|
:where(.editor) [data-inline-widget].md-snap-before::before {
|
|
271
|
-
left: -
|
|
301
|
+
left: -4px;
|
|
272
302
|
}
|
|
273
303
|
|
|
274
304
|
@keyframes md-snap-caret-blink {
|
|
@@ -290,6 +320,20 @@
|
|
|
290
320
|
z-index: 10;
|
|
291
321
|
}
|
|
292
322
|
|
|
323
|
+
/* A selected image says so with a hairline ring. It rides the overlay, not the widget: a cropped
|
|
324
|
+
widget clips its own pseudo-elements, and a border on the picture would move the layout. Held
|
|
325
|
+
just off the edge so it reads as a ring around the picture rather than part of it, over a
|
|
326
|
+
translucent dark line that keeps it legible against a pale photo. */
|
|
327
|
+
:where(.editor) .md-image-overlay::before {
|
|
328
|
+
content: '';
|
|
329
|
+
position: absolute;
|
|
330
|
+
inset: -2px;
|
|
331
|
+
border: 1px solid var(--color-accent, #567b67);
|
|
332
|
+
border-radius: calc(var(--md-image-radius, 4px) + 2px);
|
|
333
|
+
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18);
|
|
334
|
+
pointer-events: none;
|
|
335
|
+
}
|
|
336
|
+
|
|
293
337
|
:where(.editor) .md-image-overlay > * {
|
|
294
338
|
pointer-events: auto;
|
|
295
339
|
}
|
|
@@ -350,7 +394,7 @@
|
|
|
350
394
|
/* Dimmed monospace gives inline raw HTML a code-ish feel without becoming a code span. */
|
|
351
395
|
:where(.editor) .md-raw-html {
|
|
352
396
|
color: var(--md-raw-html-color, rgba(120, 120, 120, 0.85));
|
|
353
|
-
font-family: var(--font-
|
|
397
|
+
font-family: var(--font-code, ui-monospace, monospace);
|
|
354
398
|
font-size: 0.92em;
|
|
355
399
|
}
|
|
356
400
|
|
|
@@ -367,7 +411,7 @@
|
|
|
367
411
|
width: 100%;
|
|
368
412
|
box-sizing: border-box;
|
|
369
413
|
min-height: 1.4em;
|
|
370
|
-
font-family: var(--font-
|
|
414
|
+
font-family: var(--font-code, ui-monospace, monospace);
|
|
371
415
|
font-size: 0.9em;
|
|
372
416
|
line-height: 1.5;
|
|
373
417
|
color: inherit;
|
|
@@ -394,6 +438,13 @@
|
|
|
394
438
|
color: var(--syntax-code, currentColor);
|
|
395
439
|
}
|
|
396
440
|
|
|
441
|
+
/* An inline widget's source while it is revealed for editing (`$x$`, a footnote ref): the
|
|
442
|
+
inline-code wash, so the span being edited reads as a span, in the prose face so the line
|
|
443
|
+
does not reflow around it. */
|
|
444
|
+
::highlight(md-inline-reveal) {
|
|
445
|
+
background-color: var(--color-bg-secondary, rgba(128, 128, 128, 0.12));
|
|
446
|
+
}
|
|
447
|
+
|
|
397
448
|
/* Raw-HTML block source text; inline raw HTML keeps --md-raw-html-color above. */
|
|
398
449
|
:where(.editor) .text-editable-block.raw-block {
|
|
399
450
|
color: var(--syntax-comment, currentColor);
|
|
@@ -404,7 +455,7 @@
|
|
|
404
455
|
}
|
|
405
456
|
|
|
406
457
|
:where(.editor) .thematic-break-rule[role='separator'] > hr {
|
|
407
|
-
border-top-color: var(--syntax-separator, var(--color-
|
|
458
|
+
border-top-color: var(--syntax-separator, var(--color-border, #3e3e3b));
|
|
408
459
|
}
|
|
409
460
|
|
|
410
461
|
/* The [contenteditable='false'] qualifier scopes to the structurally-injected ambient
|
|
@@ -417,12 +468,69 @@
|
|
|
417
468
|
color: var(--syntax-task, currentColor);
|
|
418
469
|
}
|
|
419
470
|
|
|
420
|
-
/*
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
471
|
+
/* ── Menus ──────────────────────────────────────────────────────────────────
|
|
472
|
+
One surface for every menu the editor opens (the table's context menu, the code rail's
|
|
473
|
+
picker and overflow), copied from the host app's context menu value for value and reading
|
|
474
|
+
the same tokens, so a menu here is indistinguishable from one of the host's. */
|
|
475
|
+
:where(.editor) .md-menu {
|
|
476
|
+
position: fixed;
|
|
477
|
+
z-index: 2000;
|
|
478
|
+
min-width: 168px;
|
|
479
|
+
padding: 4px;
|
|
480
|
+
background: var(--color-bg, #2c2c2a);
|
|
481
|
+
border: 1px solid var(--color-border, #3e3e3b);
|
|
482
|
+
border-radius: 8px;
|
|
483
|
+
box-shadow: var(--menu-shadow, 0 12px 32px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.35));
|
|
484
|
+
font-family: var(--font-ui, system-ui, sans-serif);
|
|
485
|
+
font-size: 13px;
|
|
486
|
+
line-height: 1.4;
|
|
487
|
+
color: var(--color-text-primary, #e8e8e5);
|
|
488
|
+
user-select: none;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
:where(.editor) .md-menu-item {
|
|
492
|
+
display: flex;
|
|
493
|
+
align-items: center;
|
|
494
|
+
gap: 9px;
|
|
495
|
+
width: 100%;
|
|
496
|
+
padding: 7px 10px;
|
|
497
|
+
border: none;
|
|
498
|
+
border-radius: 5px;
|
|
499
|
+
background: transparent;
|
|
500
|
+
color: inherit;
|
|
501
|
+
font: inherit;
|
|
502
|
+
text-align: left;
|
|
503
|
+
cursor: pointer;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
:where(.editor) .md-menu-item:hover,
|
|
507
|
+
:where(.editor) .md-menu-item:focus-visible,
|
|
508
|
+
:where(.editor) .md-menu-item[aria-pressed='true'],
|
|
509
|
+
:where(.editor) .md-menu-item[data-active='true'] {
|
|
510
|
+
background: var(--menu-item-hover, rgba(255, 255, 255, 0.07));
|
|
511
|
+
outline: none;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
:where(.editor) .md-menu-item:disabled {
|
|
515
|
+
opacity: 0.4;
|
|
516
|
+
cursor: default;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
:where(.editor) .md-menu-item:disabled:hover {
|
|
520
|
+
background: transparent;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
:where(.editor) .md-menu-icon {
|
|
524
|
+
display: inline-flex;
|
|
525
|
+
align-items: center;
|
|
526
|
+
flex-shrink: 0;
|
|
527
|
+
color: var(--color-ui-muted, #8f8f89);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
:where(.editor) .md-menu-divider {
|
|
531
|
+
height: 1px;
|
|
532
|
+
margin: 4px 6px;
|
|
533
|
+
background: var(--color-border, #3e3e3b);
|
|
426
534
|
}
|
|
427
535
|
|
|
428
536
|
/* ── Rendered chrome, shared by every marker-hiding mode ──────────────────────
|
|
@@ -450,17 +558,33 @@
|
|
|
450
558
|
}
|
|
451
559
|
|
|
452
560
|
/* Chrome with nothing behind it has nowhere to hide: a construct whose only bytes are its own
|
|
453
|
-
markers
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
561
|
+
markers has no caret position, so an editable rung shows them dimmed as source does — but
|
|
562
|
+
only while the surface holds focus, since the seat is for a caret and a block nobody is in
|
|
563
|
+
reads as the empty construct it is. Mirrored in `cursor/widget-offset.ts` (same modes, same
|
|
564
|
+
families); reading keeps its silence. `[contenteditable]` scopes the stamp to the walk
|
|
565
|
+
containers its JS twin reads, which a decoration on the block host cannot reach. */
|
|
458
566
|
:where(.editor):is([data-presentation^='preview-'], [data-presentation='live'])
|
|
459
|
-
[contenteditable][data-content-empty]
|
|
567
|
+
[contenteditable][data-content-empty]:focus-within
|
|
460
568
|
:is(.md-marker:not([contenteditable='false']), .md-fence-line) {
|
|
461
569
|
display: inline;
|
|
462
570
|
}
|
|
463
571
|
|
|
572
|
+
/* A code block or table is a box, and prose gives it nothing to stand off from: blocks stack flush,
|
|
573
|
+
with only a text line's own leading between them. The box brings its own breathing room —
|
|
574
|
+
about a text line's leading each side, so code-to-code and code-to-prose match. Padding,
|
|
575
|
+
not margin: the height model measures the host's border box. */
|
|
576
|
+
:where(.editor) .block-host:is([data-block-kind='fencedCode'], [data-block-kind='table']) {
|
|
577
|
+
padding-block: 6px;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/* Room for the add strips (`TableBlock.svelte`) INSIDE the host's box: on the right so a
|
|
581
|
+
full-width table still leaves the column strip inside the editor's scroll box, and below so
|
|
582
|
+
the row strip never lies over whatever follows the table (the trailing insert row, a block). */
|
|
583
|
+
:where(.editor) .block-host[data-block-kind='table'] {
|
|
584
|
+
padding-right: 30px;
|
|
585
|
+
padding-bottom: 24px;
|
|
586
|
+
}
|
|
587
|
+
|
|
464
588
|
/* Ambient list markers own the hanging indent (padding/text-indent are keyed to the span's
|
|
465
589
|
ch width), so they keep their box: visibility, not display. */
|
|
466
590
|
:where(.editor):is(
|
|
@@ -498,7 +622,21 @@
|
|
|
498
622
|
visibility: visible;
|
|
499
623
|
}
|
|
500
624
|
|
|
501
|
-
/* GitHub task lists
|
|
625
|
+
/* GitHub task lists: no bullet, the box at the margin, the text one gap after it. The `- `
|
|
626
|
+
marker collapses to nothing (its bytes stay for the walk), the `[ ]` span becomes a fixed
|
|
627
|
+
slot so checked and unchecked are the same width, and the box paints in that slot. */
|
|
628
|
+
:where(.editor):is(
|
|
629
|
+
[data-presentation='reading'],
|
|
630
|
+
[data-presentation^='preview-'],
|
|
631
|
+
[data-presentation='live']
|
|
632
|
+
)
|
|
633
|
+
.list-item-block[data-list-marker='task']
|
|
634
|
+
.task-list-marker {
|
|
635
|
+
display: inline-block;
|
|
636
|
+
width: 0;
|
|
637
|
+
overflow: hidden;
|
|
638
|
+
}
|
|
639
|
+
|
|
502
640
|
:where(.editor):is(
|
|
503
641
|
[data-presentation='reading'],
|
|
504
642
|
[data-presentation^='preview-'],
|
|
@@ -506,7 +644,110 @@
|
|
|
506
644
|
)
|
|
507
645
|
.list-item-block[data-list-marker='task']
|
|
508
646
|
.task-checkbox {
|
|
647
|
+
/* Visible inside the hidden ambient marker, its `[ ]` bytes gone by colour: a hidden span
|
|
648
|
+
leaves the accessibility tree and the hit-test, and the pseudo-elements draw the box. */
|
|
509
649
|
visibility: visible;
|
|
650
|
+
color: transparent;
|
|
651
|
+
position: relative;
|
|
652
|
+
display: inline-block;
|
|
653
|
+
/* Slot + gap; `TASK_HANGING_INDENT` in task-checkbox.ts is these plus the trailing space. */
|
|
654
|
+
width: 1.2em;
|
|
655
|
+
margin-right: 0.65em;
|
|
656
|
+
vertical-align: baseline;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
:where(.editor):is(
|
|
660
|
+
[data-presentation='reading'],
|
|
661
|
+
[data-presentation^='preview-'],
|
|
662
|
+
[data-presentation='live']
|
|
663
|
+
)
|
|
664
|
+
.list-item-block[data-list-marker='task']
|
|
665
|
+
.task-checkbox::before {
|
|
666
|
+
content: '';
|
|
667
|
+
visibility: visible;
|
|
668
|
+
/* Centred by layout and sized to whole pixels, never by a translate: a transformed box
|
|
669
|
+
rasterises at fractional edges on a scaled desktop and reads shorter than it is wide.
|
|
670
|
+
The unrounded pair is the fallback for a browser without `round()`. */
|
|
671
|
+
position: absolute;
|
|
672
|
+
inset: 0;
|
|
673
|
+
margin: auto;
|
|
674
|
+
width: 1.2em;
|
|
675
|
+
height: 1.2em;
|
|
676
|
+
width: round(1.2em, 1px);
|
|
677
|
+
height: round(1.2em, 1px);
|
|
678
|
+
box-sizing: border-box;
|
|
679
|
+
border: 1.5px solid var(--color-ui-muted, #8f8f89);
|
|
680
|
+
border-radius: 0.28em;
|
|
681
|
+
background: transparent;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/* Checked: the box fills with the text colour and the tick is cut from it in the page's
|
|
685
|
+
background — two borders of a rotated box, so it needs no glyph and scales with the type. */
|
|
686
|
+
:where(.editor):is(
|
|
687
|
+
[data-presentation='reading'],
|
|
688
|
+
[data-presentation^='preview-'],
|
|
689
|
+
[data-presentation='live']
|
|
690
|
+
)
|
|
691
|
+
.list-item-block[data-task-checked='true']
|
|
692
|
+
.task-checkbox::before {
|
|
693
|
+
background: var(--color-text-primary, currentColor);
|
|
694
|
+
border-color: var(--color-text-primary, currentColor);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
:where(.editor):is(
|
|
698
|
+
[data-presentation='reading'],
|
|
699
|
+
[data-presentation^='preview-'],
|
|
700
|
+
[data-presentation='live']
|
|
701
|
+
)
|
|
702
|
+
.list-item-block[data-task-checked='true']
|
|
703
|
+
.task-checkbox::after {
|
|
704
|
+
content: '';
|
|
705
|
+
visibility: visible;
|
|
706
|
+
position: absolute;
|
|
707
|
+
/* The slot's centre, nudged up and right: the visible strokes are the L's right and
|
|
708
|
+
bottom edges, which rotation swings down and left. */
|
|
709
|
+
left: 53%;
|
|
710
|
+
top: 45%;
|
|
711
|
+
width: 0.32em;
|
|
712
|
+
height: 0.6em;
|
|
713
|
+
box-sizing: border-box;
|
|
714
|
+
border: solid var(--color-bg, #2c2c2a);
|
|
715
|
+
border-width: 0 0.15em 0.15em 0;
|
|
716
|
+
transform: translate(-50%, -50%) rotate(45deg);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/* The span is the SLOT, a full line-height tall; the box is the pseudo-element inside it. The
|
|
720
|
+
hover tint the source modes put on the span (ListItemBlock) would draw a tall rectangle
|
|
721
|
+
round the square, so in the rendered modes it moves onto the box: an open box fills with
|
|
722
|
+
the tint, a checked one is already a solid fill and keeps it. */
|
|
723
|
+
:where(.editor):is(
|
|
724
|
+
[data-presentation='reading'],
|
|
725
|
+
[data-presentation^='preview-'],
|
|
726
|
+
[data-presentation='live']
|
|
727
|
+
)
|
|
728
|
+
.list-item-block[data-list-marker='task']
|
|
729
|
+
.task-checkbox:hover {
|
|
730
|
+
background-color: transparent;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
:where(.editor):is(
|
|
734
|
+
[data-presentation='reading'],
|
|
735
|
+
[data-presentation^='preview-'],
|
|
736
|
+
[data-presentation='live']
|
|
737
|
+
)
|
|
738
|
+
.list-item-block[data-list-marker='task']
|
|
739
|
+
.task-checkbox::before {
|
|
740
|
+
transition: background-color 60ms ease-out;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
:where(.editor):is(
|
|
744
|
+
[data-presentation='reading'],
|
|
745
|
+
[data-presentation^='preview-'],
|
|
746
|
+
[data-presentation='live']
|
|
747
|
+
)
|
|
748
|
+
.list-item-block[data-list-marker='task']:not([data-task-checked='true'])
|
|
749
|
+
.task-checkbox:hover::before {
|
|
750
|
+
background-color: var(--md-marker-hover-bg, rgba(128, 128, 128, 0.15));
|
|
510
751
|
}
|
|
511
752
|
|
|
512
753
|
/* ── Reading mode ─────────────────────────────────────────────────────────────
|
|
@@ -550,6 +791,15 @@
|
|
|
550
791
|
display: inline;
|
|
551
792
|
}
|
|
552
793
|
|
|
794
|
+
/* The body's caret anchor stands in for the closer line while that line hides (see
|
|
795
|
+
`code-renderer.ts`); wherever the closer paints it would add a blank line instead. */
|
|
796
|
+
:where(.editor):not([data-presentation]) br[data-caret-anchor='closer'],
|
|
797
|
+
:where(.editor)[data-presentation^='preview-']
|
|
798
|
+
.block-host[data-focused]
|
|
799
|
+
br[data-caret-anchor='closer'] {
|
|
800
|
+
display: none;
|
|
801
|
+
}
|
|
802
|
+
|
|
553
803
|
/* Reference labels reveal on the focused block under preview-block. */
|
|
554
804
|
:where(.editor)[data-presentation='preview-block'] .block-host[data-focused] .md-ref-label {
|
|
555
805
|
display: inline;
|
|
@@ -19,7 +19,7 @@ import { isBlockOpenerRegistered } from '../schema/block-openers';
|
|
|
19
19
|
import { getBlockKindDescriptor } from '../schema/block-kind-descriptor';
|
|
20
20
|
import { rebuildContainerRawIfContainer } from '../schema/container-raw';
|
|
21
21
|
import { createSharingState } from '../tree-operations/sharing';
|
|
22
|
-
import { rebuildUnsharedAncestry } from '../tree-operations/
|
|
22
|
+
import { rebuildUnsharedAncestry } from '../tree-operations/chain-rebuild';
|
|
23
23
|
import { assertParseConverged } from './parse-convergence';
|
|
24
24
|
import { createHeadlessActions, mountBlockListState, recordingFocus, stubBlockEdit, stubStickyColumn } from './headless-actions';
|
|
25
25
|
import { assert, assertExemptionDocumented, assertIndices, assertIs, assertRebuildIsParseCanonical, assertReasonDocumented, fail, findFirstOfKind, firstChildOfKind, nodeAtPath, pathPassesThroughKind } from './conformance-core';
|
|
@@ -487,7 +487,7 @@ function assertContentStartSpaceIsRebuilt(kind, descriptor) {
|
|
|
487
487
|
/**
|
|
488
488
|
* `container.bodyWrap` is probed, never trusted: the separator settle reads it to decide whether
|
|
489
489
|
* a freed blank line belongs to the wrap, and a kind whose parse disagrees loses its body head
|
|
490
|
-
* on reload (`tree-operations/
|
|
490
|
+
* on reload (`tree-operations/settle.clearRedundantSeparator`).
|
|
491
491
|
*/
|
|
492
492
|
function assertBodyWrapMatchesParse(kind, descriptor) {
|
|
493
493
|
if (descriptor.containerContract === 'grid')
|
|
@@ -379,7 +379,8 @@ function assertRewriteReproducesSource(fixture, node, rung) {
|
|
|
379
379
|
...(node.title !== undefined ? { title: node.title } : {}),
|
|
380
380
|
...(node.label !== undefined ? { label: node.label } : {}),
|
|
381
381
|
...(node.width !== undefined ? { width: node.width } : {}),
|
|
382
|
-
...(node.height !== undefined ? { height: node.height } : {})
|
|
382
|
+
...(node.height !== undefined ? { height: node.height } : {}),
|
|
383
|
+
...(node.crop !== undefined ? { crop: node.crop } : {})
|
|
383
384
|
};
|
|
384
385
|
assertIs(rung.rewriteImage(source, fields), source, `rewriteImage re-emits ${JSON.stringify(source)} from the fields the scan read out of it`);
|
|
385
386
|
}
|
|
@@ -2,7 +2,7 @@ import { cloneMetadata, cloneNode } from './clone';
|
|
|
2
2
|
import { rebuildBlockquoteRaw } from '../schema/container-rebuilders';
|
|
3
3
|
import { rebuildContainerRaw } from '../schema/container-raw';
|
|
4
4
|
import { assignIds } from '../block-id';
|
|
5
|
-
import { emptyParagraph } from './node-
|
|
5
|
+
import { emptyParagraph } from './node-primitives';
|
|
6
6
|
import { trailingLineEnding } from '../core/lines';
|
|
7
7
|
/**
|
|
8
8
|
* Unwrap a quote-shaped container's first child (Rule U2), returning fresh clones without
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ancestry rebuild: raws re-derived along an owned spine chain innermost-first, each
|
|
3
|
+
* container's kind re-derived and the seam at its own slot asked on the way out (editor.md § 9).
|
|
4
|
+
*/
|
|
5
|
+
import type { CstNode } from '../core/nodes';
|
|
6
|
+
import type { SharingState } from './sharing';
|
|
7
|
+
import type { NodeParent } from './node-primitives';
|
|
8
|
+
import type { StructuralChange } from './structural-change';
|
|
9
|
+
import type { GrammarView } from '../schema/block-openers';
|
|
10
|
+
import { type TrackedPosition } from './settle';
|
|
11
|
+
/**
|
|
12
|
+
* Longest prefix of `chain` still attached under `root`, identity-checked level by level. A
|
|
13
|
+
* commit mutation can splice a node out mid-ceremony, and rebuilding the detached node's raw
|
|
14
|
+
* against its emptied children writes `raw: ''`; ancestors above the detachment still rebuild.
|
|
15
|
+
*/
|
|
16
|
+
export declare function attachedChainPrefix(root: NodeParent, chain: CstNode[]): CstNode[];
|
|
17
|
+
/**
|
|
18
|
+
* One container slot a rebuild re-kinded. `previous` is the rollback register: a commit
|
|
19
|
+
* unwinding after the swap has already published `replacement` into a live children array.
|
|
20
|
+
*/
|
|
21
|
+
export interface ContainerReclassification {
|
|
22
|
+
siblings: CstNode[];
|
|
23
|
+
index: number;
|
|
24
|
+
previous: CstNode;
|
|
25
|
+
replacement: CstNode;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A fold the rebuilt container's own slot owed: its bytes stopped interrupting a neighbour, so
|
|
29
|
+
* the parent's array reloads as fewer blocks. `before` is the pre-splice array, the rollback
|
|
30
|
+
* register, since the splice lands in an array no commit descriptor covers.
|
|
31
|
+
*/
|
|
32
|
+
export interface AncestrySeamFold {
|
|
33
|
+
/** Chain level of the folded container, so a caller composes the owner's path from its own. */
|
|
34
|
+
depth: number;
|
|
35
|
+
siblings: CstNode[];
|
|
36
|
+
/** The chain node owning `siblings`, or null when they are the rebuild root's children. */
|
|
37
|
+
owner: CstNode | null;
|
|
38
|
+
change: StructuralChange;
|
|
39
|
+
before: CstNode[];
|
|
40
|
+
landing: TrackedPosition;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* What the typing door knows and a bare chain does not: where the chain sits in the document,
|
|
44
|
+
* and the bytes its leaf carried before the write. Both are guesses the rebuild identity-checks.
|
|
45
|
+
*/
|
|
46
|
+
export interface ChainWriteHint {
|
|
47
|
+
path: number[];
|
|
48
|
+
leafPreviousRaw: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Rebuild raws along an owned spine chain innermost-first, re-deriving each container's kind and
|
|
52
|
+
* settling the seams at its own slot; chain- rather than path-based so it survives index shifts.
|
|
53
|
+
* Both passes gate on a boundary line of the rebuilt raw moving. `folds` is required-nullable: a
|
|
54
|
+
* fold splices the PARENT's array, so only a caller that reconciles that scope's ids/refs passes
|
|
55
|
+
* a sink.
|
|
56
|
+
*/
|
|
57
|
+
export declare function rebuildUnsharedChain(root: NodeParent | CstNode, chain: CstNode[], sharing: SharingState, folds: AncestrySeamFold[] | null, grammar: GrammarView | undefined, hint?: ChainWriteHint): ContainerReclassification[];
|
|
58
|
+
/**
|
|
59
|
+
* Unshare the spine to `path` and rebuild it innermost-first, tolerating paths that ran out of
|
|
60
|
+
* range mid-walk (post-delete rebuild passes). Prefer `rebuildUnsharedChain` when indices may
|
|
61
|
+
* have shifted since the unshare.
|
|
62
|
+
*/
|
|
63
|
+
export declare function rebuildUnsharedAncestry(root: NodeParent, path: number[], sharing: SharingState, folds: AncestrySeamFold[] | null, grammar: GrammarView | undefined): ContainerReclassification[];
|