@voithos-labs/aragonite 0.10.3 → 0.10.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1021) hide show
  1. package/README.md +2 -2
  2. package/dist/a11y-strings.d.ts +12 -5
  3. package/dist/a11y-strings.js +61 -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 +13 -20
  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 +619 -1089
  23. package/dist/components/Editor.svelte.d.ts +9 -20
  24. package/dist/components/GapCaret.svelte +26 -59
  25. package/dist/components/SelectionOverlay.svelte +36 -67
  26. package/dist/components/SelectionOverlay.svelte.d.ts +6 -4
  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 +103 -100
  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 +35 -28
  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 +58 -32
  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 +144 -202
  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 +46 -90
  65. package/dist/components/blocks/list/ListItemBlock.svelte +99 -144
  66. package/dist/components/blocks/list/ListItemBlock.svelte.d.ts +3 -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 +9 -4
  102. package/dist/components/blocks/text/click-snap-guard.js +16 -5
  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 +164 -180
  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 -105
  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 +243 -208
  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 +13 -30
  144. package/dist/components/drag-handle.js +25 -63
  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 -31
  162. package/dist/components/editor-root-listeners.js +49 -46
  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 +26 -30
  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 +380 -0
  209. package/dist/components/menu/SelectionToolbar.svelte.d.ts +14 -0
  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 +55 -68
  256. package/dist/core/inline/inline-widgets.js +55 -58
  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 +33 -17
  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 -7
  347. package/dist/cursor/height-oracle.js +26 -75
  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 +16 -8
  365. package/dist/cursor/scrollport.js +28 -5
  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 -13
  375. package/dist/cursor/visual-lines.js +72 -28
  376. package/dist/cursor/widget-edge-snap.d.ts +23 -0
  377. package/dist/cursor/widget-edge-snap.js +39 -0
  378. package/dist/cursor/widget-offset.d.ts +111 -102
  379. package/dist/cursor/widget-offset.js +352 -177
  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 +31 -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 +33 -52
  434. package/dist/editor-actions/focus/focus-landing.d.ts +11 -5
  435. package/dist/editor-actions/focus/focus-landing.js +29 -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 +55 -76
  465. package/dist/editor-actions/plugin/container.js +105 -186
  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 +91 -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 +38 -8
  550. package/dist/plugin.js +102 -74
  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 +113 -85
  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 -75
  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 +63 -47
  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 +18 -7
  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 +143 -292
  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 +79 -81
  695. package/dist/schema/commands.js +156 -116
  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 +9 -11
  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 +73 -78
  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 +93 -152
  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 +61 -104
  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 +53 -146
  807. package/dist/selection/dead-space-caret.d.ts +20 -28
  808. package/dist/selection/dead-space-caret.js +79 -87
  809. package/dist/selection/drag-pointer.d.ts +22 -5
  810. package/dist/selection/drag-pointer.js +63 -31
  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 -39
  816. package/dist/selection/keyboard-extend.js +94 -116
  817. package/dist/selection/multi-click.d.ts +37 -0
  818. package/dist/selection/multi-click.js +197 -0
  819. package/dist/selection/native-bridge.d.ts +30 -37
  820. package/dist/selection/native-bridge.js +80 -100
  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 +31 -14
  824. package/dist/selection/path-lookup.js +110 -20
  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 +9 -0
  828. package/dist/selection/pointer-gesture.js +11 -0
  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 -33
  832. package/dist/selection/primitives.js +61 -53
  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 -19
  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 +52 -0
  852. package/dist/selection/selection-drop.js +317 -0
  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 +75 -53
  864. package/dist/styles/editor.css +248 -139
  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 +19 -0
  960. package/dist/tree-operations/paste/replacement-parse.js +24 -0
  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 +329 -205
  994. package/docs/guide/directives.md +7 -7
  995. package/docs/guide/plugin-api.md +267 -183
  996. package/docs/guide/plugin-guide.md +341 -235
  997. package/docs/guide/plugin-testing.md +96 -82
  998. package/package.json +17 -21
  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/invariants/split-landing.d.ts +0 -8
  1015. package/dist/invariants/split-landing.js +0 -15
  1016. package/dist/selection/double-click-trim.d.ts +0 -17
  1017. package/dist/selection/double-click-trim.js +0 -57
  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 -29
  1021. package/dist/tree-operations/paste/replace-block-at-parent.js +0 -75
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { getContext, tick } from 'svelte';
3
- import { type BlockComponent, type StickyColumnDirection } from '../../../block-component';
3
+ import { type BlockComponent } from '../../../block-component';
4
4
  import type { NodeView } from '../../../core/node-views';
5
5
  import {
6
6
  EDITOR_POLICIES_KEY,
@@ -9,26 +9,27 @@
9
9
  type EditorPolicies,
10
10
  type EditorServices
11
11
  } from '../../../editor-keys';
12
- import { asDomTextOffset, asRawOffset } from '../../../cursor/coordinate-spaces';
13
- import { CONTENT_EMPTY_ATTR, holdsOnlyMarkerChrome } from '../../../cursor/widget-offset';
12
+ import { asRawOffset } from '../../../cursor/coordinate-spaces';
14
13
  import {
15
- createRangeFromOffsets,
16
- setCursorOffset,
17
- getRangeOffsets,
18
- getSelectionOffsets,
19
- hasSelection
20
- } from '../../../cursor/content-offsets';
14
+ CONTENT_EMPTY_ATTR,
15
+ holdsOnlyMarkerChrome,
16
+ selectRawRange,
17
+ type RawRange
18
+ } from '../../../cursor/widget-offset';
19
+ import { createSurfaceBackend } from '../../../cursor/surface-backend';
21
20
  import { handleSharedKeydown, handleSharedBeforeInput } from '../../../selection/shared-keydown';
22
21
  import {
23
22
  createEditableSurface,
24
23
  createClipboardHandlers,
25
24
  consumePendingRestore,
25
+ editableSurfaceAttributes,
26
26
  withKeydownVerdict
27
27
  } from '../editable-surface';
28
28
  import { wireSurfaceContexts, useParkFocusOnUnmount } from '../surface-wiring.svelte';
29
- import { createContentOffsetBackend, anchorTrailingNewline } from '../plain-text-backend';
29
+ import { anchorTrailingNewline, plainTextOf } from '../plain-text-backend';
30
30
  import { renderCodeBlock, sliceFencedCode } from './code-renderer';
