@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.
Files changed (300) hide show
  1. package/README.md +6 -21
  2. package/THIRD-PARTY-NOTICES.md +25 -0
  3. package/dist/a11y-strings.d.ts +19 -0
  4. package/dist/a11y-strings.js +19 -0
  5. package/dist/action-contracts.d.ts +7 -1
  6. package/dist/ambient/ambient-dom.js +5 -1
  7. package/dist/block-component.d.ts +14 -0
  8. package/dist/components/BlockDragHandle.svelte +37 -24
  9. package/dist/components/BlockHost.svelte +18 -11
  10. package/dist/components/Editor.svelte +434 -198
  11. package/dist/components/Editor.svelte.d.ts +1 -1
  12. package/dist/components/SelectionOverlay.svelte +25 -17
  13. package/dist/components/SelectionOverlay.svelte.d.ts +1 -1
  14. package/dist/components/TailInsert.svelte +107 -0
  15. package/dist/components/TailInsert.svelte.d.ts +17 -0
  16. package/dist/components/block-content-selector.d.ts +6 -2
  17. package/dist/components/block-content-selector.js +6 -2
  18. package/dist/components/blocks/ThematicBreakBlock.svelte +19 -6
  19. package/dist/components/blocks/ThematicBreakBlock.svelte.d.ts +1 -0
  20. package/dist/components/blocks/code/CodeBlock.svelte +211 -30
  21. package/dist/components/blocks/code/CodeBlockRail.svelte +704 -0
  22. package/dist/components/blocks/code/CodeBlockRail.svelte.d.ts +26 -0
  23. package/dist/components/blocks/code/code-bootstrap.js +16 -0
  24. package/dist/components/blocks/code/code-context-actions.d.ts +1 -0
  25. package/dist/components/blocks/code/code-context-actions.js +24 -0
  26. package/dist/components/blocks/code/code-fence-exit.d.ts +15 -0
  27. package/dist/components/blocks/code/code-fence-exit.js +26 -0
  28. package/dist/components/blocks/code/code-languages.d.ts +6 -0
  29. package/dist/components/blocks/code/code-languages.js +22 -3
  30. package/dist/components/blocks/code/code-renderer.js +11 -0
  31. package/dist/components/blocks/directive/DirectiveContainerBlock.svelte +1 -1
  32. package/dist/components/blocks/editable-leaf.d.ts +37 -6
  33. package/dist/components/blocks/editable-leaf.js +248 -30
  34. package/dist/components/blocks/editable-surface.d.ts +9 -0
  35. package/dist/components/blocks/editable-surface.js +22 -3
  36. package/dist/components/blocks/list/ListBlock.svelte +1 -0
  37. package/dist/components/blocks/list/ListItemBlock.svelte +14 -5
  38. package/dist/components/blocks/list/ListItemBlock.svelte.d.ts +2 -0
  39. package/dist/components/blocks/list/task-checkbox.d.ts +2 -0
  40. package/dist/components/blocks/list/task-checkbox.js +11 -2
  41. package/dist/components/blocks/surface-wiring.svelte.d.ts +4 -0
  42. package/dist/components/blocks/surface-wiring.svelte.js +8 -1
  43. package/dist/components/blocks/table/TableActionMenu.svelte +210 -86
  44. package/dist/components/blocks/table/TableActionMenu.svelte.d.ts +5 -0
  45. package/dist/components/blocks/table/TableBlock.svelte +205 -186
  46. package/dist/components/blocks/table/TableBlock.svelte.d.ts +1 -0
  47. package/dist/components/blocks/table/TableCellBlock.svelte +87 -22
  48. package/dist/components/blocks/table/TableRowBlock.svelte +4 -18
  49. package/dist/components/blocks/table/TableRowBlock.svelte.d.ts +0 -5
  50. package/dist/components/blocks/table/cell-clipboard.d.ts +10 -0
  51. package/dist/components/blocks/table/cell-clipboard.js +34 -1
  52. package/dist/components/blocks/table/cell-keydown-plan.d.ts +1 -1
  53. package/dist/components/blocks/table/cell-keydown-plan.js +3 -1
  54. package/dist/components/blocks/table/table-cell-paste.js +2 -1
  55. package/dist/components/blocks/table/table-menu-model.d.ts +35 -8
  56. package/dist/components/blocks/table/table-menu-model.js +36 -17
  57. package/dist/components/blocks/text/TextEditableBlock.svelte +58 -11
  58. package/dist/components/blocks/text/click-snap-guard.d.ts +3 -0
  59. package/dist/components/blocks/text/click-snap-guard.js +8 -0
  60. package/dist/components/blocks/text/delimiter-autopair.d.ts +71 -0
  61. package/dist/components/blocks/text/delimiter-autopair.js +216 -0
  62. package/dist/components/blocks/text/edge-policy-dispatch.d.ts +4 -0
  63. package/dist/components/blocks/text/edge-policy-dispatch.js +89 -20
  64. package/dist/components/blocks/text/live-selection-edit.d.ts +5 -5
  65. package/dist/components/blocks/text/live-selection-edit.js +37 -7
  66. package/dist/components/blocks/text/text-clipboard.js +2 -2
  67. package/dist/components/blocks/text/text-keydown.d.ts +7 -1
  68. package/dist/components/blocks/text/text-keydown.js +11 -1
  69. package/dist/components/blocks/text/text-render.d.ts +1 -1
  70. package/dist/components/blocks/text/text-render.js +3 -1
  71. package/dist/components/blocks/text/widget-interaction.d.ts +3 -0
  72. package/dist/components/blocks/text/widget-interaction.js +181 -37
  73. package/dist/components/drag-handle.d.ts +41 -0
  74. package/dist/components/drag-handle.js +134 -0
  75. package/dist/components/editor-root-focus.d.ts +19 -0
  76. package/dist/components/editor-root-focus.js +67 -0
  77. package/dist/components/editor-root-geometry.d.ts +39 -0
  78. package/dist/components/editor-root-geometry.js +91 -0
  79. package/dist/components/editor-root-keydown.d.ts +1 -1
  80. package/dist/components/editor-root-keydown.js +12 -3
  81. package/dist/components/editor-root-listeners.d.ts +3 -6
  82. package/dist/components/editor-root-listeners.js +3 -24
  83. package/dist/components/editor-root-mode-flip.d.ts +36 -0
  84. package/dist/components/editor-root-mode-flip.js +92 -0
  85. package/dist/components/image/ImageOverlayHost.svelte +14 -6
  86. package/dist/components/image/ImageProperties.svelte +512 -70
  87. package/dist/components/image/ImageProperties.svelte.d.ts +6 -1
  88. package/dist/components/image/ImageResizeHandles.svelte +67 -34
  89. package/dist/components/image/image-crop.d.ts +39 -0
  90. package/dist/components/image/image-crop.js +74 -0
  91. package/dist/components/image/image-edit-commit.d.ts +1 -0
  92. package/dist/components/image/image-edit-commit.js +21 -5
  93. package/dist/components/image/image-source-bytes.js +10 -3
  94. package/dist/components/image/image-widget-editing.js +1 -0
  95. package/dist/components/image/widget-dom.js +5 -1
  96. package/dist/components/link-card/link-card-commit.js +1 -1
  97. package/dist/components/lrd-map-gate.js +1 -1
  98. package/dist/components/menu/BlockMenu.svelte +315 -0
  99. package/dist/components/menu/BlockMenu.svelte.d.ts +34 -0
  100. package/dist/components/menu/MenuIcon.svelte +153 -0
  101. package/dist/components/menu/MenuIcon.svelte.d.ts +51 -0
  102. package/dist/components/menu/SelectionToolbar.svelte +385 -0
  103. package/dist/components/menu/SelectionToolbar.svelte.d.ts +16 -0
  104. package/dist/components/menu/clipboard-actions.d.ts +12 -0
  105. package/dist/components/menu/clipboard-actions.js +42 -0
  106. package/dist/components/menu/default-context-actions.d.ts +15 -0
  107. package/dist/components/menu/default-context-actions.js +76 -0
  108. package/dist/components/menu/flyout-placement.d.ts +6 -0
  109. package/dist/components/menu/flyout-placement.js +25 -0
  110. package/dist/core/inline/format-toggle.d.ts +12 -4
  111. package/dist/core/inline/format-toggle.js +94 -40
  112. package/dist/core/inline/image-dimensions.d.ts +3 -0
  113. package/dist/core/inline/image-dimensions.js +46 -10
  114. package/dist/core/inline/inline-widgets.d.ts +19 -0
  115. package/dist/core/inline/inline-widgets.js +5 -0
  116. package/dist/core/inline/scan/brackets.js +1 -0
  117. package/dist/core/inline/scan/plugin-syntax.d.ts +8 -0
  118. package/dist/core/inline/scan/plugin-syntax.js +15 -1
  119. package/dist/core/inline/transparency.js +3 -3
  120. package/dist/core/inline-render.d.ts +6 -0
  121. package/dist/core/inline-render.js +32 -0
  122. package/dist/core/nodes.d.ts +14 -0
  123. package/dist/cursor/edge-affinity.js +2 -1
  124. package/dist/cursor/height-oracle.d.ts +2 -3
  125. package/dist/cursor/height-oracle.js +0 -1
  126. package/dist/cursor/overlay-remeasure.js +8 -0
  127. package/dist/cursor/reveal-source.js +7 -2
  128. package/dist/cursor/scroll-hold.d.ts +10 -0
  129. package/dist/cursor/scroll-hold.js +22 -0
  130. package/dist/cursor/scrollport.d.ts +9 -0
  131. package/dist/cursor/scrollport.js +30 -1
  132. package/dist/cursor/visual-lines.d.ts +5 -4
  133. package/dist/cursor/visual-lines.js +56 -11
  134. package/dist/cursor/widget-edge-snap.d.ts +28 -0
  135. package/dist/cursor/widget-edge-snap.js +38 -0
  136. package/dist/cursor/widget-offset.d.ts +9 -0
  137. package/dist/cursor/widget-offset.js +71 -4
  138. package/dist/debug/interaction-trace.d.ts +4 -0
  139. package/dist/debug/interaction-trace.js +15 -0
  140. package/dist/decorations/decoration-state.svelte.js +1 -1
  141. package/dist/decorations/reserved-attrs.js +1 -0
  142. package/dist/editor-actions/ancestry-folds.d.ts +2 -2
  143. package/dist/editor-actions/ancestry-folds.js +1 -1
  144. package/dist/editor-actions/block-edit-scope.js +1 -1
  145. package/dist/editor-actions/commit/text-batch.d.ts +3 -2
  146. package/dist/editor-actions/commit/text-batch.js +1 -1
  147. package/dist/editor-actions/commit/undo-controller.js +4 -2
  148. package/dist/editor-actions/container-edit.js +2 -1
  149. package/dist/editor-actions/enter-completion.d.ts +2 -0
  150. package/dist/editor-actions/enter-completion.js +23 -2
  151. package/dist/editor-actions/focus/focus-dispatch.js +7 -4
  152. package/dist/editor-actions/focus/focus-landing.d.ts +10 -1
  153. package/dist/editor-actions/focus/focus-landing.js +20 -6
  154. package/dist/editor-actions/inline-range-commit.js +1 -1
  155. package/dist/editor-actions/plugin/container.d.ts +7 -0
  156. package/dist/editor-actions/plugin/container.js +3 -1
  157. package/dist/editor-actions/reorder-action.js +19 -10
  158. package/dist/editor-actions/reorder-drag.js +29 -1
  159. package/dist/editor-actions/replacement-focus.d.ts +1 -1
  160. package/dist/editor-actions/replacement-focus.js +1 -1
  161. package/dist/editor-actions/search-replace.js +1 -1
  162. package/dist/editor-actions/table-context.d.ts +4 -1
  163. package/dist/editor-actions/table-context.js +57 -1
  164. package/dist/editor-events.d.ts +3 -0
  165. package/dist/editor-keys.d.ts +33 -0
  166. package/dist/editor-props.d.ts +24 -12
  167. package/dist/index.d.ts +1 -1
  168. package/dist/plugin.d.ts +7 -0
  169. package/dist/plugin.js +16 -0
  170. package/dist/plugins/latex/BlockMath.svelte +264 -29
  171. package/dist/plugins/latex/BlockMath.svelte.d.ts +2 -0
  172. package/dist/plugins/latex/index.d.ts +2 -1
  173. package/dist/plugins/latex/latex-kind.js +60 -10
  174. package/dist/plugins/latex/math-completion.js +4 -1
  175. package/dist/plugins/latex/math-layout.d.ts +15 -0
  176. package/dist/plugins/latex/math-layout.js +13 -0
  177. package/dist/plugins/latex/math-source.d.ts +19 -0
  178. package/dist/plugins/latex/math-source.js +103 -0
  179. package/dist/plugins/latex/register.d.ts +11 -2
  180. package/dist/plugins/latex/register.js +3 -1
  181. package/dist/plugins/latex/renderer.d.ts +3 -3
  182. package/dist/plugins/latex/renderer.js +13 -6
  183. package/dist/plugins/mermaid/MermaidBlock.svelte +19 -9
  184. package/dist/plugins/parrot/ParrotBlock.svelte +3 -1
  185. package/dist/reactivity/list-windowing.svelte.d.ts +8 -8
  186. package/dist/reactivity/list-windowing.svelte.js +75 -30
  187. package/dist/schema/block-completions.d.ts +8 -0
  188. package/dist/schema/block-completions.js +11 -0
  189. package/dist/schema/commands.d.ts +9 -5
  190. package/dist/schema/commands.js +12 -7
  191. package/dist/schema/context-actions.d.ts +31 -0
  192. package/dist/schema/context-actions.js +23 -0
  193. package/dist/schema/fenced-code-raw.js +31 -1
  194. package/dist/schema/operations.d.ts +8 -1
  195. package/dist/schema/reserved-chords.js +37 -4
  196. package/dist/schema/table-cell-raw.d.ts +1 -1
  197. package/dist/schema/table-cell-raw.js +1 -1
  198. package/dist/selection/block-hit-test.js +3 -2
  199. package/dist/selection/char-endpoint-snap.js +1 -1
  200. package/dist/selection/clipboard-text.js +6 -1
  201. package/dist/selection/covered-block.d.ts +10 -0
  202. package/dist/selection/covered-block.js +24 -0
  203. package/dist/selection/cross-block/dispatch.d.ts +3 -0
  204. package/dist/selection/cross-block/dispatch.js +13 -1
  205. package/dist/selection/cross-block/format-range.d.ts +1 -1
  206. package/dist/selection/cross-block/format-range.js +4 -15
  207. package/dist/selection/cross-block/format-toggle.js +1 -1
  208. package/dist/selection/cross-block/keydown.js +3 -29
  209. package/dist/selection/cross-block/ops.js +1 -1
  210. package/dist/selection/cross-block/paste.js +31 -35
  211. package/dist/selection/cross-block/type-replace.d.ts +3 -2
  212. package/dist/selection/cross-block/type-replace.js +52 -13
  213. package/dist/selection/dead-space-caret.d.ts +13 -0
  214. package/dist/selection/dead-space-caret.js +57 -1
  215. package/dist/selection/drag-pointer.d.ts +26 -2
  216. package/dist/selection/drag-pointer.js +103 -2
  217. package/dist/selection/gap-caret.js +1 -1
  218. package/dist/selection/keyboard-extend.d.ts +3 -2
  219. package/dist/selection/keyboard-extend.js +4 -3
  220. package/dist/selection/multi-click.d.ts +42 -0
  221. package/dist/selection/multi-click.js +203 -0
  222. package/dist/selection/native-bridge.d.ts +3 -0
  223. package/dist/selection/native-bridge.js +31 -2
  224. package/dist/selection/path-lookup.d.ts +10 -2
  225. package/dist/selection/path-lookup.js +11 -4
  226. package/dist/selection/pointer-gesture.d.ts +9 -0
  227. package/dist/selection/pointer-gesture.js +11 -0
  228. package/dist/selection/primitives.d.ts +7 -0
  229. package/dist/selection/primitives.js +19 -1
  230. package/dist/selection/range-delete-ceremony.js +4 -2
  231. package/dist/selection/range-delete-chrome.js +2 -1
  232. package/dist/selection/range-delete-table-coverage.js +2 -1
  233. package/dist/selection/range-delete-table.js +3 -2
  234. package/dist/selection/range-delete.d.ts +4 -0
  235. package/dist/selection/range-delete.js +31 -3
  236. package/dist/selection/selection-drop.d.ts +34 -0
  237. package/dist/selection/selection-drop.js +253 -0
  238. package/dist/selection/selection-restore.js +1 -1
  239. package/dist/selection/selection-state.svelte.d.ts +6 -0
  240. package/dist/selection/selection-state.svelte.js +36 -1
  241. package/dist/selection/table-endpoint-snap.js +1 -1
  242. package/dist/selection/table-rect-extend.js +1 -1
  243. package/dist/styles/editor-theme.css +75 -31
  244. package/dist/styles/editor.css +268 -18
  245. package/dist/testing/container-conformance.js +2 -2
  246. package/dist/testing/inline-conformance.js +2 -1
  247. package/dist/tree-operations/blockquote.js +1 -1
  248. package/dist/tree-operations/chain-rebuild.d.ts +63 -0
  249. package/dist/tree-operations/chain-rebuild.js +142 -0
  250. package/dist/tree-operations/children.d.ts +1 -1
  251. package/dist/tree-operations/children.js +1 -1
  252. package/dist/tree-operations/cleanup.js +1 -1
  253. package/dist/tree-operations/content-write.d.ts +50 -0
  254. package/dist/tree-operations/content-write.js +263 -0
  255. package/dist/tree-operations/index.d.ts +8 -3
  256. package/dist/tree-operations/index.js +6 -2
  257. package/dist/tree-operations/list/exit-replacement.js +1 -1
  258. package/dist/tree-operations/list/unwrap-merge.js +3 -3
  259. package/dist/tree-operations/node-ops.d.ts +17 -234
  260. package/dist/tree-operations/node-ops.js +47 -1113
  261. package/dist/tree-operations/node-primitives.d.ts +75 -0
  262. package/dist/tree-operations/node-primitives.js +117 -0
  263. package/dist/tree-operations/paste/apply.js +1 -1
  264. package/dist/tree-operations/paste/body-write.d.ts +1 -1
  265. package/dist/tree-operations/paste/body-write.js +2 -2
  266. package/dist/tree-operations/paste/container-match.js +4 -2
  267. package/dist/tree-operations/paste/dispatch.js +2 -1
  268. package/dist/tree-operations/paste/find-enclosing-list.js +1 -1
  269. package/dist/tree-operations/paste/focus-target.d.ts +1 -1
  270. package/dist/tree-operations/paste/list-absorb.js +1 -1
  271. package/dist/tree-operations/paste/list-break-out.js +1 -1
  272. package/dist/tree-operations/paste/parent-scope.js +1 -1
  273. package/dist/tree-operations/paste/paste-replacement.js +1 -1
  274. package/dist/tree-operations/paste/replace-block-at-parent.d.ts +3 -1
  275. package/dist/tree-operations/paste/replace-block-at-parent.js +5 -2
  276. package/dist/tree-operations/paste/replacement-parse.d.ts +17 -0
  277. package/dist/tree-operations/paste/replacement-parse.js +22 -0
  278. package/dist/tree-operations/path-mutate.d.ts +1 -1
  279. package/dist/tree-operations/path-mutate.js +2 -1
  280. package/dist/tree-operations/reorder-unit.js +1 -1
  281. package/dist/tree-operations/reorder.d.ts +5 -2
  282. package/dist/tree-operations/reorder.js +55 -2
  283. package/dist/tree-operations/settle.d.ts +105 -0
  284. package/dist/tree-operations/settle.js +660 -0
  285. package/dist/tree-operations/table-grid-clipboard.d.ts +21 -0
  286. package/dist/tree-operations/table-grid-clipboard.js +90 -0
  287. package/dist/tree-operations/unshare.d.ts +15 -77
  288. package/dist/tree-operations/unshare.js +15 -166
  289. package/docs/guide/consumer-guide.md +136 -104
  290. package/docs/guide/plugin-api.md +73 -29
  291. package/docs/guide/plugin-guide.md +55 -23
  292. package/package.json +9 -7
  293. package/dist/components/blocks/code/CodeLanguageChip.svelte +0 -127
  294. package/dist/components/blocks/code/CodeLanguageChip.svelte.d.ts +0 -14
  295. package/dist/components/blocks/table/TableGrip.svelte +0 -91
  296. package/dist/components/blocks/table/TableGrip.svelte.d.ts +0 -8
  297. package/dist/components/blocks/table/table-drop-target.d.ts +0 -1
  298. package/dist/components/blocks/table/table-drop-target.js +0 -16
  299. package/dist/components/blocks/table/table-reorder-drag.d.ts +0 -78
  300. package/dist/components/blocks/table/table-reorder-drag.js +0 -97
