@react-x11/components 0.9.0 → 0.10.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 (550) hide show
  1. package/README.md +10 -4
  2. package/dist/charts/node.d.ts +11 -1
  3. package/dist/charts/node.d.ts.map +1 -1
  4. package/dist/charts/node.js +44 -14
  5. package/dist/charts/node.js.map +1 -1
  6. package/dist/charts/render.d.ts +12 -3
  7. package/dist/charts/render.d.ts.map +1 -1
  8. package/dist/charts/render.js +94 -25
  9. package/dist/charts/render.js.map +1 -1
  10. package/dist/code/index.d.ts.map +1 -1
  11. package/dist/code/index.js +3 -1
  12. package/dist/code/index.js.map +1 -1
  13. package/dist/code-editor/completion.d.ts.map +1 -1
  14. package/dist/code-editor/completion.js +3 -2
  15. package/dist/code-editor/completion.js.map +1 -1
  16. package/dist/code-editor/index.d.ts.map +1 -1
  17. package/dist/code-editor/index.js +19 -0
  18. package/dist/code-editor/index.js.map +1 -1
  19. package/dist/code-editor/node.d.ts +177 -7
  20. package/dist/code-editor/node.d.ts.map +1 -1
  21. package/dist/code-editor/node.js +1329 -164
  22. package/dist/code-editor/node.js.map +1 -1
  23. package/dist/code-language/languages/glsl.d.ts.map +1 -1
  24. package/dist/code-language/languages/glsl.js +10 -2
  25. package/dist/code-language/languages/glsl.js.map +1 -1
  26. package/dist/code-language/languages/javascript.d.ts.map +1 -1
  27. package/dist/code-language/languages/javascript.js +18 -3
  28. package/dist/code-language/languages/javascript.js.map +1 -1
  29. package/dist/code-language/languages/json.d.ts.map +1 -1
  30. package/dist/code-language/languages/json.js +10 -2
  31. package/dist/code-language/languages/json.js.map +1 -1
  32. package/dist/code-language/languages/shell.d.ts.map +1 -1
  33. package/dist/code-language/languages/shell.js +10 -2
  34. package/dist/code-language/languages/shell.js.map +1 -1
  35. package/dist/code-language/languages/sql.d.ts.map +1 -1
  36. package/dist/code-language/languages/sql.js +20 -2
  37. package/dist/code-language/languages/sql.js.map +1 -1
  38. package/dist/code-language/stream.d.ts +22 -0
  39. package/dist/code-language/stream.d.ts.map +1 -1
  40. package/dist/code-language/stream.js +259 -9
  41. package/dist/code-language/stream.js.map +1 -1
  42. package/dist/code-language/types.d.ts +5 -4
  43. package/dist/code-language/types.d.ts.map +1 -1
  44. package/dist/codeblock/index.d.ts +13 -2
  45. package/dist/codeblock/index.d.ts.map +1 -1
  46. package/dist/codeblock/index.js +20 -3
  47. package/dist/codeblock/index.js.map +1 -1
  48. package/dist/flow/draw.d.ts +50 -0
  49. package/dist/flow/draw.d.ts.map +1 -1
  50. package/dist/flow/draw.js +132 -33
  51. package/dist/flow/draw.js.map +1 -1
  52. package/dist/flow/gl/color.d.ts +13 -0
  53. package/dist/flow/gl/color.d.ts.map +1 -0
  54. package/dist/flow/gl/color.js +82 -0
  55. package/dist/flow/gl/color.js.map +1 -0
  56. package/dist/flow/gl/index.d.ts +60 -0
  57. package/dist/flow/gl/index.d.ts.map +1 -0
  58. package/dist/flow/gl/index.js +283 -0
  59. package/dist/flow/gl/index.js.map +1 -0
  60. package/dist/flow/gl/pack.d.ts +133 -0
  61. package/dist/flow/gl/pack.d.ts.map +1 -0
  62. package/dist/flow/gl/pack.js +408 -0
  63. package/dist/flow/gl/pack.js.map +1 -0
  64. package/dist/flow/gl/renderer.d.ts +95 -0
  65. package/dist/flow/gl/renderer.d.ts.map +1 -0
  66. package/dist/flow/gl/renderer.js +459 -0
  67. package/dist/flow/gl/renderer.js.map +1 -0
  68. package/dist/flow/gl/shaders.d.ts +79 -0
  69. package/dist/flow/gl/shaders.d.ts.map +1 -0
  70. package/dist/flow/gl/shaders.js +346 -0
  71. package/dist/flow/gl/shaders.js.map +1 -0
  72. package/dist/flow/gl/text.d.ts +318 -0
  73. package/dist/flow/gl/text.d.ts.map +1 -0
  74. package/dist/flow/gl/text.js +1103 -0
  75. package/dist/flow/gl/text.js.map +1 -0
  76. package/dist/flow/index.d.ts +1 -1
  77. package/dist/flow/index.d.ts.map +1 -1
  78. package/dist/flow/index.js +619 -64
  79. package/dist/flow/index.js.map +1 -1
  80. package/dist/flow/node.d.ts +621 -72
  81. package/dist/flow/node.d.ts.map +1 -1
  82. package/dist/flow/node.js +2253 -1018
  83. package/dist/flow/node.js.map +1 -1
  84. package/dist/flow/paint.d.ts +35 -0
  85. package/dist/flow/paint.d.ts.map +1 -0
  86. package/dist/flow/paint.js +393 -0
  87. package/dist/flow/paint.js.map +1 -0
  88. package/dist/flow/paths.d.ts +14 -0
  89. package/dist/flow/paths.d.ts.map +1 -1
  90. package/dist/flow/paths.js +45 -19
  91. package/dist/flow/paths.js.map +1 -1
  92. package/dist/flow/scene.d.ts +584 -0
  93. package/dist/flow/scene.d.ts.map +1 -0
  94. package/dist/flow/scene.js +1453 -0
  95. package/dist/flow/scene.js.map +1 -0
  96. package/dist/flow/types.d.ts +111 -1
  97. package/dist/flow/types.d.ts.map +1 -1
  98. package/dist/html/controls.d.ts +28 -0
  99. package/dist/html/controls.d.ts.map +1 -1
  100. package/dist/html/controls.js +52 -2
  101. package/dist/html/controls.js.map +1 -1
  102. package/dist/html/css/calc.d.ts +14 -0
  103. package/dist/html/css/calc.d.ts.map +1 -0
  104. package/dist/html/css/calc.js +344 -0
  105. package/dist/html/css/calc.js.map +1 -0
  106. package/dist/html/css/cascade.d.ts +240 -6
  107. package/dist/html/css/cascade.d.ts.map +1 -1
  108. package/dist/html/css/cascade.js +1327 -66
  109. package/dist/html/css/cascade.js.map +1 -1
  110. package/dist/html/css/color.d.ts +23 -0
  111. package/dist/html/css/color.d.ts.map +1 -0
  112. package/dist/html/css/color.js +740 -0
  113. package/dist/html/css/color.js.map +1 -0
  114. package/dist/html/css/content.d.ts +92 -0
  115. package/dist/html/css/content.d.ts.map +1 -0
  116. package/dist/html/css/content.js +388 -0
  117. package/dist/html/css/content.js.map +1 -0
  118. package/dist/html/css/counter-styles.d.ts +76 -0
  119. package/dist/html/css/counter-styles.d.ts.map +1 -0
  120. package/dist/html/css/counter-styles.js +893 -0
  121. package/dist/html/css/counter-styles.js.map +1 -0
  122. package/dist/html/css/decode.d.ts +12 -0
  123. package/dist/html/css/decode.d.ts.map +1 -0
  124. package/dist/html/css/decode.js +116 -0
  125. package/dist/html/css/decode.js.map +1 -0
  126. package/dist/html/css/parse.d.ts +110 -10
  127. package/dist/html/css/parse.d.ts.map +1 -1
  128. package/dist/html/css/parse.js +1473 -180
  129. package/dist/html/css/parse.js.map +1 -1
  130. package/dist/html/css/style.d.ts +498 -15
  131. package/dist/html/css/style.d.ts.map +1 -1
  132. package/dist/html/css/style.js +3698 -206
  133. package/dist/html/css/style.js.map +1 -1
  134. package/dist/html/css/ua.d.ts.map +1 -1
  135. package/dist/html/css/ua.js +57 -11
  136. package/dist/html/css/ua.js.map +1 -1
  137. package/dist/html/css/values.d.ts +37 -3
  138. package/dist/html/css/values.d.ts.map +1 -1
  139. package/dist/html/css/values.js +122 -48
  140. package/dist/html/css/values.js.map +1 -1
  141. package/dist/html/css/vars.d.ts +52 -0
  142. package/dist/html/css/vars.d.ts.map +1 -0
  143. package/dist/html/css/vars.js +358 -0
  144. package/dist/html/css/vars.js.map +1 -0
  145. package/dist/html/dom.d.ts +30 -4
  146. package/dist/html/dom.d.ts.map +1 -1
  147. package/dist/html/dom.js +278 -17
  148. package/dist/html/dom.js.map +1 -1
  149. package/dist/html/fonts.d.ts +106 -0
  150. package/dist/html/fonts.d.ts.map +1 -0
  151. package/dist/html/fonts.js +565 -0
  152. package/dist/html/fonts.js.map +1 -0
  153. package/dist/html/gif.d.ts +15 -0
  154. package/dist/html/gif.d.ts.map +1 -0
  155. package/dist/html/gif.js +229 -0
  156. package/dist/html/gif.js.map +1 -0
  157. package/dist/html/index.d.ts +50 -11
  158. package/dist/html/index.d.ts.map +1 -1
  159. package/dist/html/index.js +115 -9
  160. package/dist/html/index.js.map +1 -1
  161. package/dist/html/layout/block.d.ts +226 -3
  162. package/dist/html/layout/block.d.ts.map +1 -1
  163. package/dist/html/layout/block.js +2937 -197
  164. package/dist/html/layout/block.js.map +1 -1
  165. package/dist/html/layout/boxes.d.ts +340 -17
  166. package/dist/html/layout/boxes.d.ts.map +1 -1
  167. package/dist/html/layout/boxes.js +1714 -182
  168. package/dist/html/layout/boxes.js.map +1 -1
  169. package/dist/html/layout/cache.d.ts +58 -0
  170. package/dist/html/layout/cache.d.ts.map +1 -0
  171. package/dist/html/layout/cache.js +224 -0
  172. package/dist/html/layout/cache.js.map +1 -0
  173. package/dist/html/layout/collapse.d.ts +45 -0
  174. package/dist/html/layout/collapse.d.ts.map +1 -0
  175. package/dist/html/layout/collapse.js +246 -0
  176. package/dist/html/layout/collapse.js.map +1 -0
  177. package/dist/html/layout/css-grid.d.ts +7 -0
  178. package/dist/html/layout/css-grid.d.ts.map +1 -0
  179. package/dist/html/layout/css-grid.js +900 -0
  180. package/dist/html/layout/css-grid.js.map +1 -0
  181. package/dist/html/layout/flex.d.ts.map +1 -1
  182. package/dist/html/layout/flex.js +1025 -89
  183. package/dist/html/layout/flex.js.map +1 -1
  184. package/dist/html/layout/floats.d.ts +45 -6
  185. package/dist/html/layout/floats.d.ts.map +1 -1
  186. package/dist/html/layout/floats.js +113 -14
  187. package/dist/html/layout/floats.js.map +1 -1
  188. package/dist/html/layout/grid-lines.d.ts +39 -0
  189. package/dist/html/layout/grid-lines.d.ts.map +1 -0
  190. package/dist/html/layout/grid-lines.js +119 -0
  191. package/dist/html/layout/grid-lines.js.map +1 -0
  192. package/dist/html/layout/grid.d.ts +53 -0
  193. package/dist/html/layout/grid.d.ts.map +1 -0
  194. package/dist/html/layout/grid.js +153 -0
  195. package/dist/html/layout/grid.js.map +1 -0
  196. package/dist/html/layout/inline.d.ts +151 -1
  197. package/dist/html/layout/inline.d.ts.map +1 -1
  198. package/dist/html/layout/inline.js +3375 -174
  199. package/dist/html/layout/inline.js.map +1 -1
  200. package/dist/html/layout/shaping.d.ts +6 -0
  201. package/dist/html/layout/shaping.d.ts.map +1 -0
  202. package/dist/html/layout/shaping.js +100 -0
  203. package/dist/html/layout/shaping.js.map +1 -0
  204. package/dist/html/layout/table.d.ts +3 -0
  205. package/dist/html/layout/table.d.ts.map +1 -1
  206. package/dist/html/layout/table.js +681 -175
  207. package/dist/html/layout/table.js.map +1 -1
  208. package/dist/html/layout/tracks.d.ts +44 -0
  209. package/dist/html/layout/tracks.d.ts.map +1 -0
  210. package/dist/html/layout/tracks.js +349 -0
  211. package/dist/html/layout/tracks.js.map +1 -0
  212. package/dist/html/node.d.ts +169 -4
  213. package/dist/html/node.d.ts.map +1 -1
  214. package/dist/html/node.js +1331 -100
  215. package/dist/html/node.js.map +1 -1
  216. package/dist/html/paint.d.ts +92 -3
  217. package/dist/html/paint.d.ts.map +1 -1
  218. package/dist/html/paint.js +3503 -141
  219. package/dist/html/paint.js.map +1 -1
  220. package/dist/html/resources.d.ts +60 -14
  221. package/dist/html/resources.d.ts.map +1 -1
  222. package/dist/html/resources.js +122 -36
  223. package/dist/html/resources.js.map +1 -1
  224. package/dist/html/surfaces.d.ts +23 -0
  225. package/dist/html/surfaces.d.ts.map +1 -0
  226. package/dist/html/surfaces.js +68 -0
  227. package/dist/html/surfaces.js.map +1 -0
  228. package/dist/html/svg.d.ts +80 -0
  229. package/dist/html/svg.d.ts.map +1 -0
  230. package/dist/html/svg.js +435 -0
  231. package/dist/html/svg.js.map +1 -0
  232. package/dist/html/url.d.ts +23 -0
  233. package/dist/html/url.d.ts.map +1 -0
  234. package/dist/html/url.js +80 -0
  235. package/dist/html/url.js.map +1 -0
  236. package/dist/index.d.ts +1 -1
  237. package/dist/index.d.ts.map +1 -1
  238. package/dist/index.js.map +1 -1
  239. package/dist/internal/collate.d.ts +3 -0
  240. package/dist/internal/collate.d.ts.map +1 -0
  241. package/dist/internal/collate.js +11 -0
  242. package/dist/internal/collate.js.map +1 -0
  243. package/dist/internal/markdown/ast.d.ts +11 -0
  244. package/dist/internal/markdown/ast.d.ts.map +1 -1
  245. package/dist/internal/markdown/parse.d.ts.map +1 -1
  246. package/dist/internal/markdown/parse.js +109 -8
  247. package/dist/internal/markdown/parse.js.map +1 -1
  248. package/dist/internal/prewarm.d.ts +18 -0
  249. package/dist/internal/prewarm.d.ts.map +1 -0
  250. package/dist/internal/prewarm.js +42 -0
  251. package/dist/internal/prewarm.js.map +1 -0
  252. package/dist/internal/sdf.d.ts +20 -0
  253. package/dist/internal/sdf.d.ts.map +1 -0
  254. package/dist/internal/sdf.js +216 -0
  255. package/dist/internal/sdf.js.map +1 -0
  256. package/dist/internal/splice.d.ts +12 -0
  257. package/dist/internal/splice.d.ts.map +1 -0
  258. package/dist/internal/splice.js +23 -0
  259. package/dist/internal/splice.js.map +1 -0
  260. package/dist/internal/window.d.ts +12 -0
  261. package/dist/internal/window.d.ts.map +1 -1
  262. package/dist/internal/window.js +23 -6
  263. package/dist/internal/window.js.map +1 -1
  264. package/dist/maps/anchors.d.ts +6 -1
  265. package/dist/maps/anchors.d.ts.map +1 -1
  266. package/dist/maps/anchors.js +260 -1
  267. package/dist/maps/anchors.js.map +1 -1
  268. package/dist/maps/controller.d.ts +57 -0
  269. package/dist/maps/controller.d.ts.map +1 -1
  270. package/dist/maps/controller.js +97 -18
  271. package/dist/maps/controller.js.map +1 -1
  272. package/dist/maps/gl/buckets.d.ts +5 -1
  273. package/dist/maps/gl/buckets.d.ts.map +1 -1
  274. package/dist/maps/gl/buckets.js +5 -2
  275. package/dist/maps/gl/buckets.js.map +1 -1
  276. package/dist/maps/gl/build-worker.d.ts +2 -0
  277. package/dist/maps/gl/build-worker.d.ts.map +1 -1
  278. package/dist/maps/gl/build-worker.js +1 -1
  279. package/dist/maps/gl/build-worker.js.map +1 -1
  280. package/dist/maps/gl/cover.d.ts +23 -4
  281. package/dist/maps/gl/cover.d.ts.map +1 -1
  282. package/dist/maps/gl/cover.js +61 -48
  283. package/dist/maps/gl/cover.js.map +1 -1
  284. package/dist/maps/gl/placement.d.ts +21 -8
  285. package/dist/maps/gl/placement.d.ts.map +1 -1
  286. package/dist/maps/gl/placement.js +133 -58
  287. package/dist/maps/gl/placement.js.map +1 -1
  288. package/dist/maps/gl/renderer.d.ts +36 -4
  289. package/dist/maps/gl/renderer.d.ts.map +1 -1
  290. package/dist/maps/gl/renderer.js +81 -24
  291. package/dist/maps/gl/renderer.js.map +1 -1
  292. package/dist/maps/gl/shaders.d.ts +18 -17
  293. package/dist/maps/gl/shaders.d.ts.map +1 -1
  294. package/dist/maps/gl/shaders.js +34 -32
  295. package/dist/maps/gl/shaders.js.map +1 -1
  296. package/dist/maps/gl/store.d.ts +10 -0
  297. package/dist/maps/gl/store.d.ts.map +1 -1
  298. package/dist/maps/gl/store.js +47 -4
  299. package/dist/maps/gl/store.js.map +1 -1
  300. package/dist/maps/gl/text.d.ts +153 -24
  301. package/dist/maps/gl/text.d.ts.map +1 -1
  302. package/dist/maps/gl/text.js +379 -63
  303. package/dist/maps/gl/text.js.map +1 -1
  304. package/dist/maps/gl/view.d.ts +293 -2
  305. package/dist/maps/gl/view.d.ts.map +1 -1
  306. package/dist/maps/gl/view.js +317 -82
  307. package/dist/maps/gl/view.js.map +1 -1
  308. package/dist/maps/icons.d.ts +32 -0
  309. package/dist/maps/icons.d.ts.map +1 -0
  310. package/dist/maps/icons.js +151 -0
  311. package/dist/maps/icons.js.map +1 -0
  312. package/dist/maps/index.d.ts +2 -0
  313. package/dist/maps/index.d.ts.map +1 -1
  314. package/dist/maps/index.js +2 -0
  315. package/dist/maps/index.js.map +1 -1
  316. package/dist/maps/labels.d.ts +56 -4
  317. package/dist/maps/labels.d.ts.map +1 -1
  318. package/dist/maps/labels.js +213 -46
  319. package/dist/maps/labels.js.map +1 -1
  320. package/dist/maps/node.d.ts +17 -0
  321. package/dist/maps/node.d.ts.map +1 -1
  322. package/dist/maps/node.js +64 -30
  323. package/dist/maps/node.js.map +1 -1
  324. package/dist/maps/proj.d.ts +48 -0
  325. package/dist/maps/proj.d.ts.map +1 -1
  326. package/dist/maps/proj.js +73 -0
  327. package/dist/maps/proj.js.map +1 -1
  328. package/dist/maps/sources.d.ts +5 -3
  329. package/dist/maps/sources.d.ts.map +1 -1
  330. package/dist/maps/sources.js +5 -3
  331. package/dist/maps/sources.js.map +1 -1
  332. package/dist/maps/style.d.ts +35 -0
  333. package/dist/maps/style.d.ts.map +1 -1
  334. package/dist/maps/style.js.map +1 -1
  335. package/dist/maps/styles.d.ts +12 -0
  336. package/dist/maps/styles.d.ts.map +1 -1
  337. package/dist/maps/styles.js +120 -6
  338. package/dist/maps/styles.js.map +1 -1
  339. package/dist/maps/tiles.d.ts +31 -11
  340. package/dist/maps/tiles.d.ts.map +1 -1
  341. package/dist/maps/tiles.js +61 -27
  342. package/dist/maps/tiles.js.map +1 -1
  343. package/dist/maps/types.d.ts +28 -4
  344. package/dist/maps/types.d.ts.map +1 -1
  345. package/dist/markdown/index.d.ts.map +1 -1
  346. package/dist/markdown/index.js +112 -43
  347. package/dist/markdown/index.js.map +1 -1
  348. package/dist/markdown/spans.d.ts.map +1 -1
  349. package/dist/markdown/spans.js +6 -0
  350. package/dist/markdown/spans.js.map +1 -1
  351. package/dist/qml/containers.d.ts.map +1 -1
  352. package/dist/qml/containers.js +6 -1
  353. package/dist/qml/containers.js.map +1 -1
  354. package/dist/qml/interaction.d.ts.map +1 -1
  355. package/dist/qml/interaction.js +38 -5
  356. package/dist/qml/interaction.js.map +1 -1
  357. package/dist/qml/layouts.d.ts.map +1 -1
  358. package/dist/qml/layouts.js +21 -6
  359. package/dist/qml/layouts.js.map +1 -1
  360. package/dist/qml/qtquick.d.ts.map +1 -1
  361. package/dist/qml/qtquick.js +9 -2
  362. package/dist/qml/qtquick.js.map +1 -1
  363. package/dist/qml/react.d.ts.map +1 -1
  364. package/dist/qml/react.js +9 -7
  365. package/dist/qml/react.js.map +1 -1
  366. package/dist/reorder/clock.d.ts +7 -0
  367. package/dist/reorder/clock.d.ts.map +1 -0
  368. package/dist/reorder/clock.js +26 -0
  369. package/dist/reorder/clock.js.map +1 -0
  370. package/dist/reorder/index.d.ts +25 -3
  371. package/dist/reorder/index.d.ts.map +1 -1
  372. package/dist/reorder/index.js +64 -19
  373. package/dist/reorder/index.js.map +1 -1
  374. package/dist/rich-text-editor/index.d.ts +0 -11
  375. package/dist/rich-text-editor/index.d.ts.map +1 -1
  376. package/dist/rich-text-editor/index.js +35 -1
  377. package/dist/rich-text-editor/index.js.map +1 -1
  378. package/dist/rich-text-editor/keymap.d.ts.map +1 -1
  379. package/dist/rich-text-editor/keymap.js +2 -1
  380. package/dist/rich-text-editor/keymap.js.map +1 -1
  381. package/dist/rich-text-editor/keys.d.ts +17 -6
  382. package/dist/rich-text-editor/keys.d.ts.map +1 -1
  383. package/dist/rich-text-editor/keys.js +135 -26
  384. package/dist/rich-text-editor/keys.js.map +1 -1
  385. package/dist/rich-text-editor/marks.d.ts +9 -0
  386. package/dist/rich-text-editor/marks.d.ts.map +1 -0
  387. package/dist/rich-text-editor/marks.js +83 -0
  388. package/dist/rich-text-editor/marks.js.map +1 -0
  389. package/dist/rich-text-editor/render.d.ts.map +1 -1
  390. package/dist/rich-text-editor/render.js +28 -10
  391. package/dist/rich-text-editor/render.js.map +1 -1
  392. package/dist/rich-text-editor/toolbar.d.ts.map +1 -1
  393. package/dist/rich-text-editor/toolbar.js +1 -1
  394. package/dist/rich-text-editor/toolbar.js.map +1 -1
  395. package/dist/rich-text-editor/virtual.d.ts.map +1 -1
  396. package/dist/rich-text-editor/virtual.js +17 -0
  397. package/dist/rich-text-editor/virtual.js.map +1 -1
  398. package/dist/richtext/node.d.ts +46 -2
  399. package/dist/richtext/node.d.ts.map +1 -1
  400. package/dist/richtext/node.js +187 -4
  401. package/dist/richtext/node.js.map +1 -1
  402. package/dist/richtext/runs.d.ts +13 -8
  403. package/dist/richtext/runs.d.ts.map +1 -1
  404. package/dist/richtext/runs.js +18 -8
  405. package/dist/richtext/runs.js.map +1 -1
  406. package/dist/table/index.d.ts.map +1 -1
  407. package/dist/table/index.js +23 -0
  408. package/dist/table/index.js.map +1 -1
  409. package/dist/table/rows.d.ts +3 -2
  410. package/dist/table/rows.d.ts.map +1 -1
  411. package/dist/table/rows.js +20 -6
  412. package/dist/table/rows.js.map +1 -1
  413. package/dist/terminal/index.d.ts.map +1 -1
  414. package/dist/terminal/index.js +4 -0
  415. package/dist/terminal/index.js.map +1 -1
  416. package/dist/terminal/vt/pty.d.ts +13 -2
  417. package/dist/terminal/vt/pty.d.ts.map +1 -1
  418. package/dist/terminal/vt/pty.js +18 -3
  419. package/dist/terminal/vt/pty.js.map +1 -1
  420. package/dist/terminal-output/index.d.ts.map +1 -1
  421. package/dist/terminal-output/index.js +6 -1
  422. package/dist/terminal-output/index.js.map +1 -1
  423. package/dist/three/canvas.d.ts.map +1 -1
  424. package/dist/three/canvas.js +85 -7
  425. package/dist/three/canvas.js.map +1 -1
  426. package/dist/three/events.d.ts +22 -4
  427. package/dist/three/events.d.ts.map +1 -1
  428. package/dist/three/events.js +34 -4
  429. package/dist/three/events.js.map +1 -1
  430. package/dist/tree/index.d.ts.map +1 -1
  431. package/dist/tree/index.js +17 -0
  432. package/dist/tree/index.js.map +1 -1
  433. package/package.json +42 -33
  434. package/src/charts/node.ts +62 -26
  435. package/src/charts/render.ts +120 -30
  436. package/src/code/index.ts +3 -1
  437. package/src/code-editor/completion.ts +3 -2
  438. package/src/code-editor/index.ts +19 -0
  439. package/src/code-editor/node.ts +1574 -184
  440. package/src/code-language/languages/glsl.ts +12 -2
  441. package/src/code-language/languages/javascript.ts +21 -4
  442. package/src/code-language/languages/json.ts +12 -2
  443. package/src/code-language/languages/shell.ts +12 -2
  444. package/src/code-language/languages/sql.ts +22 -2
  445. package/src/code-language/stream.ts +257 -17
  446. package/src/code-language/types.ts +5 -4
  447. package/src/codeblock/index.ts +20 -3
  448. package/src/flow/draw.ts +167 -41
  449. package/src/flow/gl/color.ts +85 -0
  450. package/src/flow/gl/index.ts +342 -0
  451. package/src/flow/gl/pack.ts +585 -0
  452. package/src/flow/gl/renderer.ts +679 -0
  453. package/src/flow/gl/shaders.ts +371 -0
  454. package/src/flow/gl/text.ts +1295 -0
  455. package/src/flow/index.ts +794 -67
  456. package/src/flow/node.ts +2496 -1256
  457. package/src/flow/paint.ts +511 -0
  458. package/src/flow/paths.ts +80 -15
  459. package/src/flow/scene.ts +2199 -0
  460. package/src/flow/types.ts +113 -1
  461. package/src/html/controls.ts +73 -2
  462. package/src/html/css/calc.ts +385 -0
  463. package/src/html/css/cascade.ts +1403 -62
  464. package/src/html/css/color.ts +755 -0
  465. package/src/html/css/content.ts +417 -0
  466. package/src/html/css/counter-styles.ts +973 -0
  467. package/src/html/css/decode.ts +130 -0
  468. package/src/html/css/parse.ts +1514 -160
  469. package/src/html/css/style.ts +4102 -222
  470. package/src/html/css/ua.ts +58 -12
  471. package/src/html/css/values.ts +150 -50
  472. package/src/html/css/vars.ts +348 -0
  473. package/src/html/dom.ts +284 -17
  474. package/src/html/fonts.ts +641 -0
  475. package/src/html/gif.ts +233 -0
  476. package/src/html/index.ts +180 -20
  477. package/src/html/layout/block.ts +3456 -230
  478. package/src/html/layout/boxes.ts +2100 -190
  479. package/src/html/layout/cache.ts +289 -0
  480. package/src/html/layout/collapse.ts +317 -0
  481. package/src/html/layout/css-grid.ts +1063 -0
  482. package/src/html/layout/flex.ts +1115 -106
  483. package/src/html/layout/floats.ts +128 -14
  484. package/src/html/layout/grid-lines.ts +141 -0
  485. package/src/html/layout/grid.ts +181 -0
  486. package/src/html/layout/inline.ts +3943 -192
  487. package/src/html/layout/shaping.ts +140 -0
  488. package/src/html/layout/table.ts +696 -186
  489. package/src/html/layout/tracks.ts +437 -0
  490. package/src/html/node.ts +1481 -118
  491. package/src/html/paint.ts +4293 -169
  492. package/src/html/resources.ts +161 -50
  493. package/src/html/surfaces.ts +81 -0
  494. package/src/html/svg.ts +493 -0
  495. package/src/html/url.ts +86 -0
  496. package/src/index.ts +2 -0
  497. package/src/internal/collate.ts +12 -0
  498. package/src/internal/markdown/ast.ts +11 -0
  499. package/src/internal/markdown/parse.ts +154 -11
  500. package/src/internal/prewarm.ts +45 -0
  501. package/src/internal/sdf.ts +227 -0
  502. package/src/internal/splice.ts +25 -0
  503. package/src/internal/window.ts +36 -5
  504. package/src/maps/anchors.ts +307 -1
  505. package/src/maps/controller.ts +116 -31
  506. package/src/maps/gl/buckets.ts +5 -1
  507. package/src/maps/gl/build-worker.ts +13 -2
  508. package/src/maps/gl/cover.ts +79 -44
  509. package/src/maps/gl/placement.ts +221 -69
  510. package/src/maps/gl/renderer.ts +104 -20
  511. package/src/maps/gl/shaders.ts +35 -32
  512. package/src/maps/gl/store.ts +66 -17
  513. package/src/maps/gl/text.ts +444 -71
  514. package/src/maps/gl/view.ts +361 -96
  515. package/src/maps/icons.ts +183 -0
  516. package/src/maps/index.ts +4 -0
  517. package/src/maps/labels.ts +269 -49
  518. package/src/maps/node.ts +82 -49
  519. package/src/maps/proj.ts +87 -0
  520. package/src/maps/sources.ts +5 -3
  521. package/src/maps/style.ts +32 -0
  522. package/src/maps/styles.ts +215 -4
  523. package/src/maps/tiles.ts +64 -31
  524. package/src/maps/types.ts +28 -4
  525. package/src/markdown/index.ts +149 -67
  526. package/src/markdown/spans.ts +5 -0
  527. package/src/qml/containers.tsx +6 -1
  528. package/src/qml/interaction.tsx +42 -5
  529. package/src/qml/layouts.tsx +21 -6
  530. package/src/qml/qtquick.tsx +9 -2
  531. package/src/qml/react.tsx +7 -5
  532. package/src/reorder/clock.ts +27 -0
  533. package/src/reorder/index.ts +100 -27
  534. package/src/rich-text-editor/index.ts +34 -1
  535. package/src/rich-text-editor/keymap.ts +1 -1
  536. package/src/rich-text-editor/keys.ts +135 -26
  537. package/src/rich-text-editor/marks.ts +101 -0
  538. package/src/rich-text-editor/render.ts +49 -12
  539. package/src/rich-text-editor/toolbar.ts +1 -1
  540. package/src/rich-text-editor/virtual.ts +25 -0
  541. package/src/richtext/node.ts +235 -14
  542. package/src/richtext/runs.ts +23 -12
  543. package/src/table/index.ts +29 -0
  544. package/src/table/rows.ts +18 -8
  545. package/src/terminal/index.ts +4 -0
  546. package/src/terminal/vt/pty.ts +16 -2
  547. package/src/terminal-output/index.ts +6 -1
  548. package/src/three/canvas.ts +102 -8
  549. package/src/three/events.ts +49 -9
  550. package/src/tree/index.ts +19 -0