31
31
  import {
32
+ getCloserFor,
32
33
  getLineLeadingWhitespace,
33
34
  isBetweenEmptyPair,
34
35
  isBetweenEmptyBracketPair
@@ -36,31 +37,34 @@
36
37
  import { indentLines, dedentLines, type IndentResult } from './code-indent';
37
38
  import { computeCodeEnter } from './code-enter';
38
39
  import { computeAutoPair } from './code-beforeinput';
39
- import {
40
- fenceShapeOf,
41
- reconcileFenceWrite,
42
- writeFenceInfo
43
- } from '../../../schema/fenced-code-raw';
44
- import { hidesMarkers } from '../../../presentation-mode';
40
+ import { fenceShapeOf, writeFenceInfo } from '../../../schema/fenced-code-raw';
41
+ import { fenceLanguage } from '../../../core/parsers/fence-syntax';
42
+ import { hidesMarkers, paintsFocusedMarkers } from '../../../presentation-mode';
45
43
  import CodeBlockRail from './CodeBlockRail.svelte';
46
44
  import { computeFenceExit, computeTypedFenceExit } from './code-fence-exit';
47
45
  import {
48
46
  classifyFenceBoundary,
47
+ bodyWindow,
49
48
  clampCaretToBody,
50
49
  clampEnterOffsetToBody,
51
50
  clampRangeToBody,
52
51
  computeFenceRangedEdit,
52
+ computeRangedEdit,
53
53
  crossesFenceBoundary,
54
54
  fenceEditSpan,
55
55
  isStructureOnlyRange,
56
- type CodeRange
56
+ orderedRange
57
57
  } from './code-fence-boundary';
58
58
  import { metadataOf, type CstNode } from '../../../core/nodes';
59
- import { trimTrailingLineEnding, trailingLineEnding } from '../../../core/lines';
59
+ import {
60
+ documentLineEnding,
61
+ isBlankText,
62
+ trimTrailingLineEnding,
63
+ trailingLineEnding
64
+ } from '../../../core/lines';
60
65
  import { pasteDispatch } from '../../../tree-operations/paste/dispatch';
61
66
  import { nodeAt, emptyParagraph } from '../../../tree-operations';
62
67
  import { type CommandId } from '../../../schema/commands';
63
- import { reorderRunCommand } from '../../../editor-actions/reorder-action';
64
68
 
65
69
  const ELECTRIC_INDENT_UNIT = '\t';
66
70
 
@@ -72,60 +76,54 @@
72
76
  focusActions,
73
77
  controller,
74
78
  pasteCoordinator,
75
- stickyColumn,
76
- edgeAffinity,
79
+ caretMemory,
77
80
  selection,
78
81
  getDoc,
79
82
  getEditorRoot,
80
- grammar,
81
83
  activePlugins,
82
- events: editorEvents
84
+ events: editorEvents,
85
+ reading
83
86
  } = wiring.deps;
84
- const { reorder } = getContext<EditorServices>(EDITOR_SERVICES_KEY);
85
- const {
86
- presentationMode: getPresentationMode,
87
- onPasteImage,
88
- onRunCode,
89
- codeMenuItems
90
- } = getContext<EditorPolicies>(EDITOR_POLICIES_KEY);
91
- const presentationMode = $derived(getPresentationMode?.() ?? 'source');
87
+ // The ending a line written into this block takes: its own, else the document's.
88
+ const blockEnding = () => trailingLineEnding(node.raw, documentLineEnding(getDoc()));
89
+ const { menuPresence } = getContext<EditorServices>(EDITOR_SERVICES_KEY);
90
+ const { onPasteImage, onRunCode, codeMenuItems } =
91
+ getContext<EditorPolicies>(EDITOR_POLICIES_KEY);
92
+ const presentationMode = $derived(reading.mode());
92
93
  const readOnly = $derived(presentationMode === 'reading');
94
+ // A fence line takes edits where the mode paints it, as the focused block's markers; where it
95
+ // is hidden, an edit that reaches it clamps to the body. A caret arriving lands in the body.
96
+ const fenceLinesEditable = $derived(paintsFocusedMarkers(presentationMode));
93
97
  let el: HTMLDivElement | undefined = $state();
94
98
  let composing = $state(false);
95
99
  let pendingCursorOffset = $state<number | null>(null);
96
100
  let pendingSelection = $state<{ start: number; end: number } | null>(null);
97
101
  let lastRenderedRaw = '';
98
- let preEditOffset = 0;
99
102
 
100
- const { backend, getFocusOffset, getTextLen, readText } = createContentOffsetBackend(
101
- () => el ?? null
102
- );
103
+ const backend = createSurfaceBackend({ getEl: () => el ?? null });
103
104
 
104
105
  const editableSurface = createEditableSurface({
105
106
  ...wiring.deps,
106
107
  getEl: () => el ?? null,
107
- getAmbientLength: () => 0,
108
108
  backend,
109
+ // A caret arriving from outside lands on the body in every mode, by a column or a placed
110
+ // offset; only a click or an arrow inside the block reaches a fence line the mode paints.
111
+ columnWindow: () => bodyWindow(node),
112
+ clampLanding: (offset) => clampCaretToBody(node, offset),
109
113
  getMyPath: () => myPath,
110
114
  getIndex: () => index,
111
115
  getComposing: () => composing,
112
116
  setComposing: (value) => {
113
117
  composing = value;
114
118
  },
115
- getPreEditOffset: () => preEditOffset,
116
- setPreEditOffset: (offset) => {
117
- preEditOffset = offset;
118
- },
119
119
  setPendingCursor: (offset) => {
120
120
  pendingCursorOffset = offset;
121
121
  },
122
- getPresentationMode,
123
- getFocusOffset,
124
- getTextLen,
125
- readText,
126
- // Hands back the caret the RECONCILED bytes want: the write seam can grow the
127
- // fence or drop a character, either of which moves the caret off the DOM's.
128
- commitInput: (text, preEdit, savedOffset) => commitDisplay(text, preEdit, savedOffset)
122
+ getFocusOffset: backend.getFocusOffset,
123
+ getTextLen: () => plainTextOf(el).length,
124
+ readText: () => plainTextOf(el),
125
+ commitInput: (text, preEdit, savedOffset) => commitDisplay(text, preEdit, savedOffset),
126
+ handleBeforeInput: onBeforeInput
129
127
  });
130
128
 
131
129
  const crossBlock = editableSurface.crossBlock;
@@ -136,27 +134,9 @@
136
134
  export const editable = true;
137
135
  export const focusable = true;
138
136
 
139
- // Every caret-landing door clamps onto editable content: a caret on a fence line
140
- // takes keystrokes the fence guard refuses, and a PARKED caret there is as dead as
141
- // a placed one, so both verbs clamp.
142
- export function focus(offset: number): void {
143
- editableSurface.surface.focus(clampCaretToBody(node, offset));
144
- }
145
-
146
- export function parkCaret(offset: number): void {
147
- editableSurface.surface.parkCaret(clampCaretToBody(node, offset));
148
- }
149
-
150
- // The column walk resolves against pixels, so it can only be corrected after the
151
- // fact: re-seat when it lands on a fence line, leave it alone when it doesn't.
152
- export function focusAtColumn(x: number, from: StickyColumnDirection): void {
153
- editableSurface.surface.focusAtColumn(x, from);
154
- const landed = backend.getRaw();
155
- if (landed === null) return;
156
- const seated = clampCaretToBody(node, landed);
157
- if (seated !== landed) backend.setRaw(asRawOffset(seated));
158
- }
159
-
137
+ export const focus = editableSurface.surface.focus;
138
+ export const parkCaret = editableSurface.surface.parkCaret;
139
+ export const focusAtColumn = editableSurface.surface.focusAtColumn;
160
140
  export const getCursorOffset = editableSurface.surface.getCursorOffset;