@@ -18,7 +18,7 @@ declare const Editor: import("svelte").Component<$$ComponentProps, {
18
18
  setSelection: (selection: EditorSelection) => Promise<boolean>;
19
19
  placeCaretAtPoint: (x: number, y: number) => boolean;
20
20
  insertMarkdown: (md: string) => boolean;
21
- runCommand: (commandId: string) => boolean;
21
+ runCommand: (commandId: string, arg?: unknown) => boolean;
22
22
  canRunCommand: (commandId: string) => boolean;
23
23
  isCommandActive: (commandId: string) => boolean;
24
24
  getEvents: () => EditorEvents;
@@ -9,10 +9,11 @@
9
9
  } from '../editor-keys';
10
10
  import {
11
11
  normalize,
12
+ blockPaintsWholeBox,
12
13
  classifyBlockForSelection,
13
14
  charOffsetOf,
14
15
  cellIndexOf,
15
- type BlockSelectionClass
16
+ type EditorSelection
16
17
  } from '../selection/primitives';
17
18
  import { snapCrossBlockTableEndpoints } from '../selection/table-endpoint-snap';
18
19
  import { wireOverlayRemeasure } from '../cursor/overlay-remeasure';
@@ -27,7 +28,7 @@
27
28
  path: number[];
28
29
  blockRef: BlockComponent | undefined;