package/src/maps/tiles.ts CHANGED
@@ -33,8 +33,8 @@
33
33
  import type { PreparedStyle } from './paint.js';
34
34
  import type { VectorTile } from './mvt.js';
35
35
  import { parseTile } from './mvt.js';
36
- import { tileKey } from './proj.js';
37
- import type { TileId } from './proj.js';
36
+ import { BELOW, FILL_DEPTH, fillFromBelow, tileKey } from './proj.js';
37
+ import type { TileCell, TileId } from './proj.js';
38
38
  import { pyramidOf } from './sources.js';
39
39
  import type { MapSource, TileData } from './sources.js';
40
40
 
@@ -247,6 +247,10 @@ export class TileCache {
247
247
  /** Bumped by a style change, which retires every surface without
248
248
  * touching the data behind it. */
249
249
  private _generation = 0;
250
+ /** The key of every tile with a picture, and of its ancestors up to
251
+ * `FILL_DEPTH` levels above it — see {@link descendantsWithSurface}.
252
+ * Built when first asked, and dropped whenever a picture comes or goes. */
253
+ private _below: Set<string> | null = null;
250
254
 
251
255
  constructor(options: TileCacheOptions = {}) {
252
256
  this._options = options;
@@ -492,7 +496,8 @@ export class TileCache {
492
496
  }
493
497
 
494
498
  /**
495
- * The finished **descendants** of a tile, and where each sits inside it.
499
+ * The finished **descendants** of a tile, where each sits inside it, and
500
+ * the gaps they leave.
496
501
  *
497
502
  * The mirror of {@link ancestorWithSurface}, and the half a map needs
498
503
  * when it zooms *out*: the tiles already in hand are then the target's
@@ -501,42 +506,64 @@ export class TileCache {
501
506
  * over it, which is exactly as odd as it sounds — until the coarser tile
502
507
  * has been fetched, rasterized and composited.
503
508
  *
504
- * `depth` is how many levels down to look, and it is small on purpose: a
505
- * level down is 4 tiles, two is 16, and beyond that the pieces are too
506
- * small to be worth the composites.
509
+ * Each quarter of the square is taken from the nearest level that has it,
510
+ * down to `FILL_DEPTH` — see `fillFromBelow`. The first cut took one
511
+ * level for the whole square, the nearest with anything in it, and looked
512
+ * two down. Both left the view blank where a zoom out needs it most: the
513
+ * edges, where the level the map came from covers only part of a coarser
514
+ * tile and the rest is one level further down or nowhere; and a zoom out
515
+ * of more than two levels, which a flick of the wheel is.
516
+ *
517
+ * The search goes only where {@link _heldBelow} says there is something,
518
+ * so a hole with nothing under it — every tile of a zoom *in* — costs four
519
+ * lookups rather than three hundred.
507
520
  *
508
521
  * `generation` as for {@link ancestorWithSurface}.
509
522
  */
510
523
  descendantsWithSurface(
511
524
  source: MapSource,
512
525
  tile: TileId,
513
- depth = 2,
514
526
  generation?: number,
515
- ): { entry: CachedTile; x: number; y: number; span: number }[] {
516
- for (let down = 1; down <= depth; down++) {
517
- const span = 1 << down;
518
- const found: { entry: CachedTile; x: number; y: number; span: number }[] =
519
- [];
520
- for (let dy = 0; dy < span; dy++) {
521
- for (let dx = 0; dx < span; dx++) {
522
- const entry = this._entries.get(
523
- this.key(source, {
524
- z: tile.z + down,
525
- x: (tile.x << down) + dx,
526
- y: (tile.y << down) + dy,
527
- }),
528
- );
529
- if (entry?.shown && drawnFor(entry.shown, generation)) {
530
- entry.lastUsed = this._frame;
531
- found.push({ entry, x: dx, y: dy, span });
532
- }
533
- }
527
+ ): {
528
+ pieces: (TileCell & { tile: TileId; value: CachedTile })[];
529
+ gaps: TileCell[];
530
+ } {
531
+ const below = this._heldBelow();
532
+ const { pieces, gaps } = fillFromBelow(tile, FILL_DEPTH, (under) => {
533
+ const key = this.key(source, under);
534
+ if (!below.has(key)) return undefined;
535
+ const entry = this._entries.get(key);
536
+ if (entry?.shown && drawnFor(entry.shown, generation)) {
537
+ // Stamped, for the reason `ancestorWithSurface` gives.
538
+ entry.lastUsed = this._frame;
539
+ return entry;
540
+ }
541
+ return BELOW;
542
+ });
543
+ return { pieces, gaps };
544
+ }
545
+
546
+ /** The keys of every tile with a picture and of its ancestors up to
547
+ * `FILL_DEPTH` levels above — so a search under a hole can tell where
548
+ * there is nothing without asking for each tile there. A superset where
549
+ * a picture is of another generation, which only costs the search a
550
+ * level. */
551
+ private _heldBelow(): Set<string> {
552
+ if (this._below) return this._below;
553
+ const below = new Set<string>();
554
+ for (const entry of this._entries.values()) {
555
+ if (!entry.shown) continue;
556
+ below.add(entry.key);
557
+ let { z, x, y } = entry.tile;
558
+ for (let up = 1; up <= FILL_DEPTH && z > 0; up++) {
559
+ z--;
560
+ x >>= 1;
561
+ y >>= 1;
562
+ below.add(this.key(entry.data.source, { z, x, y }));
534
563
  }
535
- // The nearest level that has anything wins: one level down is both
536
- // the sharpest and the fewest composites.
537
- if (found.length > 0) return found;
538
564
  }
539
- return [];
565
+ this._below = below;
566
+ return below;
540
567
  }
541
568
 
542
569
  /**
@@ -612,6 +639,7 @@ export class TileCache {
612
639
  if (entry.shown) this._release(entry.shown);
613
640
  entry.shown = entry.drawing;
614
641
  entry.drawing = null;
642
+ this._below = null;
615
643
  return true;
616
644
  }
617
645
 
@@ -629,6 +657,7 @@ export class TileCache {
629
657
  * composited again, and otherwise kept until eviction got round to it.
630
658
  */
631
659
  swap(): void {
660
+ this._below = null;
632
661
  for (const entry of this._entries.values()) {
633
662
  if (entry.drawing && !drawnFor(entry.drawing, this._generation)) {
634
663
  this._release(entry.drawing);
@@ -746,7 +775,10 @@ export class TileCache {
746
775
  }
747
776
 
748
777
  private _dropSurface(entry: CachedTile): void {
749
- if (entry.shown) this._release(entry.shown);
778
+ if (entry.shown) {
779
+ this._release(entry.shown);
780
+ this._below = null;
781
+ }
750
782
  if (entry.drawing) this._release(entry.drawing);
751
783
  entry.shown = null;
752
784
  entry.drawing = null;
@@ -780,6 +812,7 @@ export class TileCache {
780
812
  for (const data of this._data.values()) data.abort?.();
781
813
  this._data.clear();
782
814
  this._surfaceBytes = 0;
815
+ this._below = null;
783
816
  }
784
817
 
785
818
  /** Every entry — for a test, and for the `onTiles` diagnostic. */
package/src/maps/types.ts CHANGED
@@ -26,6 +26,7 @@ export type {
26
26
  SymbolLayer,
27
27
  Zoomed,
28
28
  } from './style.js';
29
+ export type { MapIcon } from './icons.js';
29
30
 
30
31
  /** Which renderer draws a map — see `<Map renderer>`. */
31
32
  export type MapRenderer = 'gl' | 'retained';
@@ -94,7 +95,9 @@ export interface MapFrameStats {
94
95
  * What covers a hole while zooming *in*. */
95
96
  fromAncestor: number;
96
97
  /** …and how many from their finer descendants, scaled down. What covers
97
- * a hole while zooming *out*, where there is no ancestor to borrow. */
98
+ * a hole while zooming *out*, where there is no ancestor to borrow.
99
+ * Descendants cover what they can and an ancestor the gaps between them,
100
+ * so a hole covered partly from each counts in both. */
98
101
  fromDescendant: number;
99
102
  /** Tiles still to rasterize (retained) or to build (GL) — non-zero means
100
103
  * the map is still sharpening and another frame is already scheduled. */
@@ -369,11 +372,32 @@ export interface MapGlProps {
369
372
  */
370
373
  levelFade?: number;
371
374
  /**
372
- * Trade detail for frame rate while the camera moves. `true` holds each
373
- * moving frame to 12 ms; `{ budgetMs }` to another budget. When the camera
374
- * settles the next frame draws everything again.
375
+ * Trade detail for frame rate while the camera moves. **On by default**,
376
+ * holding each moving frame to 12 ms; `{ budgetMs }` picks another budget
377
+ * and `false` turns it off. When the camera settles the next frame draws
378
+ * everything again.
379
+ *
380
+ * It is on by default because the alternative is a renderer that can take
381
+ * the whole thread: unbudgeted, a fly across ten zoom levels left the
382
+ * event loop unable to run a `setTimeout` for a second at a time, with
383
+ * nothing individually slow inside it. An app embedding a map should not
384
+ * have to know that to keep its own clock running.
375
385
  */
376
386
  adaptive?: boolean | { budgetMs?: number };
387
+ /**
388
+ * Place labels in every frame while the camera moves, and set a new
389
+ * name's text in the frame it is placed in, so the names always match
390
+ * the zoom on screen. Off by default: new names then wait until the zoom
391
+ * has been still for 120 ms, and arrive a readback later.
392
+ *
393
+ * What it costs: a zoom crosses several label sets, so names arrive and
394
+ * leave at every step of it (each fading, over 220 ms), and each new name
395
+ * is set on this thread in the frame that needs it — up to 8 ms a frame,
396
+ * the rest the frame after. Needs a text engine that sets a string
397
+ * synchronously (react-x11 2.21's layout coverage); on one that cannot,
398
+ * names still arrive a readback later, but are placed every frame.
399
+ */
400
+ labelsWhileMoving?: boolean;
377
401
  /** Build tiles' geometry on this many worker threads, so no frame pays
378
402
  * for a tile arriving. `0` (the default) builds on this thread, a few
379
403
  * milliseconds a frame. */
@@ -77,6 +77,7 @@ import { runsOf, plainTextOf } from './spans.js';
77
77
  import type { InlineStyles } from './spans.js';
78
78
  import { useLinkClicks } from '../richtext/index.js';
79
79
  import { hx } from './hx.js';
80
+ import { useFontPrewarm } from '../internal/prewarm.js';
80
81
 
81
82
  export type {
82
83
  AttributeValue,
@@ -365,7 +366,12 @@ function renderBlocks(blocks: BlockNode[], ctx: RenderCtx): ReactNode[] {
365
366
  return blocks.map((b, i) => renderBlock(b, ctx, i));
366
367
  }
367
368
 
368
- function renderBlock(block: BlockNode, ctx: RenderCtx, key: number): ReactNode {
369
+ function renderBlock(
370
+ block: BlockNode,
371
+ ctx: RenderCtx,
372
+ key: number,
373
+ first = key === 0,
374
+ ): ReactNode {
369
375
  const look = ctx.look;
370
376
  switch (block.type) {
371
377
  case 'paragraph':
@@ -378,7 +384,7 @@ function renderBlock(block: BlockNode, ctx: RenderCtx, key: number): ReactNode {
378
384
  weight: 700,
379
385
  });
380
386
  return richtext(key, runsOf(block.children, s), {
381
- marginTop: key === 0 ? 0 : Math.round(look.blockGap * 0.6),
387
+ marginTop: first ? 0 : Math.round(look.blockGap * 0.6),
382
388
  });
383
389
  }
384
390
 
@@ -510,7 +516,7 @@ function renderCode(
510
516
  flexDirection: 'column',
511
517
  },
512
518
  },
513
- richtext('code', runs, codeTextStyle(code), false),
519
+ richtext('code', runs, codeTextStyle(code, false), false),
514
520
  );
515
521
  }
516
522
 
@@ -553,38 +559,46 @@ function renderList(list: ListBlock, ctx: RenderCtx, key: number): ReactNode {
553
559
  ),
554
560
  );
555
561
  } else {
562
+ // the text itself, sized as the column the box around it used to be:
563
+ // a list is a few boxes per item, and at 600 KB there were 1,582 of
564
+ // these for yoga to lay out and absolutize on every width change
556
565
  marker = hx(
557
- 'box',
558
- { selectable: false, style: markerStyle },
559
- hx(
560
- 'text',
561
- {
562
- style: {
563
- color: look.dim,
564
- fontSize: look.inline.size,
565
- fontFamily: look.inline.family,
566
- },
566
+ 'text',
567
+ {
568
+ selectable: false,
569
+ style: {
570
+ flexShrink: 0,
571
+ width: markerWidth,
572
+ color: look.dim,
573
+ fontSize: look.inline.size,
574
+ fontFamily: look.inline.family,
567
575
  },
568
- list.ordered ? `${list.start + i}.` : '•',
569
- ),
576
+ },
577
+ list.ordered ? `${list.start + i}.` : '•',
570
578
  );
571
579
  }
580
+ const only = item.children.length === 1 ? item.children[0] : undefined;
572
581
  return hx(
573
582
  'box',
574
583
  { key: i, style: STYLES.itemRow },
575
584
  marker,
576
- hx(
577
- 'box',
578
- {
579
- style: {
580
- ...STYLES.column,
581
- gap: Math.round(look.blockGap * 0.4),
582
- flexGrow: 1,
583
- flexShrink: 1,
584
- },
585
- },
586
- ...renderBlocks(item.children, ctx),
587
- ),
585
+ // An item that is one paragraph — nearly every item — is the
586
+ // paragraph, taking the rest of the row; the column is for an item of
587
+ // several blocks, which needs the gap between them.
588
+ only?.type === 'paragraph'
589
+ ? richtext(0, runsOf(only.children, look.inline), STYLES.itemText)
590
+ : hx(
591
+ 'box',
592
+ {
593
+ style: {
594
+ ...STYLES.column,
595
+ gap: Math.round(look.blockGap * 0.4),
596
+ flexGrow: 1,
597
+ flexShrink: 1,
598
+ },
599
+ },
600
+ ...renderBlocks(item.children, ctx),
601
+ ),
588
602
  );
589
603
  });
590
604
  return hx('box', { key, style: { ...STYLES.column, gap } }, ...items);
@@ -598,6 +612,7 @@ function renderTable(
598
612
  const look = ctx.look;
599
613
  const size = look.inline.size;
600
614
  const padX = Math.round(size * 0.6);
615
+ const padY = Math.round(size * 0.35);
601
616
  const cols = table.align.length;
602
617
 
603
618
  // Column widths: max-content per column, measured through the app's font
@@ -645,24 +660,19 @@ function renderTable(
645
660
  borderTopColor: divided ? look.border : undefined,
646
661
  },
647
662
  },
663
+ // A cell is its text. The padding it needs is a margin: the cell has
664
+ // no background or border of its own — the row paints both — so the
665
+ // space around the text looks the same either way, and there is no
666
+ // box per cell for yoga to lay out.
648
667
  ...cells.map((cell, c) =>
649
- h(
650
- 'box',
651
- {
652
- key: c,
653
- style: {
654
- width: widths[c],
655
- paddingLeft: padX,
656
- paddingRight: padX,
657
- paddingTop: Math.round(size * 0.35),
658
- paddingBottom: Math.round(size * 0.35),
659
- },
660
- },
661
- richtext('c', runsOf(cell, s), {
662
- textAlign: table.align[c] ?? undefined,
663
- flexGrow: 1,
664
- }),
665
- ),
668
+ richtext(c, runsOf(cell, s), {
669
+ textAlign: table.align[c] ?? undefined,
670
+ width: widths[c] - padX * 2,
671
+ marginLeft: padX,
672
+ marginRight: padX,
673
+ marginTop: padY,
674
+ marginBottom: padY,
675
+ }),
666
676
  ),
667
677
  );
668
678
 
@@ -696,14 +706,26 @@ function renderTable(
696
706
  const STYLES = {
697
707
  column: { flexDirection: 'column' },
698
708
  itemRow: { flexDirection: 'row' },
709
+ itemText: { flexGrow: 1, flexShrink: 1 },
699
710
  markerBox: { flexDirection: 'row', flexShrink: 0 },
700
711
  } as const satisfies Record<string, Style>;
701
712
 
702
713
  // --- the component ---------------------------------------------------------
703
714
 
715
+ /** What the last render made for one top-level block. */
716
+ interface RenderedBlock {
717
+ raw: string;
718
+ live: boolean;
719
+ first: boolean;
720
+ key: number;
721
+ element: ReactNode;
722
+ }
723
+
704
724
  interface BlockCache {
705
725
  epoch: string;
706
- map: Map<string, ReactNode>;
726
+ blocks: RenderedBlock[];
727
+ /** a key no block has had */
728
+ next: number;
707
729
  }
708
730
 
709
731
  /**
@@ -725,6 +747,14 @@ export function Markdown(props: MarkdownProps): ReactElement {
725
747
  // same widening `hx.ts` documents for the `theme` prop.
726
748
  const theme = useTheme() as unknown as Record<string, unknown>;
727
749
  const app = useApp() as { fonts?: FontsMeasureLike } | null;
750
+ // a document with code in it sets that code in the mono family, and its
751
+ // render is the head start (a fence or a code span needs a backtick or a
752
+ // tilde fence; an indented block is rare enough to find its own way)
753
+ useFontPrewarm(
754
+ source.includes('`') || source.includes('~~~')
755
+ ? (props.monoFamily ?? 'monospace')
756
+ : null,
757
+ );
728
758
 
729
759
  const links = useLinkClicks(onLink);
730
760
  const menu = useSelectionMenu(selectable);
@@ -760,12 +790,19 @@ export function Markdown(props: MarkdownProps): ReactElement {
760
790
  [scope],
761
791
  );
762
792
 
793
+ // The last parse, which the next one resumes from: an edit or a streamed
794
+ // chunk reads the blocks around the change, and a 600 KB document is not
795
+ // read again whole for one paragraph (ParseOptions.previous). Only ever a
796
+ // hint — a parse resumed from it answers what a parse from scratch would.
797
+ const lastParse = React.useRef<Document | null>(null);
763
798
  const doc: Document = React.useMemo(() => {
764
799
  const parsed = parse(source, {
765
800
  partial,
766
801
  ...(isComponent ? { isComponent } : null),
767
802
  ...(evaluate ? { expressions: true } : null),
803
+ ...(lastParse.current ? { previous: lastParse.current } : null),
768
804
  });
805
+ lastParse.current = parsed;
769
806
  // Expressions resolve to text here rather than during the render, so
770
807
  // every `runsOf` caller downstream keeps seeing an inline tree it
771
808
  // already understands. `raws` is carried through, so the block cache
@@ -774,10 +811,18 @@ export function Markdown(props: MarkdownProps): ReactElement {
774
811
  return evaluate ? resolveExpressions(parsed, evaluate) : parsed;
775
812
  }, [source, partial, isComponent, evaluate]);
776
813
 
777
- // Per-block element cache, keyed on the block's raw source (+ whether it
778
- // is the live tail). Streaming appends re-render only the block that
779
- // changed; everything else is the same ReactElement, so React bails out
780
- // and the retained nodes keep their layout caches.
814
+ // Per-block element cache: a block whose raw source is what it was (and
815
+ // is still the live tail, or not, and still first, or not) is the same
816
+ // ReactElement, so React bails out and the retained nodes keep their
817
+ // layout caches. Streaming appends re-render only the block that changed.
818
+ //
819
+ // Each block keeps its React key from one render to the next, found by
820
+ // lining the blocks up with the last render's from both ends: those the
821
+ // change left alone keep theirs, and the changed ones in the middle take
822
+ // the keys of the ones they replace, in order, so an edited paragraph is
823
+ // updated where it stands. Keyed by index, a paragraph inserted mid-way
824
+ // moved every block after it onto another block's key, and all of them
825
+ // were rendered and laid out again: a second, in a 600 KB document.
781
826
  const cacheRef = React.useRef<BlockCache | null>(null);
782
827
  const fonts = app?.fonts ?? null;
783
828
  // Neither the fences map nor `resolveLanguage` can be part of a string
@@ -812,13 +857,35 @@ export function Markdown(props: MarkdownProps): ReactElement {
812
857
  }
813
858
  const epoch = `${look.key}|${fonts ? 'f' : '-'}|${seamsRef.current.gen}`;
814
859
  if (!cacheRef.current || cacheRef.current.epoch !== epoch) {
815
- cacheRef.current = { epoch, map: new Map() };
860
+ // the keys carry over, so a new epoch updates each block in place
861
+ cacheRef.current = {
862
+ epoch,
863
+ blocks: (cacheRef.current?.blocks ?? []).map((b) => ({
864
+ ...b,
865
+ element: undefined,
866
+ })),
867
+ next: cacheRef.current?.next ?? 0,
868
+ };
816
869
  }
817
870
  const cache = cacheRef.current;
818
871
 
819
872
  const children: ReactNode[] = [];
820
873
  {
821
- const nextMap = new Map<string, ReactNode>();
874
+ const was = cache.blocks;
875
+ const n = doc.blocks.length;
876
+ let head = 0;
877
+ while (head < n && head < was.length && was[head].raw === doc.raws[head]) {
878
+ head += 1;
879
+ }
880
+ let tail = 0;
881
+ while (
882
+ tail < n - head &&
883
+ tail < was.length - head &&
884
+ was[was.length - 1 - tail].raw === doc.raws[n - 1 - tail]
885
+ ) {
886
+ tail += 1;
887
+ }
888
+ const kept: RenderedBlock[] = [];
822
889
  const ctx: RenderCtx = {
823
890
  look,
824
891
  fonts,
@@ -827,24 +894,39 @@ export function Markdown(props: MarkdownProps): ReactElement {
827
894
  components: props.components,
828
895
  ...(evaluate ? { evaluate } : null),
829
896
  };
830
- for (let i = 0; i < doc.blocks.length; i += 1) {
831
- const live = partial && i === doc.blocks.length - 1;
832
- const cacheKey = `${i}|${live ? 'L' : '.'}|${doc.raws[i]}`;
833
- const hit = cache.map.get(cacheKey) ?? nextMap.get(cacheKey);
834
- if (hit !== undefined) {
835
- children.push(hit);
836
- nextMap.set(cacheKey, hit);
837
- continue;
838
- }
839
- const element = renderBlock(
840
- doc.blocks[i],
841
- live ? { ...ctx, live } : ctx,
842
- i,
843
- );
897
+ for (let i = 0; i < n; i += 1) {
898
+ const raw = doc.raws[i];
899
+ const live = partial && i === n - 1;
900
+ const first = i === 0;
901
+ // the block this one stands for in the last render, if any
902
+ const before =
903
+ i < head
904
+ ? was[i]
905
+ : i >= n - tail
906
+ ? was[was.length - n + i]
907
+ : i < was.length - tail
908
+ ? was[i]
909
+ : undefined;
910
+ const key = before ? before.key : cache.next++;
911
+ const element =
912
+ before &&
913
+ before.element !== undefined &&
914
+ before.raw === raw &&
915
+ before.live === live &&
916
+ before.first === first
917
+ ? before.element
918
+ : renderBlock(
919
+ doc.blocks[i],
920
+ live ? { ...ctx, live } : ctx,
921
+ key,
922
+ first,
923
+ );
844
924
  children.push(element);
845
- nextMap.set(cacheKey, element);
925
+ kept.push({ raw, live, first, key, element });
846
926
  }
847
- cache.map = nextMap; // old entries fall away with the text that made them
927
+ // what the next render lines up against; the rest falls away with the
928
+ // text that made it
929
+ cache.blocks = kept;
848
930
  }
849
931
 
850
932
  const rootStyle: Style = {
@@ -88,6 +88,11 @@ function pushRun(
88
88
  out: TextRun[],
89
89
  ): void {
90
90
  if (text.length === 0) return;
91
+ // A tab in running text reads as a space, as HTML sets it, and each text
92
+ // engine draws U+0009 as whatever its font has for it: a box in ntk's
93
+ // fonts, CoreText's own stops 28 points apart. It is laid out as the
94
+ // space it reads as, the same length, so every offset holds.
95
+ if (text.includes('\t')) text = text.replace(/\t/g, ' ');
91
96
  const inLink = st.href !== undefined;
92
97
  const color = st.code ? s.codeColor : inLink ? s.linkColor : s.color;
93
98
  const run: TextRun = {
@@ -25,6 +25,7 @@ import {
25
25
  } from './view-utils.js';
26
26
  import { delegateExtras, resolveModel } from './models.js';
27
27
  import { warn } from './globals.js';
28
+ import { scaleOf } from '../internal/units.js';
28
29
 
29
30
  // --- positioners -----------------------------------------------------------
30
31
 
@@ -126,7 +127,11 @@ function FlickableView({ inst }: { inst: QmlInstance }): ReactElement {
126
127
  useEffect(() => {
127
128
  const node = hostNode(inst) as ScrollableNode | null;
128
129
  if (!node || typeof node.scrollTo !== 'function') return;
129
- if (node.scrollX !== cx || node.scrollY !== cy)
130
+ // The node's offsets are device pixels; `contentX`/`contentY`,
131
+ // `scrollTo` and `onScroll`'s payload are logical. Compared raw, every
132
+ // scroll the pane made came back to it as a `scrollTo` to where it was.
133
+ const s = scaleOf(node);
134
+ if (node.scrollX / s !== cx || node.scrollY / s !== cy)
130
135
  node.scrollTo({ x: cx, y: cy });
131
136
  }, [inst, cx, cy]);
132
137
  return (
@@ -29,6 +29,7 @@ import {
29
29
  qmlColor,
30
30
  str,
31
31
  } from './view-utils.js';
32
+ import { scaleOf } from '../internal/units.js';
32
33
 
33
34
  // --- Keys + focus ----------------------------------------------------------
34
35
 
@@ -56,6 +57,7 @@ interface PointerEventLike {
56
57
  interface WheelEventLike extends PointerEventLike {
57
58
  deltaX?: number;
58
59
  deltaY?: number;
60
+ smooth?: boolean;
59
61
  }
60
62
 
61
63
  // Qt's modifier flags, so `mouse.modifiers & Qt.ShiftModifier` reads as
@@ -130,6 +132,20 @@ export function keyFocusProps(inst: QmlInstance): Record<string, unknown> {
130
132
 
131
133
  // --- MouseArea -------------------------------------------------------------
132
134
 
135
+ // The wheel, from react-x11's units into Qt's. react-x11 hands a handler
136
+ // logical pixels, 48 to a notch (its `WheelEvent` declaration), positive
137
+ // where the content advances: down, and right. Qt's `angleDelta` is eighths
138
+ // of a degree, 120 to a notch, positive where the wheel turns away from the
139
+ // user: up, and *left* — xcb's plugin maps button 6 to +120, and
140
+ // `QWheelEvent::inverted` and `QAbstractSlider` both say a scroll to the
141
+ // right is negative. (The QML WheelEvent page says "up/right"; every
142
+ // platform plugin disagrees.) So both axes flip, and a notch down is -120.
143
+ const ANGLE_PER_PX = 120 / 48;
144
+
145
+ /** One axis of Qt's wheel from react-x11's: flipped, times `per`. */
146
+ const qtWheelAxis = (px: number | undefined, per = 1): number =>
147
+ px ? -px * per : 0; // an axis that did not move is 0, not -0
148
+
133
149
  function MouseAreaView({ inst }: { inst: QmlInstance }): ReactElement {
134
150
  const enabled = inst.slot('enabled').peek() !== false;
135
151
  const hoverEnabled = inst.slot('hoverEnabled').peek() === true;
@@ -137,10 +153,16 @@ function MouseAreaView({ inst }: { inst: QmlInstance }): ReactElement {
137
153
  applyMotion(inst, style);
138
154
 
139
155
  const mouse = (e: PointerEventLike) => {
140
- const abs = hostNode(inst)?.abs;
156
+ // `e.x` is logical and `abs` device (react-x11's docs/scale.md), so the
157
+ // area's origin is divided into the event's unit first. Not
158
+ // `getClientRects()`, the same box already divided: it answers nothing
159
+ // for a box with no area, and a 0×0 MouseArea still hears a click on a
160
+ // child that hangs outside it.
161
+ const node = hostNode(inst);
162
+ const s = scaleOf(node);
141
163
  return {
142
- x: e.x - (abs?.x ?? 0),
143
- y: e.y - (abs?.y ?? 0),
164
+ x: e.x - (node?.abs.x ?? 0) / s,
165
+ y: e.y - (node?.abs.y ?? 0) / s,
144
166
  button: e.button,
145
167
  modifiers: modifiersOf(e),
146
168
  accepted: true,
@@ -170,7 +192,18 @@ function MouseAreaView({ inst }: { inst: QmlInstance }): ReactElement {
170
192
  handlers.onWheel = (e: WheelEventLike) => {
171
193
  inst.emit('wheel', {
172
194
  ...mouse(e),
173
- angleDelta: { x: e.deltaX ?? 0, y: e.deltaY ?? 0 },
195
+ angleDelta: {
196
+ x: qtWheelAxis(e.deltaX, ANGLE_PER_PX),
197
+ y: qtWheelAxis(e.deltaY, ANGLE_PER_PX),
198
+ },
199
+ // Pixels only where a device measured them — a touchpad, a
200
+ // high-resolution wheel: react-x11's `smooth`. A notch's 48 are a
201
+ // toolkit's choice rather than a measurement, so a notched wheel
202
+ // leaves (0, 0), as Qt's X11 plugin does, and a handler falls back
203
+ // to angleDelta the way Qt's docs tell it to.
204
+ pixelDelta: e.smooth
205
+ ? { x: qtWheelAxis(e.deltaX), y: qtWheelAxis(e.deltaY) }
206
+ : { x: 0, y: 0 },
174
207
  });
175
208
  };
176
209
  if (hoverEnabled) {
@@ -229,7 +262,11 @@ function useImplicitLineHeight(inst: QmlInstance, text: string): void {
229
262
  text || 'Mg',
230
263
  node.resolvedTextStyle(),
231
264
  );
232
- inst.slots.get('implicitHeight')?.assign(Math.ceil(probe.height) + 8);
265
+ // Laid out at the resolved size, which is the device one (TextView,
266
+ // in qtquick.tsx), so the height is divided back into logical pixels.
267
+ inst.slots
268
+ .get('implicitHeight')
269
+ ?.assign(Math.ceil(probe.height / scaleOf(node)) + 8);
233
270
  } catch {
234
271
  // No fonts loaded (headless without the fonts option): leave 0.
235
272
  }