@react-x11/components 0.8.0 → 0.9.0

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 (323) hide show
  1. package/README.md +95 -34
  2. package/dist/charts/node.d.ts +1 -1
  3. package/dist/charts/node.d.ts.map +1 -1
  4. package/dist/charts/node.js +6 -2
  5. package/dist/charts/node.js.map +1 -1
  6. package/dist/embed/client.d.ts +48 -3
  7. package/dist/embed/client.d.ts.map +1 -1
  8. package/dist/embed/client.js +79 -5
  9. package/dist/embed/client.js.map +1 -1
  10. package/dist/embed/index.d.ts +1 -1
  11. package/dist/embed/index.d.ts.map +1 -1
  12. package/dist/embed/index.js +1 -1
  13. package/dist/embed/index.js.map +1 -1
  14. package/dist/html/node.d.ts +3 -1
  15. package/dist/html/node.d.ts.map +1 -1
  16. package/dist/html/node.js +7 -5
  17. package/dist/html/node.js.map +1 -1
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/{markdown → internal/markdown}/ast.d.ts +12 -0
  23. package/dist/internal/markdown/ast.d.ts.map +1 -0
  24. package/dist/internal/markdown/ast.js +22 -0
  25. package/dist/internal/markdown/ast.js.map +1 -0
  26. package/dist/internal/markdown/parse.d.ts.map +1 -0
  27. package/dist/{markdown → internal/markdown}/parse.js +112 -22
  28. package/dist/internal/markdown/parse.js.map +1 -0
  29. package/dist/internal/markdown/stringify.d.ts +4 -0
  30. package/dist/internal/markdown/stringify.d.ts.map +1 -0
  31. package/dist/internal/markdown/stringify.js +684 -0
  32. package/dist/internal/markdown/stringify.js.map +1 -0
  33. package/dist/internal/markdown/tags.d.ts.map +1 -0
  34. package/dist/internal/markdown/tags.js.map +1 -0
  35. package/dist/internal/scroll.d.ts +3 -2
  36. package/dist/internal/scroll.d.ts.map +1 -1
  37. package/dist/internal/scroll.js +1 -0
  38. package/dist/internal/scroll.js.map +1 -1
  39. package/dist/maps/anchors.d.ts +98 -0
  40. package/dist/maps/anchors.d.ts.map +1 -0
  41. package/dist/maps/anchors.js +531 -0
  42. package/dist/maps/anchors.js.map +1 -0
  43. package/dist/maps/controller.d.ts +283 -0
  44. package/dist/maps/controller.d.ts.map +1 -0
  45. package/dist/maps/controller.js +743 -0
  46. package/dist/maps/controller.js.map +1 -0
  47. package/dist/maps/gl/buckets.d.ts +95 -0
  48. package/dist/maps/gl/buckets.d.ts.map +1 -0
  49. package/dist/maps/gl/buckets.js +362 -0
  50. package/dist/maps/gl/buckets.js.map +1 -0
  51. package/dist/maps/gl/build-worker.d.ts +13 -0
  52. package/dist/maps/gl/build-worker.d.ts.map +1 -0
  53. package/dist/maps/gl/build-worker.js +44 -0
  54. package/dist/maps/gl/build-worker.js.map +1 -0
  55. package/dist/maps/gl/color.d.ts +8 -0
  56. package/dist/maps/gl/color.d.ts.map +1 -0
  57. package/dist/maps/gl/color.js +57 -0
  58. package/dist/maps/gl/color.js.map +1 -0
  59. package/dist/maps/gl/cover.d.ts +51 -0
  60. package/dist/maps/gl/cover.d.ts.map +1 -0
  61. package/dist/maps/gl/cover.js +124 -0
  62. package/dist/maps/gl/cover.js.map +1 -0
  63. package/dist/maps/gl/index.d.ts +3 -0
  64. package/dist/maps/gl/index.d.ts.map +1 -0
  65. package/dist/maps/gl/index.js +20 -0
  66. package/dist/maps/gl/index.js.map +1 -0
  67. package/dist/maps/gl/markers.d.ts +28 -0
  68. package/dist/maps/gl/markers.d.ts.map +1 -0
  69. package/dist/maps/gl/markers.js +60 -0
  70. package/dist/maps/gl/markers.js.map +1 -0
  71. package/dist/maps/gl/overlays.d.ts +68 -0
  72. package/dist/maps/gl/overlays.d.ts.map +1 -0
  73. package/dist/maps/gl/overlays.js +300 -0
  74. package/dist/maps/gl/overlays.js.map +1 -0
  75. package/dist/maps/gl/pane.d.ts +12 -0
  76. package/dist/maps/gl/pane.d.ts.map +1 -0
  77. package/dist/maps/gl/pane.js +37 -0
  78. package/dist/maps/gl/pane.js.map +1 -0
  79. package/dist/maps/gl/placement.d.ts +111 -0
  80. package/dist/maps/gl/placement.d.ts.map +1 -0
  81. package/dist/maps/gl/placement.js +567 -0
  82. package/dist/maps/gl/placement.js.map +1 -0
  83. package/dist/maps/gl/renderer.d.ts +352 -0
  84. package/dist/maps/gl/renderer.d.ts.map +1 -0
  85. package/dist/maps/gl/renderer.js +1127 -0
  86. package/dist/maps/gl/renderer.js.map +1 -0
  87. package/dist/maps/gl/shaders.d.ts +120 -0
  88. package/dist/maps/gl/shaders.d.ts.map +1 -0
  89. package/dist/maps/gl/shaders.js +451 -0
  90. package/dist/maps/gl/shaders.js.map +1 -0
  91. package/dist/maps/gl/store.d.ts +115 -0
  92. package/dist/maps/gl/store.d.ts.map +1 -0
  93. package/dist/maps/gl/store.js +469 -0
  94. package/dist/maps/gl/store.js.map +1 -0
  95. package/dist/maps/gl/text.d.ts +154 -0
  96. package/dist/maps/gl/text.d.ts.map +1 -0
  97. package/dist/maps/gl/text.js +382 -0
  98. package/dist/maps/gl/text.js.map +1 -0
  99. package/dist/maps/gl/view.d.ts +54 -0
  100. package/dist/maps/gl/view.d.ts.map +1 -0
  101. package/dist/maps/gl/view.js +974 -0
  102. package/dist/maps/gl/view.js.map +1 -0
  103. package/dist/maps/index.d.ts +1 -1
  104. package/dist/maps/index.d.ts.map +1 -1
  105. package/dist/maps/index.js +216 -52
  106. package/dist/maps/index.js.map +1 -1
  107. package/dist/maps/labels.d.ts +37 -16
  108. package/dist/maps/labels.d.ts.map +1 -1
  109. package/dist/maps/labels.js +188 -119
  110. package/dist/maps/labels.js.map +1 -1
  111. package/dist/maps/node.d.ts +162 -56
  112. package/dist/maps/node.d.ts.map +1 -1
  113. package/dist/maps/node.js +607 -515
  114. package/dist/maps/node.js.map +1 -1
  115. package/dist/maps/overlay.d.ts +72 -9
  116. package/dist/maps/overlay.d.ts.map +1 -1
  117. package/dist/maps/overlay.js +108 -28
  118. package/dist/maps/overlay.js.map +1 -1
  119. package/dist/maps/paint.d.ts +3 -0
  120. package/dist/maps/paint.d.ts.map +1 -1
  121. package/dist/maps/paint.js.map +1 -1
  122. package/dist/maps/proj.d.ts +14 -0
  123. package/dist/maps/proj.d.ts.map +1 -1
  124. package/dist/maps/proj.js +28 -0
  125. package/dist/maps/proj.js.map +1 -1
  126. package/dist/maps/renderer.d.ts +69 -0
  127. package/dist/maps/renderer.d.ts.map +1 -0
  128. package/dist/maps/renderer.js +66 -0
  129. package/dist/maps/renderer.js.map +1 -0
  130. package/dist/maps/sources.d.ts +25 -3
  131. package/dist/maps/sources.d.ts.map +1 -1
  132. package/dist/maps/sources.js +17 -0
  133. package/dist/maps/sources.js.map +1 -1
  134. package/dist/maps/theme.d.ts +19 -0
  135. package/dist/maps/theme.d.ts.map +1 -0
  136. package/dist/maps/theme.js +44 -0
  137. package/dist/maps/theme.js.map +1 -0
  138. package/dist/maps/tiles.d.ts +117 -17
  139. package/dist/maps/tiles.d.ts.map +1 -1
  140. package/dist/maps/tiles.js +163 -30
  141. package/dist/maps/tiles.js.map +1 -1
  142. package/dist/maps/types.d.ts +188 -20
  143. package/dist/maps/types.d.ts.map +1 -1
  144. package/dist/markdown/expressions.d.ts +1 -1
  145. package/dist/markdown/expressions.d.ts.map +1 -1
  146. package/dist/markdown/expressions.js.map +1 -1
  147. package/dist/markdown/index.d.ts +7 -6
  148. package/dist/markdown/index.d.ts.map +1 -1
  149. package/dist/markdown/index.js +9 -7
  150. package/dist/markdown/index.js.map +1 -1
  151. package/dist/markdown/spans.d.ts +1 -1
  152. package/dist/markdown/spans.d.ts.map +1 -1
  153. package/dist/media-player/index.d.ts +11 -3
  154. package/dist/media-player/index.d.ts.map +1 -1
  155. package/dist/media-player/index.js +13 -2
  156. package/dist/media-player/index.js.map +1 -1
  157. package/dist/rich-text-editor/clipboard.d.ts +23 -0
  158. package/dist/rich-text-editor/clipboard.d.ts.map +1 -0
  159. package/dist/rich-text-editor/clipboard.js +307 -0
  160. package/dist/rich-text-editor/clipboard.js.map +1 -0
  161. package/dist/rich-text-editor/collab.d.ts +32 -0
  162. package/dist/rich-text-editor/collab.d.ts.map +1 -0
  163. package/dist/rich-text-editor/collab.js +55 -0
  164. package/dist/rich-text-editor/collab.js.map +1 -0
  165. package/dist/rich-text-editor/commands.d.ts +50 -0
  166. package/dist/rich-text-editor/commands.d.ts.map +1 -0
  167. package/dist/rich-text-editor/commands.js +376 -0
  168. package/dist/rich-text-editor/commands.js.map +1 -0
  169. package/dist/rich-text-editor/drag.d.ts +68 -0
  170. package/dist/rich-text-editor/drag.d.ts.map +1 -0
  171. package/dist/rich-text-editor/drag.js +148 -0
  172. package/dist/rich-text-editor/drag.js.map +1 -0
  173. package/dist/rich-text-editor/html.d.ts +145 -0
  174. package/dist/rich-text-editor/html.d.ts.map +1 -0
  175. package/dist/rich-text-editor/html.js +516 -0
  176. package/dist/rich-text-editor/html.js.map +1 -0
  177. package/dist/rich-text-editor/index.d.ts +263 -0
  178. package/dist/rich-text-editor/index.d.ts.map +1 -0
  179. package/dist/rich-text-editor/index.js +822 -0
  180. package/dist/rich-text-editor/index.js.map +1 -0
  181. package/dist/rich-text-editor/inline.d.ts +94 -0
  182. package/dist/rich-text-editor/inline.d.ts.map +1 -0
  183. package/dist/rich-text-editor/inline.js +252 -0
  184. package/dist/rich-text-editor/inline.js.map +1 -0
  185. package/dist/rich-text-editor/keymap.d.ts +71 -0
  186. package/dist/rich-text-editor/keymap.d.ts.map +1 -0
  187. package/dist/rich-text-editor/keymap.js +393 -0
  188. package/dist/rich-text-editor/keymap.js.map +1 -0
  189. package/dist/rich-text-editor/keys.d.ts +29 -0
  190. package/dist/rich-text-editor/keys.d.ts.map +1 -0
  191. package/dist/rich-text-editor/keys.js +93 -0
  192. package/dist/rich-text-editor/keys.js.map +1 -0
  193. package/dist/rich-text-editor/look.d.ts +71 -0
  194. package/dist/rich-text-editor/look.d.ts.map +1 -0
  195. package/dist/rich-text-editor/look.js +342 -0
  196. package/dist/rich-text-editor/look.js.map +1 -0
  197. package/dist/rich-text-editor/markdown.d.ts +18 -0
  198. package/dist/rich-text-editor/markdown.d.ts.map +1 -0
  199. package/dist/rich-text-editor/markdown.js +496 -0
  200. package/dist/rich-text-editor/markdown.js.map +1 -0
  201. package/dist/rich-text-editor/nodes.d.ts +135 -0
  202. package/dist/rich-text-editor/nodes.d.ts.map +1 -0
  203. package/dist/rich-text-editor/nodes.js +397 -0
  204. package/dist/rich-text-editor/nodes.js.map +1 -0
  205. package/dist/rich-text-editor/render.d.ts +68 -0
  206. package/dist/rich-text-editor/render.d.ts.map +1 -0
  207. package/dist/rich-text-editor/render.js +500 -0
  208. package/dist/rich-text-editor/render.js.map +1 -0
  209. package/dist/rich-text-editor/schema.d.ts +16 -0
  210. package/dist/rich-text-editor/schema.d.ts.map +1 -0
  211. package/dist/rich-text-editor/schema.js +386 -0
  212. package/dist/rich-text-editor/schema.js.map +1 -0
  213. package/dist/rich-text-editor/store.d.ts +11 -0
  214. package/dist/rich-text-editor/store.d.ts.map +1 -0
  215. package/dist/rich-text-editor/store.js +43 -0
  216. package/dist/rich-text-editor/store.js.map +1 -0
  217. package/dist/rich-text-editor/suggest.d.ts +127 -0
  218. package/dist/rich-text-editor/suggest.d.ts.map +1 -0
  219. package/dist/rich-text-editor/suggest.js +0 -0
  220. package/dist/rich-text-editor/suggest.js.map +1 -0
  221. package/dist/rich-text-editor/tables.d.ts +41 -0
  222. package/dist/rich-text-editor/tables.d.ts.map +1 -0
  223. package/dist/rich-text-editor/tables.js +204 -0
  224. package/dist/rich-text-editor/tables.js.map +1 -0
  225. package/dist/rich-text-editor/toolbar.d.ts +58 -0
  226. package/dist/rich-text-editor/toolbar.d.ts.map +1 -0
  227. package/dist/rich-text-editor/toolbar.js +548 -0
  228. package/dist/rich-text-editor/toolbar.js.map +1 -0
  229. package/dist/rich-text-editor/view.d.ts +368 -0
  230. package/dist/rich-text-editor/view.d.ts.map +1 -0
  231. package/dist/rich-text-editor/view.js +1968 -0
  232. package/dist/rich-text-editor/view.js.map +1 -0
  233. package/dist/rich-text-editor/virtual.d.ts +54 -0
  234. package/dist/rich-text-editor/virtual.d.ts.map +1 -0
  235. package/dist/rich-text-editor/virtual.js +262 -0
  236. package/dist/rich-text-editor/virtual.js.map +1 -0
  237. package/dist/richtext/node.d.ts +25 -2
  238. package/dist/richtext/node.d.ts.map +1 -1
  239. package/dist/richtext/node.js +46 -24
  240. package/dist/richtext/node.js.map +1 -1
  241. package/dist/terminal/backends.d.ts +4 -1
  242. package/dist/terminal/backends.d.ts.map +1 -1
  243. package/dist/terminal/backends.js.map +1 -1
  244. package/dist/terminal/index.d.ts +18 -7
  245. package/dist/terminal/index.d.ts.map +1 -1
  246. package/dist/terminal/index.js +28 -11
  247. package/dist/terminal/index.js.map +1 -1
  248. package/package.json +23 -4
  249. package/src/charts/node.ts +6 -2
  250. package/src/embed/client.ts +102 -8
  251. package/src/embed/index.ts +2 -0
  252. package/src/html/node.ts +7 -5
  253. package/src/index.ts +2 -0
  254. package/src/{markdown → internal/markdown}/ast.ts +24 -7
  255. package/src/{markdown → internal/markdown}/parse.ts +134 -24
  256. package/src/internal/markdown/stringify.ts +772 -0
  257. package/src/internal/scroll.ts +5 -3
  258. package/src/maps/anchors.ts +607 -0
  259. package/src/maps/controller.ts +999 -0
  260. package/src/maps/gl/buckets.ts +457 -0
  261. package/src/maps/gl/build-worker.ts +55 -0
  262. package/src/maps/gl/color.ts +62 -0
  263. package/src/maps/gl/cover.ts +170 -0
  264. package/src/maps/gl/index.ts +23 -0
  265. package/src/maps/gl/markers.ts +83 -0
  266. package/src/maps/gl/overlays.ts +379 -0
  267. package/src/maps/gl/pane.ts +42 -0
  268. package/src/maps/gl/placement.ts +816 -0
  269. package/src/maps/gl/renderer.ts +1576 -0
  270. package/src/maps/gl/shaders.ts +486 -0
  271. package/src/maps/gl/store.ts +566 -0
  272. package/src/maps/gl/text.ts +495 -0
  273. package/src/maps/gl/view.ts +1224 -0
  274. package/src/maps/index.ts +270 -81
  275. package/src/maps/labels.ts +214 -121
  276. package/src/maps/node.ts +763 -629
  277. package/src/maps/overlay.ts +148 -43
  278. package/src/maps/paint.ts +3 -0
  279. package/src/maps/proj.ts +31 -0
  280. package/src/maps/renderer.ts +155 -0
  281. package/src/maps/sources.ts +38 -3
  282. package/src/maps/theme.ts +51 -0
  283. package/src/maps/tiles.ts +191 -33
  284. package/src/maps/types.ts +188 -20
  285. package/src/markdown/expressions.ts +5 -1
  286. package/src/markdown/index.ts +14 -11
  287. package/src/markdown/spans.ts +1 -1
  288. package/src/media-player/index.ts +18 -4
  289. package/src/rich-text-editor/clipboard.ts +439 -0
  290. package/src/rich-text-editor/collab.ts +91 -0
  291. package/src/rich-text-editor/commands.ts +448 -0
  292. package/src/rich-text-editor/dom-globals.d.ts +23 -0
  293. package/src/rich-text-editor/drag.ts +211 -0
  294. package/src/rich-text-editor/html.ts +619 -0
  295. package/src/rich-text-editor/index.ts +1331 -0
  296. package/src/rich-text-editor/inline.ts +345 -0
  297. package/src/rich-text-editor/keymap.ts +510 -0
  298. package/src/rich-text-editor/keys.ts +119 -0
  299. package/src/rich-text-editor/look.ts +427 -0
  300. package/src/rich-text-editor/markdown.ts +653 -0
  301. package/src/rich-text-editor/nodes.ts +497 -0
  302. package/src/rich-text-editor/render.ts +800 -0
  303. package/src/rich-text-editor/schema.ts +431 -0
  304. package/src/rich-text-editor/store.ts +39 -0
  305. package/src/rich-text-editor/suggest.ts +597 -0
  306. package/src/rich-text-editor/tables.ts +272 -0
  307. package/src/rich-text-editor/toolbar.ts +724 -0
  308. package/src/rich-text-editor/view.ts +2287 -0
  309. package/src/rich-text-editor/virtual.ts +347 -0
  310. package/src/richtext/node.ts +59 -30
  311. package/src/terminal/backends.ts +4 -1
  312. package/src/terminal/index.ts +43 -15
  313. package/dist/markdown/ast.d.ts.map +0 -1
  314. package/dist/markdown/ast.js +0 -17
  315. package/dist/markdown/ast.js.map +0 -1
  316. package/dist/markdown/parse.d.ts.map +0 -1
  317. package/dist/markdown/parse.js.map +0 -1
  318. package/dist/markdown/tags.d.ts.map +0 -1
  319. package/dist/markdown/tags.js.map +0 -1
  320. /package/dist/{markdown → internal/markdown}/parse.d.ts +0 -0
  321. /package/dist/{markdown → internal/markdown}/tags.d.ts +0 -0
  322. /package/dist/{markdown → internal/markdown}/tags.js +0 -0
  323. /package/src/{markdown → internal/markdown}/tags.ts +0 -0