29
30
  blockEl: HTMLElement | null | undefined;
30
- /** This container's children paint their own overlays, so it paints none. */
31
+ /** This container's children paint the range's endpoint rects, so it measures none. */
31
32
  delegatesPainting?: boolean;
32
33
  /** This container measures its own rects instead of delegating. Both are decided
33
34
  * at BlockHost, which hands the same pair to DecorationOverlay. */
@@ -41,23 +42,26 @@
41
42
  const getEditorRoot = editorDoc?.editorRoot;
42
43
  const getDoc = editorDoc?.doc;
43
44
 
44
- const classification = $derived.by<BlockSelectionClass>(() => {
45
- if (delegatesPainting) return 'outside';
46
- if (!selection?.isCustomRendered || !selection.anchor || !selection.focus) {
47
- return 'outside';
48
- }
49
- return classifyBlockForSelection(path, {
50
- anchor: selection.anchor,
51
- focus: selection.focus
52
- });
45
+ const range = $derived.by<EditorSelection | null>(() => {
46
+ if (!selection?.isCustomRendered || !selection.anchor || !selection.focus) return null;
47
+ return { anchor: selection.anchor, focus: selection.focus };
53
48
  });
54
49
 
50
+ const classification = $derived(range ? classifyBlockForSelection(path, range) : 'outside');
51
+
52
+ // Delegation-blind on purpose: a block the range holds whole paints one box over everything it
53
+ // renders, chrome included, and the seam already keeps its children from painting under it.
54
+ const paintsWholeBox = $derived(
55
+ range !== null && blockPaintsWholeBox(path, range, selection?.wholeUnitPath ?? null)
56
+ );
57
+
55
58
  // The measuring effect and the template read this one predicate, so a rendered
56
59
  // rect is always one the effect measured; two predicates render a stale box.
57
60
  const paintsEndpoints = $derived(
58
- classification === 'start' ||
59
- classification === 'end' ||
60
- (classification === 'single-block' && containerPaintsRects)
61
+ !delegatesPainting &&
62
+ (classification === 'start' ||
63
+ classification === 'end' ||
64
+ (classification === 'single-block' && containerPaintsRects))
61
65
  );
62
66
 
63
67
  interface LocalRect {
@@ -67,7 +71,9 @@
67
71
  height: number;
68
72
  }
69
73
 
70
- /** Merge rects on the same visual line into a single rect to prevent double-highlight. */
74
+ /** Merge rects on the same visual line into a single rect to prevent double-highlight. Same
75
+ * line means vertically overlapping, not equal tops: an inline widget (a KaTeX box) stands
76
+ * taller than the text beside it, and two rects painted over one span read twice as dark. */
71
77
  function mergeRectsPerLine(rects: LocalRect[]): LocalRect[] {
72
78
  if (rects.length <= 1) return rects;
73
79
  const sorted = [...rects].sort((a, b) => a.top - b.top);
@@ -76,7 +82,9 @@
76
82
 
77
83
  for (let i = 1; i < sorted.length; i++) {
78
84
  const r = sorted[i];
79
- if (Math.abs(r.top - current.top) < 2) {
85
+ const overlap =
86
+ Math.min(current.top + current.height, r.top + r.height) - Math.max(current.top, r.top);
87
+ if (overlap > Math.min(current.height, r.height) * 0.5) {
80
88
  const left = Math.min(current.left, r.left);
81
89
  const right = Math.max(current.left + current.width, r.left + r.width);
82
90
  const top = Math.min(current.top, r.top);
@@ -146,7 +154,7 @@
146
154
  });
147
155
  </script>
148
156
 
149
- {#if classification === 'middle'}
157
+ {#if paintsWholeBox}
150
158
  <div class="selection-overlay selection-overlay-middle" contenteditable="false"></div>
151
159
  {:else if paintsEndpoints}
152
160
  {#each endpointRects as rect, i (i)}
@@ -3,7 +3,7 @@ type $$ComponentProps = {
3
3
  path: number[];
4
4
  blockRef: BlockComponent | undefined;
5
5
  blockEl: HTMLElement | null | undefined;
6
- /** This container's children paint their own overlays, so it paints none. */
6
+ /** This container's children paint the range's endpoint rects, so it measures none. */
7
7
  delegatesPainting?: boolean;
8
8
  /** This container measures its own rects instead of delegating. Both are decided
9
9
  * at BlockHost, which hands the same pair to DecorationOverlay. */
@@ -0,0 +1,107 @@
1
+ <script lang="ts">
2
+ /**
3
+ * The row below the last block: a full-width strip that adds an empty paragraph at the end
4
+ * of the document and lands the caret in it, with a `+` in the left gutter that does the
5
+ * same — so there is always a way to write below whatever the last block is (a table, a
6
+ * fence, an equation), and a place to add the next block from.
7
+ */
8
+ import type { BlockEditActions } from '../action-contracts';
9
+ import { TAIL_ADD_BLOCK, TAIL_ADD_ROW } from '../a11y-strings';
10
+ import MenuIcon from './menu/MenuIcon.svelte';
11
+
12
+ let {
13
+ blockEdit,
14
+ childCount,
15
+ readOnly,
16
+ onPlus
17
+ }: {
18
+ blockEdit: BlockEditActions | undefined;
19
+ childCount: number;
20
+ readOnly: boolean;
21
+ /** The `+`: the editor appends the paragraph and opens the block menu over it. */
22
+ onPlus: (button: HTMLElement) => void;
23
+ } = $props();
24
+
25
+ // The mint's own focus lands the caret; the mousedown is swallowed so nothing else seats one.
26
+ function append(): void {
27
+ if (readOnly) return;
28
+ void blockEdit?.insertParagraph(childCount, '');
29
+ }
30
+ </script>
31
+
32
+ {#if !readOnly}
33
+ <div class="editor-tail">
34
+ <button
35
+ type="button"
36
+ class="editor-tail-plus"
37
+ aria-label={TAIL_ADD_BLOCK}
38
+ title={TAIL_ADD_BLOCK}
39
+ onmousedown={(e) => e.preventDefault()}
40
+ onclick={(e) => onPlus(e.currentTarget)}><MenuIcon name="plus" size={14} /></button
41
+ >
42
+ <button
43
+ type="button"
44
+ class="editor-tail-row"
45
+ aria-label={TAIL_ADD_ROW}
46
+ onmousedown={(e) => e.preventDefault()}
47
+ onclick={append}
48
+ ></button>
49
+ </div>
50
+ {/if}
51
+
52
+ <style>
53
+ .editor-tail {
54
+ position: relative;
55
+ display: flex;
56
+ align-items: center;
57
+ height: 34px;
58
+ margin-top: 2px;
59
+ }
60
+ .editor-tail-row {
61
+ flex: 1;
62
+ height: 100%;
63
+ padding: 0;
64
+ border: 0;
65
+ background: transparent;
66
+ cursor: text;
67
+ }
68
+ .editor-tail-row:focus-visible {
69
+ outline: 1px solid var(--color-border, #3e3e3b);
70
+ outline-offset: -1px;
71
+ border-radius: 4px;
72
+ }
73
+ /* In the editor's gutter, exactly where a block's drag handle sits (`BlockDragHandle`): the
74
+ root's 1rem padding holds a 0.85rem slot, and this is the handle of the imaginary last line. */
75
+ .editor-tail-plus {
76
+ position: absolute;
77
+ left: -1rem;
78
+ top: 50%;
79
+ transform: translateY(-50%);
80
+ display: flex;
81
+ align-items: center;
82
+ justify-content: center;
83
+ width: 1rem;
84
+ height: 1rem;
85
+ padding: 0;
86
+ border: 0;
87
+ border-radius: 3px;
88
+ background: transparent;
89
+ color: var(--color-ui-muted, #8f8f89);
90
+ cursor: pointer;
91
+ opacity: 0;
92
+ transition: opacity 120ms ease-out;
93
+ }
94
+ .editor-tail:hover .editor-tail-plus,
95
+ .editor-tail-plus:focus-visible {
96
+ opacity: 1;
97
+ }
98
+ .editor-tail-plus:hover {
99
+ background: var(--color-ui-faint, rgba(255, 255, 255, 0.07));
100
+ color: var(--color-text-primary, #e8e8e5);
101
+ }
102
+ @media (prefers-reduced-motion: reduce) {
103
+ .editor-tail-plus {
104
+ transition: none;
105
+ }
106
+ }
107
+ </style>
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The row below the last block: a full-width strip that adds an empty paragraph at the end
3
+ * of the document and lands the caret in it, with a `+` in the left gutter that does the
4
+ * same — so there is always a way to write below whatever the last block is (a table, a
5
+ * fence, an equation), and a place to add the next block from.
6
+ */
7
+ import type { BlockEditActions } from '../action-contracts';
8
+ type $$ComponentProps = {
9
+ blockEdit: BlockEditActions | undefined;
10
+ childCount: number;
11
+ readOnly: boolean;
12
+ /** The `+`: the editor appends the paragraph and opens the block menu over it. */
13
+ onPlus: (button: HTMLElement) => void;
14
+ };
15
+ declare const TailInsert: import("svelte").Component<$$ComponentProps, {}, "">;
16
+ type TailInsert = ReturnType<typeof TailInsert>;
17
+ export default TailInsert;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * A block's content element is the first child of its `data-block-path` wrapper that is not chrome
3
- * wrapped around it (child order: badges, content, the code block's language chip, selection
3
+ * wrapped around it (child order: badges, content, the code block's rail, selection
4
4
  * overlay, decoration overlays, drag handle). One definition, shared by the runtime and the e2e
5
5
  * page-object.
6
6
  */
@@ -9,4 +9,8 @@
9
9
  export declare const BLOCK_CONTENT_SELECTOR = ":scope > :not(.selection-overlay):not(.decoration-badge)";
10
10
  /** For a Playwright `locator`, which enumerates ALL matches, so every chrome child
11
11
  * must be named — the decoration overlay is one per painted mark, not per block. */
12
- export declare const BLOCK_CONTENT_LOCATOR_SELECTOR = ":scope > *:not(.selection-overlay):not(.decoration-overlay):not(.block-drag-handle):not(.decoration-badge):not(.code-lang-chip)";
12
+ export declare const BLOCK_CONTENT_LOCATOR_SELECTOR = ":scope > *:not(.selection-overlay):not(.decoration-overlay):not(.block-drag-handle):not(.decoration-badge):not(.code-rail)";
13
+ /** Marks the element a block's drag grip centres on (`drag-handle.ts`); absent, the block's
14
+ * first line of text is it. Here rather than beside the handle so the ambient-prefix DOM
15
+ * builder can set it without reaching into the components layer. */
16
+ export declare const DRAG_ANCHOR_ATTR = "data-drag-anchor";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * A block's content element is the first child of its `data-block-path` wrapper that is not chrome
3
- * wrapped around it (child order: badges, content, the code block's language chip, selection
3
+ * wrapped around it (child order: badges, content, the code block's rail, selection
4
4
  * overlay, decoration overlays, drag handle). One definition, shared by the runtime and the e2e
5
5
  * page-object.
6
6
  */
@@ -9,4 +9,8 @@
9
9
  export const BLOCK_CONTENT_SELECTOR = ':scope > :not(.selection-overlay):not(.decoration-badge)';
10
10
  /** For a Playwright `locator`, which enumerates ALL matches, so every chrome child
11
11
  * must be named — the decoration overlay is one per painted mark, not per block. */
12
- export const BLOCK_CONTENT_LOCATOR_SELECTOR = ':scope > *:not(.selection-overlay):not(.decoration-overlay):not(.block-drag-handle):not(.decoration-badge):not(.code-lang-chip)';
12
+ export const BLOCK_CONTENT_LOCATOR_SELECTOR = ':scope > *:not(.selection-overlay):not(.decoration-overlay):not(.block-drag-handle):not(.decoration-badge):not(.code-rail)';
13
+ /** Marks the element a block's drag grip centres on (`drag-handle.ts`); absent, the block's
14
+ * first line of text is it. Here rather than beside the handle so the ambient-prefix DOM
15
+ * builder can set it without reaching into the components layer. */
16
+ export const DRAG_ANCHOR_ATTR = 'data-drag-anchor';
@@ -72,13 +72,21 @@
72
72
  export function runCommand(id: CommandId): boolean {
73
73
  return reorderRunCommand(id, reorder, () => myPath);
74
74
  }
75
+
76
+ // The rule has no text to measure, so any non-empty range over it is its whole box — what a
77
+ // range ending on it, or the rule taken as a unit, paints.
78
+ export function measurePartialRects(startOffset: number, endOffset: number): DOMRect[] {
79
+ if (endOffset <= startOffset || !boxEl) return [];
80
+ return [boxEl.getBoundingClientRect()];
81
+ }
75
82
  void ({
76
83
  editable,
77
84
  focusable,
78
85
  focus,
79
86
  parkCaret,
80
87
  getCursorOffset,
81
- runCommand
88
+ runCommand,
89
+ measurePartialRects
82
90
  } satisfies BlockComponent);
83
91
 
84
92
  // ── Event Handlers ──────────────────────────────────────────────────
@@ -136,21 +144,26 @@
136
144
  position: relative;
137
145
  }
138
146
 
147
+ /* The rule is a hairline, so the SPACE around it is what reads as a division. Cramped
148
+ padding on a heavy line reads as a border instead. */
139
149
  .thematic-break-rule {
140
150
  outline: none;
141
- padding: 8px 0;
151
+ padding: 14px 0;
142
152
  }
143
153
 
144
- /* `:focus-within`: whole-block focus lands on the host, not the separator. */
154
+ /* `:focus-within`: whole-block focus lands on the host, not the separator. Painted as the
155
+ SAME wash the selection overlay uses, not an accent ring: a rule that showed focus one
156
+ way and selection another read as two different states of the same block. */
145
157
  .thematic-break-block:focus-within .thematic-break-rule {
146
- outline: 2px solid var(--color-accent, #567b67);
147
- outline-offset: 2px;
158
+ background: var(--selection-overlay-bg, rgba(100, 150, 255, 0.3));
148
159
  border-radius: 2px;
149
160
  }
150
161
 
151
162
  hr {
152
163
  border: none;
153
- border-top: 2px solid var(--color-ui-muted, #a4a4a4);
164
+ /* A hairline on the BORDER token, not the muted-UI one: a divider separates, and at
165
+ 2px of mid-grey it competed with the text it sits between. */
166
+ border-top: 1px solid var(--color-border, #3e3e3b);
154
167
  margin: 0;
155
168
  }
156
169
  </style>
@@ -12,6 +12,7 @@ declare const ThematicBreakBlock: import("svelte").Component<$$ComponentProps, {
12
12
  parkCaret: (_offset: number) => void;
13
13
  getCursorOffset: () => number | null;
14
14
  runCommand: (id: CommandId) => boolean;
15
+ measurePartialRects: (startOffset: number, endOffset: number) => DOMRect[];
15
16
  }, "">;
16
17
  type ThematicBreakBlock = ReturnType<typeof ThematicBreakBlock>;
17
18
  export default ThematicBreakBlock;