@voithos-labs/aragonite 0.10.4 → 0.10.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1021) hide show
  1. package/README.md +2 -2
  2. package/dist/a11y-strings.d.ts +11 -5
  3. package/dist/a11y-strings.js +60 -5
  4. package/dist/action-contracts.d.ts +242 -155
  5. package/dist/action-contracts.js +2 -2
  6. package/dist/active-editor.d.ts +3 -3
  7. package/dist/active-editor.js +8 -9
  8. package/dist/ambient/ambient-dom.d.ts +2 -5
  9. package/dist/ambient/ambient-dom.js +16 -62
  10. package/dist/assert.js +6 -5
  11. package/dist/block-component.d.ts +135 -109
  12. package/dist/block-component.js +30 -22
  13. package/dist/block-id.d.ts +6 -10
  14. package/dist/block-id.js +25 -14
  15. package/dist/bounded-memo.d.ts +5 -5
  16. package/dist/bounded-memo.js +6 -6
  17. package/dist/components/BlockDragHandle.svelte +12 -21
  18. package/dist/components/BlockHost.svelte +56 -134
  19. package/dist/components/BlockList.svelte +22 -19
  20. package/dist/components/DecorationOverlay.svelte +9 -10
  21. package/dist/components/DecorationOverlay.svelte.d.ts +2 -2
  22. package/dist/components/Editor.svelte +603 -1126
  23. package/dist/components/Editor.svelte.d.ts +9 -20
  24. package/dist/components/GapCaret.svelte +26 -59
  25. package/dist/components/SelectionOverlay.svelte +26 -51
  26. package/dist/components/SelectionOverlay.svelte.d.ts +5 -3
  27. package/dist/components/TailInsert.svelte +8 -55
  28. package/dist/components/TailInsert.svelte.d.ts +4 -6
  29. package/dist/components/block-content-selector.d.ts +11 -11
  30. package/dist/components/block-content-selector.js +11 -11
  31. package/dist/components/block-el-lookup.d.ts +6 -0
  32. package/dist/components/block-el-lookup.js +27 -0
  33. package/dist/components/blocks/BlockquoteBlock.svelte +3 -3
  34. package/dist/components/blocks/ThematicBreakBlock.svelte +22 -63
  35. package/dist/components/blocks/ThematicBreakBlock.svelte.d.ts +0 -2
  36. package/dist/components/blocks/code/CodeBlock.svelte +255 -276
  37. package/dist/components/blocks/code/CodeBlock.svelte.d.ts +2 -3
  38. package/dist/components/blocks/code/CodeBlockRail.svelte +72 -87
  39. package/dist/components/blocks/code/CodeBlockRail.svelte.d.ts +9 -4
  40. package/dist/components/blocks/code/code-beforeinput.d.ts +1 -1
  41. package/dist/components/blocks/code/code-bootstrap.d.ts +3 -5
  42. package/dist/components/blocks/code/code-bootstrap.js +29 -34
  43. package/dist/components/blocks/code/code-context-actions.js +5 -4
  44. package/dist/components/blocks/code/code-enter.js +2 -2
  45. package/dist/components/blocks/code/code-fence-boundary.d.ts +29 -46
  46. package/dist/components/blocks/code/code-fence-boundary.js +40 -66
  47. package/dist/components/blocks/code/code-fence-exit.d.ts +6 -11
  48. package/dist/components/blocks/code/code-fence-exit.js +24 -25
  49. package/dist/components/blocks/code/code-indent.d.ts +2 -2
  50. package/dist/components/blocks/code/code-indent.js +4 -7
  51. package/dist/components/blocks/code/code-languages.d.ts +16 -12
  52. package/dist/components/blocks/code/code-languages.js +57 -39
  53. package/dist/components/blocks/code/code-paste-surface.d.ts +3 -2
  54. package/dist/components/blocks/code/code-paste-surface.js +9 -18
  55. package/dist/components/blocks/code/code-renderer.d.ts +21 -5
  56. package/dist/components/blocks/code/code-renderer.js +90 -125
  57. package/dist/components/blocks/directive/DirectiveContainerBlock.svelte +5 -8
  58. package/dist/components/blocks/directive/activate-directives.d.ts +4 -4
  59. package/dist/components/blocks/directive/activate-directives.js +18 -13
  60. package/dist/components/blocks/editable-leaf.d.ts +50 -74
  61. package/dist/components/blocks/editable-leaf.js +141 -203
  62. package/dist/components/blocks/editable-surface.d.ts +96 -100
  63. package/dist/components/blocks/editable-surface.js +101 -109
  64. package/dist/components/blocks/list/ListBlock.svelte +45 -90
  65. package/dist/components/blocks/list/ListItemBlock.svelte +93 -147
  66. package/dist/components/blocks/list/ListItemBlock.svelte.d.ts +1 -0
  67. package/dist/components/blocks/list/task-checkbox.d.ts +5 -2
  68. package/dist/components/blocks/list/task-checkbox.js +12 -7
  69. package/dist/components/blocks/plain-text-backend.d.ts +4 -20
  70. package/dist/components/blocks/plain-text-backend.js +9 -43
  71. package/dist/components/blocks/surface-wiring.svelte.d.ts +8 -9
  72. package/dist/components/blocks/surface-wiring.svelte.js +15 -34
  73. package/dist/components/blocks/table/TableActionMenu.svelte +19 -18
  74. package/dist/components/blocks/table/TableActionMenu.svelte.d.ts +3 -1
  75. package/dist/components/blocks/table/TableBlock.svelte +100 -165
  76. package/dist/components/blocks/table/TableBlock.svelte.d.ts +3 -3
  77. package/dist/components/blocks/table/TableCellBlock.svelte +307 -385
  78. package/dist/components/blocks/table/TableCellBlock.svelte.d.ts +1 -0
  79. package/dist/components/blocks/table/TableRowBlock.svelte +60 -104
  80. package/dist/components/blocks/table/TableRowBlock.svelte.d.ts +0 -1
  81. package/dist/components/blocks/table/cell-keydown-plan.d.ts +4 -9
  82. package/dist/components/blocks/table/cell-keydown-plan.js +8 -12
  83. package/dist/components/blocks/table/cell-pointer.d.ts +18 -23
  84. package/dist/components/blocks/table/cell-pointer.js +49 -71
  85. package/dist/components/blocks/table/cell-render.d.ts +24 -29
  86. package/dist/components/blocks/table/cell-render.js +29 -31
  87. package/dist/components/blocks/table/selected-cells.d.ts +7 -7
  88. package/dist/components/blocks/table/selected-cells.js +9 -13
  89. package/dist/components/blocks/table/table-caret-at-point.d.ts +4 -4
  90. package/dist/components/blocks/table/table-caret-at-point.js +5 -5
  91. package/dist/components/blocks/table/table-cell-paste.d.ts +5 -11
  92. package/dist/components/blocks/table/table-cell-paste.js +27 -43
  93. package/dist/components/blocks/table/table-drag-hit-test.js +2 -1
  94. package/dist/components/blocks/table/table-menu-model.d.ts +4 -8
  95. package/dist/components/blocks/table/table-menu-model.js +6 -10
  96. package/dist/components/blocks/table/table-navigation.js +2 -2
  97. package/dist/components/blocks/text/TextEditableBlock.svelte +392 -310
  98. package/dist/components/blocks/text/TextEditableBlock.svelte.d.ts +2 -1
  99. package/dist/components/blocks/text/auto-pair-record.d.ts +23 -0
  100. package/dist/components/blocks/text/auto-pair-record.js +51 -0
  101. package/dist/components/blocks/text/click-snap-guard.d.ts +8 -6
  102. package/dist/components/blocks/text/click-snap-guard.js +10 -7
  103. package/dist/components/blocks/text/composition-seat.d.ts +17 -14
  104. package/dist/components/blocks/text/composition-seat.js +11 -11
  105. package/dist/components/blocks/text/construct-edge-delete.d.ts +20 -20
  106. package/dist/components/blocks/text/construct-edge-delete.js +50 -65
  107. package/dist/components/blocks/text/construct-reveal.d.ts +16 -21
  108. package/dist/components/blocks/text/construct-reveal.js +13 -14
  109. package/dist/components/blocks/text/delimiter-autopair.d.ts +51 -34
  110. package/dist/components/blocks/text/delimiter-autopair.js +87 -103
  111. package/dist/components/blocks/text/edge-policy-dispatch.d.ts +44 -46
  112. package/dist/components/blocks/text/edge-policy-dispatch.js +150 -181
  113. package/dist/components/blocks/text/edge-seat.d.ts +17 -26
  114. package/dist/components/blocks/text/edge-seat.js +43 -70
  115. package/dist/components/blocks/text/link-at-point.d.ts +9 -9
  116. package/dist/components/blocks/text/link-at-point.js +12 -15
  117. package/dist/components/blocks/text/live-join-seam.d.ts +6 -9
  118. package/dist/components/blocks/text/live-join-seam.js +75 -112
  119. package/dist/components/blocks/text/live-selection-edit.d.ts +14 -43
  120. package/dist/components/blocks/text/live-selection-edit.js +32 -108
  121. package/dist/components/blocks/text/live-split-rebalance.d.ts +9 -13
  122. package/dist/components/blocks/text/live-split-rebalance.js +50 -67
  123. package/dist/components/blocks/text/marker-completion.d.ts +7 -12
  124. package/dist/components/blocks/text/marker-completion.js +17 -10
  125. package/dist/components/blocks/text/pending-mark-insert.d.ts +11 -18
  126. package/dist/components/blocks/text/pending-mark-insert.js +30 -49
  127. package/dist/components/blocks/text/screen-diff.d.ts +5 -15
  128. package/dist/components/blocks/text/screen-diff.js +5 -19
  129. package/dist/components/blocks/text/text-clipboard.d.ts +23 -32
  130. package/dist/components/blocks/text/text-clipboard.js +27 -32
  131. package/dist/components/blocks/text/text-keydown.d.ts +20 -30
  132. package/dist/components/blocks/text/text-keydown.js +54 -51
  133. package/dist/components/blocks/text/text-render.d.ts +25 -35
  134. package/dist/components/blocks/text/text-render.js +82 -61
  135. package/dist/components/blocks/text/widget-adjacency.d.ts +9 -9
  136. package/dist/components/blocks/text/widget-adjacency.js +17 -17
  137. package/dist/components/blocks/text/widget-interaction.d.ts +67 -43
  138. package/dist/components/blocks/text/widget-interaction.js +212 -199
  139. package/dist/components/blocks/widget-portal.d.ts +20 -29
  140. package/dist/components/blocks/widget-portal.js +16 -14
  141. package/dist/components/built-in-blocks.d.ts +3 -4
  142. package/dist/components/built-in-blocks.js +17 -18
  143. package/dist/components/drag-handle.d.ts +12 -35
  144. package/dist/components/drag-handle.js +22 -68
  145. package/dist/components/editor-built-ins.d.ts +1 -0
  146. package/dist/components/editor-built-ins.js +16 -0
  147. package/dist/components/editor-root-clipboard.d.ts +6 -6
  148. package/dist/components/editor-root-clipboard.js +16 -27
  149. package/dist/components/editor-root-document-swap.d.ts +49 -0
  150. package/dist/components/editor-root-document-swap.js +54 -0
  151. package/dist/components/editor-root-focus.d.ts +5 -4
  152. package/dist/components/editor-root-focus.js +51 -22
  153. package/dist/components/editor-root-focused-surface.d.ts +35 -0
  154. package/dist/components/editor-root-focused-surface.js +65 -0
  155. package/dist/components/editor-root-geometry.d.ts +15 -24
  156. package/dist/components/editor-root-geometry.js +27 -31
  157. package/dist/components/editor-root-gestures.d.ts +39 -0
  158. package/dist/components/editor-root-gestures.js +189 -0
  159. package/dist/components/editor-root-keydown.d.ts +10 -25
  160. package/dist/components/editor-root-keydown.js +19 -43
  161. package/dist/components/editor-root-listeners.d.ts +22 -24
  162. package/dist/components/editor-root-listeners.js +49 -24
  163. package/dist/components/editor-root-menus.d.ts +51 -0
  164. package/dist/components/editor-root-menus.js +147 -0
  165. package/dist/components/editor-root-mode-flip.d.ts +16 -11
  166. package/dist/components/editor-root-mode-flip.js +36 -34
  167. package/dist/components/editor-root-scroll-host.d.ts +22 -0
  168. package/dist/components/editor-root-scroll-host.js +34 -0
  169. package/dist/components/editor-root-test-surface.d.ts +48 -0
  170. package/dist/components/editor-root-test-surface.js +6 -0
  171. package/dist/components/image/ImageOverlayHost.svelte +44 -35
  172. package/dist/components/image/ImageOverlayHost.svelte.d.ts +5 -6
  173. package/dist/components/image/ImageProperties.svelte +37 -41
  174. package/dist/components/image/ImageProperties.svelte.d.ts +9 -4
  175. package/dist/components/image/ImageResizeHandles.svelte +14 -26
  176. package/dist/components/image/image-crop.d.ts +5 -11
  177. package/dist/components/image/image-crop.js +5 -11
  178. package/dist/components/image/image-edit-commit.d.ts +19 -16
  179. package/dist/components/image/image-edit-commit.js +74 -38
  180. package/dist/components/image/image-resize.d.ts +2 -5
  181. package/dist/components/image/image-resize.js +3 -6
  182. package/dist/components/image/image-widget-editing.d.ts +3 -3
  183. package/dist/components/image/image-widget-editing.js +9 -9
  184. package/dist/components/image/widget-dom.d.ts +2 -3
  185. package/dist/components/image/widget-dom.js +19 -24
  186. package/dist/components/image/widget-selection-state.svelte.d.ts +10 -11
  187. package/dist/components/image/widget-selection-state.svelte.js +26 -19
  188. package/dist/components/kind-cue.svelte.d.ts +21 -0
  189. package/dist/components/kind-cue.svelte.js +35 -0
  190. package/dist/components/link-card/LinkCard.svelte +115 -64
  191. package/dist/components/link-card/LinkCard.svelte.d.ts +7 -5
  192. package/dist/components/link-card/LinkCardHost.svelte +42 -33
  193. package/dist/components/link-card/LinkCardHost.svelte.d.ts +10 -8
  194. package/dist/components/link-card/link-card-commit.d.ts +16 -19
  195. package/dist/components/link-card/link-card-commit.js +21 -30
  196. package/dist/components/link-card/link-card-entry.d.ts +13 -23
  197. package/dist/components/link-card/link-card-entry.js +16 -24
  198. package/dist/components/link-card/link-card-state.svelte.d.ts +17 -21
  199. package/dist/components/link-card/link-card-state.svelte.js +2 -2
  200. package/dist/components/lrd-map-gate.d.ts +4 -11
  201. package/dist/components/lrd-map-gate.js +5 -11
  202. package/dist/components/menu/BlockMenu.svelte +20 -81
  203. package/dist/components/menu/BlockMenu.svelte.d.ts +11 -9
  204. package/dist/components/menu/InlineMenuHost.svelte +191 -0
  205. package/dist/components/menu/InlineMenuHost.svelte.d.ts +13 -0
  206. package/dist/components/menu/MenuIcon.svelte +3 -103
  207. package/dist/components/menu/MenuIcon.svelte.d.ts +2 -44
  208. package/dist/components/menu/SelectionToolbar.svelte +30 -35
  209. package/dist/components/menu/SelectionToolbar.svelte.d.ts +3 -5
  210. package/dist/components/menu/clipboard-actions.d.ts +3 -4
  211. package/dist/components/menu/clipboard-actions.js +3 -4
  212. package/dist/components/menu/default-context-actions.d.ts +4 -13
  213. package/dist/components/menu/default-context-actions.js +49 -67
  214. package/dist/components/menu/flyout-placement.d.ts +2 -2
  215. package/dist/components/menu/flyout-placement.js +2 -2
  216. package/dist/components/menu/menu-presence.svelte.d.ts +12 -0
  217. package/dist/components/menu/menu-presence.svelte.js +19 -0
  218. package/dist/components/paste-image-arm.d.ts +6 -11
  219. package/dist/components/paste-image-arm.js +11 -18
  220. package/dist/components/portal.d.ts +2 -5
  221. package/dist/components/portal.js +4 -7
  222. package/dist/core/directive/activate.d.ts +4 -5
  223. package/dist/core/directive/activate.js +8 -9
  224. package/dist/core/directive/container-opener.js +13 -12
  225. package/dist/core/directive/grammar.d.ts +2 -5
  226. package/dist/core/directive/grammar.js +10 -10
  227. package/dist/core/directive/kinds.d.ts +4 -7
  228. package/dist/core/directive/kinds.js +14 -16
  229. package/dist/core/directive/registry.d.ts +12 -9
  230. package/dist/core/directive/registry.js +19 -20
  231. package/dist/core/directive/text-recognizer.d.ts +3 -2
  232. package/dist/core/directive/text-recognizer.js +5 -9
  233. package/dist/core/escapable.d.ts +1 -5
  234. package/dist/core/escapable.js +1 -5
  235. package/dist/core/inline/backticks.d.ts +3 -4
  236. package/dist/core/inline/backticks.js +3 -4
  237. package/dist/core/inline/character-refs.js +2 -1
  238. package/dist/core/inline/destination-bytes.d.ts +6 -3
  239. package/dist/core/inline/destination-bytes.js +50 -8
  240. package/dist/core/inline/entity-widget.d.ts +4 -3
  241. package/dist/core/inline/entity-widget.js +6 -6
  242. package/dist/core/inline/format-toggle.d.ts +22 -28
  243. package/dist/core/inline/format-toggle.js +97 -129
  244. package/dist/core/inline/html-entities.d.ts +2 -3
  245. package/dist/core/inline/html-entities.js +2 -3
  246. package/dist/core/inline/html-tag-grammar.js +6 -2
  247. package/dist/core/inline/image-dimensions.d.ts +2 -0
  248. package/dist/core/inline/image-dimensions.js +19 -2
  249. package/dist/core/inline/image-source-bytes.d.ts +11 -0
  250. package/dist/core/inline/image-source-bytes.js +71 -0
  251. package/dist/core/inline/index.d.ts +28 -21
  252. package/dist/core/inline/index.js +56 -34
  253. package/dist/core/inline/inline-cache.d.ts +12 -15
  254. package/dist/core/inline/inline-cache.js +11 -14
  255. package/dist/core/inline/inline-widgets.d.ts +54 -75
  256. package/dist/core/inline/inline-widgets.js +54 -62
  257. package/dist/core/inline/link-destination.d.ts +31 -0
  258. package/dist/core/inline/link-destination.js +129 -0
  259. package/dist/core/inline/link-reference-resolver.d.ts +8 -6
  260. package/dist/core/inline/link-reference-resolver.js +10 -6
  261. package/dist/core/inline/link-source-bytes.d.ts +31 -0
  262. package/dist/{components/blocks/text → core/inline}/link-source-bytes.js +43 -54
  263. package/dist/core/inline/live-edit/read-back.d.ts +29 -0
  264. package/dist/core/inline/live-edit/read-back.js +50 -0
  265. package/dist/core/inline/picture.d.ts +10 -0
  266. package/dist/core/inline/picture.js +40 -0
  267. package/dist/core/inline/scan/autolinks.d.ts +7 -8
  268. package/dist/core/inline/scan/autolinks.js +80 -59
  269. package/dist/core/inline/scan/brackets.d.ts +2 -2
  270. package/dist/core/inline/scan/brackets.js +6 -103
  271. package/dist/core/inline/scan/code-spans.d.ts +4 -0
  272. package/dist/core/inline/scan/code-spans.js +8 -0
  273. package/dist/core/inline/scan/emphasis.js +10 -14
  274. package/dist/core/inline/scan/index.d.ts +3 -1
  275. package/dist/core/inline/scan/index.js +32 -33
  276. package/dist/core/inline/scan/plugin-syntax.d.ts +28 -36
  277. package/dist/core/inline/scan/plugin-syntax.js +75 -89
  278. package/dist/core/inline/scan/scan-state.d.ts +2 -0
  279. package/dist/core/inline/scan/scan-state.js +1 -0
  280. package/dist/core/inline/scan/simple-nodes.d.ts +2 -5
  281. package/dist/core/inline/scan/simple-nodes.js +2 -5
  282. package/dist/core/inline/scan/triggers.d.ts +17 -0
  283. package/dist/core/inline/scan/triggers.js +26 -0
  284. package/dist/core/inline/scan/url.js +8 -10
  285. package/dist/core/inline/transparency.d.ts +2 -1
  286. package/dist/core/inline/transparency.js +31 -15
  287. package/dist/core/inline/visibility.d.ts +30 -49
  288. package/dist/core/inline/visibility.js +31 -49
  289. package/dist/core/inline/walk.d.ts +4 -10
  290. package/dist/core/inline/walk.js +4 -10
  291. package/dist/core/inline-render.d.ts +22 -27
  292. package/dist/core/inline-render.js +51 -60
  293. package/dist/core/lines.d.ts +67 -26
  294. package/dist/core/lines.js +164 -33
  295. package/dist/core/metadata-parity.d.ts +9 -0
  296. package/dist/core/metadata-parity.js +25 -0
  297. package/dist/core/node-views.d.ts +7 -6
  298. package/dist/core/node-views.js +5 -5
  299. package/dist/core/nodes.d.ts +34 -44
  300. package/dist/core/nodes.js +4 -12
  301. package/dist/core/parser.d.ts +27 -34
  302. package/dist/core/parser.js +53 -67
  303. package/dist/core/parsers/blockquote.d.ts +5 -8
  304. package/dist/core/parsers/blockquote.js +11 -10
  305. package/dist/core/parsers/built-in-openers.d.ts +2 -5
  306. package/dist/core/parsers/built-in-openers.js +5 -8
  307. package/dist/core/parsers/fence-syntax.d.ts +36 -7
  308. package/dist/core/parsers/fence-syntax.js +61 -11
  309. package/dist/core/parsers/fenced-code.d.ts +16 -0
  310. package/dist/core/parsers/fenced-code.js +16 -15
  311. package/dist/core/parsers/heading.d.ts +19 -2
  312. package/dist/core/parsers/heading.js +50 -2
  313. package/dist/core/parsers/html-block.d.ts +3 -6
  314. package/dist/core/parsers/html-block.js +10 -11
  315. package/dist/core/parsers/indented-code.d.ts +1 -1
  316. package/dist/core/parsers/indented-code.js +2 -8
  317. package/dist/core/parsers/link-reference.d.ts +5 -3
  318. package/dist/core/parsers/link-reference.js +116 -120
  319. package/dist/core/parsers/list.d.ts +12 -5
  320. package/dist/core/parsers/list.js +53 -36
  321. package/dist/core/parsers/paragraph.d.ts +3 -3
  322. package/dist/core/parsers/paragraph.js +14 -5
  323. package/dist/core/parsers/table-completion.d.ts +2 -5
  324. package/dist/core/parsers/table-completion.js +7 -10
  325. package/dist/core/parsers/table.d.ts +8 -8
  326. package/dist/core/parsers/table.js +23 -26
  327. package/dist/core/parsers/thematic-break.js +15 -14
  328. package/dist/core/paths.d.ts +13 -0
  329. package/dist/core/paths.js +31 -0
  330. package/dist/core/terminator-escalation.d.ts +0 -7
  331. package/dist/core/terminator-escalation.js +5 -8
  332. package/dist/core/url-policy.d.ts +2 -5
  333. package/dist/core/url-policy.js +8 -12
  334. package/dist/cursor/caret-memory.d.ts +34 -0
  335. package/dist/cursor/caret-memory.js +82 -0
  336. package/dist/cursor/coordinate-spaces.d.ts +26 -19
  337. package/dist/cursor/coordinate-spaces.js +32 -20
  338. package/dist/cursor/dom-walk.d.ts +7 -13
  339. package/dist/cursor/dom-walk.js +7 -13
  340. package/dist/cursor/edge-affinity.d.ts +7 -35
  341. package/dist/cursor/edge-affinity.js +13 -44
  342. package/dist/cursor/focused-caret.d.ts +6 -8
  343. package/dist/cursor/focused-caret.js +7 -16
  344. package/dist/cursor/height-model.d.ts +3 -3
  345. package/dist/cursor/height-model.js +5 -5
  346. package/dist/cursor/height-oracle.d.ts +10 -6
  347. package/dist/cursor/height-oracle.js +26 -74
  348. package/dist/cursor/observe-resize.d.ts +13 -0
  349. package/dist/cursor/observe-resize.js +43 -0
  350. package/dist/cursor/overlay-rects.d.ts +2 -5
  351. package/dist/cursor/overlay-rects.js +2 -5
  352. package/dist/cursor/overlay-remeasure.d.ts +6 -7
  353. package/dist/cursor/overlay-remeasure.js +10 -14
  354. package/dist/cursor/pending-marks.d.ts +7 -9
  355. package/dist/cursor/pending-marks.js +6 -27
  356. package/dist/cursor/point-offset.d.ts +16 -10
  357. package/dist/cursor/point-offset.js +60 -25
  358. package/dist/cursor/reveal-source.d.ts +7 -11
  359. package/dist/cursor/reveal-source.js +10 -18
  360. package/dist/cursor/scroll-ancestors.d.ts +9 -20
  361. package/dist/cursor/scroll-ancestors.js +14 -26
  362. package/dist/cursor/scroll-owner.d.ts +92 -0
  363. package/dist/cursor/scroll-owner.js +283 -0
  364. package/dist/cursor/scrollport.d.ts +14 -15
  365. package/dist/cursor/scrollport.js +7 -13
  366. package/dist/cursor/sticky-column.d.ts +6 -29
  367. package/dist/cursor/sticky-column.js +6 -49
  368. package/dist/cursor/sticky-measure.d.ts +14 -9
  369. package/dist/cursor/sticky-measure.js +99 -49
  370. package/dist/cursor/surface-backend.d.ts +41 -0
  371. package/dist/cursor/surface-backend.js +78 -0
  372. package/dist/cursor/typography-estimates.d.ts +3 -3
  373. package/dist/cursor/typography-estimates.js +3 -3
  374. package/dist/cursor/visual-lines.d.ts +25 -14
  375. package/dist/cursor/visual-lines.js +45 -46
  376. package/dist/cursor/widget-edge-snap.d.ts +10 -15
  377. package/dist/cursor/widget-edge-snap.js +13 -12
  378. package/dist/cursor/widget-offset.d.ts +110 -104
  379. package/dist/cursor/widget-offset.js +344 -179
  380. package/dist/debug/diagnostics-report.d.ts +6 -6
  381. package/dist/debug/diagnostics-report.js +5 -5
  382. package/dist/debug/dump-tree.js +2 -2
  383. package/dist/debug/editor-diagnostics.d.ts +15 -0
  384. package/dist/debug/editor-diagnostics.js +33 -0
  385. package/dist/debug/inspect.d.ts +2 -2
  386. package/dist/debug/inspect.js +4 -4
  387. package/dist/debug/interaction-trace.d.ts +14 -15
  388. package/dist/debug/interaction-trace.js +19 -20
  389. package/dist/debug/operations-log.d.ts +1 -1
  390. package/dist/debug/operations-log.js +1 -1
  391. package/dist/decorations/buckets.d.ts +6 -12
  392. package/dist/decorations/buckets.js +4 -11
  393. package/dist/decorations/decoration-state.svelte.d.ts +2 -3
  394. package/dist/decorations/decoration-state.svelte.js +24 -26
  395. package/dist/decorations/island-dom.d.ts +10 -18
  396. package/dist/decorations/island-dom.js +25 -50
  397. package/dist/decorations/reserved-attrs.d.ts +6 -8
  398. package/dist/decorations/reserved-attrs.js +30 -17
  399. package/dist/decorations/types.d.ts +6 -7
  400. package/dist/decorations/types.js +2 -1
  401. package/dist/decorations/use-block-decorations.svelte.d.ts +19 -0
  402. package/dist/decorations/use-block-decorations.svelte.js +71 -0
  403. package/dist/decorations/widget-dom.d.ts +3 -3
  404. package/dist/decorations/widget-dom.js +5 -5
  405. package/dist/dev-warn.d.ts +5 -2
  406. package/dist/dev-warn.js +16 -4
  407. package/dist/editor-actions/ancestry-folds.d.ts +9 -14
  408. package/dist/editor-actions/ancestry-folds.js +13 -18
  409. package/dist/editor-actions/block-edit-core.d.ts +49 -22
  410. package/dist/editor-actions/block-edit-core.js +279 -151
  411. package/dist/editor-actions/block-edit-scope.d.ts +63 -50
  412. package/dist/editor-actions/block-edit-scope.js +100 -48
  413. package/dist/editor-actions/block-edit.d.ts +2 -3
  414. package/dist/editor-actions/block-edit.js +14 -90
  415. package/dist/editor-actions/commit/history.d.ts +4 -4
  416. package/dist/editor-actions/commit/history.js +33 -34
  417. package/dist/editor-actions/commit/reading-write-gate.d.ts +18 -0
  418. package/dist/editor-actions/commit/reading-write-gate.js +56 -0
  419. package/dist/editor-actions/commit/text-batch.d.ts +7 -11
  420. package/dist/editor-actions/commit/text-batch.js +6 -7
  421. package/dist/editor-actions/commit/undo-controller.d.ts +6 -4
  422. package/dist/editor-actions/commit/undo-controller.js +346 -216
  423. package/dist/editor-actions/container-block-component.d.ts +32 -51
  424. package/dist/editor-actions/container-block-component.js +66 -92
  425. package/dist/editor-actions/container-edit.d.ts +4 -2
  426. package/dist/editor-actions/container-edit.js +14 -44
  427. package/dist/editor-actions/container-exit-overrides.d.ts +6 -4
  428. package/dist/editor-actions/container-exit-overrides.js +19 -21
  429. package/dist/editor-actions/deps.d.ts +25 -32
  430. package/dist/editor-actions/enter-completion.d.ts +12 -15
  431. package/dist/editor-actions/enter-completion.js +49 -51
  432. package/dist/editor-actions/focus/focus-dispatch.d.ts +24 -25
  433. package/dist/editor-actions/focus/focus-dispatch.js +28 -50
  434. package/dist/editor-actions/focus/focus-landing.d.ts +8 -11
  435. package/dist/editor-actions/focus/focus-landing.js +15 -14
  436. package/dist/editor-actions/focus/focus.d.ts +3 -2
  437. package/dist/editor-actions/focus/focus.js +42 -59
  438. package/dist/editor-actions/index.d.ts +4 -3
  439. package/dist/editor-actions/index.js +5 -4
  440. package/dist/editor-actions/inline-range-commit.d.ts +18 -16
  441. package/dist/editor-actions/inline-range-commit.js +45 -54
  442. package/dist/editor-actions/leaf-write.d.ts +11 -0
  443. package/dist/editor-actions/leaf-write.js +102 -0
  444. package/dist/editor-actions/list-context.d.ts +9 -10
  445. package/dist/editor-actions/list-context.js +115 -110
  446. package/dist/editor-actions/list-overrides.d.ts +13 -5
  447. package/dist/editor-actions/list-overrides.js +36 -12
  448. package/dist/editor-actions/merge-fallback.d.ts +10 -16
  449. package/dist/editor-actions/merge-fallback.js +11 -22
  450. package/dist/editor-actions/nested/container-actions.d.ts +37 -0
  451. package/dist/editor-actions/nested/container-actions.js +42 -0
  452. package/dist/editor-actions/nested/emptied-container.d.ts +5 -0
  453. package/dist/editor-actions/nested/emptied-container.js +5 -0
  454. package/dist/editor-actions/nested/nested-actions.d.ts +22 -25
  455. package/dist/editor-actions/nested/nested-actions.js +17 -15
  456. package/dist/editor-actions/nested/nested-block-edit.d.ts +3 -4
  457. package/dist/editor-actions/nested/nested-block-edit.js +40 -134
  458. package/dist/editor-actions/nested/nested-focus.d.ts +2 -3
  459. package/dist/editor-actions/nested/nested-focus.js +33 -21
  460. package/dist/editor-actions/paste-coordinator.d.ts +3 -2
  461. package/dist/editor-actions/paste-coordinator.js +17 -13
  462. package/dist/editor-actions/plugin/chrome-leaf.d.ts +11 -9
  463. package/dist/editor-actions/plugin/chrome-leaf.js +14 -13
  464. package/dist/editor-actions/plugin/container.d.ts +54 -82
  465. package/dist/editor-actions/plugin/container.js +105 -188
  466. package/dist/editor-actions/plugin/directive-container.d.ts +4 -4
  467. package/dist/editor-actions/plugin/directive-container.js +7 -8
  468. package/dist/editor-actions/reorder-action.d.ts +7 -12
  469. package/dist/editor-actions/reorder-action.js +32 -48
  470. package/dist/editor-actions/reorder-drag.d.ts +12 -8
  471. package/dist/editor-actions/reorder-drag.js +45 -41
  472. package/dist/editor-actions/replacement-focus.d.ts +13 -21
  473. package/dist/editor-actions/replacement-focus.js +32 -33
  474. package/dist/editor-actions/search-replace.js +71 -67
  475. package/dist/editor-actions/stored-caret.d.ts +7 -0
  476. package/dist/editor-actions/stored-caret.js +10 -0
  477. package/dist/editor-actions/table-context.d.ts +9 -11
  478. package/dist/editor-actions/table-context.js +70 -93
  479. package/dist/editor-actions/unwrap-strategies.d.ts +4 -5
  480. package/dist/editor-actions/unwrap-strategies.js +52 -63
  481. package/dist/editor-actions/whole-block-focus-surface.d.ts +19 -28
  482. package/dist/editor-actions/whole-block-focus-surface.js +43 -53
  483. package/dist/editor-events.d.ts +25 -29
  484. package/dist/editor-events.js +17 -28
  485. package/dist/editor-keys.d.ts +96 -104
  486. package/dist/editor-keys.js +11 -24
  487. package/dist/editor-props.d.ts +88 -71
  488. package/dist/editor-rects.d.ts +23 -34
  489. package/dist/editor-rects.js +9 -77
  490. package/dist/env.d.ts +6 -4
  491. package/dist/env.js +8 -4
  492. package/dist/index.d.ts +6 -2
  493. package/dist/index.js +5 -2
  494. package/dist/inline-menu/inline-menu-session.d.ts +37 -0
  495. package/dist/inline-menu/inline-menu-session.js +98 -0
  496. package/dist/inline-menu/inline-menu-state.svelte.d.ts +63 -0
  497. package/dist/inline-menu/inline-menu-state.svelte.js +409 -0
  498. package/dist/inline-menu/types.d.ts +77 -0
  499. package/dist/inline-menu/types.js +7 -0
  500. package/dist/invariants/child-id-parity.d.ts +23 -0
  501. package/dist/invariants/child-id-parity.js +39 -0
  502. package/dist/invariants/commit-paths.d.ts +4 -4
  503. package/dist/invariants/commit-paths.js +4 -4
  504. package/dist/invariants/commit-scope.d.ts +4 -4
  505. package/dist/invariants/commit-scope.js +9 -8
  506. package/dist/invariants/context-keys.d.ts +2 -5
  507. package/dist/invariants/context-keys.js +3 -6
  508. package/dist/invariants/descriptor.d.ts +2 -6
  509. package/dist/invariants/descriptor.js +2 -6
  510. package/dist/invariants/inline-transitions.d.ts +9 -16
  511. package/dist/invariants/inline-transitions.js +10 -18
  512. package/dist/invariants/install.d.ts +18 -27
  513. package/dist/invariants/install.js +29 -30
  514. package/dist/invariants/keeps-a-block.d.ts +7 -0
  515. package/dist/invariants/keeps-a-block.js +14 -0
  516. package/dist/invariants/landable-caret.d.ts +5 -7
  517. package/dist/invariants/landable-caret.js +8 -11
  518. package/dist/invariants/landing-focus-scroll.d.ts +7 -0
  519. package/dist/invariants/landing-focus-scroll.js +13 -0
  520. package/dist/invariants/landing-value.d.ts +13 -0
  521. package/dist/invariants/landing-value.js +27 -0
  522. package/dist/invariants/marker-css-parity.d.ts +5 -6
  523. package/dist/invariants/marker-css-parity.js +11 -12
  524. package/dist/invariants/measures-in-own-list.d.ts +6 -0
  525. package/dist/invariants/measures-in-own-list.js +13 -0
  526. package/dist/invariants/node-shape.d.ts +18 -37
  527. package/dist/invariants/node-shape.js +123 -79
  528. package/dist/invariants/open-tail.d.ts +7 -0
  529. package/dist/invariants/open-tail.js +45 -0
  530. package/dist/invariants/placement-ends-widget.d.ts +8 -0
  531. package/dist/invariants/placement-ends-widget.js +13 -0
  532. package/dist/invariants/registry.d.ts +27 -66
  533. package/dist/invariants/registry.js +61 -137
  534. package/dist/invariants/render-fidelity.d.ts +4 -4
  535. package/dist/invariants/render-fidelity.js +5 -5
  536. package/dist/invariants/selection-endpoints.d.ts +6 -7
  537. package/dist/invariants/selection-endpoints.js +18 -16
  538. package/dist/invariants/single-node-sink.d.ts +4 -5
  539. package/dist/invariants/single-node-sink.js +4 -5
  540. package/dist/invariants/snapshot-integrity.d.ts +5 -6
  541. package/dist/invariants/snapshot-integrity.js +1 -1
  542. package/dist/invariants/structural-descriptor.d.ts +6 -15
  543. package/dist/invariants/structural-descriptor.js +6 -15
  544. package/dist/menu-icons.d.ts +47 -0
  545. package/dist/menu-icons.js +113 -0
  546. package/dist/perf/instruments.d.ts +20 -5
  547. package/dist/perf/instruments.js +35 -15
  548. package/dist/perf/use-mount-gauge.svelte.js +4 -4
  549. package/dist/plugin.d.ts +37 -8
  550. package/dist/plugin.js +100 -77
  551. package/dist/plugins/admonitions/AdmonitionBlock.svelte +14 -11
  552. package/dist/plugins/admonitions/admonition-kind.js +12 -10
  553. package/dist/plugins/admonitions/convert-document.d.ts +5 -5
  554. package/dist/plugins/admonitions/convert-document.js +8 -7
  555. package/dist/plugins/admonitions/gh-alert.d.ts +8 -1
  556. package/dist/plugins/admonitions/gh-alert.js +21 -22
  557. package/dist/plugins/admonitions/github-alert-kind.d.ts +5 -7
  558. package/dist/plugins/admonitions/github-alert-kind.js +28 -37
  559. package/dist/plugins/admonitions/index.js +2 -2
  560. package/dist/plugins/admonitions/kinds.d.ts +1 -1
  561. package/dist/plugins/admonitions/register.js +11 -2
  562. package/dist/plugins/details/DetailsBlock.svelte +20 -20
  563. package/dist/plugins/details/details-disclosure.svelte.d.ts +5 -6
  564. package/dist/plugins/details/details-disclosure.svelte.js +6 -7
  565. package/dist/plugins/details/details-kind.d.ts +6 -7
  566. package/dist/plugins/details/details-kind.js +44 -59
  567. package/dist/plugins/emoji/emoji-recognizer.d.ts +4 -7
  568. package/dist/plugins/emoji/emoji-recognizer.js +7 -14
  569. package/dist/plugins/footnotes/FootnoteDefinition.svelte +33 -16
  570. package/dist/plugins/footnotes/FootnoteReference.svelte +39 -19
  571. package/dist/plugins/footnotes/constants.d.ts +2 -0
  572. package/dist/plugins/footnotes/constants.js +3 -0
  573. package/dist/plugins/footnotes/footnote-definition.d.ts +8 -6
  574. package/dist/plugins/footnotes/footnote-definition.js +69 -45
  575. package/dist/plugins/footnotes/footnote-lookup.d.ts +3 -3
  576. package/dist/plugins/footnotes/footnote-lookup.js +14 -26
  577. package/dist/plugins/footnotes/footnote-numbering.d.ts +11 -11
  578. package/dist/plugins/footnotes/footnote-numbering.js +22 -31
  579. package/dist/plugins/footnotes/footnote-reference.d.ts +4 -4
  580. package/dist/plugins/footnotes/footnote-reference.js +8 -13
  581. package/dist/plugins/footnotes/index.js +2 -3
  582. package/dist/plugins/highlight-occurrences/highlight-occurrences-plugin.d.ts +5 -8
  583. package/dist/plugins/highlight-occurrences/highlight-occurrences-plugin.js +8 -3
  584. package/dist/plugins/highlight-occurrences/occurrence-source.d.ts +10 -12
  585. package/dist/plugins/highlight-occurrences/occurrence-source.js +21 -18
  586. package/dist/plugins/highlight-occurrences/occurrences.d.ts +11 -11
  587. package/dist/plugins/highlight-occurrences/occurrences.js +14 -36
  588. package/dist/plugins/highlight-occurrences/word-char.d.ts +1 -0
  589. package/dist/plugins/highlight-occurrences/word-char.js +4 -0
  590. package/dist/plugins/latex/BlockMath.svelte +58 -75
  591. package/dist/plugins/latex/BlockMath.svelte.d.ts +2 -4
  592. package/dist/plugins/latex/MathInline.svelte +10 -9
  593. package/dist/plugins/latex/flanking.d.ts +1 -0
  594. package/dist/plugins/latex/flanking.js +3 -0
  595. package/dist/plugins/latex/index.d.ts +1 -1
  596. package/dist/plugins/latex/latex-kind.d.ts +4 -4
  597. package/dist/plugins/latex/latex-kind.js +78 -67
  598. package/dist/plugins/latex/math-completion.d.ts +1 -1
  599. package/dist/plugins/latex/math-completion.js +5 -8
  600. package/dist/plugins/latex/math-layout.d.ts +2 -8
  601. package/dist/plugins/latex/math-layout.js +0 -9
  602. package/dist/plugins/latex/math-renderer.d.ts +17 -20
  603. package/dist/plugins/latex/math-renderer.js +21 -38
  604. package/dist/plugins/latex/math-source.d.ts +4 -8
  605. package/dist/plugins/latex/math-source.js +36 -81
  606. package/dist/plugins/latex/register.d.ts +10 -11
  607. package/dist/plugins/latex/register.js +24 -10
  608. package/dist/plugins/latex/renderer.d.ts +9 -10
  609. package/dist/plugins/latex/renderer.js +9 -24
  610. package/dist/plugins/mermaid/MermaidBlock.svelte +51 -45
  611. package/dist/plugins/mermaid/index.js +1 -1
  612. package/dist/plugins/mermaid/mermaid-kind.d.ts +4 -7
  613. package/dist/plugins/mermaid/mermaid-kind.js +30 -47
  614. package/dist/plugins/mermaid/mermaid-renderer.d.ts +9 -16
  615. package/dist/plugins/mermaid/mermaid-renderer.js +12 -31
  616. package/dist/plugins/mermaid/register.d.ts +3 -3
  617. package/dist/plugins/mermaid/register.js +5 -5
  618. package/dist/plugins/mermaid/renderer.d.ts +5 -5
  619. package/dist/plugins/mermaid/renderer.js +8 -11
  620. package/dist/plugins/parrot/ParrotBlock.svelte +15 -6
  621. package/dist/plugins/parrot/ParrotBlock.svelte.d.ts +2 -2
  622. package/dist/plugins/parrot/parrot-plugin.js +3 -3
  623. package/dist/plugins/slash-commands/filter.d.ts +23 -0
  624. package/dist/plugins/slash-commands/filter.js +31 -0
  625. package/dist/plugins/slash-commands/index.d.ts +2 -0
  626. package/dist/plugins/slash-commands/index.js +2 -0
  627. package/dist/plugins/slash-commands/slash-commands-plugin.d.ts +12 -0
  628. package/dist/plugins/slash-commands/slash-commands-plugin.js +40 -0
  629. package/dist/plugins/slash-commands/slash-source.d.ts +36 -0
  630. package/dist/plugins/slash-commands/slash-source.js +108 -0
  631. package/dist/plugins/toc/TocBlock.svelte +23 -22
  632. package/dist/plugins/toc/TocBlock.svelte.d.ts +2 -3
  633. package/dist/plugins/toc/heading-outline.d.ts +7 -12
  634. package/dist/plugins/toc/heading-outline.js +22 -36
  635. package/dist/plugins/toc/navigation-queue.d.ts +2 -4
  636. package/dist/plugins/toc/toc-plugin.d.ts +5 -5
  637. package/dist/plugins/toc/toc-plugin.js +20 -13
  638. package/dist/presentation-mode.d.ts +15 -23
  639. package/dist/presentation-mode.js +19 -25
  640. package/dist/reactivity/block-list-state.svelte.d.ts +9 -11
  641. package/dist/reactivity/block-list-state.svelte.js +8 -9
  642. package/dist/reactivity/block-window.svelte.d.ts +12 -6
  643. package/dist/reactivity/block-window.svelte.js +44 -17
  644. package/dist/reactivity/child-list.d.ts +34 -0
  645. package/dist/reactivity/child-list.js +48 -0
  646. package/dist/reactivity/content-version.svelte.d.ts +4 -7
  647. package/dist/reactivity/content-version.svelte.js +3 -5
  648. package/dist/reactivity/hold-across.d.ts +39 -0
  649. package/dist/reactivity/hold-across.js +57 -0
  650. package/dist/reactivity/layout-state.svelte.d.ts +27 -0
  651. package/dist/reactivity/layout-state.svelte.js +51 -0
  652. package/dist/reactivity/list-tree.d.ts +39 -0
  653. package/dist/reactivity/list-tree.js +132 -0
  654. package/dist/reactivity/list-windowing.svelte.d.ts +50 -71
  655. package/dist/reactivity/list-windowing.svelte.js +141 -310
  656. package/dist/reactivity/measure-batch.d.ts +6 -8
  657. package/dist/reactivity/measure-batch.js +5 -6
  658. package/dist/reactivity/publish-ref.svelte.d.ts +16 -41
  659. package/dist/reactivity/publish-ref.svelte.js +21 -85
  660. package/dist/reactivity/scope-geometry.d.ts +6 -13
  661. package/dist/reactivity/scope-geometry.js +7 -14
  662. package/dist/reactivity/state-registry.d.ts +5 -5
  663. package/dist/reactivity/state-registry.js +11 -15
  664. package/dist/reactivity/use-container-windowing.svelte.d.ts +13 -26
  665. package/dist/reactivity/use-container-windowing.svelte.js +64 -74
  666. package/dist/reactivity/use-measured-child.svelte.d.ts +10 -0
  667. package/dist/reactivity/use-measured-child.svelte.js +41 -0
  668. package/dist/reactivity/use-window-floor.svelte.d.ts +2 -0
  669. package/dist/reactivity/use-window-floor.svelte.js +27 -0
  670. package/dist/reactivity/window-slice.d.ts +4 -4
  671. package/dist/reactivity/window-slice.js +0 -2
  672. package/dist/renderer-slot.d.ts +48 -0
  673. package/dist/renderer-slot.js +85 -0
  674. package/dist/scan-index.d.ts +4 -4
  675. package/dist/scan-index.js +4 -4
  676. package/dist/schema/block-commands.d.ts +69 -54
  677. package/dist/schema/block-commands.js +91 -104
  678. package/dist/schema/block-completions.d.ts +16 -19
  679. package/dist/schema/block-completions.js +25 -32
  680. package/dist/schema/block-component-registry.d.ts +13 -14
  681. package/dist/schema/block-component-registry.js +19 -17
  682. package/dist/schema/block-kind-descriptor.d.ts +234 -168
  683. package/dist/schema/block-kind-descriptor.js +151 -66
  684. package/dist/schema/block-openers.d.ts +48 -39
  685. package/dist/schema/block-openers.js +73 -83
  686. package/dist/schema/built-in-descriptors.d.ts +3 -5
  687. package/dist/schema/built-in-descriptors.js +96 -80
  688. package/dist/schema/child-spans.d.ts +12 -10
  689. package/dist/schema/child-spans.js +68 -34
  690. package/dist/schema/closure.d.ts +18 -16
  691. package/dist/schema/closure.js +24 -14
  692. package/dist/schema/command-id.d.ts +6 -8
  693. package/dist/schema/command-id.js +20 -25
  694. package/dist/schema/commands.d.ts +78 -84
  695. package/dist/schema/commands.js +152 -117
  696. package/dist/schema/container-raw.d.ts +51 -11
  697. package/dist/schema/container-raw.js +143 -14
  698. package/dist/schema/container-rebuilders.d.ts +17 -15
  699. package/dist/schema/container-rebuilders.js +30 -22
  700. package/dist/schema/context-actions.d.ts +25 -13
  701. package/dist/schema/context-actions.js +32 -17
  702. package/dist/schema/define-plugin-block.d.ts +8 -6
  703. package/dist/schema/define-plugin-block.js +6 -4
  704. package/dist/schema/fenced-code-raw.d.ts +30 -17
  705. package/dist/schema/fenced-code-raw.js +155 -107
  706. package/dist/schema/global-commands.d.ts +6 -6
  707. package/dist/schema/global-commands.js +14 -22
  708. package/dist/schema/height-estimates.d.ts +31 -0
  709. package/dist/schema/height-estimates.js +64 -0
  710. package/dist/schema/inline-construct-policy.d.ts +42 -55
  711. package/dist/schema/inline-construct-policy.js +36 -35
  712. package/dist/schema/insert-catalogue.d.ts +30 -0
  713. package/dist/schema/insert-catalogue.js +95 -0
  714. package/dist/schema/keybinding-overrides.d.ts +9 -11
  715. package/dist/schema/keybinding-overrides.js +1 -1
  716. package/dist/schema/keybindings.d.ts +15 -7
  717. package/dist/schema/keybindings.js +21 -9
  718. package/dist/schema/merge-rules.d.ts +5 -7
  719. package/dist/schema/merge-rules.js +7 -9
  720. package/dist/schema/opener-priorities.d.ts +4 -4
  721. package/dist/schema/opener-priorities.js +4 -4
  722. package/dist/schema/operations.d.ts +8 -10
  723. package/dist/schema/operations.js +3 -3
  724. package/dist/schema/page-role.d.ts +14 -0
  725. package/dist/schema/page-role.js +19 -0
  726. package/dist/schema/plugin-activation.d.ts +4 -6
  727. package/dist/schema/plugin-activation.js +12 -10
  728. package/dist/schema/plugin-editor-context.d.ts +25 -10
  729. package/dist/schema/plugin-editor-context.js +40 -9
  730. package/dist/schema/plugin-install.d.ts +49 -17
  731. package/dist/schema/plugin-install.js +51 -25
  732. package/dist/schema/plugin-kind.d.ts +12 -8
  733. package/dist/schema/plugin-kind.js +35 -42
  734. package/dist/schema/plugin-name.js +3 -3
  735. package/dist/schema/plugin-registry.d.ts +54 -0
  736. package/dist/schema/plugin-registry.js +70 -0
  737. package/dist/schema/reading.d.ts +23 -0
  738. package/dist/schema/reading.js +7 -0
  739. package/dist/schema/register-once.d.ts +3 -5
  740. package/dist/schema/register-once.js +7 -16
  741. package/dist/schema/registration-checks.d.ts +12 -16
  742. package/dist/schema/registration-checks.js +35 -51
  743. package/dist/schema/registration-pairs.d.ts +54 -0
  744. package/dist/schema/registration-pairs.js +48 -0
  745. package/dist/schema/registration-pending.d.ts +8 -12
  746. package/dist/schema/registration-pending.js +9 -9
  747. package/dist/schema/registry-reset.d.ts +8 -4
  748. package/dist/schema/registry-reset.js +13 -26
  749. package/dist/schema/registry-view.d.ts +25 -13
  750. package/dist/schema/registry-view.js +26 -20
  751. package/dist/schema/reserved-chords.d.ts +9 -10
  752. package/dist/schema/reserved-chords.js +63 -80
  753. package/dist/schema/reserved-chrome.d.ts +12 -11
  754. package/dist/schema/reserved-chrome.js +15 -11
  755. package/dist/schema/setext-raw.d.ts +13 -0
  756. package/dist/schema/setext-raw.js +33 -0
  757. package/dist/schema/stored-as.d.ts +20 -0
  758. package/dist/schema/stored-as.js +6 -0
  759. package/dist/schema/table-cell-raw.d.ts +18 -7
  760. package/dist/schema/table-cell-raw.js +28 -7
  761. package/dist/schema/whole-block-unit.d.ts +5 -4
  762. package/dist/schema/whole-block-unit.js +5 -4
  763. package/dist/search/document-scan.d.ts +3 -3
  764. package/dist/search/document-scan.js +2 -2
  765. package/dist/search/matcher.d.ts +1 -1
  766. package/dist/search/regex-executor.d.ts +5 -6
  767. package/dist/search/regex-executor.js +6 -8
  768. package/dist/search/replace.d.ts +2 -5
  769. package/dist/search/replace.js +2 -5
  770. package/dist/search/search-state.svelte.d.ts +5 -5
  771. package/dist/search/search-state.svelte.js +12 -16
  772. package/dist/selection/autoscroll.d.ts +6 -9
  773. package/dist/selection/block-hit-test.d.ts +16 -24
  774. package/dist/selection/block-hit-test.js +29 -22
  775. package/dist/selection/caret-doors.d.ts +15 -14
  776. package/dist/selection/caret-doors.js +37 -26
  777. package/dist/selection/caret-landing.d.ts +62 -0
  778. package/dist/selection/caret-landing.js +157 -0
  779. package/dist/selection/caret-restore.d.ts +17 -10
  780. package/dist/selection/caret-restore.js +10 -22
  781. package/dist/selection/caret-target.d.ts +30 -0
  782. package/dist/selection/caret-target.js +84 -0
  783. package/dist/selection/char-endpoint-snap.d.ts +6 -10
  784. package/dist/selection/char-endpoint-snap.js +8 -14
  785. package/dist/selection/clipboard-text.d.ts +5 -12
  786. package/dist/selection/clipboard-text.js +69 -172
  787. package/dist/selection/covered-block.d.ts +6 -8
  788. package/dist/selection/covered-block.js +8 -19
  789. package/dist/selection/cross-block/clipboard.d.ts +3 -2
  790. package/dist/selection/cross-block/clipboard.js +13 -4
  791. package/dist/selection/cross-block/dispatch.d.ts +47 -43
  792. package/dist/selection/cross-block/dispatch.js +12 -23
  793. package/dist/selection/cross-block/format-range.d.ts +18 -21
  794. package/dist/selection/cross-block/format-range.js +104 -103
  795. package/dist/selection/cross-block/format-toggle.d.ts +10 -15
  796. package/dist/selection/cross-block/format-toggle.js +28 -33
  797. package/dist/selection/cross-block/keydown.d.ts +4 -4
  798. package/dist/selection/cross-block/keydown.js +92 -125
  799. package/dist/selection/cross-block/ops.d.ts +19 -34
  800. package/dist/selection/cross-block/ops.js +110 -95
  801. package/dist/selection/cross-block/paste.d.ts +2 -3
  802. package/dist/selection/cross-block/paste.js +59 -96
  803. package/dist/selection/cross-block/pointer.d.ts +17 -15
  804. package/dist/selection/cross-block/pointer.js +74 -25
  805. package/dist/selection/cross-block/type-replace.d.ts +4 -6
  806. package/dist/selection/cross-block/type-replace.js +51 -134
  807. package/dist/selection/dead-space-caret.d.ts +19 -30
  808. package/dist/selection/dead-space-caret.js +70 -88
  809. package/dist/selection/drag-pointer.d.ts +7 -9
  810. package/dist/selection/drag-pointer.js +23 -33
  811. package/dist/selection/gap-caret.d.ts +17 -28
  812. package/dist/selection/gap-caret.js +14 -26
  813. package/dist/selection/grid-selection.d.ts +12 -0
  814. package/dist/selection/grid-selection.js +22 -0
  815. package/dist/selection/keyboard-extend.d.ts +27 -40
  816. package/dist/selection/keyboard-extend.js +94 -117
  817. package/dist/selection/multi-click.d.ts +13 -18
  818. package/dist/selection/multi-click.js +32 -38
  819. package/dist/selection/native-bridge.d.ts +29 -39
  820. package/dist/selection/native-bridge.js +78 -127
  821. package/dist/selection/nearest-block.d.ts +17 -12
  822. package/dist/selection/nearest-block.js +37 -18
  823. package/dist/selection/path-lookup.d.ts +25 -16
  824. package/dist/selection/path-lookup.js +101 -18
  825. package/dist/selection/path-math.d.ts +9 -11
  826. package/dist/selection/path-math.js +5 -7
  827. package/dist/selection/pointer-gesture.d.ts +5 -5
  828. package/dist/selection/pointer-gesture.js +5 -5
  829. package/dist/selection/pointer-session.d.ts +10 -16
  830. package/dist/selection/pointer-session.js +6 -7
  831. package/dist/selection/primitives.d.ts +64 -40
  832. package/dist/selection/primitives.js +57 -67
  833. package/dist/selection/range-coverage.d.ts +94 -0
  834. package/dist/selection/range-coverage.js +365 -0
  835. package/dist/selection/range-delete-ceremony.d.ts +28 -74
  836. package/dist/selection/range-delete-ceremony.js +100 -141
  837. package/dist/selection/range-delete-chrome.d.ts +20 -33
  838. package/dist/selection/range-delete-chrome.js +53 -78
  839. package/dist/selection/range-delete-table-coverage.d.ts +11 -25
  840. package/dist/selection/range-delete-table-coverage.js +42 -112
  841. package/dist/selection/range-delete-table.d.ts +14 -12
  842. package/dist/selection/range-delete-table.js +106 -310
  843. package/dist/selection/range-delete.d.ts +18 -23
  844. package/dist/selection/range-delete.js +83 -123
  845. package/dist/selection/round-trip-restore.d.ts +18 -0
  846. package/dist/selection/round-trip-restore.js +19 -0
  847. package/dist/selection/selection-announcer.d.ts +17 -0
  848. package/dist/selection/selection-announcer.js +25 -0
  849. package/dist/selection/selection-description.d.ts +4 -3
  850. package/dist/selection/selection-description.js +5 -4
  851. package/dist/selection/selection-drop.d.ts +34 -16
  852. package/dist/selection/selection-drop.js +159 -95
  853. package/dist/selection/selection-restore.d.ts +20 -33
  854. package/dist/selection/selection-restore.js +21 -44
  855. package/dist/selection/selection-state.svelte.d.ts +50 -42
  856. package/dist/selection/selection-state.svelte.js +144 -98
  857. package/dist/selection/shared-keydown.d.ts +22 -27
  858. package/dist/selection/shared-keydown.js +25 -45
  859. package/dist/selection/table-endpoint-snap.d.ts +17 -41
  860. package/dist/selection/table-endpoint-snap.js +54 -80
  861. package/dist/selection/table-rect-extend.d.ts +3 -6
  862. package/dist/selection/table-rect-extend.js +19 -14
  863. package/dist/styles/editor-theme.css +60 -53
  864. package/dist/styles/editor.css +201 -143
  865. package/dist/testing/conformance-core.d.ts +50 -18
  866. package/dist/testing/conformance-core.js +88 -50
  867. package/dist/testing/container-conformance.d.ts +48 -84
  868. package/dist/testing/container-conformance.js +159 -285
  869. package/dist/testing/headless-actions.d.ts +34 -19
  870. package/dist/testing/headless-actions.js +116 -65
  871. package/dist/testing/headless-block-list.svelte.d.ts +16 -0
  872. package/dist/testing/headless-block-list.svelte.js +22 -0
  873. package/dist/testing/inline-conformance.d.ts +15 -22
  874. package/dist/testing/inline-conformance.js +131 -148
  875. package/dist/testing/kind-conformance.d.ts +19 -24
  876. package/dist/testing/kind-conformance.js +204 -117
  877. package/dist/testing/kit-reading.d.ts +7 -0
  878. package/dist/testing/kit-reading.js +16 -0
  879. package/dist/testing/mount-dom-stubs.d.ts +4 -5
  880. package/dist/testing/mount-dom-stubs.js +8 -5
  881. package/dist/testing/parse-convergence.d.ts +10 -10
  882. package/dist/testing/parse-convergence.js +14 -49
  883. package/dist/testing.d.ts +13 -9
  884. package/dist/testing.js +28 -38
  885. package/dist/tree-operations/blockquote.d.ts +8 -14
  886. package/dist/tree-operations/blockquote.js +25 -45
  887. package/dist/tree-operations/chain-rebuild.d.ts +34 -25
  888. package/dist/tree-operations/chain-rebuild.js +115 -52
  889. package/dist/tree-operations/children.d.ts +5 -9
  890. package/dist/tree-operations/children.js +7 -11
  891. package/dist/tree-operations/cleanup.d.ts +6 -7
  892. package/dist/tree-operations/cleanup.js +14 -11
  893. package/dist/tree-operations/clone.js +5 -4
  894. package/dist/tree-operations/container-lift.d.ts +10 -5
  895. package/dist/tree-operations/container-lift.js +20 -14
  896. package/dist/tree-operations/container-offsets.d.ts +22 -0
  897. package/dist/tree-operations/container-offsets.js +89 -0
  898. package/dist/tree-operations/content-write.d.ts +52 -29
  899. package/dist/tree-operations/content-write.js +155 -110
  900. package/dist/tree-operations/index.d.ts +4 -4
  901. package/dist/tree-operations/index.js +4 -4
  902. package/dist/tree-operations/keep-one-block.d.ts +10 -0
  903. package/dist/tree-operations/keep-one-block.js +19 -0
  904. package/dist/tree-operations/leaf-range.d.ts +33 -0
  905. package/dist/tree-operations/leaf-range.js +67 -0
  906. package/dist/tree-operations/list/empty-check.d.ts +2 -3
  907. package/dist/tree-operations/list/empty-check.js +4 -4
  908. package/dist/tree-operations/list/exit-replacement.d.ts +4 -6
  909. package/dist/tree-operations/list/exit-replacement.js +4 -9
  910. package/dist/tree-operations/list/item-partition.d.ts +2 -2
  911. package/dist/tree-operations/list/item-partition.js +2 -2
  912. package/dist/tree-operations/list/list-builders.d.ts +18 -16
  913. package/dist/tree-operations/list/list-builders.js +59 -30
  914. package/dist/tree-operations/list/ordered-markers.d.ts +7 -16
  915. package/dist/tree-operations/list/ordered-markers.js +7 -16
  916. package/dist/tree-operations/list/reconcile-task.d.ts +16 -7
  917. package/dist/tree-operations/list/reconcile-task.js +80 -23
  918. package/dist/tree-operations/list/sublist-separator.d.ts +7 -7
  919. package/dist/tree-operations/list/sublist-separator.js +20 -27
  920. package/dist/tree-operations/list/task-paragraph.d.ts +25 -0
  921. package/dist/tree-operations/list/task-paragraph.js +54 -0
  922. package/dist/tree-operations/list/unwrap-merge.d.ts +8 -16
  923. package/dist/tree-operations/list/unwrap-merge.js +44 -79
  924. package/dist/tree-operations/node-ops.d.ts +30 -52
  925. package/dist/tree-operations/node-ops.js +152 -218
  926. package/dist/tree-operations/node-primitives.d.ts +44 -31
  927. package/dist/tree-operations/node-primitives.js +84 -60
  928. package/dist/tree-operations/open-tail.d.ts +25 -0
  929. package/dist/tree-operations/open-tail.js +100 -0
  930. package/dist/tree-operations/parse-block.d.ts +15 -2
  931. package/dist/tree-operations/parse-block.js +19 -4
  932. package/dist/tree-operations/paste/apply.d.ts +7 -8
  933. package/dist/tree-operations/paste/apply.js +33 -63
  934. package/dist/tree-operations/paste/body-write.d.ts +8 -6
  935. package/dist/tree-operations/paste/body-write.js +13 -14
  936. package/dist/tree-operations/paste/container-match.d.ts +7 -10
  937. package/dist/tree-operations/paste/container-match.js +76 -58
  938. package/dist/tree-operations/paste/container-paste.d.ts +3 -3
  939. package/dist/tree-operations/paste/container-paste.js +3 -3
  940. package/dist/tree-operations/paste/dispatch.d.ts +26 -29
  941. package/dist/tree-operations/paste/dispatch.js +68 -53
  942. package/dist/tree-operations/paste/focus-target.d.ts +11 -14
  943. package/dist/tree-operations/paste/focus-target.js +13 -18
  944. package/dist/tree-operations/paste/hooks.d.ts +7 -12
  945. package/dist/tree-operations/paste/hooks.js +49 -46
  946. package/dist/tree-operations/paste/line-ending.d.ts +11 -0
  947. package/dist/tree-operations/paste/line-ending.js +32 -0
  948. package/dist/tree-operations/paste/list-absorb.d.ts +8 -11
  949. package/dist/tree-operations/paste/list-absorb.js +17 -19
  950. package/dist/tree-operations/paste/list-break-out.d.ts +12 -11
  951. package/dist/tree-operations/paste/list-break-out.js +24 -32
  952. package/dist/tree-operations/paste/parent-scope.d.ts +8 -12
  953. package/dist/tree-operations/paste/parent-scope.js +9 -16
  954. package/dist/tree-operations/paste/paste-deps.d.ts +14 -9
  955. package/dist/tree-operations/paste/paste-replacement.d.ts +20 -3
  956. package/dist/tree-operations/paste/paste-replacement.js +73 -42
  957. package/dist/tree-operations/paste/paste-transforms.d.ts +5 -7
  958. package/dist/tree-operations/paste/paste-transforms.js +18 -27
  959. package/dist/tree-operations/paste/replacement-parse.d.ts +9 -7
  960. package/dist/tree-operations/paste/replacement-parse.js +12 -10
  961. package/dist/tree-operations/paste/strategy.d.ts +1 -1
  962. package/dist/tree-operations/paste/strategy.js +1 -1
  963. package/dist/tree-operations/paste/table-slice.js +15 -10
  964. package/dist/tree-operations/paste-surfaces.d.ts +18 -29
  965. package/dist/tree-operations/paste-surfaces.js +14 -10
  966. package/dist/tree-operations/path-mutate.d.ts +7 -8
  967. package/dist/tree-operations/path-mutate.js +4 -4
  968. package/dist/tree-operations/reorder-unit.d.ts +4 -5
  969. package/dist/tree-operations/reorder-unit.js +5 -6
  970. package/dist/tree-operations/reorder.d.ts +7 -9
  971. package/dist/tree-operations/reorder.js +39 -40
  972. package/dist/tree-operations/settle.d.ts +42 -53
  973. package/dist/tree-operations/settle.js +241 -162
  974. package/dist/tree-operations/sharing.d.ts +5 -5
  975. package/dist/tree-operations/splice-many.d.ts +5 -5
  976. package/dist/tree-operations/splice-many.js +5 -5
  977. package/dist/tree-operations/stored-as.d.ts +13 -0
  978. package/dist/tree-operations/stored-as.js +48 -0
  979. package/dist/tree-operations/structural-change.d.ts +11 -15
  980. package/dist/tree-operations/structural-change.js +10 -14
  981. package/dist/tree-operations/structural-suffix.d.ts +22 -0
  982. package/dist/tree-operations/structural-suffix.js +61 -0
  983. package/dist/tree-operations/sub-table-copy.d.ts +7 -0
  984. package/dist/tree-operations/sub-table-copy.js +40 -36
  985. package/dist/tree-operations/table-grid-clipboard.d.ts +2 -7
  986. package/dist/tree-operations/table-grid-clipboard.js +11 -36
  987. package/dist/tree-operations/table-mutations.d.ts +7 -3
  988. package/dist/tree-operations/table-mutations.js +45 -9
  989. package/dist/tree-operations/unshare.d.ts +11 -15
  990. package/dist/tree-operations/unshare.js +15 -17
  991. package/dist/undo/manager.js +1 -1
  992. package/dist/undo/types.d.ts +2 -2
  993. package/docs/guide/consumer-guide.md +327 -205
  994. package/docs/guide/directives.md +7 -7
  995. package/docs/guide/plugin-api.md +253 -185
  996. package/docs/guide/plugin-guide.md +332 -235
  997. package/docs/guide/plugin-testing.md +96 -82
  998. package/package.json +12 -16
  999. package/dist/ambient/ambient-cursor.d.ts +0 -41
  1000. package/dist/ambient/ambient-cursor.js +0 -120
  1001. package/dist/components/blocks/code/code-paste.d.ts +0 -24
  1002. package/dist/components/blocks/code/code-paste.js +0 -21
  1003. package/dist/components/blocks/table/cell-clipboard.d.ts +0 -33
  1004. package/dist/components/blocks/table/cell-clipboard.js +0 -67
  1005. package/dist/components/blocks/text/hidden-suffix.d.ts +0 -10
  1006. package/dist/components/blocks/text/hidden-suffix.js +0 -15
  1007. package/dist/components/blocks/text/link-source-bytes.d.ts +0 -37
  1008. package/dist/components/image/image-source-bytes.d.ts +0 -15
  1009. package/dist/components/image/image-source-bytes.js +0 -80
  1010. package/dist/cursor/content-offsets.d.ts +0 -29
  1011. package/dist/cursor/content-offsets.js +0 -151
  1012. package/dist/cursor/reveal-anchor.d.ts +0 -30
  1013. package/dist/cursor/reveal-anchor.js +0 -31
  1014. package/dist/cursor/scroll-hold.d.ts +0 -10
  1015. package/dist/cursor/scroll-hold.js +0 -22
  1016. package/dist/invariants/split-landing.d.ts +0 -8
  1017. package/dist/invariants/split-landing.js +0 -15
  1018. package/dist/tree-operations/list/terminator.d.ts +0 -17
  1019. package/dist/tree-operations/list/terminator.js +0 -60
  1020. package/dist/tree-operations/paste/replace-block-at-parent.d.ts +0 -31
  1021. package/dist/tree-operations/paste/replace-block-at-parent.js +0 -78