@@ -0,0 +1,347 @@
1
+ // Long documents: only the top-level blocks near the viewport are drawn.
2
+ //
3
+ // The machinery is `<Tree>`'s and `<Table>`'s — the height index
4
+ // (../internal/heights.ts), the window (../internal/window.ts) and the owed
5
+ // reveal (../internal/scroll.ts) — laid over the document's top-level blocks
6
+ // and keyed by their block keys (./keys.ts), so a height measured once
7
+ // survives every edit that keeps its block. Each drawn block is in a box of
8
+ // its own, measured after layout (./render.ts, `renderBlockRange`), and the
9
+ // blocks outside the window are two spacers, so the scrollbar measures the
10
+ // whole document.
11
+ //
12
+ // The view's geometry is laid-out text — a caret, a hit, the line an arrow
13
+ // key moves to — so a block that is not drawn has none. The view asks this
14
+ // window (`BlockWindow`) whether the block a position is in is drawn, and
15
+ // when it is not, because the reader scrolled away from the caret, it has
16
+ // the block revealed first and does what it meant to once the block is laid
17
+ // out (./view.ts: `scrollToSelection` and `move`).
18
+ //
19
+ // A block is measured with the gap after it, so that the index's offsets are
20
+ // where blocks start: the content column keeps its `gap`, and each spacer
21
+ // gives back the one gap it stands beside.
22
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
23
+ import type { Node as PMNode } from 'prosemirror-model';
24
+ import type { DrawnNode, ScrollableNode } from 'react-x11';
25
+
26
+ import { RowHeights } from '../internal/heights.js';
27
+ import type { RowKey } from '../internal/heights.js';
28
+ import { useReveal } from '../internal/scroll.js';
29
+ import {
30
+ afterLayout,
31
+ cancelAfterLayout,
32
+ cancelLater,
33
+ later,
34
+ } from '../internal/timers.js';
35
+ import type { DelayTick, LayoutTick } from '../internal/timers.js';
36
+ import { scaleOf } from '../internal/units.js';
37
+ import {
38
+ BURST_BUDGET,
39
+ DEFAULT_OVERSCAN,
40
+ DEFAULT_PREFETCH,
41
+ SETTLE_BUDGET,
42
+ useVirtualWindow,
43
+ } from '../internal/window.js';
44
+ import type { BlockKeys } from './keys.js';
45
+
46
+ /** Top-level blocks past which `virtual: 'auto'` draws only a window of
47
+ * them — `<Tree>`'s threshold, and far more than a composer ever holds. */
48
+ export const VIRTUAL_THRESHOLD = 200;
49
+
50
+ /** What the view asks of a long document's window. */
51
+ export interface BlockWindow {
52
+ /** Whether top-level block `index` is drawn and laid out. */
53
+ drawn(index: number): boolean;
54
+ /** Scroll top-level block `index` into view, and so draw it; `then` runs
55
+ * once it is laid out — unless the reader scrolls somewhere else first,
56
+ * which drops it. */
57
+ reveal(index: number, then: () => void): void;
58
+ }
59
+
60
+ interface Row {
61
+ id: string;
62
+ }
63
+
64
+ interface Drawn {
65
+ node: DrawnNode;
66
+ at: number;
67
+ }
68
+
69
+ /** The document's top-level blocks, by key, in order. */
70
+ function topBlocks(doc: PMNode, keys: BlockKeys): Row[] {
71
+ const rows: Row[] = [];
72
+ doc.forEach((_node, offset) => {
73
+ rows.push({ id: keys.keyAt(offset) ?? `p${offset}` });
74
+ });
75
+ return rows;
76
+ }
77
+
78
+ export interface BlockWindowInputs {
79
+ doc: PMNode;
80
+ keys: BlockKeys;
81
+ virtual: boolean | 'auto';
82
+ /** What a block nobody has measured is guessed at, gap included —
83
+ * logical pixels, like every length here. */
84
+ estimate: number;
85
+ /** The content column's gap between blocks. */
86
+ gap: number;
87
+ }
88
+
89
+ export interface BlockWindowState {
90
+ virtualizing: boolean;
91
+ /** The top-level blocks to draw, `last` exclusive. */
92
+ first: number;
93
+ last: number;
94
+ /** The spacers before and after them — 0 for none. */
95
+ above: number;
96
+ below: number;
97
+ /** The scroll pane. */
98
+ box: { current: ScrollableNode | null };
99
+ /** The pane's handlers, while the window is on. */
100
+ onViewport(ev: { width: number; height: number }): void;
101
+ onScroll(ev: { scrollY: number }): void;
102
+ /** A drawn block's box as it mounts, and null as it goes. */
103
+ register(key: string, at: number, node: unknown): void;
104
+ /** What the view asks — see `BlockWindow`. */
105
+ window: BlockWindow;
106
+ }
107
+
108
+ /** The window over a document's top-level blocks. Call every render, with
109
+ * the document about to be drawn. */
110
+ export function useBlockWindow(inputs: BlockWindowInputs): BlockWindowState {
111
+ const { doc, keys, virtual, estimate, gap } = inputs;
112
+ const box = useRef<ScrollableNode | null>(null);
113
+ const [, setMeasured] = useState(0);
114
+ const rows = useMemo(() => topBlocks(doc, keys), [doc, keys]);
115
+ const rowsRef = useRef(rows);
116
+ rowsRef.current = rows;
117
+ const gapRef = useRef(gap);
118
+ gapRef.current = gap;
119
+ /** The drawn blocks' boxes, by key, with the index each was drawn at. */
120
+ const nodes = useRef(new Map<RowKey, Drawn>());
121
+ const virtualizing =
122
+ virtual === true || (virtual === 'auto' && rows.length > VIRTUAL_THRESHOLD);
123
+
124
+ // One index per editor, for as long as it is mounted. A new look is a new
125
+ // height for every block, so what was measured under the old one goes.
126
+ const [heights] = useState(() => new RowHeights(estimate));
127
+ const estimated = useRef(estimate);
128
+ if (estimated.current !== estimate) {
129
+ estimated.current = estimate;
130
+ heights.reset();
131
+ }
132
+ heights.sync(rows, estimate);
133
+
134
+ const win = useVirtualWindow({
135
+ box,
136
+ heights,
137
+ rows,
138
+ exact: false,
139
+ virtualizing,
140
+ overscan: DEFAULT_OVERSCAN,
141
+ prefetch: DEFAULT_PREFETCH,
142
+ // a block is built whole or not at all: no skeletons
143
+ threshold: Number.POSITIVE_INFINITY,
144
+ burstBudget: BURST_BUDGET,
145
+ settleBudget: SETTLE_BUDGET,
146
+ });
147
+ const reveal = useReveal({ box, rows: rowsRef, nodes, heights });
148
+
149
+ /** A reveal the view is waiting on, and what it does once the block is
150
+ * laid out. */
151
+ const owed = useRef<{ id: string; then: () => void } | null>(null);
152
+
153
+ const drawnAt = useCallback((index: number): boolean => {
154
+ const row = rowsRef.current[index];
155
+ const drawn = row ? nodes.current.get(row.id) : undefined;
156
+ return !!drawn && drawn.at === index && drawn.node.abs.height > 0;
157
+ }, []);
158
+
159
+ /** What the drawn blocks laid out at, into the index — `<Tree>`'s pass:
160
+ * what grew above the viewport comes back out of the offset, so the text
161
+ * being read does not move. */
162
+ const measure = (): boolean => {
163
+ const pane = box.current;
164
+ const list = rowsRef.current;
165
+ const anchor = pane ? heights.indexAt(pane.scrollY / scaleOf(pane)) : 0;
166
+ let shift = 0;
167
+ let changed = false;
168
+ for (const [id, { node, at }] of nodes.current) {
169
+ if (list[at]?.id !== id || !(node.abs.height > 0)) continue;
170
+ // `abs` is device, the index logical (../internal/units.ts)
171
+ const height = node.abs.height / scaleOf(node) + gapRef.current;
172
+ const was = heights.heightAt(at);
173
+ if (!heights.measure(id, at, height)) continue;
174
+ changed = true;
175
+ if (at < anchor) shift += height - was;
176
+ }
177
+ if (!changed) return false;
178
+ reveal.nudge(shift);
179
+ setMeasured((n) => n + 1);
180
+ return true;
181
+ };
182
+
183
+ /** The estimate learns the measured mean — idle only, and the screen
184
+ * kept still by the same anchor arithmetic. */
185
+ const adapt = (): boolean => {
186
+ const pane = box.current;
187
+ if (!pane) return false;
188
+ const anchor = heights.indexAt(pane.scrollY / scaleOf(pane));
189
+ const before = heights.offsetAt(anchor);
190
+ if (!heights.adapt()) return false;
191
+ reveal.nudge(heights.offsetAt(anchor) - before);
192
+ setMeasured((n) => n + 1);
193
+ return true;
194
+ };
195
+
196
+ /** Whether a drawn block has no size yet: a commit can land between frame
197
+ * flushes, and a pass over it reads zeros. */
198
+ const unsized = (): boolean => {
199
+ const list = rowsRef.current;
200
+ for (const [id, { node, at }] of nodes.current) {
201
+ if (list[at]?.id === id && !(node.abs.height > 0)) return true;
202
+ }
203
+ return false;
204
+ };
205
+
206
+ /** Hand the view the block it was waiting on, once it is laid out — or
207
+ * drop the wait, when the block has left the document. */
208
+ const settle = (): void => {
209
+ const o = owed.current;
210
+ if (!o) return;
211
+ const drawn = nodes.current.get(o.id);
212
+ if (
213
+ drawn &&
214
+ rowsRef.current[drawn.at]?.id === o.id &&
215
+ drawn.node.abs.height > 0
216
+ ) {
217
+ owed.current = null;
218
+ o.then();
219
+ } else if (!rowsRef.current.some((row) => row.id === o.id)) {
220
+ owed.current = null;
221
+ }
222
+ };
223
+
224
+ // The tick after layout, and everything only known there: what the blocks
225
+ // measured, whether an owed scroll can go further, where the pane really
226
+ // is, and whether the block the view waits on is laid out — in that order,
227
+ // each able to move what the next one reads.
228
+ const ticks = useRef<{ layout: LayoutTick; look: DelayTick; tries: number }>({
229
+ layout: null,
230
+ look: null,
231
+ tries: 0,
232
+ });
233
+ const pass = useRef<() => void>(() => {});
234
+ pass.current = (): void => {
235
+ if (!virtualizing) return;
236
+ const pane = box.current;
237
+ // `onViewport` reports a change, so a window turned on after the pane's
238
+ // first layout has never heard its size: read it here
239
+ if (pane && win.viewRef.current.height === 0 && pane.abs.height > 0) {
240
+ const s = scaleOf(pane);
241
+ win.sized(pane.abs.width / s, pane.abs.height / s);
242
+ }
243
+ const moved = win.fast() ? false : measure();
244
+ const adapted = !win.scrolling() && adapt();
245
+ reveal.retry(moved || adapted);
246
+ win.sync();
247
+ settle();
248
+ // look again, briefly, while a block is unsized or the view still waits
249
+ // — nothing else would come back for them
250
+ const t = ticks.current;
251
+ if ((unsized() || owed.current !== null) && t.tries++ < 8) {
252
+ t.look = later(() => {
253
+ t.look = null;
254
+ pass.current();
255
+ }, 16);
256
+ }
257
+ };
258
+ const kick = useCallback((): void => {
259
+ const t = ticks.current;
260
+ cancelAfterLayout(t.layout);
261
+ cancelLater(t.look);
262
+ t.look = null;
263
+ t.tries = 0;
264
+ t.layout = afterLayout(() => {
265
+ t.layout = null;
266
+ pass.current();
267
+ });
268
+ }, []);
269
+ useEffect(() => {
270
+ if (virtualizing) kick();
271
+ });
272
+ useEffect(
273
+ () => () => {
274
+ const t = ticks.current;
275
+ cancelAfterLayout(t.layout);
276
+ cancelLater(t.look);
277
+ },
278
+ [],
279
+ );
280
+
281
+ const { sized, scrolled, sync } = win;
282
+ const onViewport = useCallback(
283
+ (ev: { width: number; height: number }): void => {
284
+ sized(ev.width, ev.height);
285
+ // the content changed size: an owed scroll may reach further, and the
286
+ // pane may have re-clamped its offset without a word
287
+ reveal.retry(true);
288
+ sync();
289
+ },
290
+ [sized, reveal, sync],
291
+ );
292
+ const onScroll = useCallback(
293
+ (ev: { scrollY: number }): void => {
294
+ // a scroll this editor did not ask for is the reader's, and what the
295
+ // view was waiting to do gives way to it
296
+ if (!reveal.heard(ev.scrollY)) owed.current = null;
297
+ scrolled(ev.scrollY);
298
+ },
299
+ [reveal, scrolled],
300
+ );
301
+
302
+ const register = useCallback(
303
+ (key: string, at: number, node: unknown): void => {
304
+ const map = nodes.current;
305
+ if (node) map.set(key, { node: node as DrawnNode, at });
306
+ else if (map.get(key)?.at === at) map.delete(key);
307
+ },
308
+ [],
309
+ );
310
+
311
+ const window = useMemo<BlockWindow>(
312
+ () => ({
313
+ drawn: drawnAt,
314
+ reveal: (index, then) => {
315
+ const row = rowsRef.current[index];
316
+ if (!row) return;
317
+ if (drawnAt(index)) {
318
+ then();
319
+ return;
320
+ }
321
+ owed.current = { id: row.id, then };
322
+ reveal.to(row.id);
323
+ // the reveal may need no render of its own — a block already in the
324
+ // window, not yet laid out — so a pass is asked for here
325
+ kick();
326
+ },
327
+ }),
328
+ [drawnAt, reveal, kick],
329
+ );
330
+
331
+ const { first, last } = win.slice;
332
+ return {
333
+ virtualizing,
334
+ first,
335
+ last,
336
+ above: virtualizing && first > 0 ? Math.max(0, win.slice.above - gap) : 0,
337
+ below:
338
+ virtualizing && last < rows.length
339
+ ? Math.max(0, win.slice.below - gap)
340
+ : 0,
341
+ box,
342
+ onViewport,
343
+ onScroll,
344
+ register,
345
+ window,
346
+ };
347
+ }
@@ -37,6 +37,7 @@ import {
37
37
  paintRunBackgrounds,
38
38
  paintRunRules,
39
39
  } from './runs.js';