161
141
  export const getSelectedText = editableSurface.surface.getSelectedText;
162
142
  export const setSelection = editableSurface.surface.setSelection;
@@ -168,24 +148,17 @@
168
148
  return trimTrailingLineEnding(node.raw);
169
149
  }
170
150
 
171
- /**
172
- * The block's ONE display-commit door: no gesture calls `updateBlockContent` directly (pinned
173
- * by `lint/code-commit-funnel`). The write seam sits inside rather than at each caller, so
174
- * every gesture gets fence reconciliation by construction.
175
- */
176
- function commitDisplay(display: string, undoAnchor: number, caret: number): number {
177
- const written = reconcileFenceWrite({
178
- display,
179
- caret,
180
- fence: fenceShapeOf(node),
181
- mode: 'authored'
182
- });
183
- void blockEdit.updateBlockContent(
151
+ /** Commits edited display text and returns the caret as stored, since the fence rule can grow
152
+ * the fence or drop a character; null when the write was refused. */
153
+ function commitDisplay(display: string, undoAnchor: number, caret: number): number | null {
154
+ const write = blockEdit.updateBlockContent(
184
155
  index,
185
- written.display + trailingLineEnding(node.raw),
186
- undoAnchor
156
+ display + blockEnding(),
157
+ 'authored',
158
+ undoAnchor,
159
+ caret
187
160
  );
188
- return written.caret;
161
+ return write.admitted ? write.caret : null;
189
162
  }
190
163
 
191
164
  $effect(() => {
@@ -193,34 +166,24 @@
193
166
  if (node.raw === lastRenderedRaw && pendingCursorOffset === null && pendingSelection === null)
194
167
  return;
195
168
 
196
- el.replaceChildren(renderCodeBlock(node));
169
+ el.replaceChildren(renderCodeBlock(node, activePlugins));
197
170
  anchorTrailingNewline(el);
198
- // The walk container's own stamp, and the only surviving consumer of the emptiness
199
- // read: both the marker-hiding CSS and the caret walk key off this attribute. The
200
- // rail no longer gates on it — a content-empty fence gets one either way.
171
+ // The marker-hiding CSS and the caret traversal read this attribute; the side gutter does
172
+ // not, since an empty fence gets one either way.
201
173
  el.toggleAttribute(CONTENT_EMPTY_ATTR, holdsOnlyMarkerChrome(el));
202
174
  lastRenderedRaw = node.raw;
203
175
 
204
- // Restore only while this block still holds focus: an edit reparsing to multiple
205
- // blocks moves the caret to the split-off sibling, and a blur would otherwise yank
206
- // the global selection back. The pending fields clear regardless, never re-armed.
176
+ // Restore only while this block holds focus: an edit reparsing into several blocks moves
177
+ // the caret to the split-off sibling. The pending fields clear either way.
207
178
  if (pendingSelection !== null) {
208
- consumePendingRestore(el, pendingSelection, (range) => {
209
- const domRange = createRangeFromOffsets(
210
- el!,
211
- asDomTextOffset(range.start),
212
- asDomTextOffset(range.end)
213
- );
214
- if (!domRange) return;
215
- const sel = window.getSelection();
216
- sel?.removeAllRanges();
217
- sel?.addRange(domRange);
218
- });
179
+ consumePendingRestore(el, pendingSelection, (range) =>
180
+ selectRawRange(el!, range.start, range.end)
181
+ );
219
182
  pendingSelection = null;
220
183
  pendingCursorOffset = null;
221
184
  } else if (pendingCursorOffset !== null) {
222
185
  consumePendingRestore(el, pendingCursorOffset, (offset) =>
223
- setCursorOffset(el!, asDomTextOffset(offset))
186
+ backend.setRaw(asRawOffset(offset), { clamp: 'exact' })
224
187
  );
225
188
  pendingCursorOffset = null;
226
189
  }
@@ -228,48 +191,47 @@
228
191
 
229
192
  useParkFocusOnUnmount(() => el ?? null, getEditorRoot);
230
193
 
231
- // ── The rail ──────────────────────────────────────────────────────────────
194
+ // A commit can turn this block into another kind (a `math` info string makes a math fence),
195
+ // and a step deferred past that commit then has no code block left to act on.
196
+ const isStillCode = () => node.kind === 'fencedCode';
197
+
198
+ // ── The side gutter ───────────────────────────────────────────────────────
232
199
 
233
- // The rail stands in for fence chrome the mode paints nothing for: never in source, which
234
- // paints its own always. A content-empty block DOES paint dimmed markers of its own and
235
- // still gets the rail — the picker is the authoring path now, and a fence with no language
236
- // is exactly where it is wanted. The two overlapping is the same accepted redundancy as a
237
- // focused preview block showing fence and rail together.
200
+ // The side gutter stands in for fence markers the mode does not draw, so source mode never gets
201
+ // one. An empty fence gets it too, dimmed markers and all: the picker is how a language is set.
238
202
  const showRail = $derived(hidesMarkers(presentationMode));
239
203
  const infoString = $derived(metadataOf(node, 'fencedCode').info);
240
204
 
241
- /** The fence body alone, which is what a host executes or a copy writes — never the
242
- * opener and closer lines, which are this block's syntax rather than its content. */
205
+ /** The fence body alone, which is what a host runs or a copy writes, never the opener
206
+ * and closer lines, which are this block's syntax rather than its content. */
243
207
  function bodyText(): string {
244
208
  return sliceFencedCode(node).body;
245
209
  }
246
210
 
247
211
  function runRequest(): CodeRunRequest {
248
- return { code: bodyText(), info: infoString, path: myPath };
212
+ return {
213
+ code: bodyText(),
214
+ info: infoString,
215
+ language: fenceLanguage(infoString),
216
+ path: myPath
217
+ };
249
218
  }
250
219
 
251
- /**
252
- * A fence with no language and no body, the moment it takes focus. Gated on FIRST focus
253
- * per mount, not on the creating edit: a block made by an insert command mounts AFTER the
254
- * commit that made it and never hears that edit, so the caret arriving is the only signal
255
- * every creation path shares. Loading a document focuses nothing and opens no pickers.
256
- */
220
+ /** Offers the language picker on the first focus of an empty fence with no language. Keyed on
221
+ * focus, since a block an insert command creates mounts after that commit. */
257
222
  let autoOpenLanguage = $state(false);
258
223
  let languageOffered = false;
259
224
  function onSurfaceFocus(): void {
260
225
  if (languageOffered || readOnly || !showRail) return;
261
226
  languageOffered = true;
262
- // A caret that STEPPED into an existing fence is passing through, and a picker taking
263
- // focus there traps the walk. A typed opener is still open, and a click or an insert
264
- // command seats the caret with no arrival key noted: those are the authoring moments.
265
- const steppedIn = metadataOf(node, 'fencedCode').closed && edgeAffinity.get() !== null;
266
- const offerLanguage = infoString === '' && bodyText().trim() === '' && !steppedIn;
267
- // Deferred past the commit's OWN focus work. Creating a fence focuses this surface
268
- // twice — once as it mounts, once when the commit seats its caret — and opening on the
269
- // first would put the field up only for the second to blur it straight back down. A
270
- // fence that is still bare is completed first (language or not), so the picker opens
271
- // over a real block.
227
+ // A caret that stepped into an existing fence is passing through, and a picker would trap
228
+ // it; a click or an insert command records no arrival key, and that is the user authoring.
229
+ const steppedIn = metadataOf(node, 'fencedCode').closed && caretMemory.side() !== null;
230
+ const offerLanguage = infoString === '' && isBlankText(bodyText()) && !steppedIn;
231
+ // Deferred past the commit's own caret placement, which focuses this block a second time
232
+ // and would blur a picker opened on the first. A bare fence is completed before it opens.
272
233
  void tick().then(() => {
234
+ if (!isStillCode()) return;
273
235
  const completed = completeBareFence();
274
236
  if (!offerLanguage) return;
275
237
  if (completed) {
@@ -282,22 +244,17 @@
282
244
  });
283
245
  }
284
246
 
285
- /**
286
- * A fence with no body line — a just-typed opener, or an opener glued to its closer — is a
287
- * block whose only bytes are its own chrome: nowhere for a caret, so the markers must paint.
288
- * Writes opener, one empty body line, closer, with the caret on that line. Block math gets
289
- * this from the Enter-completion seam, which a fence cannot use: ``` parses as an (unclosed)
290
- * fence the moment it is typed, so no paragraph is left for that seam to claim.
291
- */
247
+ /** A fence with no body line has nowhere for a caret, so it is written as opener, one empty
248
+ * body line and closer, with the caret on that line. True when it wrote. */
292
249
  function completeBareFence(): boolean {
293
250
  if (!el) return false;
294
251
  const meta = metadataOf(node, 'fencedCode');
295
252
  const slice = sliceFencedCode(node);
296
253
  const text = getDisplayText();
297
- const ending = trailingLineEnding(node.raw);
254
+ const ending = blockEnding();
298
255
  const offset = backend.getRaw() ?? 0;
299
256
  if (!meta.closed) {
300
- if (slice.body.trim() !== '') return false;
257
+ if (!isBlankText(slice.body)) return false;
301
258
  const closer = meta.fenceMarker.repeat(meta.fenceLength);
302
259
  const completed = text + ending + ending + closer;
303
260
  pendingCursorOffset = commitDisplay(completed, offset, text.length + ending.length);
@@ -321,11 +278,11 @@
321
278
  }
322
279
  }
323
280
 
324
- // The chip's write: the opener's info span, through the display funnel so the fence rule
325
- // runs over it, isolated so no typing burst on either side joins its undo entry.
281
+ // What the language chip writes: the opener's info string, through the one commit above so
282
+ // the fence rule runs over it, kept apart so no typing on either side joins its undo entry.
326
283
  function commitLanguage(info: string): void {
327
- // Unchanged or refused bytes are a close, not a write — no entry, no edit event. The seed
328
- // is `meta.info`, TRIMMED, so a byte test alone lets a bare Enter respell a padded fence.
284
+ // Unchanged or refused bytes close the field without writing. The field starts from the
285
+ // trimmed info, so comparing fence bytes alone would let a bare Enter respell padding.
329
286
  if (info === infoString) {
330
287
  returnCaretToBody();
331
288
  return;
@@ -339,22 +296,16 @@
339
296
  returnCaretToBody();
340
297
  }
341
298
 
342
- /**
343
- * This block's own door, not `moveFocus`: the rail is chrome over one block. Offset 0 is
344
- * NOT the body — on an UNCLOSED fence the opener run counts as content by design (that is
345
- * what lets a just-typed ` ``` ` be deleted back out), so `focus(0)` parks the caret BEFORE
346
- * the backticks and the next keystroke rewrites the opener. `clampRangeToBody` clamps
347
- * unconditionally, which is the "wherever the body starts" this needs.
348
- */
299
+ /** Puts the caret at the body start after the side gutter closes; not `focus(0)`, which on an
300
+ * unclosed fence sits before the backticks. */
349
301
  function returnCaretToBody(): void {
350
- // Focus first and SEAT through the pending-caret channel the render effect drains. A
351
- // bare `focus()` after a tick raced the commit's own re-render, which replaces every
352
- // child of the walk container and dropped the seat on the floor.
302
+ // The caret goes through the pending field the render effect reads: a bare `focus()` after
303
+ // a tick races the commit's re-render, which replaces every child and loses the caret.
353
304
  el?.focus({ preventScroll: true });
354
305
  void tick().then(() => {
355
- // Read the body AFTER the commit lands. Writing a language lengthens the opener, so
356
- // an offset measured against the pre-commit node points into the info string that
357
- // just grew — the caret arrived inside `js` and typing split it.
306
+ if (!isStillCode()) return;
307
+ // Read the body after the commit lands: a new language lengthens the opener, so an
308
+ // offset taken before the commit would put the caret inside the info string.
358
309
  const at = clampRangeToBody(node, { start: 0, end: 0 }).start;
359
310
  pendingCursorOffset = at;
360
311
  focus(at);
@@ -366,16 +317,18 @@
366
317
  const onInput = editableSurface.onInput;
367
318
  const onCompositionEnd = editableSurface.onCompositionEnd;
368
319
 
369
- // An IME deletes the selection as it starts composing, and beforeinput's
370
- // insertCompositionText is not cancelable — so a fence-crossing selection shrinks
371
- // onto its body span here, before the composition owns the surface.
320
+ // An IME deletes the selection as it starts composing, and its `insertCompositionText` is not
321
+ // cancelable, so with the fence lines hidden the block deletes the body part itself first.
372
322
  function onCompositionStart(): void {
373
- const sel = el ? getSelectionOffsets(el) : null;
374
- if (sel && crossesFenceBoundary(node, sel)) {
375
- const span = fenceEditSpan(node, sel);
376
- setSelection(span.start, span.end);
377
- }
323
+ const sel = backend.getRawSelection();
378
324
  editableSurface.onCompositionStart();
325
+ if (!sel || sel.start === sel.end || fenceLinesEditable) return;
326
+ const edit = computeFenceRangedEdit(node, sel, '');
327
+ const caret = edit ? edit.newCursor : clampCaretToBody(node, sel.start);
328
+ // Synchronous, since the IME composes at wherever the caret is once this handler returns.
329
+ if (edit) pendingCursorOffset = commitDisplay(edit.newText, caret, caret);
330
+ else setSelection(caret, caret);
331
+ editableSurface.notePreEditOffset(caret);
379
332
  }
380
333
 
381
334
  async function onBeforeInput(e: InputEvent): Promise<void> {
@@ -385,15 +338,17 @@
385
338
  // Gated on !composing so an IME emitting it mid-composition does not sync.
386
339
  if (e.inputType === 'insertLineBreak' && !composing && el) {
387
340
  e.preventDefault();
388
- // Mobile/IME paths skip onKeyDown so preEditOffset may be stale; capture fresh.
389
- const branchPreEditOffset = backend.getRaw() ?? 0;
390
341
  const result = computeCodeEnter({
391
342
  display: getDisplayText(),
392
343
  selection: enterSpliceSpan(currentRange()),
393
344
  mode: 'soft',
394
- ending: trailingLineEnding(node.raw)
345
+ ending: blockEnding()
395
346
  });
396
- pendingCursorOffset = commitDisplay(result.newText, branchPreEditOffset, result.newCursor);
347
+ pendingCursorOffset = commitDisplay(
348
+ result.newText,
349
+ editableSurface.getPreEditOffset(),
350
+ result.newCursor
351
+ );
397
352
  return;
398
353
  }
399
354
  if (composing || e.inputType !== 'insertText' || !el) return;
@@ -401,7 +356,10 @@
401
356
  if (!data || data.length !== 1) return;
402
357
 
403
358
  const text = getDisplayText();
404
- const selOffsets = getSelectionOffsets(el);
359
+ const rawSelection = backend.getRawSelection();
360
+ // A wrap is the one range edit that reaches here; with the fence lines hidden it wraps the body.
361
+ const selOffsets =
362
+ rawSelection && !fenceLinesEditable ? fenceEditSpan(node, rawSelection) : rawSelection;
405
363
  const offset = selOffsets ? selOffsets.start : (backend.getRaw() ?? 0);
406
364
 
407
365
  const meta = metadataOf(node, 'fencedCode');
@@ -416,6 +374,8 @@
416
374
  return;
417
375
  }
418
376
 
377
+ // A marker run is syntax, not code: a backtick typed onto one widens the fence instead.
378
+ if (collapsed && !isInBody(offset)) return;
419
379
  const result = computeAutoPair({
420
380
  text,
421
381
  selection: selOffsets ?? { start: offset, end: offset },
@@ -426,63 +386,71 @@
426
386
 
427
387
  e.preventDefault();
428
388
  if (result.kind === 'skip') {
429
- setCursorOffset(el, asDomTextOffset(result.caretOffset));
389
+ backend.setRaw(asRawOffset(result.caretOffset), { clamp: 'exact' });
430
390
  return;
431
391
  }
432
392
  if (result.kind === 'wrap') {
433
- // Both endpoints sit inside the body, so whatever the seam inserts ahead of
434
- // the wrap's start moves its end by the same delta.
435
- const start = commitDisplay(result.newText, preEditOffset, result.selection.start);
393
+ // Both endpoints sit inside the body, so whatever is inserted ahead of the
394
+ // wrap's start moves its end by the same amount.
395
+ const start = commitDisplay(
396
+ result.newText,
397
+ editableSurface.getPreEditOffset(),
398
+ result.selection.start
399
+ );
400
+ if (start === null) return;
436
401
  const shift = start - result.selection.start;
437
402
  pendingSelection = { start, end: result.selection.end + shift };
438
403
  } else {
439
- pendingCursorOffset = commitDisplay(result.newText, preEditOffset, result.caretOffset);
404
+ pendingCursorOffset = commitDisplay(
405
+ result.newText,
406
+ editableSurface.getPreEditOffset(),
407
+ result.caretOffset
408
+ );
440
409
  }
441
410
  }
442
411
 
443
412
  // ── Fence-crossing edits ──────────────────────────────────────────────────
444
413
 
445
- /**
446
- * Where an Enter-family splice lands (the `code.newline` command and the soft
447
- * break): a caret clamps out of the fence lines, a selection is replaced on its
448
- * body span like every other ranged edit here.
449
- */
450
- function enterSpliceSpan(range: CodeRange): CodeRange {
414
+ /** Where an Enter or soft break splices: a caret clamps out of the fence lines, and a
415
+ * selection is replaced on its body span like every other ranged edit here. */
416
+ function enterSpliceSpan(range: RawRange): RawRange {
451
417
  if (range.start !== range.end) return fenceEditSpan(node, range);
452
418
  const at = clampEnterOffsetToBody(node, range.start);
453
419
  return { start: at, end: at };
454
420
  }
455
421
 
456
- /**
457
- * The one guard for every native edit that rewrites a range here — delete,
458
- * forward-delete, type-over, word delete, drag. One that crosses a fence line is
459
- * re-sited onto the body rather than left to splice the fence away.
460
- */
422
+ /** The one check for every browser edit that rewrites a range here. With the fence lines
423
+ * hidden, one that crosses a fence line moves onto the body instead of splicing it away. */
461
424
  function guardFenceRangedEdit(e: InputEvent): boolean {
462
- if (composing || !el) return false;
463
- const range = pendingEditRange(e, el);
425
+ if (composing || !el || fenceLinesEditable) return false;
426
+ const range = pendingEditRange(e);
464
427
  if (!range) return false;
465
- if (!crossesFenceBoundary(node, range)) return guardHiddenFenceDelete(e, range);
428
+ if (wrapsBody(e, range)) return false;
429
+ // Chromium's own replace of a range opening on a highlighted token also removes the hidden
430
+ // opener, so the block writes every replacement, inside the body or not.
431
+ if (!crossesFenceBoundary(node, range) && !replacesRange(e, range)) {
432
+ return guardHiddenFenceDelete(e, range);
433
+ }
466
434
 
467
435
  e.preventDefault();
468
436
  const insert = rangedEditInsertion(e, fenceEditSpan(node, range));
469
437
  if (insert === null) return true;
470
438
  const edit = computeFenceRangedEdit(node, range, insert);
471
439
  if (!edit) return true;
472
- // Mobile/IME beforeinput arrives without a preceding keydown, so the undo
473
- // anchor reads fresh rather than trusting preEditOffset (see the soft-break arm).
474
- pendingCursorOffset = commitDisplay(edit.newText, backend.getRaw() ?? 0, edit.newCursor);
440
+ pendingCursorOffset = commitDisplay(
441
+ edit.newText,
442
+ editableSurface.getPreEditOffset(),
443
+ edit.newCursor
444
+ );
475
445
  return true;
476
446
  }
477
447
 
478
448
  /**
479
- * A delete while the fence lines hide is applied here, whatever range the engine reports:
480
- * Chromium, deleting the last visible character of a line, also removes the unrendered nodes
481
- * beside it — the opener's whole fence line — so a Backspace on the last body character
482
- * left `\n\`\`\`` and reparsed the block into a fresh fence. The span is clamped to the body.
449
+ * A delete while the fence lines are hidden is applied here, clamped to the body: Chromium,
450
+ * deleting the last visible character of a line, also removes the unrendered fence line beside it.
483
451
  */
484
- function guardHiddenFenceDelete(e: InputEvent, range: CodeRange): boolean {
485
- if (!showRail || !/^delete(?!By)/.test(e.inputType)) return false;
452
+ function guardHiddenFenceDelete(e: InputEvent, range: RawRange): boolean {
453
+ if (!/^delete(?!By)/.test(e.inputType)) return false;
486
454
  e.preventDefault();
487
455
  const span = clampRangeToBody(node, range);
488
456
  if (span.end > span.start) {
@@ -496,39 +464,49 @@
496
464
  return true;
497
465
  }
498
466
 
499
- /**
500
- * What the pending edit will rewrite. `getTargetRanges()` is the authority — a word
501
- * delete at a collapsed caret reports the word, not the caret — and is
502
- * feature-detected because jsdom does not implement it.
503
- */
504
- function pendingEditRange(e: InputEvent, surface: HTMLElement): CodeRange | null {
467
+ function isInBody(offset: number): boolean {
468
+ const body = bodyWindow(node);
469
+ return offset >= body.start && offset <= body.end;
470
+ }
471
+
472
+ function replacesRange(e: InputEvent, range: RawRange): boolean {
473
+ const replacing = e.inputType === 'insertText' || e.inputType === 'insertReplacementText';
474
+ return replacing && range.start !== range.end;
475
+ }
476
+
477
+ /** A bracket or quote typed over a range wraps it (the auto-pair path), unless the range
478
+ * holds no body at all. */
479
+ function wrapsBody(e: InputEvent, range: RawRange): boolean {
480
+ if (e.inputType !== 'insertText' || e.data?.length !== 1 || range.start === range.end) {
481
+ return false;
482
+ }
483
+ return getCloserFor(e.data) !== null && !isStructureOnlyRange(node, range);
484
+ }
485
+
486
+ /** `getTargetRanges()` wins, since a word delete at a collapsed caret reports the word; it is
487
+ * feature-detected because jsdom lacks it. */
488
+ function pendingEditRange(e: InputEvent): RawRange | null {
505
489
  const targets = typeof e.getTargetRanges === 'function' ? e.getTargetRanges() : [];
506
- if (targets.length > 0) return getRangeOffsets(surface, targets[0]);
507
- const selected = getSelectionOffsets(surface);
490
+ if (targets.length > 0) return backend.rawRangeOf(targets[0]);
491
+ const selected = backend.getRawSelection();
508
492
  if (selected) return selected;
509
493
  const caret = backend.getRaw();
510
494
  return caret === null ? null : { start: caret, end: caret };
511
495
  }
512
496
 
513
- /**
514
- * The text each claimed input type writes over its span: only a payload readable off the event
515
- * or mintable here is re-sited, every other type is REFUSED (null: prevented, nothing
516
- * committed). Text riding a `dataTransfer` would reach `parse()` without the paste transforms
517
- * (G4.11).
518
- */
519
- function rangedEditInsertion(e: InputEvent, span: CodeRange): string | null {
497
+ /** The text an input type writes over its span, or null to refuse it. A `dataTransfer`
498
+ * payload is refused, since it would skip the paste transforms (G4.11). */
499
+ function rangedEditInsertion(e: InputEvent, span: RawRange): string | null {
520
500
  if (e.inputType.startsWith('delete')) return '';
521
501
  switch (e.inputType) {
522
502
  case 'insertText':
523
503
  return e.data ?? '';
524
504
  case 'insertLineBreak':
525
- return trailingLineEnding(node.raw);
505
+ return blockEnding();
526
506
  // The keydown path auto-indents (computeCodeEnter 'normal'), and a mobile or
527
507
  // IME insertParagraph is the same gesture arriving without a keydown.
528
508
  case 'insertParagraph':
529
- return (
530
- trailingLineEnding(node.raw) + getLineLeadingWhitespace(getDisplayText(), span.start)
531
- );
509
+ return blockEnding() + getLineLeadingWhitespace(getDisplayText(), span.start);
532
510
  default:
533
511
  return null;
534
512
  }
@@ -538,11 +516,9 @@
538
516
  if (composing) return;
539
517
  if (!el) return;
540
518
 
541
- preEditOffset = backend.getRaw() ?? 0;
542
-
543
519
  if ((await handleSharedKeydown(e, sharedCtx)) || editableSurface.isDetached()) return;
544
520
 
545
- if (wiring.dispatchChord(e, { kind: node.kind, runCommand })) return;
521
+ if (wiring.dispatchChord(e, { kind: node.kind, runCommand, getPath: () => myPath })) return;
546
522
  }
547
523
 
548
524
  const onKeyDownTraced = withKeydownVerdict(onKeyDown);
@@ -550,7 +526,6 @@
550
526
  // ── Commands ────────────────────────────────────────────────────────
551
527
 
552
528
  export function runCommand(id: CommandId): boolean {
553
- if (reorderRunCommand(id, reorder, () => myPath)) return true;
554
529
  switch (id) {
555
530
  case 'format.toggleStrong':
556
531
  case 'format.toggleEmphasis':
@@ -576,21 +551,18 @@
576
551
  }
577
552
 
578
553
  function codeBackspace(): boolean {
579
- if (!el || hasSelection()) return false;
554
+ if (!el || backend.getRawSelection() !== null) return false;
580
555
  const offset = backend.getRaw() ?? 0;
581
- // offset===0 is the universal contract; the classifyFenceBoundary check catches the
582
- // fence boundary, where a native Backspace would delete the opener's terminating `\n`.
556
+ // Offset 0 always leaves the block; so does the body start, where a native Backspace would
557
+ // delete the opener's terminating `\n`.
583
558
  if (
584
559
  offset === 0 ||
585
560
  classifyFenceBoundary({ node, offset, forward: false }).kind === 'exitPrev'
586
561
  ) {
587
- // At the top of an EMPTY fence the block is the only thing the press could mean:
588
- // there is no text to delete and nothing to merge, and stepping the caret out
589
- // leaves a block the user just asked to be rid of. A fence with a body keeps the
590
- // step-out — one press must never take code with it.
591
- if (bodyText().trim() === '') {
592
- void blockEdit.deleteBlock(index);
593
- focusActions.moveFocus(index - 1, 'end');
562
+ // At the top of an empty fence the key can only mean the block, so it goes; a fence
563
+ // with a body keeps the step-out, since one keypress must never take code with it.
564
+ if (isBlankText(bodyText())) {
565
+ void blockEdit.deleteBlock(index, 'Backspace');
594
566
  return true;
595
567
  }
596
568
  focusActions.moveFocus(index - 1, 'end');
@@ -603,14 +575,14 @@
603
575
  const pairSpan = { start: offset - 1, end: offset + 1 };
604
576
  if (isBetweenEmptyPair(text, offset) && !crossesFenceBoundary(node, pairSpan)) {
605
577
  const newText = text.slice(0, offset - 1) + text.slice(offset + 1);
606
- pendingCursorOffset = commitDisplay(newText, preEditOffset, offset - 1);
578
+ pendingCursorOffset = commitDisplay(newText, offset, offset - 1);
607
579
  return true;
608
580
  }
609
581
  return false;
610
582
  }
611
583
 
612
584
  function codeDelete(): boolean {
613
- if (!el || hasSelection()) return false;
585
+ if (!el || backend.getRawSelection() !== null) return false;
614
586
  const offset = backend.getRaw() ?? 0;
615
587
  if (classifyFenceBoundary({ node, offset, forward: true }).kind === 'exitNext') {
616
588
  // The root's forward asymmetry (past-end appends a paragraph) would strand a
@@ -622,17 +594,16 @@
622
594
  }
623
595
 
624
596
  // The browser's insertParagraph adds <div>/<br> elements that don't affect
625
- // textContent, so the CST never sees the edit — handle Enter via the CST path.
597
+ // textContent, so the CST never sees the edit; Enter goes through the CST instead.
626
598
  function codeNewline(): boolean {
627
599
  if (!el) return false;
628
- // Read the caret live: cross-block dispatch calls runCommand without an
629
- // onKeyDown to refresh preEditOffset, so the undo anchor must read fresh.
600
+ // Read live: a command dispatched from another block arrives with no input event here.
630
601
  const offset = backend.getRaw() ?? 0;
631
602
  const text = getDisplayText();
632
603
  const meta = metadataOf(node, 'fencedCode');
633
604
 
634
605
  // Source mode paints the markers and never completes a bare fence on focus, so Enter is
635
- // where it happens there; the marker-hiding rungs already did it as the caret arrived.
606
+ // where it happens there; the marker-hiding modes did it as the caret arrived.
636
607
  if (completeBareFence()) {
637
608
  if (infoString === '' && !readOnly && !languageOffered) {
638
609
  languageOffered = true;
@@ -645,7 +616,7 @@
645
616
 
646
617
  const exit = computeFenceExit({ text, offset, meta });
647
618
  if (exit.kind === 'closeAndExit') {
648
- closeUnclosedFenceAndDescend(exit.newText);
619
+ closeUnclosedFenceAndDescend(exit.newText, offset);
649
620
  return true;
650
621
  }
651
622
  if (exit.kind !== 'none') {
@@ -662,7 +633,7 @@
662
633
 
663
634
  // Electric indent: between an empty bracket pair, expand into three lines with an
664
635
  // extra indent on the middle. Quote pairs stay inline; a selection is replaced.
665
- const ending = trailingLineEnding(node.raw);
636
+ const ending = blockEnding();
666
637
  if (span.start === span.end && isBetweenEmptyBracketPair(text, span.start)) {
667
638
  const at = span.start;
668
639
  const indent = getLineLeadingWhitespace(text, at);
@@ -683,9 +654,8 @@
683
654
  return true;
684
655
  }
685
656
 
686
- // A closed-fence Enter-exit lands within the fence's OWN container scope: the next
687
- // sibling, else a paragraph minted in-scope. Without this a nested last child would
688
- // delegate the caret outside its container.
657
+ // Leaving a closed fence with Enter stays inside the fence's own container (the next sibling,
658
+ // or a new paragraph there), so a nested last child keeps the caret inside.
689
659
  function exitDownward(): void {
690
660
  const container = myPath.length > 1 ? nodeAt(getDoc(), myPath.slice(0, -1)) : null;
691
661
  const isNestedLastChild = !!container?.children && index === container.children.length - 1;
@@ -693,11 +663,11 @@
693
663
  else focusActions.moveFocus(index + 1, 'start');
694
664
  }
695
665
 
696
- // Leaving an unclosed fence downward mints its closer, keeping save→reload from lazy-absorbing
697
- // the trailing blocks into it. Closer and fresh paragraph land as ONE replaceBlock commit.
698
- function closeUnclosedFenceAndDescend(closedDisplay: string): void {
666
+ // Leaving an unclosed fence downward writes its closer, which stops a save and reload from
667
+ // absorbing the blocks below into it. Closer and new paragraph land as one commit.
668
+ function closeUnclosedFenceAndDescend(closedDisplay: string, caretBefore: number): void {
699
669
  const meta = metadataOf(node, 'fencedCode');
700
- const lineEnding = trailingLineEnding(node.raw);
670
+ const lineEnding = blockEnding();
701
671
  const closedFence: CstNode = {
702
672
  kind: 'fencedCode',
703
673
  leadingTrivia: '',
@@ -705,12 +675,14 @@
705
675
  metadata: { ...meta, closed: true }
706
676
  };
707
677
  // The blank separator line and the paragraph's own line are both pure line
708
- // ending, so both take the fence's (G4.20) — the same one the closer above got.
678
+ // ending, so both take the one the closer above got.
709
679
  const paragraphBelow = emptyParagraph(lineEnding, lineEnding);
710
- void blockEdit.replaceBlock(index, [closedFence, paragraphBelow], {
711
- replacementIndex: 1,
712
- offset: 0
713
- });
680
+ void blockEdit.replaceBlock(
681
+ index,
682
+ [closedFence, paragraphBelow],
683
+ { replacementIndex: 1, offset: 0 },
684
+ { snapshotOffset: caretBefore }
685
+ );
714
686
  }
715
687
 
716
688
  void ({
@@ -726,14 +698,15 @@
726
698
 
727
699
  function currentRange(): { start: number; end: number } {
728
700
  if (!el) return { start: 0, end: 0 };
729
- const sel = getSelectionOffsets(el);
701
+ const sel = backend.getRawSelection();
730
702
  if (sel) return sel;
731
703
  const cursor = backend.getRaw() ?? 0;
732
704
  return { start: cursor, end: cursor };
733
705
  }
734
706
 
735
- function applyIndentResult(result: IndentResult): void {
736
- const start = commitDisplay(result.text, result.selection.start, result.selection.start);
707
+ function applyIndentResult(result: IndentResult, caretBefore: number): void {
708
+ const start = commitDisplay(result.text, caretBefore, result.selection.start);
709
+ if (start === null) return;
737
710
  if (result.selection.start === result.selection.end) {
738
711
  pendingCursorOffset = start;
739
712
  return;
@@ -744,20 +717,21 @@
744
717
  pendingSelection = { start, end: result.selection.end + shift };
745
718
  }
746
719
 
747
- // Both gestures rewrite whole LINES, so their range clamps out of the fence lines —
748
- // the multi-line sibling of codeNewline's clampEnterOffsetToBody. `el` is required
749
- // only because currentRange() reads the DOM selection through it.
720
+ // Indent and dedent rewrite whole lines, so their range clamps off the fence lines. `el` is
721
+ // checked only because `currentRange()` reads the DOM selection through it.
750
722
  function indentSelection(): void {
751
723
  if (!el) return;
752
- applyIndentResult(indentLines(getDisplayText(), clampRangeToBody(node, currentRange())));
724
+ const range = clampRangeToBody(node, currentRange());
725
+ applyIndentResult(indentLines(getDisplayText(), range), range.start);
753
726
  }
754
727
 
755
728
  function dedentSelection(): void {
756
729
  if (!el) return;
757
730
  const text = getDisplayText();
758
- const result = dedentLines(text, clampRangeToBody(node, currentRange()));
731
+ const range = clampRangeToBody(node, currentRange());
732
+ const result = dedentLines(text, range);
759
733
  if (result.text === text) return;
760
- applyIndentResult(result);
734
+ applyIndentResult(result, range.start);
761
735
  }
762
736
 
763
737
  // ── Pointer + clipboard ─────────────────────────────────────────────
@@ -766,11 +740,10 @@
766
740
  void crossBlock.handlePointerDown(e);
767
741
  }
768
742
 
769
- // Code has no ambient markers, so its DOM-text selection IS its raw slice: copy falls
770
- // to the seam's visible-selection default, and cut writes that string before deleting.
743
+ // Code has no marker prefix, so a selection of its DOM text is a slice of its raw: copy
744
+ // falls back to the shared visible-selection default, and cut writes that before deleting.
771
745
  const clipboard = createClipboardHandlers({
772
- stickyColumn,
773
- edgeAffinity,
746
+ caretMemory,
774
747
  selection,
775
748
  getDoc,
776
749
  crossBlock,
@@ -778,24 +751,26 @@
778
751
  caret: editableSurface.caret,
779
752
  events: editorEvents,
780
753
  onPasteImage,
781
- // Copy is verbatim while the delete clamps: the clipboard keeps the literal bytes
782
- // selected, fence characters included, and only the body half is removed.
754
+ // Copy is verbatim; where the fence lines are hidden the delete clamps, so the clipboard keeps
755
+ // the fence characters selected while only the body half is removed.
783
756
  cutTail: (e) => {
784
757
  e.clipboardData?.setData('text/plain', window.getSelection()?.toString() ?? '');
785
758
  if (!el) return;
786
- const selOffsets = getSelectionOffsets(el);
759
+ const selOffsets = backend.getRawSelection();
787
760
  if (!selOffsets) return;
788
- const edit = computeFenceRangedEdit(node, selOffsets, '');
761
+ const edit = fenceLinesEditable
762
+ ? computeRangedEdit(getDisplayText(), selOffsets, '')
763
+ : computeFenceRangedEdit(node, selOffsets, '');
789
764
  if (!edit) return;
790
765
  pendingCursorOffset = commitDisplay(edit.newText, edit.newCursor, edit.newCursor);
791
766
  },
792
767
  pasteTail: async (pastedText) => {
793
768
  if (!el) return;
794
- // Paste refuses where typing refuses: a target confined to fence structure has
795
- // nothing to paste into. The tree-op owns the splice, so the span goes to it.
769
+ // Where the fence lines are hidden, paste refuses where typing refuses: a target confined
770
+ // to fence structure has nothing to paste into. The tree-op owns the splice.
796
771
  const target = currentRange();
797
- if (isStructureOnlyRange(node, target)) return;
798
- const sel = fenceEditSpan(node, target);
772
+ if (!fenceLinesEditable && isStructureOnlyRange(node, target)) return;
773
+ const sel = fenceLinesEditable ? orderedRange(target) : fenceEditSpan(node, target);
799
774
  const result = await pasteDispatch(
800
775
  {
801
776
  pastedText,
@@ -807,7 +782,7 @@
807
782
  doc: getDoc(),
808
783
  blockEdit,
809
784
  controller: pasteCoordinator,
810
- grammar,
785
+ reading,
811
786
  activePlugins
812
787
  }
813
788
  );
@@ -819,23 +794,25 @@
819
794
  });
820
795
  const { onCopy, onCut, onPaste } = clipboard;
821
796
 
822
- export function insertMarkdown(md: string): boolean {
797
+ export function insertMarkdown(md: string): Promise<boolean> {
823
798
  return clipboard.insertMarkdown(md);
824
799
  }
825
800
  </script>
826
801
 
802
+ <!-- The textbox role arrives through the spread, where the compiler cannot see it. -->
803
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
827
804
  <div
828
805
  bind:this={el}
829
806
  tabindex="0"
830
807
  class="code-block"
831
808
  contenteditable={readOnly ? 'false' : 'true'}
832
809
  aria-readonly={readOnly ? 'true' : undefined}
833
- role="textbox"
810
+ {...editableSurfaceAttributes(node, null)}
834
811
  spellcheck="false"
835
812
  oninput={onInput}
836
813
  onfocus={onSurfaceFocus}
837
814
  onkeydown={onKeyDownTraced}
838
- onbeforeinput={onBeforeInput}
815
+ onbeforeinput={editableSurface.onBeforeInput}
839
816
  oncopy={onCopy}
840
817
  oncut={onCut}
841
818
  onpaste={onPaste}
@@ -843,11 +820,12 @@
843
820
  oncompositionstart={onCompositionStart}
844
821
  oncompositionend={onCompositionEnd}
845
822
  ></div>
846
- <!-- Beside the walk container, never inside it: the render effect replaces that element's
847
- children on every commit, and the offset walk counts everything that survives there. -->
823
+ <!-- Beside the editable element, never inside it: the render effect replaces that element's
824
+ children on every commit, and the offset traversal would count the gutter's text. -->
848
825
  {#if showRail}
849
826
  <CodeBlockRail
850
827
  info={infoString}
828
+ activation={activePlugins}
851
829
  editable={!readOnly}
852
830
  autoOpen={autoOpenLanguage}
853
831
  onCommit={commitLanguage}
@@ -855,6 +833,7 @@
855
833
  onRun={onRunCode ? () => onRunCode(runRequest()) : undefined}
856
834
  onCopy={copyBody}
857
835
  menuItems={codeMenuItems ? () => codeMenuItems(runRequest()) : undefined}
836
+ {menuPresence}
858
837
  />
859
838
  {/if}
860
839
 
@@ -883,7 +862,7 @@
883
862
 
884
863
  /* The caret is the primary focus signal inside the box; the border only warms, so a
885
864
  click into code does not flash a heavy ring across the page. */
886
- /* Focus lives in the rail's search field while the picker is open — outside this element —
865
+ /* Focus lives in the gutter's search field while the picker is open, outside this element,
887
866
  so the block would otherwise drop its focused look mid-interaction. */
888
867
  .code-block:focus,
889
868
  .code-block:has(~ :global(.code-rail-open)) {