@@ -1,14 +1,13 @@
1
1
  <script lang="ts">
2
2
  import { getContext, tick } from 'svelte';
3
- import type { BlockEditActions, TableContext } from '../../../action-contracts';
3
+ import type { ContentWrite, TableContext } from '../../../action-contracts';
4
4
  import { type BlockComponent } from '../../../block-component';
5
5
  import { type CommandId } from '../../../schema/commands';
6
- import { eventToChord } from '../../../schema/keybindings';
6
+ import { endsSelectAllRun } from '../../../schema/keybindings';
7
7
  import {
8
8
  createInlineFormatActiveMemo,
9
9
  toggleInlineFormat
10
10
  } from '../../../core/inline/format-toggle';
11
- import { paintsFocusedMarkers } from '../../../presentation-mode';
12
11
  import {
13
12
  inlineMarkForCommand,
14
13
  type InlineMarkKind
@@ -23,32 +22,35 @@
23
22
  type EditorPolicies,
24
23
  type EditorServices
25
24
  } from '../../../editor-keys';
26
- import type { TableAlignment } from '../../../core/nodes';
27
- import { trimTrailingLineEnding, normalizeLineEndings } from '../../../core/lines';
25
+ import type { AnyInlineKind, TableAlignment } from '../../../core/nodes';
26
+ import {
27
+ documentLineEnding,
28
+ normalizeLineEndings,
29
+ trimTrailingLineEnding
30
+ } from '../../../core/lines';
28
31
  import { pasteDispatch } from '../../../tree-operations/paste/dispatch';