40
+ import type { FillContext } from './runs.js';
40
41
  import { codeUnitOffsets } from '../internal/text.js';
41
42
 
42
43
  /** The element name — registration key, `node.kind` and JSX tag alike. */
@@ -215,8 +216,18 @@ export class RichTextNode extends Node {
215
216
  private _layouts = new Map<string, TextLayoutLike | null>();
216
217
  private _text: string | null = null;
217
218
 
218
- constructor(props: Record<string, unknown>, app: NtkApp) {
219
- super(ELEMENT, props, app);
219
+ /**
220
+ * `kind` is for a subclass registered under a name of its own — the rich
221
+ * text editor's text blocks are `<richtext>` plus a caret and a selection
222
+ * the editor owns (`src/rich-text-editor/nodes.ts`). A node's `kind` must be
223
+ * the name it was registered under, so the subclass passes its own.
224
+ */
225
+ constructor(
226
+ props: Record<string, unknown>,
227
+ app: NtkApp,
228
+ kind: string = ELEMENT,
229
+ ) {
230
+ super(kind, props, app);
220
231
  }
221
232
 
222
233
  /**
@@ -302,8 +313,10 @@ export class RichTextNode extends Node {
302
313
  * The layout this node is currently painted with — and, because it is the
303
314
  * one thing every accessor below answers from, the reason a caret rect and
304
315
  * a glyph cannot disagree (docs/extending.md, "answer from what you draw").
316
+ * Protected rather than private for the editor's subclass, whose line-wise
317
+ * caret motion reads the lines off the same layout the glyphs came from.
305
318
  */
306
- private _paintLayout(): TextLayoutLike | null {
319
+ protected paintLayout(): TextLayoutLike | null {
307
320
  const wrap = (this.props as unknown as RichTextProps).wrap !== false;
308
321
  return this._layoutFor(wrap ? this.abs.width : Infinity);
309
322
  }
@@ -347,14 +360,14 @@ export class RichTextNode extends Node {
347
360
  }
348
361
 
349
362
  override textIndexAt(x: number, y: number): number {
350
- const layout = this._paintLayout();
363
+ const layout = this.paintLayout();
351
364
  if (!layout) return 0;
352
365
  const i = layout.indexAt(x - this.abs.x, y - this.abs.y);
353
366
  return Math.max(0, Math.min([...this.textContent()].length, i));
354
367
  }
355
368
 
356
369
  override textCaretRect(index: number): Rect | null {
357
- const layout = this._paintLayout();
370
+ const layout = this.paintLayout();
358
371
  if (!layout) return null;
359
372
  const caret = layout.caretPosition(index);
360
373
  return {
@@ -366,7 +379,7 @@ export class RichTextNode extends Node {
366
379
  }
367
380
 
368
381
  override textRangeRects(start: number, end: number): Rect[] {
369
- const layout = this._paintLayout();
382
+ const layout = this.paintLayout();
370
383
  if (!layout) return [];
371
384
  return rangeBands(layout, this.textContent(), start, end).map((band) => ({
372
385
  x: this.abs.x + band.x,
@@ -381,7 +394,7 @@ export class RichTextNode extends Node {
381
394
  * selection seam: core deliberately left hover and `cursorAt` out of
382
395
  * #291, so following a link stays this package's. */
383
396
  hrefAtPoint(x: number, y: number): string | null {
384
- const layout = this._paintLayout();
397
+ const layout = this.paintLayout();
385
398
  if (!layout) return null;
386
399
  const s = this._scale;
387
400
  const lx = x * s - this.abs.x;
@@ -401,7 +414,7 @@ export class RichTextNode extends Node {
401
414
 
402
415
  override paint(ctx: Context2D): void {
403
416
  super.paint(ctx); // background, border, clip to `abs`
404
- const layout = this._paintLayout();
417
+ const layout = this.paintLayout();
405
418
  if (!layout || !canFill(ctx)) return;
406
419
  const { x, y } = this.abs;
407
420
  const s = this._scale;
@@ -412,28 +425,8 @@ export class RichTextNode extends Node {
412
425
  // terminal's cell backgrounds
413
426
  for (const line of layout.lines) paintRunBackgrounds(ctx, line, x, y, s);
414
427
 
415
- // 2. the band the document selection has claimed of this element's text,
416
- // translucent so the ink keeps its contrast on either palette (the
417
- // same reasoning as `<textarea>`'s). The range and the colour both
418
- // arrive from the surface above; `textRangeRects` is what a custom
419
- // element and core's own `<text>` both fill, so they cannot drift.
420
- const range = this.selectionRange;
421
- // The colour is the condition, not just the range: core types it
422
- // `string | null` and defines it as what to fill the rectangles with
423
- // *while a selection is set*, so a null one is "nothing to draw"
424
- // rather than a band in the default ink.
425
- const selectionColor = this.selectionColor;
426
- if (selectionColor && range && range.end > range.start) {
427
- ctx.fillStyle = selectionColor;
428
- for (const r of this.textRangeRects(range.start, range.end)) {
429
- ctx.fillRect(
430
- Math.round(r.x),
431
- Math.round(r.y),
432
- Math.ceil(r.width),
433
- Math.ceil(r.height),
434
- );
435
- }
436
- }
428
+ // 2. the band a selection has claimed of this element's text
429
+ this.paintSelection(ctx);
437
430
 
438
431
  // 3. the ink
439
432
  layout.draw(ctx, x, y);
@@ -441,6 +434,42 @@ export class RichTextNode extends Node {
441
434
  // 4. rules over the ink: link underlines, strikethrough
442
435
  for (const line of layout.lines) paintRunRules(ctx, line, x, y, s);
443
436
 
437
+ // 5. anything that belongs over everything — a subclass's caret
438
+ this.paintOverlay(ctx);
439
+
444
440
  ctx.restore();
445
441
  }
442
+
443
+ /**
444
+ * The selection band, between the run backgrounds and the ink. The default
445
+ * is core's document selection: the band the `selectable` surface above
446
+ * has claimed of this element's text, translucent so the ink keeps its
447
+ * contrast on either palette (the same reasoning as `<textarea>`'s). The
448
+ * range and the colour both arrive from that surface; `textRangeRects` is
449
+ * what a custom element and core's own `<text>` both fill, so they cannot
450
+ * drift. An element with a selection of its own — the editor's text
451
+ * blocks — overrides this and fills that one instead.
452
+ */
453
+ protected paintSelection(ctx: FillContext): void {
454
+ const range = this.selectionRange;
455
+ // The colour is the condition, not just the range: core types it
456
+ // `string | null` and defines it as what to fill the rectangles with
457
+ // *while a selection is set*, so a null one is "nothing to draw"
458
+ // rather than a band in the default ink.
459
+ const selectionColor = this.selectionColor;
460
+ if (!selectionColor || !range || range.end <= range.start) return;
461
+ ctx.fillStyle = selectionColor;
462
+ for (const r of this.textRangeRects(range.start, range.end)) {
463
+ ctx.fillRect(
464
+ Math.round(r.x),
465
+ Math.round(r.y),
466
+ Math.ceil(r.width),
467
+ Math.ceil(r.height),
468
+ );
469
+ }
470
+ }
471
+
472
+ /** Drawn last, over the ink and the rules: nothing here, a caret in the
473
+ * editor's subclass. Inside the same save/restore as the rest. */
474
+ protected paintOverlay(_ctx: FillContext): void {}
446
475
  }
@@ -21,7 +21,10 @@
21
21
  * program installed and is the only backend `write()` can work on.
22
22
  *
23
23
  * `'auto'` takes the first embeddable emulator that is installed and falls
24
- * back to `'vt'`. That order — rather than vt first — is deliberate: an
24
+ * back to `'vt'` — and on a react-x11 backend that cannot host an embedded
25
+ * window at all (the native macOS one) it takes `'vt'` without looking for
26
+ * the other three, because an emulator found on `PATH` there is one this app
27
+ * cannot show. That order — rather than vt first — is deliberate: an
25
28
  * external emulator is battle-tested, and a user who installed one expressed
26
29
  * a preference. Moving vt to the front is a later, deliberate decision.
27
30
  */
@@ -23,7 +23,9 @@
23
23
  // rendered as a native element rather than as somebody else's X window. It is
24
24
  // what makes `write()` real — the pty is ours — and what works on a machine
25
25
  // with no emulator installed, which is why `'auto'` ends there rather than at
26
- // the `fallback`.
26
+ // the `fallback`. It is also the only half that works on a react-x11 backend
27
+ // with no XEmbed at all — the native macOS one — so `'auto'` goes straight
28
+ // there when the app cannot host an emulator's window, whatever `PATH` holds.
27
29
  //
28
30
  // **`write()` still returns `false` on the XEmbed backends**, and that is not
29
31
  // an oversight: the pty belongs to xterm, so "type this" would have to be
@@ -40,12 +42,13 @@ import React, {
40
42
  useState,
41
43
  } from 'react';
42
44
  import type { ReactElement, ReactNode, Ref } from 'react';
43
- import { useTheme } from 'react-x11';
45
+ import { useApp, useTheme } from 'react-x11';
44
46
  import type { ForeignProps } from 'react-x11';
45
47
  import type { Style } from 'react-x11/style';
46
48
 
47
49
  import {
48
50
  BackendUnavailableError,
51
+ canHostXEmbed,
49
52
  resolveBackend,
50
53
  useEmbeddedClient,
51
54
  } from '../embed/index.js';
@@ -153,7 +156,13 @@ export interface TerminalProps {
153
156
  /**
154
157
  * Which terminal. Default `'auto'`: the first of xterm, urxvt, alacritty
155
158
  * that is installed, and `'vt'` — this package's own emulator, which needs
156
- * nothing installed — when none of them is.
159
+ * nothing installed — when none of them is, or when this react-x11 backend
160
+ * cannot embed another program's window at all (the native macOS one), in
161
+ * which case the three are not even looked for.
162
+ *
163
+ * Name one of the three on such a backend and it is taken at its word,
164
+ * not quietly swapped for vt: `status` is `'unavailable'`, `fallback`
165
+ * renders and `onError` gets an `EmbedUnsupportedError`.
157
166
  */
158
167
  backend?: TerminalBackendName;
159
168
  fontFamily?: string;
@@ -179,11 +188,14 @@ export interface TerminalProps {
179
188
  onExit?: (info: ExitInfo) => void;
180
189
  /** The emulator's `_NET_WM_NAME` changed: what the shell says is running. */
181
190
  onTitleChange?: (title: string) => void;
182
- /** Spawn failures, and the `BackendUnavailableError` for a machine with no
183
- * emulator installed. Without a handler neither is reported anywhere —
184
- * `status` and `fallback` are the visible half. */
191
+ /** Spawn failures, the `BackendUnavailableError` for a machine with no
192
+ * emulator installed, and the `EmbedUnsupportedError` for an emulator
193
+ * named on a react-x11 backend that cannot embed one. Without a handler
194
+ * none of it is reported anywhere — `status` and `fallback` are the
195
+ * visible half. */
185
196
  onError?: (err: Error) => void;
186
- /** Rendered instead of the surface when no backend is installed. */
197
+ /** Rendered instead of the surface when no backend is available — none
198
+ * installed, or the one named cannot be embedded here. */
187
199
  fallback?: ReactNode;
188
200
  /** False holds off spawning — a pane in a tab that is not open yet. */
189
201
  enabled?: boolean;
@@ -290,8 +302,10 @@ function warnVtOnly(props: TerminalProps): void {
290
302
  * while the pointer is *over* an embedded emulator, keys go straight to it.
291
303
  *
292
304
  * **The vt backend is the floor.** With `backend="auto"` (the default), a
293
- * machine with no emulator installed gets this package's own — so `fallback`
294
- * renders only when the pty module or `@xterm/headless` is missing too.
305
+ * machine with no emulator installed gets this package's own, and so does an
306
+ * app on a react-x11 backend with no XEmbed — the native macOS one — whatever
307
+ * is installed. `fallback` renders only when the pty module or
308
+ * `@xterm/headless` is missing too.
295
309
  */
296
310
  export function Terminal(props: TerminalProps): ReactElement {
297
311
  const {
@@ -302,6 +316,9 @@ export function Terminal(props: TerminalProps): ReactElement {
302
316
  stopSignal,
303
317
  } = props;
304
318
  const theme = useTheme() as unknown as Record<string, unknown>;
319
+ // Whether an emulator's window can be hosted here at all. It decides the
320
+ // ladder below before `PATH` is asked anything.
321
+ const embeddable = canHostXEmbed(useApp());
305
322
 
306
323
  // Everything that goes into the command line, as one string.
307
324
  //
@@ -386,12 +403,15 @@ export function Terminal(props: TerminalProps): ReactElement {
386
403
  // --- which half of the component is running ------------------------------
387
404
  //
388
405
  // `'vt'` asks for it outright; `'auto'` arrives here only after the PATH
389
- // probe found no emulator, which is what makes vt the floor rather than a
390
- // parallel option. Both halves' hooks run unconditionally — the one that is
391
- // not in use is simply disabled — because that is what hooks require and
392
- // because a `<Terminal>` that flips backends must not remount the other one.
406
+ // probe found no emulator — or without probing at all on an app that could
407
+ // not host one it found, which on a Mac with XQuartz is exactly what `PATH`
408
+ // offers. That is what makes vt the floor rather than a parallel option.
409
+ // Both halves' hooks run unconditionally — the one that is not in use is
410
+ // simply disabled — because that is what hooks require and because a
411
+ // `<Terminal>` that flips backends must not remount the other one.
393
412
  const [vtFallback, setVtFallback] = useState(false);
394
- const vt = backend === 'vt' || (backend === 'auto' && vtFallback);
413
+ const vt =
414
+ backend === 'vt' || (backend === 'auto' && (vtFallback || !embeddable));
395
415
  useEffect(() => {
396
416
  if (backend !== 'auto') setVtFallback(false);
397
417
  }, [backend]);
@@ -549,11 +569,19 @@ export function Terminal(props: TerminalProps): ReactElement {
549
569
 
550
570
  // No backend installed is an ordinary state of a perfectly healthy machine,
551
571
  // not an error to report — the same call `useDesktopCalendarEvents` makes
552
- // about a desktop with no Evolution Data Server.
572
+ // about a desktop with no Evolution Data Server. So is an emulator named on
573
+ // an app that cannot host one.
553
574
  if (client.status === 'unavailable' && props.fallback !== undefined) {
554
575
  return h(React.Fragment, null, props.fallback);
555
576
  }
556
577
 
578
+ // …and without a `fallback` that app still gets no `<foreign>`, which has
579
+ // no socket to be there: on the Cocoa backend it hands `onReady` a window id
580
+ // of `undefined`, and on core's headless mock mounting one throws from the
581
+ // commit. A box in the terminal's own background holds the layout, as it
582
+ // does while the vt module loads.
583
+ if (!embeddable) return hx('box', { style: styles });
584
+
557
585
  const foreign: ForeignElementProps = {
558
586
  onReady: client.handleReady,
559
587
  onEmbedded: title.onEmbedded,
@@ -1 +0,0 @@
1
- {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/markdown/ast.ts"],"names":[],"mappings":"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"}
@@ -1,17 +0,0 @@
1
- // The markdown AST `parse.ts` produces and `index.ts` renders. Deliberately
2
- // small: it is the GFM constructs this component draws, not a general
3
- // mdast — but it is shaped so that growing it stays additive. In particular
4
- // `component` is the MDX direction: `ComponentBlock` is parsed and rendered
5
- // (docs/prd-mdx.md, M1), and `ComponentInline` is still reserved — see the
6
- // note on it for why the inline half needs machinery `<richtext>` does not
7
- // have yet.
8
- /**
9
- * A spread (`{...props}`) is an attribute with no name, so it is keyed
10
- * `...0`, `...1`, … in the order it appeared. An attribute name cannot start
11
- * with `.`, so these cannot collide with one; a renderer walking
12
- * `Object.entries` in insertion order applies each spread where it was
13
- * written, which is what decides whether it overrides `height` or `height`
14
- * overrides it.
15
- */
16
- export const SPREAD_PREFIX = '...';
17
- //# sourceMappingURL=ast.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/markdown/ast.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,sEAAsE;AACtE,4EAA4E;AAC5E,4EAA4E;AAC5E,2EAA2E;AAC3E,2EAA2E;AAC3E,YAAY;AAqEZ;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/markdown/parse.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAGV,QAAQ,EACR,UAAU,EAGV,YAAY,EAEb,MAAM,UAAU,CAAC;AA4IlB,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,QAAQ,CAkB1E;AA+kBD;;;GAGG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EACjB,WAAW,UAAQ,GAClB,UAAU,EAAE,CA8Pd"}