29
- import { blockNodeAt, isBlockNode, nodeAt } from '../../../tree-operations/node-primitives';
30
- import { cutRangeFromDisplay } from '../../../tree-operations/node-ops';
32
+ import { blockNodeAt } from '../../../tree-operations/node-primitives';
33
+ import { replaceRangeInLeaf } from '../../../tree-operations/leaf-range';
34
+ import { storedAsAt } from '../../../tree-operations/stored-as';
35
+ import { keepsKindAt } from '../../../core/inline/live-edit/read-back';
31
36
  import { applyLiveRangeEdit } from '../text/live-selection-edit';
32
- import {
33
- gridToHtmlTable,
34
- parseClipboardGrid,
35
- tileGridTo
36
- } from '../../../tree-operations/table-grid-clipboard';
37
- import { tableCellCount } from '../../../selection/table-endpoint-snap';
37
+ import { parseClipboardGrid, tileGridTo } from '../../../tree-operations/table-grid-clipboard';
38
38
  import { pathsEqual } from '../../../selection/path-math';
39
39
  import { applyDelimiterAutoPair } from '../text/delimiter-autopair';
40
- import { hasSelection as hasSelectionHelper } from '../../../cursor/content-offsets';
41
40
  import { FALLBACK_CONTENT_WIDTH } from '../../../cursor/typography-estimates';
42
41
  import {
43
42
  rawTextOfNode,
44
43
  containerDomTextLength,
45
44
  landableDomTextBounds,
46
- createRangeAtDomTextOffsets,
47
45
  screenVisibilityOf,
48
- selectionFocusWalkOffset
46
+ rawSelectionFocus
49
47
  } from '../../../cursor/widget-offset';
50
- import { asRawOffset, toDomTextOffset, type RawOffset } from '../../../cursor/coordinate-spaces';
51
- import { createAmbientCursorIO } from '../../../ambient/ambient-cursor';
48
+ import {
49
+ asRawOffset,
50
+ rowMajorCellIndex,
51
+ type RawOffset
52
+ } from '../../../cursor/coordinate-spaces';
53
+ import { createSurfaceBackend } from '../../../cursor/surface-backend';
52
54
  import { getCurrentCursorEditorRelativeX } from '../../../cursor/sticky-measure';
53
55
  import { handleSharedKeydown, handleSharedBeforeInput } from '../../../selection/shared-keydown';
54
56
  import {
@@ -59,6 +61,7 @@
59
61
  } from '../editable-surface';
60
62
  import { wireSurfaceContexts, useParkFocusOnUnmount } from '../surface-wiring.svelte';
61
63
  import { resetForPointerDown } from '../../../selection/cross-block/pointer';
64
+ import type { PointerPressOptions } from '../../../selection/cross-block/dispatch';
62
65
  import { publishRefSlot, type RefSlots } from '../../../reactivity/publish-ref.svelte';
63
66
  import {
64
67
  selectWholeDocument,
@@ -69,13 +72,7 @@
69
72
  import { isAtFirstVisualLine, isAtLastVisualLine } from '../../../cursor/visual-lines';
70
73
  import { cellKeydownPlan, type CellKeyPlan, type CellKeyState } from './cell-keydown-plan';
71
74
  import { tableAxisCommand } from './cell-table-commands';
72
- import {
73
- intraTableRectPayload,
74
- intraTableRectBounds,
75
- intraTableRectGrid
76
- } from './cell-clipboard';
77
- import { escapedCellOffset } from './table-cell-paste';
78
- import type { CellSelectionPoint, SelectionPoint } from '../../../selection/primitives';
75
+ import { cellPoint } from '../../../selection/primitives';
79
76
  import type { ClipboardAction } from './table-menu-model';
80
77
  import {
81
78
  installCellDragListener,
@@ -84,6 +81,7 @@
84
81
  type CellAnchor
85
82
  } from './cell-pointer';
86
83
  import { createCellRender } from './cell-render';
84
+ import { useBlockDecorations } from '../../../decorations/use-block-decorations.svelte';
87
85
  import type { IndexedDecoration } from '../../../decorations/buckets';
88
86
  import type { ReplaceDecoration, WidgetDecoration } from '../../../decorations/types';
89
87
  import { createWidgetInteraction } from '../text/widget-interaction';
@@ -96,9 +94,6 @@
96
94
 
97
95
  type ExitDirection = 'up' | 'down';
98
96
 
99
- // The chord that continues a select-all run rather than ending it.
100
- const SELECT_ALL_CHORD = 'Mod+A';
101
-
102
97
  let {
103
98
  node,
104
99
  index,
@@ -119,152 +114,130 @@
119
114
  slots?: RefSlots<BlockComponent>;
120
115
  } = $props();
121
116
 
122
- // A cell's position among its row's children IS its column.
117
+ // A cell's position among its row's children is its column.
123
118
  const colIdx = $derived(index);
119
+ // A GFM table's first row is always its header.
120
+ const isHeaderRow = $derived(rowIdx === 0);
124
121
 
125
122
  const wiring = wireSurfaceContexts();
126
123
  const {
127
- blockEdit: parentBlockEdit,
124
+ blockEdit,
128
125
  focusActions,
129
126
  controller,
130
127
  pasteCoordinator,
131
- stickyColumn,
132
- edgeAffinity,
128
+ caretMemory,
133
129
  selection,
134
130
  getDoc,
135
131
  getBlockElByPath,
136
132
  getEditorRoot,
137
- grammar,
138
133
  activePlugins,
139
134
  events: editorEvents,
140
- linkRef
135
+ reading
141
136
  } = wiring.deps;
137
+ const { grammar } = reading;
138
+ // Made per gesture, never derived: a derived value would subscribe the cell to the tree.
139
+ const storedAs = () => storedAsAt(getDoc(), myPath, reading);
142
140
  const tableContext = getContext<TableContext>(TABLE_CONTEXT_KEY);
143
141
  const {
144
- pendingMarks,
142
+ autoPairs,
145
143
  widgetSelection,
146
144
  linkCard,
147
- reorder,
148
145
  rects,
149
- decorations: decorationEngine
146
+ decorations: decorationEngine,
147
+ rangeCoverage
150
148
  } = getContext<EditorServices>(EDITOR_SERVICES_KEY);
149
+ const ownPairs = autoPairs.forBlock();
151
150
  const {
152
- presentationMode: getPresentationMode,
153
151
  theme: getTheme,
154
152
  resolveLinkUrl,
155
153
  onPasteImage
156
154
  } = getContext<EditorPolicies>(EDITOR_POLICIES_KEY);
157
155
  const { contentVersion: getContentVersion, lifetime: editorLifetime } =
158
156
  getContext<EditorDoc>(EDITOR_DOC_KEY);
159
- const presentationMode = $derived(getPresentationMode?.() ?? 'source');
160
- const readOnly = $derived(presentationMode === 'reading');
157
+ const readOnly = $derived(reading.mode() === 'reading');
161
158
 
162
- // A constant fallback keeps an empty island set out of the render key.
159
+ // A shared constant keeps an empty decoration list out of the render key.
163
160
  const NO_ISLANDS: IndexedDecoration<WidgetDecoration | ReplaceDecoration>[] = [];
164
161
 
165
- // ── The cell's write door ───────────────────────────────────────────────
166
- //
167
- // Every write of this cell's raw goes through `blockEdit`; the escape is the kind's
168
- // (`normalizeRawWrite`, at the write sink). The caret half stays here: `caretAfter` addresses
169
- // the text the caller wrote, so the sink's backslashes move it; `caretBefore` addresses the
170
- // already-escaped pre-write bytes and stays unmapped.
171
- const blockEdit: BlockEditActions = {
172
- ...parentBlockEdit,
173
- updateBlockContent(i, text, caretBefore, caretAfter) {
174
- const cellText = trimTrailingLineEnding(text);
175
- return parentBlockEdit.updateBlockContent(
176
- i,
177
- cellText,
178
- caretBefore,
179
- caretAfter === undefined ? undefined : escapedCellOffset(cellText, caretAfter)
180
- );
181
- }
182
- };
183
-
184
162
  let el: HTMLDivElement | undefined = $state();
163
+
164
+ // The cell renders no block host, so its own element carries the decorations addressed to it.
165
+ const blockDecorations = useBlockDecorations({
166
+ getPath: () => myPath,
167
+ getEl: () => el ?? null,
168
+ engine: decorationEngine,
169
+ onRenderError: (error) => editorEvents?.emit('error', error),
170
+ badgeRefusal: "a table cell's children are its editable text, re-rendered on every edit"
171
+ });
172
+
185
173
  let composing = $state(false);
186
- // A revealed widget source is ephemeral DOM, so onInput skips the per-keystroke CST
187
- // commit and the cell commits once on reveal exit (mirrors TextEditableBlock).
174
+ // A widget's shown source lives only in the DOM, so `onInput` skips the per-keystroke CST
175
+ // commit and the cell commits once when it is hidden, as TextEditableBlock does.
188
176
  let revealing = $state(false);
189
177
  let pendingCursorOffset = $state<number | null>(null);
190
178
 
191
- // The door's other half, and the ONLY write of `pendingCursorOffset` besides the render
192
- // effect's clear. A pending cursor never passes through `blockEdit`, so the caller hands
193
- // over the text its offset addresses; no text means it already stands in escaped space.
194
- function parkCursor(offset: number | null, writtenText?: string): void {
195
- pendingCursorOffset =
196
- offset === null || writtenText === undefined
197
- ? offset
198
- : escapedCellOffset(writtenText, offset);
179
+ // The only writer of `pendingCursorOffset` besides the render's clear. The offset counts
180
+ // stored bytes, escapes included: a write hands back its caret already mapped.
181
+ function parkCursor(offset: number | null): void {
182
+ pendingCursorOffset = offset;
183
+ }
184
+
185
+ // A refused write landed no bytes, so it parks no caret.
186
+ function parkWrite(write: ContentWrite): void {
187
+ if (write.admitted) parkCursor(write.caret);
199
188
  }
200
189
 
201
- let preEditOffset = 0;
202
- // Y is load-bearing for the reveal hit-test: a column-aligned click on another
203
- // visual line must not reveal.
190
+ // Y matters for the hit test: a click at the same column on another visual line
191
+ // must not open a source.
204
192
  let lastClickClientX: number | null = null;
205
193
  let lastClickClientY: number | null = null;
206
194
 
207
- // Cells carry no ambient marker; at zero ambient the factory is plain widget-aware
208
- // raw-unit cursor IO (textContent math undercounts widget bytes).
209
- const cursor = createAmbientCursorIO({
210
- getEl: () => el ?? null,
211
- getAmbientLength: () => 0
195
+ const cursor = createSurfaceBackend({
196
+ getEl: () => el ?? null
212
197
  });
213
198
 
214
199
  const editableSurface = createEditableSurface({
215
200
  ...wiring.deps,
216
- // The wiring's blockEdit is the parent door; this surface writes through the
217
- // cell's escaping one above.
218
- blockEdit,
219
201
  getEl: () => el ?? null,
220
- getAmbientLength: () => 0,
221
202
  isInputSuppressed: () => revealing,
222
- backend: {
223
- getRaw: () => cursor.getRaw(),
224
- setRaw: (offset) => cursor.setRaw(offset),
225
- buildRange: (start, end) =>
226
- createRangeAtDomTextOffsets(el!, toDomTextOffset(start, 0), toDomTextOffset(end, 0))
227
- },
203
+ backend: cursor,
228
204
  getMyPath: () => myPath,
229
205
  getIndex: () => index,
230
206
  getComposing: () => composing,
231
207
  setComposing: (value) => {
232
208
  composing = value;
233
209
  },
234
- getPreEditOffset: () => preEditOffset,
235
- setPreEditOffset: (offset) => {
236
- preEditOffset = offset;
237
- },
238
210
  setPendingCursor: (offset) => parkCursor(offset),
239
- getPresentationMode,
240
211
  getFocusOffset: () => getRawFocusOffset(),
241
212
  getTextLen: () => (el ? containerDomTextLength(el) : 0),
242
213
  readText: () => readCellText(),
243
214
  relocateComposedText: (after, composedAt) => compositionSeat.relocate(after, composedAt),
244
- // `saved` re-focuses if the edit remounts the cell, so it is reported through
245
- // the door's escape.
246
215
  commitInput: (text, preEdit, saved) => {
247
- void blockEdit.updateBlockContent(index, text, preEdit, saved);
248
- return escapedCellOffset(text, saved);
249
- }
216
+ const write = blockEdit.updateBlockContent(index, text, 'authored', preEdit, saved);
217
+ return write.admitted ? write.caret : null;
218
+ },
219
+ handleBeforeInput: onBeforeInput
250
220
  });
251
221
 
252
- // The same seat the keydown dispatch takes, for the one insertion a keydown cannot reach.
222
+ // The same placement rules the keydown dispatch uses, for the one insertion it cannot reach.
253
223
  const compositionSeat = createCompositionSeat({
254
224
  getDisplayText: () => trimTrailingLineEnding(node.raw),
255
- getInlines: () => resolvedInlineContent(node, linkRef),
256
- getAffinity: () => edgeAffinity.get(),
225
+ getInlines: () => resolvedInlineContent(node, reading),
226
+ reading,
227
+ getAffinity: caretMemory.side,
257
228
  getScreen: () => screenVisibilityOf(el ?? null),
258
- consumePendingMarks: () => pendingMarks.consume(),
259
- restorePendingMarks: (marks) => pendingMarks.restore(marks)
229
+ consumePendingMarks: caretMemory.pendingMarks.consume,
230
+ restorePendingMarks: caretMemory.pendingMarks.restore
260
231
  });
261
232
 
262
233
  const crossBlock = editableSurface.crossBlock;
263
234
  const sharedCtx = editableSurface.sharedCtx;
264
235
 
265
- // The prose inline-widget seams, threaded with cell-shaped deps: zero ambient, no
266
- // snap overlay (cells render no image widgets), and the escaping blockEdit.
236
+ // The same inline-widget code prose uses, with cell-shaped dependencies: no marker prefix,
237
+ // no snap indicator, since cells render no image widgets.
267
238
  const widgetInteraction = createWidgetInteraction({
239
+ getLineEnding: () => documentLineEnding(getDoc()),
240
+ storedAs,
268
241
  get node() {
269
242
  return node;
270
243
  },
@@ -275,28 +248,30 @@
275
248
  return myPath;
276
249
  },
277
250
  getEl: () => el ?? null,
278
- getAmbientLength: () => 0,
279
251
  getEditorContentWidth: () => getEditorRoot()?.clientWidth ?? FALLBACK_CONTENT_WIDTH,
280
252
  cursor,
281
253
  widgetSelection,
282
254
  blockEdit,
283
255
  focusActions,
284
256
  setSnapTarget: () => {},
285
- setPendingCursor: (offset, writtenText) => parkCursor(offset, writtenText),
257
+ setPendingCursor: parkCursor,
286
258
  readRawText: () => readCellText(),
287
259
  setRevealing: (value) => {
288
260
  revealing = value;
289
261
  },
290
262
  isCrossBlock: () => selection.isCrossBlock,
291
- getPresentationMode,
292
- get linkRef() {
293
- return linkRef;
263
+ get reading() {
264
+ return reading;
294
265
  }
295
266
  });
296
267
 
297
- // The one caret-edge dispatch (G4.12), same seam prose uses: a plain edge key against
298
- // a CST widget or a decoration island resolves against its declarative policy.
268
+ // A widget's editing policy under this editor's grammar, the one the cell rendered with.
269
+ const widgetEditing = (kind: AnyInlineKind) => getInlineWidgetEditing(kind, grammar);
270
+
271
+ // The caret-edge dispatch prose uses, so an edge key against a CST or decoration widget
272
+ // resolves against its declared policy here too (G4.12).
299
273
  const edgeDispatch = createEdgePolicyDispatch({
274
+ getLineEnding: () => documentLineEnding(getDoc()),
300
275
  get node() {
301
276
  return node;
302
277
  },
@@ -306,42 +281,43 @@
306
281
  get containerParent() {
307
282
  return blockNodeAt(getDoc(), myPath.slice(0, -1));
308
283
  },
309
- get linkRef() {
310
- return linkRef;
284
+ get reading() {
285
+ return reading;
311
286
  },
312
287
  getEl: () => el ?? null,
313
- getAmbientLength: () => 0,
288
+ storedAs,
314
289
  hasIslands: () =>
315
290
  decorationEngine ? decorationEngine.islandsForPath(myPath).length > 0 : false,
316
291
  getRawSelection: () => cursor.getRawSelection(),
317
292
  blockEdit,
318
- setPendingCursor: (offset, _source, writtenText) => parkCursor(offset, writtenText),
293
+ setPendingCursor: parkCursor,
319
294
  setSnapTarget: () => {},
320
295
  isRevealing: () => widgetInteraction.isRevealing(),
321
- // A non-reveal widget reached through this seam is an ARROW's entry, so step the
322
- // caret over it like native contenteditable.
296
+ // A widget that cannot show its source, reached this way, was reached by an arrow
297
+ // key, so step the caret over it as contenteditable would.
323
298
  enterWidget: (widget, fromTrailingEdge) => {
324
- if (getInlineWidgetEditing(widget.kind)?.revealSource) {
299
+ if (widgetEditing(widget.kind)?.revealSource) {
325
300
  widgetInteraction.enterWidget(widget, fromTrailingEdge);
326
301
  } else {
327
- cursor.setRaw(asRawOffset(fromTrailingEdge ? widget.start : widget.end));
302
+ cursor.setRaw(asRawOffset(fromTrailingEdge ? widget.start : widget.end), {
303
+ clamp: 'reachable'
304
+ });
328
305
  }
329
306
  },
330
- // A cell paints no widget-selection overlay, so the prose select-then-delete default
331
- // would show nothing between the presses. Scoped to what the cell actually PAINTS as
332
- // a widget, and merged onto the registered policy rather than replacing it.
307
+ // A cell draws no selection outline around a widget, so a drawn widget deletes whole
308
+ // instead of being selected first; the registered policy is otherwise kept.
333
309
  widgetEdgePolicy: (widget) => {
334
- const registered = getInlineWidgetEditing(widget.kind);
310
+ const registered = widgetEditing(widget.kind);
335
311
  if (!el || registered?.revealSource) return undefined;
336
312
  return widgetElByStart(el, widget.start)
337
313
  ? { ...registered, deleteGranularity: 'atomic' }
338
314
  : undefined;
339
315
  },
340
316
  isReading: () => readOnly,
341
- getEdgeAffinity: () => edgeAffinity.get(),
342
- noteOutside: edgeAffinity.noteExtreme,
343
- pendingMarks,
344
- installedAs: 'cell'
317
+ getEdgeAffinity: caretMemory.side,
318
+ noteOutside: caretMemory.noteExtreme,
319
+ pendingMarks: caretMemory.pendingMarks,
320
+ ownPairs
345
321
  });
346
322
 
347
323
  // ── BlockComponent interface ────────────────────────────────────────
@@ -357,14 +333,13 @@
357
333
  export const setSelection = editableSurface.surface.setSelection;
358
334
  export const measurePartialRects = editableSurface.surface.measurePartialRects;
359
335
 
360
- /** The card's query for this cell. `range` is null at the chord's arm, where a create would
361
- * have to answer the pipe escapes in cell raw, and the live one at the pressed read. */
336
+ // The chord passes a null `range`, so a cell never creates a link; the pressed state passes
337
+ // the live selection.
362
338
  const linkCardQuery = (contentEl: HTMLElement, range: { start: number; end: number } | null) => ({
363
339
  contentEl,
364
340
  block: node,
365
341
  path: myPath,
366
- linkRef,
367
- mode: presentationMode,
342
+ reading,
368
343
  selection: range,
369
344
  crossBlockRange: selection.isCrossBlock
370
345
  });
@@ -372,8 +347,8 @@
372
347
  // A toolbar asks once per button on every selection change, so the buttons share the parse.
373
348
  const formatActive = createInlineFormatActiveMemo();
374
349
 
375
- // The pressed-state read: the same cell text and selection the toggle itself takes, and for
376
- // the card the same construct its own entry resolves.
350
+ // Whether a button shows as pressed: the same cell text and selection the toggle itself
351
+ // uses, and for the card the same construct its own entry resolves.
377
352
  export function isCommandActive(id: CommandId): boolean {
378
353
  if (!el) return false;
379
354
  const marked = inlineMarkForCommand(id);
@@ -385,57 +360,62 @@
385
360
  const selection = cursor.getRawSelection() ?? { start: caret, end: caret };
386
361
  const cellText = readCellText();
387
362
  return formatActive(
388
- { display: cellText, content: { start: 0, end: cellText.length }, selection },
363
+ { display: cellText, content: { start: 0, end: cellText.length }, selection, reading },
389
364
  marked.kind
390
365
  );
391
366
  }
392
367
 
393
- // Claims the chord even with no caret to act on: declining leaves Mod+B to the browser's
394
- // own contenteditable bold, an edit this surface never authored.
368
+ // Takes the chord even with no caret to act on: declining leaves Mod+B to the browser's
369
+ // own contenteditable bold, an edit this block never wrote.
395
370
  function toggleFormat(format: InlineMarkKind): boolean {
396
371
  if (!el) return true;
397
372
  const caret = cursor.getRaw();
398
- // A collapsed caret is the empty-pair contract, not a bail — see toggleInlineFormat.
373
+ // A collapsed caret is the empty-pair case, not a refusal; see `toggleInlineFormat`.
399
374
  const offsets =
400
375
  cursor.getRawSelection() ?? (caret === null ? null : { start: caret, end: caret });
401
376
  if (!offsets) return true;
402
- // Same fork as the prose surface, on the same question the toggle door asks: a surface
403
- // painting no delimiter would hold an abandoned empty pair as invisible garbage in the
404
- // cell's bytes (live-mode.md § 4.3).
405
- if (!paintsFocusedMarkers(presentationMode) && offsets.start === offsets.end) {
377
+ // A mode that draws no delimiter would keep an empty pair as invisible bytes, so the mark
378
+ // waits for the next insertion instead (live-mode.md § 4.3).
379
+ if (reading.hidesDelimitersAtCaret() && offsets.start === offsets.end) {
406
380
  controller.flushDebouncedCheckpoint();
407
- pendingMarks.toggle(format);
381
+ caretMemory.pendingMarks.toggle(format);
408
382
  return true;
409
383
  }
410
- // A cell has no markers of its own, so the whole read is content — taken from the DOM text
411
- // rather than `getContentRange(node)`, whose bytes carry the escapes the door writes.
384
+ // A cell has no markers of its own, so the whole read is content, taken from the DOM text
385
+ // rather than `getContentRange(node)`, whose bytes carry the escapes the write adds.
412
386
  const cellText = readCellText();
413
387
  const result = toggleInlineFormat(
414
- { display: cellText, content: { start: 0, end: cellText.length }, selection: offsets },
415
- format,
416
- presentationMode
388
+ {
389
+ display: cellText,
390
+ content: { start: 0, end: cellText.length },
391
+ selection: offsets,
392
+ reading
393
+ },
394
+ format
417
395
  );
418
396
  if (!result) return true;
419
- // Anchor undo at the live post-toggle caret: cross-block dispatch arrives with no
420
- // preceding onKeyDown, so `preEditOffset` would be stale (mirrors TextEditableBlock).
421
397
  // A command is not typing, so the toggle's bytes are their own undo step.
422
- controller.isolateUndoEntry(() =>
423
- blockEdit.updateBlockContent(index, result.newDisplay, result.newSelStart, result.newSelStart)
424
- );
425
- // The door may have inserted backslashes inside the toggled span, so both selection
426
- // edges are read back through the escape.
427
- const selStart = escapedCellOffset(result.newDisplay, result.newSelStart);
428
- const selEnd = escapedCellOffset(result.newDisplay, result.newSelEnd);
398
+ let write!: ContentWrite;
399
+ controller.isolateUndoEntry(() => {
400
+ write = blockEdit.updateBlockContent(
401
+ index,
402
+ result.newDisplay,
403
+ 'literal',
404
+ offsets.start,
405
+ result.newSelStart
406
+ );
407
+ });
408
+ if (!write.admitted) return true;
409
+ // The write may have escaped a pipe inside the toggled span, so the far edge moves too.
410
+ const selStart = write.caret;
411
+ const selEnd = write.storedOffset(result.newSelEnd);
429
412
  void tick().then(() => setSelection(selStart, selEnd));
430
413
  return true;
431
414
  }
432
415
 
433
- /**
434
- * The cell's mutation funnel. A live reveal holds this cell's bytes in ephemeral DOM the CST
435
- * has not seen, so a mutation would either splice the pre-reveal source or re-derive the whole
436
- * row from cell raws — dropping the edit. Fold, settle, then act.
437
- */
438
- function afterRevealFold(run: () => void): void {
416
+ // A shown source holds bytes the tree has not seen, so a command runs only after the source
417
+ // is hidden and its edit written.
418
+ export function afterSourceCommit(run: () => void): void {
439
419
  if (!widgetInteraction.isRevealing()) {
440
420
  run();
441
421
  return;
@@ -444,14 +424,14 @@
444
424
  void (fold?.settled ?? tick()).then(run);
445
425
  }
446
426
 
447
- /** One arm per command this cell owns, resolved BEFORE any fold so the fold sits between
448
- * resolution and mutation — the prose surface's split. Null declines the chord. */
427
+ /** One entry per command this cell owns, resolved before a shown source is hidden, so hiding
428
+ * fits between resolving and writing, as the prose block does. Null declines the chord. */
449
429
  function cellCommand(id: CommandId, contentEl: HTMLElement): (() => void) | null {
450
- // The format chords are rows: the construct that declares a mark names the command that
451
- // toggles it, so this surface grows a new one without an arm.
430
+ // The format chords come from the policy table: a construct that declares a mark names
431
+ // the command that toggles it, so a new one needs no branch here.
452
432
  const marked = inlineMarkForCommand(id);
453
433
  if (marked) return () => void toggleFormat(marked.kind);
454
- // Consumed whether or not it enters, the prose surface's rule on this surface too:
434
+ // Consumed whether or not a card opens, the same rule the prose block follows:
455
435
  // `reservedChords()` reports Mod+K as the editor's wherever the keymaps bind it.
456
436
  if (id === 'link.openCard') {
457
437
  return () => enterLinkCardAtCaret({ ...linkCardQuery(contentEl, null), card: linkCard });
@@ -461,16 +441,12 @@
461
441
  return () =>
462
442
  void tableContext[axisCommand.action](axisCommand.axis === 'row' ? rowIdx : colIdx);
463
443
  }
464
- // Moves the whole table: the reorder walk resolves the unit at the nearest ancestor
465
- // that reorders its children, which a table's grid rows are not.
466
- if (id === 'block.moveUp' || id === 'block.moveDown') {
467
- return () => void reorder.nudgeReorderUnit(myPath, id === 'block.moveUp' ? -1 : 1);
468
- }
469
444
  if (id !== 'cell.enter' && id !== 'cell.tab' && id !== 'cell.shiftTab') return null;
470
445
  const plan = cellKeydownPlan(
471
446
  {
472
447
  key: id === 'cell.enter' ? 'Enter' : 'Tab',
473
- ctrlOrMeta: false,
448
+ ctrlKey: false,
449
+ metaKey: false,
474
450
  shiftKey: id === 'cell.shiftTab',
475
451
  altKey: false
476
452
  },
@@ -480,19 +456,18 @@
480
456
  return () => void applyCellPlan(plan);
481
457
  }
482
458
 
483
- // Every chord the `tableCell` keymap binds arrives here, including from cross-block
484
- // dispatch, which carries no event — so the 'native'/'select-all-step' plans are
485
- // declined by the arm table and only the action plans run.
459
+ // Every `tableCell` keymap chord arrives here, some with no event behind them, so only the
460
+ // plans that act without one run.
486
461
  export function runCommand(id: CommandId): boolean {
487
462
  if (!el) return false;
488
463
  const perform = cellCommand(id, el);
489
464
  if (!perform) return false;
490
- afterRevealFold(perform);
465
+ afterSourceCommit(perform);
491
466
  return true;
492
467
  }
493
468
 
494
- // The ONE surface literal: the row mounts this cell with no `bind:this`, so the published slot
495
- // is the only channel a caller reaches it through — and the parity G4.38 scans.
469
+ // The row mounts this cell without `bind:this`, so this registered reference is the only way
470
+ // a caller reaches it (G4.38).
496
471
  $effect(() => {
497
472
  if (!slots) return;
498
473
  const self = {
@@ -506,6 +481,7 @@
506
481
  setSelection,
507
482
  measurePartialRects,
508
483
  runCommand,
484
+ afterSourceCommit,
509
485
  getSelectionOffsets,
510
486
  applyMenuClipboard,
511
487
  snapCaretToPoint,
@@ -523,13 +499,10 @@
523
499
  get node() {
524
500
  return node;
525
501
  },
526
- get linkRef() {
527
- return linkRef;
502
+ get reading() {
503
+ return reading;
528
504
  },
529
505
  resolveLinkUrl,
530
- get presentationMode() {
531
- return presentationMode;
532
- },
533
506
  getTheme,
534
507
  getDocument: () => getDoc(),
535
508
  getContentVersion,
@@ -549,7 +522,8 @@
549
522
  });
550
523
  if (pendingCursorOffset !== null) {
551
524
  consumePendingRestore(el, pendingCursorOffset, (offset) => {
552
- if (!widgetInteraction.revealInterior(offset)) cursor.setRaw(asRawOffset(offset));
525
+ if (!widgetInteraction.revealInterior(offset))
526
+ cursor.setRaw(asRawOffset(offset), { clamp: 'exact' });
553
527
  });
554
528
  pendingCursorOffset = null;
555
529
  }
@@ -559,8 +533,8 @@
559
533
 
560
534
  useParkFocusOnUnmount(() => el ?? null, getEditorRoot);
561
535
 
562
- // A selection move that leaves a revealed source but stays inside the cell folds the
563
- // reveal; blur owns the focus-leaving fold. Composition suppresses it like onInput.
536
+ // A selection move that leaves a shown source but stays inside the cell hides it; blur
537
+ // handles focus leaving the cell. A composition suppresses this as it does `onInput`.
564
538
  $effect(() => {
565
539
  const root = el;
566
540
  if (!root) return;
@@ -577,16 +551,15 @@
577
551
  return el ? rawTextOfNode(el, node.raw) : '';
578
552
  }
579
553
 
580
- // Zero-ambient cell: the walk offset IS the raw offset.
581
554
  function getRawFocusOffset(): RawOffset | null {
582
- return el ? selectionFocusWalkOffset(el, 0) : null;
555
+ return el ? rawSelectionFocus(el) : null;
583
556
  }
584
557
 
585
558
  // ── Event handlers ─────────────────────────────────────────────────────
586
559
 
587
560
  const onInput = editableSurface.onInput;
588
- // Captured before the surface's own handler: its cross-block half clears the affinity, and
589
- // the first mid-composition `input` re-arms it to the typed side.
561
+ // Captured before the shared handler: its cross-block half clears the arrival side, and the
562
+ // first `input` during the composition resets that side to the typed one.
590
563
  function onCompositionStart(): void {
591
564
  compositionSeat.noteStart();
592
565
  editableSurface.onCompositionStart();
@@ -597,12 +570,10 @@
597
570
  compositionSeat.noteEnd();
598
571
  }
599
572
 
600
- // Shared by the live keydown path and the cross-block dispatch entry, which differ
601
- // only in where the offset comes from; both guard `el` before calling.
573
+ // Callers guard `el` first.
602
574
  function cellPlanState(offset: number): CellKeyState {
603
- // Zero-ambient cell: the walk offsets ARE the raw offsets the plan compares. Deliberately
604
- // unguarded by mode, unlike the prose bounds — a cell's hop follows what is ON SCREEN, so
605
- // the bound tracks preview-inline's proximity reveal.
575
+ // A cell has no marker prefix, so these are raw offsets; they follow what is on screen,
576
+ // not the mode, since a cell's move follows what the user sees.
606
577
  const bounds = landableDomTextBounds(el!);
607
578
  return {
608
579
  rowIdx,
@@ -612,7 +583,7 @@
612
583
  offset,
613
584
  contentStart: bounds.start,
614
585
  contentEnd: bounds.end,
615
- collapsed: !hasSelectionHelper(),
586
+ collapsed: cursor.getRawSelection() === null,
616
587
  selectAllCount: selection.selectAllCount
617
588
  };
618
589
  }
@@ -620,21 +591,19 @@
620
591
  async function onKeyDown(e: KeyboardEvent): Promise<void> {
621
592
  if (composing || !el) return;
622
593
 
623
- // Ahead of the plan, in the shared prelude's position: the prelude's own reset is
624
- // reachable only on the 'native' arm, so every key the plan claims would leave the
625
- // select-all run armed. `eventToChord` declines bare modifiers and uppercases.
626
- const chord = eventToChord(e);
627
- if (chord !== null && chord !== SELECT_ALL_CHORD) selection.resetSelectAllCount();
594
+ // Reset before `cellKeydownPlan`: the shared reset runs only for keys the plan leaves to the
595
+ // browser, so a key the plan takes would leave the select-all run active.
596
+ if (endsSelectAllRun(e)) selection.resetSelectAllCount();
628
597
 
629
- // Must precede cellKeydownPlan, which claims arrows and preventDefaults without
630
- // reaching here — leaving a live selection the next keystroke would range-replace.
598
+ // Must run before `cellKeydownPlan`, which takes arrows and calls `preventDefault`
599
+ // without reaching here, leaving a live selection the next keystroke would replace.
631
600
  if (selection.isCrossBlock && (await crossBlock.handleKeyDown(e))) return;
632
601
 
633
- // Reveal/selection intercepts before the plan, which would otherwise read a
634
- // mid-reveal ArrowUp/Down as cell nav.
602
+ // The source-showing and selection handlers run before the plan, which would otherwise
603
+ // read an ArrowUp or ArrowDown inside a shown source as cell navigation.
635
604
  if ((await widgetInteraction.handleRevealingKeydown(e)) || editableSurface.isDetached()) return;
636
- // Enter is a cell's exception: prose splits, a cell hops rows, and hopping would
637
- // carry the ephemeral edit out of the surface that owns it. Commit and stay put.
605
+ // Enter is a cell's exception: prose splits, a cell moves a row, and moving would
606
+ // carry the uncommitted edit out of the cell that owns it. Commit and stay put.
638
607
  if (widgetInteraction.isRevealing() && e.key === 'Enter' && !e.ctrlKey && !e.metaKey) {
639
608
  e.preventDefault();
640
609
  widgetInteraction.foldRevealBeforeMutation();
@@ -644,22 +613,24 @@
644
613
  return;
645
614
  if (widgetInteraction.handleShiftArrowIntoWidget(e)) return;
646
615
 
647
- preEditOffset = cursor.getRaw() ?? 0;
616
+ const caretBeforeKey = cursor.getRaw() ?? 0;
648
617
 
649
- // FIRST, because neither the navigation plan's boundary branches nor the shared
650
- // prelude's ArrowLeft@0 hop tests modifiers: either would eat the column reorder at
651
- // a cell's left edge. Also the only point a consumer `keybindings` override reaches.
652
- if (wiring.dispatchChord(e, { kind: node.kind, runCommand })) return;
618
+ // Before the plan, whose edge branches ignore modifiers and would eat a column move. A move
619
+ // from a cell moves the whole table, since a table's grid rows are not reorderable children.
620
+ const target = {
621
+ kind: node.kind,
622
+ runCommand,
623
+ getPath: () => myPath,
624
+ afterSourceCommit
625
+ };
626
+ if (wiring.dispatchChord(e, target)) return;
653
627
 
654
- const plan = cellKeydownPlan(
655
- { key: e.key, ctrlOrMeta: e.ctrlKey || e.metaKey, shiftKey: e.shiftKey, altKey: e.altKey },
656
- cellPlanState(preEditOffset)
657
- );
628
+ const plan = cellKeydownPlan(e, cellPlanState(caretBeforeKey));
658
629
 
659
630
  switch (plan.kind) {
660
631
  case 'native': {
661
- // The first Shift+ArrowUp/Down at a cell's vertical edge takes a whole row;
662
- // the shared prose extend would instead walk the next doc-order leaf.
632
+ // The first Shift+ArrowUp or Down at a cell's vertical edge takes a whole row;
633
+ // the shared prose extend would instead go to the next block in document order.
663
634
  if (
664
635
  !selection.isCrossBlock &&
665
636
  e.shiftKey &&
@@ -667,19 +638,19 @@
667
638
  !e.ctrlKey &&
668
639
  !e.metaKey &&
669
640
  (e.key === 'ArrowUp' || e.key === 'ArrowDown') &&
670
- startIntraTableRect(e.key, preEditOffset)
641
+ startIntraTableRect(e.key, caretBeforeKey)
671
642
  ) {
672
643
  e.preventDefault();
673
644
  return;
674
645
  }
675
646
  if (await handleSharedKeydown(e, sharedCtx)) return;
676
- // Runs only where the plan yielded 'native': at the text boundaries the plan
677
- // claims, an entered widget sits outside the boundary and the dispatch declines.
647
+ // Runs only where the plan answered 'native': at the text boundaries the plan
648
+ // takes, an entered widget sits outside it and the dispatch declines.
678
649
  if (edgeDispatch.handleKeydown(e, cursor.getRaw())) return;
679
650
  return;
680
651
  }
681
- // The document-level two-stage Ctrl+A, cell first: the intra-cell step stays native,
682
- // the second press takes the document.
652
+ // The document's two-stage Ctrl+A, cell first: the step inside the cell is the
653
+ // browser's, and the second keypress takes the document.
683
654
  case 'select-all-step':
684
655
  selection.incrementSelectAllCount();
685
656
  if (plan.step === 'native') return;
@@ -688,7 +659,7 @@
688
659
  return;
689
660
  default:
690
661
  e.preventDefault();
691
- // Reading mode keeps navigation and swallows the structural plans.
662
+ // Reading mode keeps navigation and consumes the structural plans.
692
663
  if (readOnly && plan.kind !== 'focus-cell' && plan.kind !== 'exit') return;
693
664
  await applyCellPlan(plan);
694
665
  return;
@@ -697,9 +668,8 @@
697
668
 
698
669
  const onKeyDownTraced = withKeydownVerdict(onKeyDown);
699
670
 
700
- // The navigation plans, no live event needed; the caller preventDefaults. The fold is here
701
- // rather than at each caller: insert-row-below rebuilds every row from cell raws, so an open
702
- // reveal's edit would be re-derived away.
671
+ // A shown source is hidden first: insert-row-below rebuilds every row from the cell raws and
672
+ // would discard its edit. The caller calls `preventDefault`.
703
673
  async function applyCellPlan(plan: CellKeyPlan): Promise<void> {
704
674
  const fold = widgetInteraction.foldRevealBeforeMutation();
705
675
  if (fold) await fold.settled;
@@ -717,42 +687,33 @@
717
687
  }
718
688
  }
719
689
 
720
- // Enter an intra-table rectangle from a collapsed cell caret on the first
721
- // Shift+ArrowUp/Down. Gated on the cell's visual edge so a multi-line cell still
722
- // extends its own text first (prose parity). Returns false to fall through.
690
+ // Only at the cell's first or last visual line, so a wrapped cell extends its own text first,
691
+ // as prose does. False falls through.
723
692
  function startIntraTableRect(key: 'ArrowUp' | 'ArrowDown', offset: number): boolean {
724
693
  if (!el) return false;
725
694
  const bounds = landableDomTextBounds(el);
726
695
  const atEdge =
727
696
  key === 'ArrowDown'
728
- ? isAtLastVisualLine(el, offset, bounds.end)
729
- : isAtFirstVisualLine(el, offset, bounds.start);
697
+ ? isAtLastVisualLine(el, offset, bounds)
698
+ : isAtFirstVisualLine(el, offset, bounds);
730
699
  if (!atEdge) return false;
731
700
 
732
701
  const tablePath = myPath.slice(0, -2);
733
- const currentIdx = rowIdx * columnCount + colIdx;
734
- const currentPoint: SelectionPoint = { path: tablePath, offset: currentIdx };
735
- const ext = intraTableRectExtension(getDoc(), currentPoint, currentPoint, key);
702
+ const anchor = cellPoint(tablePath, rowMajorCellIndex(rowIdx, colIdx, columnCount));
703
+ const ext = intraTableRectExtension(getDoc(), anchor, anchor, key);
736
704
  if (!ext) return false;
737
705
 
738
- const anchor = {
739
- path: tablePath,
740
- offset: currentIdx,
741
- cellCoordinate: true
742
- } satisfies CellSelectionPoint;
743
706
  if (ext.kind === 'cell') {
744
- selection.enterCrossBlock(anchor, { path: tablePath.slice(), offset: ext.offset });
707
+ selection.enterCrossBlock(anchor, cellPoint(tablePath, ext.offset));
745
708
  return true;
746
709
  }
747
- // Enter the rect at the current cell, then hand off to the block-level extend so
748
- // the selection leaves the table. The seed is minted before the extend can answer, so
749
- // a decline (no block past the table) has to take it back: the stored pair would be an
750
- // invisible selection the next Backspace deletes the whole cell through.
751
- selection.enterCrossBlock(anchor, { path: tablePath.slice(), offset: currentIdx });
710
+ // Recorded before the block-level extend answers, so a refusal (no block past the table)
711
+ // takes it back: left behind, the next Backspace would delete a whole cell through it.
712
+ selection.enterCrossBlock(anchor, cellPoint(tablePath, anchor.offset));
752
713
  const extended =
753
714
  ext.direction === 'forward'
754
- ? extendFocusToNextBlock(selection, getDoc(), el, ext.fromCellPath, 'vertical')
755
- : extendFocusToPreviousBlock(selection, getDoc(), el, ext.fromCellPath, 'start');
715
+ ? extendFocusToNextBlock(selection, getDoc(), grammar, el, ext.fromCellPath, 'vertical')
716
+ : extendFocusToPreviousBlock(selection, getDoc(), grammar, el, ext.fromCellPath, 'start');
756
717
  if (!extended) {
757
718
  selection.collapse();
758
719
  return false;
@@ -767,25 +728,24 @@
767
728
  else tableContext.exitDownward(x);
768
729
  }
769
730
 
770
- // The cell at the prose surface's live ranged-edit arm: a native edit over a range spanning
771
- // hidden delimiters is the destructive family with no seam offsets of its own.
731
+ // The cell's version of the prose block's live range edit: a browser edit over a range
732
+ // spanning hidden delimiters, the one destructive case with no offsets of its own.
772
733
  function handleLiveSelectionEdit(e: InputEvent): boolean {
773
734
  return applyLiveRangeEdit(
774
735
  e,
775
736
  node,
776
737
  cursor,
777
- presentationMode,
778
- linkRef,
779
- '',
738
+ storedAs(),
780
739
  widgetInteraction.isRevealing,
781
740
  (edit) => {
782
- void blockEdit.updateBlockContent(index, edit.raw, edit.range.start, edit.caret);
783
- parkCursor(edit.caret, edit.raw);
741
+ parkWrite(
742
+ blockEdit.updateBlockContent(index, edit.raw, 'authored', edit.range.start, edit.caret)
743
+ );
784
744
  }
785
745
  );
786
746
  }
787
747
 
788
- // The cell at the prose surface's self-closing delimiter arm (delimiter-autopair.ts).
748
+ // The cell's version of the prose block's self-closing delimiters (delimiter-autopair.ts).
789
749
  function handleDelimiterAutoPair(e: InputEvent): boolean {
790
750
  return applyDelimiterAutoPair(e, {
791
751
  text: readCellText,
@@ -794,12 +754,14 @@
794
754
  hasSelection: () => cursor.getRawSelection() !== null,
795
755
  isRevealing: widgetInteraction.isRevealing,
796
756
  foldReveal: () => widgetInteraction.foldRevealBeforeMutation(),
797
- markersPaint: () => paintsFocusedMarkers(presentationMode),
798
- setCaret: (offset) => cursor.setRaw(asRawOffset(offset)),
799
- seatOutside: edgeAffinity.noteExtreme,
757
+ setCaret: (offset) => cursor.setRaw(asRawOffset(offset), { clamp: 'exact' }),
758
+ seatOutside: caretMemory.noteExtreme,
759
+ // Each auto-pair caller asks this itself until the caret-edge key table gives it one caller.
760
+ keepsKind: (line) => keepsKindAt(node, line, storedAs()),
761
+ reading,
762
+ ownPairs,
800
763
  write: (text, caretBefore, caretAfter) => {
801
- void blockEdit.updateBlockContent(index, text, caretBefore, caretAfter);
802
- parkCursor(caretAfter, text);
764
+ parkWrite(blockEdit.updateBlockContent(index, text, 'authored', caretBefore, caretAfter));
803
765
  }
804
766
  });
805
767
  }
@@ -813,8 +775,8 @@
813
775
  // which the inline-HTML pipeline renders as a live widget.
814
776
  e.preventDefault();
815
777
  if (!el) return;
816
- // Both reads below are taken AFTER the fold: the committed text is what the offset
817
- // they splice must be measured against.
778
+ // Both reads below happen after the source is hidden: the committed text is what
779
+ // the offset they splice must be measured against.
818
780
  const fold = widgetInteraction.foldRevealBeforeMutation();
819
781
  if (fold) await fold.settled;
820
782
  const offset = cursor.getRaw() ?? 0;
@@ -822,8 +784,7 @@
822
784
  const inserted = '<br>';
823
785
  const newText = text.slice(0, offset) + inserted + text.slice(offset);
824
786
  const caret = offset + inserted.length;
825
- void blockEdit.updateBlockContent(index, newText, offset, caret);
826
- parkCursor(caret, newText);
787
+ parkWrite(blockEdit.updateBlockContent(index, newText, 'authored', offset, caret));
827
788
  return;
828
789
  }
829
790
  }
@@ -835,84 +796,75 @@
835
796
  if (e.button === 2) return;
836
797
  lastClickClientX = e.clientX;
837
798
  lastClickClientY = e.clientY;
838
- // A press on a reveal-source widget is an owned gesture: suppress the browser caret
839
- // default and skip the drag so nothing races the reveal's own placement.
799
+ // A click on a widget that can show its source is this editor's gesture: cancel the
800
+ // browser's caret default and skip the drag so nothing races its own placement.
840
801
  if (widgetInteraction.isPointOnRevealWidget(e.clientX, e.clientY)) {
841
802
  e.preventDefault();
842
803
  return;
843
804
  }
844
805
  const tableEl = el.closest('[role="table"]') as HTMLElement | null;
845
- if (!tableEl) {
846
- crossBlock.handlePointerDown(e);
847
- return;
848
- }
849
- const tablePath = myPath.slice(0, -2);
850
- const anchor: CellAnchor = {
851
- tableEl,
852
- tablePath,
853
- rowIdx,
854
- colIdx,
855
- columnCount
856
- };
857
-
858
- resetForPointerDown(selection, stickyColumn, edgeAffinity, e.shiftKey);
806
+ if (tableEl && e.shiftKey && shiftClickFromAnotherCell(e, tableEl)) return;
807
+ // Every other press goes through the shared handler, which places one in the cell's padding.
808
+ crossBlock.handlePointerDown(e, tableEl && !e.shiftKey ? cellDrag(e, tableEl, el) : {});
809
+ }
859
810
 
860
- if (e.shiftKey) {
861
- const prevCoords = cellCoordsOfElement(document.activeElement, tableEl);
862
- if (prevCoords && (prevCoords.rowIdx !== rowIdx || prevCoords.colIdx !== colIdx)) {
863
- handleCellShiftClick(
864
- selection,
865
- { ...anchor, rowIdx: prevCoords.rowIdx, colIdx: prevCoords.colIdx },
866
- { rowIdx, colIdx }
867
- );
868
- e.preventDefault();
869
- return;
870
- }
871
- crossBlock.handlePointerDown(e);
872
- return;
873
- }
811
+ function anchorIn(tableEl: HTMLElement): CellAnchor {
812
+ return { tableEl, tablePath: myPath.slice(0, -2), rowIdx, colIdx, columnCount };
813
+ }
874
814
 
875
- const editorRoot = getEditorRoot();
876
- if (!editorRoot) return;
877
- installCellDragListener({ editorRoot, selection, lifetimeSignal: editorLifetime }, anchor, e);
815
+ /** Shift+click with another cell of this table focused grows a cell rectangle from it. */
816
+ function shiftClickFromAnotherCell(e: PointerEvent, tableEl: HTMLElement): boolean {
817
+ const prev = cellCoordsOfElement(document.activeElement, tableEl);
818
+ if (!prev || (prev.rowIdx === rowIdx && prev.colIdx === colIdx)) return false;
819
+ resetForPointerDown(selection, caretMemory, true);
820
+ handleCellShiftClick(
821
+ selection,
822
+ { ...anchorIn(tableEl), rowIdx: prev.rowIdx, colIdx: prev.colIdx },
823
+ { rowIdx, colIdx }
824
+ );
825
+ e.preventDefault();
826
+ return true;
878
827
  }
879
828
 
880
- // Copy/cut/paste through the shared skeleton. The cell's extra arms are the intra-table
881
- // rectangle (copied as a GFM sub-table) and the intra-cell raw slice, which preserves
882
- // widget bytes like `<br>` that the browser's rendered-textContent copy drops.
883
- // The rectangle's spreadsheet form rides beside the GFM: Excel and Sheets read text/html.
884
- function writeRectHtml(e: ClipboardEvent): void {
885
- const grid = intraTableRectGrid({ selection, getDoc });
886
- if (grid) e.clipboardData?.setData('text/html', gridToHtmlTable(grid));
829
+ /** A plain press in a cell runs the cell rectangle drag, not the cross-block one. */
830
+ function cellDrag(
831
+ e: PointerEvent,
832
+ tableEl: HTMLElement,
833
+ cellEl: HTMLElement
834
+ ): PointerPressOptions {
835
+ return {
836
+ ownDrag: (padding) => {
837
+ const editorRoot = getEditorRoot();
838
+ if (!editorRoot) return;
839
+ installCellDragListener(
840
+ { editorRoot, selection, lifetimeSignal: editorLifetime },
841
+ anchorIn(tableEl),
842
+ e,
843
+ padding && { surface: cellEl, press: padding }
844
+ );
845
+ }
846
+ };
887
847
  }
888
848
 
889
- // A grid (tabs from a spreadsheet, or a GFM table) fills cells from here — the rectangle's
890
- // top-left when one is live, else this cell — growing the table to fit. A whole-table
891
- // selection keeps its replace route; a non-grid payload keeps the ordinary paste.
849
+ // A pasted grid (spreadsheet tabs or a GFM table) fills cells from the live rectangle's
850
+ // top-left or this cell, growing the table; a whole-table selection still replaces.
892
851
  async function pasteGridHere(text: string): Promise<boolean> {
893
852
  const grid = parseClipboardGrid(text);
894
853
  if (!grid) return false;
895
854
  const tablePath = myPath.slice(0, -2);
896
- const bounds = intraTableRectBounds({ selection, getDoc });
897
- const inThisTable = bounds !== null && pathsEqual(bounds.tablePath, tablePath);
898
- if (bounds && !inThisTable) return false;
899
- const tableNode = nodeAt(getDoc(), tablePath);
900
- const wholeTable =
901
- bounds !== null &&
902
- tableNode !== null &&
903
- isBlockNode(tableNode) &&
904
- bounds.rows * bounds.cols === tableCellCount(tableNode);
905
- if (wholeTable) return false;
906
- const origin = bounds ? { rowIdx: bounds.top, colIdx: bounds.left } : { rowIdx, colIdx };
907
- const fitted = bounds ? tileGridTo(grid, bounds.rows, bounds.cols) : grid;
908
- if (bounds) selection.collapse();
855
+ const cells = rangeCoverage()?.grid ?? null;
856
+ if (cells && !pathsEqual(cells.path, tablePath)) return false;
857
+ if (cells?.kind === 'table') return false;
858
+ const rect = cells?.rect;
859
+ const origin = rect ? { rowIdx: rect.top, colIdx: rect.left } : { rowIdx, colIdx };
860
+ const fitted = rect ? tileGridTo(grid, rect.rows, rect.cols) : grid;
861
+ if (rect) selection.collapse();
909
862
  await tableContext.pasteGrid(origin, fitted);
910
863
  return true;
911
864
  }
912
865
 
913
866
  const clipboard = createClipboardHandlers({
914
- stickyColumn,
915
- edgeAffinity,
867
+ caretMemory,
916
868
  selection,
917
869
  getDoc,
918
870
  crossBlock,
@@ -921,17 +873,9 @@
921
873
  events: editorEvents,
922
874
  onPasteImage,
923
875
  foldReveal: () => widgetInteraction.foldRevealBeforeMutation(),
924
- copyPreHook: (e) => {
925
- const rectPayload = intraTableRectPayload({ selection, getDoc });
926
- if (rectPayload === null) return false;
927
- e.preventDefault();
928
- e.clipboardData?.setData('text/plain', rectPayload);
929
- writeRectHtml(e);
930
- return true;
931
- },
932
876
  pastePreHook: pasteGridHere,
933
- // During a reveal the swapped DOM holds an edit `node.raw` hasn't seen; copy never
934
- // mutates, so it slices the live DOM text rather than folding first.
877
+ // While a source is shown the DOM holds an edit `node.raw` has not seen; copy never
878
+ // writes, so it slices the live DOM text rather than hiding it first.
935
879
  copyTail: (e) => {
936
880
  if (!el) return;
937
881
  const offsets = cursor.getRawSelection();
@@ -942,18 +886,8 @@
942
886
  : trimTrailingLineEnding(node.raw);
943
887
  e.clipboardData?.setData('text/plain', display.slice(offsets.start, offsets.end));
944
888
  },
945
- // Clears the cells in place, without `tableCoverageDelete` — only Backspace's
946
- // structural delete opts into row/column/table removal.
947
- cutPreHook: async (e) => {
948
- const rectPayload = intraTableRectPayload({ selection, getDoc });
949
- if (rectPayload === null) return false;
950
- e.clipboardData?.setData('text/plain', rectPayload);
951
- writeRectHtml(e);
952
- await crossBlock.performCrossBlockDeleteFromEvent();
953
- return true;
954
- },
955
- // The write must be sync (clipboardData closes after the event), and the truncation
956
- // goes through the CST: native deleteByCut would leave a stale snapshot anchor.
889
+ // The write has to be synchronous, since `clipboardData` closes after the event, and
890
+ // the truncation goes through the CST: the browser's own cut leaves a stale undo anchor.
957
891
  cutTail: (e) => {
958
892
  if (!el) return;
959
893
  const offsets = cursor.getRawSelection();
@@ -971,16 +905,14 @@
971
905
  });
972
906
  const { onCopy, onCut, onPaste } = clipboard;
973
907
 
974
- // ── Shared mutation primitives (event handlers + right-click menu) ───────
908
+ // ── Shared edit helpers (event handlers and the right-click menu) ────────
975
909
 
976
- // The truncation is a join like the paste's delete half: in live the runs it strands are
977
- // bytes the reader never saw, so it crosses the same seam ahead of the escaping sink
978
- // (live-mode.md § 4.5).
910
+ // Through the join rules, since in live mode the delete can strand delimiter runs the user
911
+ // never saw (live-mode.md § 4.5).
979
912
  function deleteCellRange(start: number, end: number): void {
980
- const display = trimTrailingLineEnding(node.raw);
981
- const cut = cutRangeFromDisplay(node, display, { start, end }, presentationMode, linkRef);
982
- void blockEdit.updateBlockContent(index, cut.display, start, cut.offset);
983
- parkCursor(cut.offset, cut.display);
913
+ const cut = replaceRangeInLeaf(node, { start, end }, '', storedAs());
914
+ const display = trimTrailingLineEnding(cut.raw);
915
+ parkWrite(blockEdit.updateBlockContent(index, display, 'literal', start, cut.caret));
984
916
  }
985
917
 
986
918
  async function applyCellPaste(
@@ -998,23 +930,17 @@
998
930
  doc: getDoc(),
999
931
  blockEdit,
1000
932
  controller: pasteCoordinator,
1001
- grammar,
1002
- activePlugins,
1003
- // The delete half is a join like any other, and a cell's is no more literal than a
1004
- // paragraph's: without the seam a live cut pastes the runs it stranded into view.
1005
- seam: { presentationMode, linkRef }
933
+ reading,
934
+ activePlugins
1006
935
  }
1007
936
  );
1008
- // Already escaped: the cell's paste surface reports its caret in escaped space.
1009
937
  if (result.inlineCaretOffset !== undefined) parkCursor(result.inlineCaretOffset);
1010
938
  }
1011
939
 
1012
940
  // ── Right-click menu clipboard (no ClipboardEvent) ──────────────────────
1013
941
  //
1014
- // Copy/Cut restore the range and fire `execCommand('copy')`, keeping the clipboard write
1015
- // synchronous the way Tauri needs and `navigator.clipboard.writeText` isn't. `execCommand('cut')`
1016
- // is unusable because onCut's write trails an await, so Cut copies then deletes; paste has no
1017
- // sync equivalent at all.
942
+ // Cut copies then deletes: `onCut` writes the clipboard after an await, which a scripted
943
+ // `execCommand('cut')` has already closed.
1018
944
 
1019
945
  function getSelectionOffsets(): { start: number; end: number } | null {
1020
946
  const range = cursor.getRawSelection();
@@ -1028,20 +954,17 @@
1028
954
  sel: { start: number; end: number }
1029
955
  ): Promise<void> {
1030
956
  if (!el) return;
1031
- // Belt behind TableBlock's menu-open gate: paste and cut mutate.
1032
- if (readOnly && action !== 'copy') return;
1033
- // Right-click deliberately skips the pointerdown reset, so the reveal is still open here
1034
- // and `sel` was captured in the REVEALED DOM's coordinates — a fold before any of it.
957
+ // Right-click deliberately skips the pointerdown reset, so a source may still be showing
958
+ // and `sel` was captured against that DOM, which is why it is hidden before anything else.
1035
959
  const fold = widgetInteraction.foldRevealBeforeMutation();
1036
960
  if (fold) await fold.settled;
1037
- // A rectangle has no cell-local range to restore: refocusing keeps it live in
1038
- // SelectionState, and the onCopy/onCut rect arms do the rest.
1039
- const hasRect = action !== 'paste' && intraTableRectPayload({ selection, getDoc }) !== null;
961
+ // A rectangle has no range inside one cell to restore: refocusing keeps it live in
962
+ // `SelectionState`, and the copy and cut branches for a rectangle do the rest.
963
+ const hasRect = action !== 'paste' && !!rangeCoverage()?.grid;
1040
964
  if (action !== 'paste' && !hasRect && sel.start === sel.end) return;
1041
965
  // Clicking the menu item moved focus off the cell, so every branch refocuses before
1042
966
  // mutating: execCommand needs the restored range, paste needs a focused caret.
1043
- stickyColumn.reset();
1044
- edgeAffinity.reset();
967
+ caretMemory.forget();
1045
968
  el.focus({ preventScroll: true });
1046
969
  if (action === 'paste') {
1047
970
  let raw: string;
@@ -1058,7 +981,7 @@
1058
981
  }
1059
982
  if (hasRect) {
1060
983
  document.execCommand('copy');
1061
- if (action === 'cut') await crossBlock.performCrossBlockDeleteFromEvent();
984
+ if (action === 'cut') await crossBlock.performCrossBlockCut();
1062
985
  return;
1063
986
  }
1064
987
  setSelection(sel.start, sel.end);
@@ -1066,9 +989,8 @@
1066
989
  if (action === 'cut') deleteCellRange(sel.start, sel.end);
1067
990
  }
1068
991
 
1069
- // A click past a widget drops the caret at an element-level position with no text
1070
- // anchor, so snap to the nearest widget edge (or reveal). Normal text clicks fall
1071
- // through untouched.
992
+ // A click past a widget leaves the caret with no text to sit in, so it moves to the
993
+ // nearest widget edge.
1072
994
  function onClick(e: MouseEvent): void {
1073
995
  const x = lastClickClientX;
1074
996
  const y = lastClickClientY;
@@ -1098,16 +1020,18 @@
1098
1020
  }
1099
1021
  </script>
1100
1022
 
1023
+ <!-- The cell is an editing host, which the compiler cannot see through a role it has to compute. -->
1024
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
1101
1025
  <div
1102
1026
  bind:this={el}
1103
1027
  tabindex="0"
1104
- class="table-cell"
1028
+ class={['table-cell', ...blockDecorations.classes]}
1105
1029
  contenteditable={readOnly ? 'false' : 'true'}
1106
- role="cell"
1030
+ role={isHeaderRow ? 'columnheader' : 'cell'}
1107
1031
  style:text-align={alignment === 'none' ? undefined : alignment}
1108
1032
  oninput={onInput}
1109
1033
  onkeydown={onKeyDownTraced}
1110
- onbeforeinput={onBeforeInput}
1034
+ onbeforeinput={editableSurface.onBeforeInput}
1111
1035
  onpointerdown={onPointerDown}
1112
1036
  onclick={onClick}
1113
1037
  oncopy={onCopy}
@@ -1120,10 +1044,8 @@
1120
1044
  ></div>
1121
1045
 
1122
1046
  <style>
1123
- /* Two sides only. The grid has no `border-collapse`, so a cell drawing all four put two
1124
- 1px lines on every shared edge — visibly heavier inside the table than around it. The
1125
- container draws the top and left, these draw the right and bottom, and every rule in
1126
- the grid is one line wide. */
1047
+ /* The right and bottom only: the grid has no `border-collapse`, so the table draws the top
1048
+ and left and every shared edge stays one line wide. */
1127
1049
  .table-cell {
1128
1050
  outline: none;
1129
1051
  padding: 4px 8px;