@react-x11/components 0.1.0 → 0.2.1

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 (788) hide show
  1. package/README.md +979 -21
  2. package/dist/ansi/cast.d.ts +48 -0
  3. package/dist/ansi/cast.d.ts.map +1 -0
  4. package/dist/ansi/cast.js +135 -0
  5. package/dist/ansi/cast.js.map +1 -0
  6. package/dist/ansi/index.d.ts +10 -0
  7. package/dist/ansi/index.d.ts.map +1 -0
  8. package/dist/ansi/index.js +27 -0
  9. package/dist/ansi/index.js.map +1 -0
  10. package/dist/ansi/palette.d.ts +79 -0
  11. package/dist/ansi/palette.d.ts.map +1 -0
  12. package/dist/ansi/palette.js +155 -0
  13. package/dist/ansi/palette.js.map +1 -0
  14. package/dist/ansi/parse.d.ts +114 -0
  15. package/dist/ansi/parse.d.ts.map +1 -0
  16. package/dist/ansi/parse.js +687 -0
  17. package/dist/ansi/parse.js.map +1 -0
  18. package/dist/ansi/sgr.d.ts +87 -0
  19. package/dist/ansi/sgr.d.ts.map +1 -0
  20. package/dist/ansi/sgr.js +302 -0
  21. package/dist/ansi/sgr.js.map +1 -0
  22. package/dist/ansi/utf8.d.ts +15 -0
  23. package/dist/ansi/utf8.d.ts.map +1 -0
  24. package/dist/ansi/utf8.js +82 -0
  25. package/dist/ansi/utf8.js.map +1 -0
  26. package/dist/calendar/Calendar.d.ts +136 -0
  27. package/dist/calendar/Calendar.d.ts.map +1 -0
  28. package/dist/calendar/Calendar.js +460 -0
  29. package/dist/calendar/Calendar.js.map +1 -0
  30. package/dist/calendar/DatePicker.d.ts +52 -0
  31. package/dist/calendar/DatePicker.d.ts.map +1 -0
  32. package/dist/calendar/DatePicker.js +257 -0
  33. package/dist/calendar/DatePicker.js.map +1 -0
  34. package/dist/calendar/dates.d.ts +90 -0
  35. package/dist/calendar/dates.d.ts.map +1 -0
  36. package/dist/calendar/dates.js +236 -0
  37. package/dist/calendar/dates.js.map +1 -0
  38. package/dist/calendar/index.d.ts +8 -0
  39. package/dist/calendar/index.d.ts.map +1 -0
  40. package/dist/calendar/index.js +15 -0
  41. package/dist/calendar/index.js.map +1 -0
  42. package/dist/charts/components.d.ts +141 -0
  43. package/dist/charts/components.d.ts.map +1 -0
  44. package/dist/charts/components.js +580 -0
  45. package/dist/charts/components.js.map +1 -0
  46. package/dist/charts/data.d.ts +198 -0
  47. package/dist/charts/data.d.ts.map +1 -0
  48. package/dist/charts/data.js +616 -0
  49. package/dist/charts/data.js.map +1 -0
  50. package/dist/charts/hx.d.ts +21 -0
  51. package/dist/charts/hx.d.ts.map +1 -0
  52. package/dist/charts/hx.js +15 -0
  53. package/dist/charts/hx.js.map +1 -0
  54. package/dist/charts/index.d.ts +27 -0
  55. package/dist/charts/index.d.ts.map +1 -0
  56. package/dist/charts/index.js +38 -0
  57. package/dist/charts/index.js.map +1 -0
  58. package/dist/charts/node.d.ts +96 -0
  59. package/dist/charts/node.d.ts.map +1 -0
  60. package/dist/charts/node.js +720 -0
  61. package/dist/charts/node.js.map +1 -0
  62. package/dist/charts/render.d.ts +153 -0
  63. package/dist/charts/render.d.ts.map +1 -0
  64. package/dist/charts/render.js +762 -0
  65. package/dist/charts/render.js.map +1 -0
  66. package/dist/charts/scale.d.ts +42 -0
  67. package/dist/charts/scale.d.ts.map +1 -0
  68. package/dist/charts/scale.js +173 -0
  69. package/dist/charts/scale.js.map +1 -0
  70. package/dist/charts/spec.d.ts +91 -0
  71. package/dist/charts/spec.d.ts.map +1 -0
  72. package/dist/charts/spec.js +33 -0
  73. package/dist/charts/spec.js.map +1 -0
  74. package/dist/charts/timers.d.ts +6 -0
  75. package/dist/charts/timers.d.ts.map +1 -0
  76. package/dist/charts/timers.js +14 -0
  77. package/dist/charts/timers.js.map +1 -0
  78. package/dist/code/hx.d.ts +24 -0
  79. package/dist/code/hx.d.ts.map +1 -0
  80. package/dist/code/hx.js +25 -0
  81. package/dist/code/hx.js.map +1 -0
  82. package/dist/code/index.d.ts +45 -0
  83. package/dist/code/index.d.ts.map +1 -0
  84. package/dist/code/index.js +93 -0
  85. package/dist/code/index.js.map +1 -0
  86. package/dist/code-editor/completion.d.ts +26 -0
  87. package/dist/code-editor/completion.d.ts.map +1 -0
  88. package/dist/code-editor/completion.js +129 -0
  89. package/dist/code-editor/completion.js.map +1 -0
  90. package/dist/code-editor/doc.d.ts +35 -0
  91. package/dist/code-editor/doc.d.ts.map +1 -0
  92. package/dist/code-editor/doc.js +162 -0
  93. package/dist/code-editor/doc.js.map +1 -0
  94. package/dist/code-editor/hx.d.ts +13 -0
  95. package/dist/code-editor/hx.d.ts.map +1 -0
  96. package/dist/code-editor/hx.js +10 -0
  97. package/dist/code-editor/hx.js.map +1 -0
  98. package/dist/code-editor/index.d.ts +88 -0
  99. package/dist/code-editor/index.d.ts.map +1 -0
  100. package/dist/code-editor/index.js +401 -0
  101. package/dist/code-editor/index.js.map +1 -0
  102. package/dist/code-editor/node.d.ts +343 -0
  103. package/dist/code-editor/node.d.ts.map +1 -0
  104. package/dist/code-editor/node.js +1521 -0
  105. package/dist/code-editor/node.js.map +1 -0
  106. package/dist/code-language/hljs.d.ts +47 -0
  107. package/dist/code-language/hljs.d.ts.map +1 -0
  108. package/dist/code-language/hljs.js +211 -0
  109. package/dist/code-language/hljs.js.map +1 -0
  110. package/dist/code-language/index.d.ts +22 -0
  111. package/dist/code-language/index.d.ts.map +1 -0
  112. package/dist/code-language/index.js +20 -0
  113. package/dist/code-language/index.js.map +1 -0
  114. package/dist/code-language/languages/glsl.d.ts +4 -0
  115. package/dist/code-language/languages/glsl.d.ts.map +1 -0
  116. package/dist/code-language/languages/glsl.js +99 -0
  117. package/dist/code-language/languages/glsl.js.map +1 -0
  118. package/dist/code-language/languages/javascript.d.ts +10 -0
  119. package/dist/code-language/languages/javascript.d.ts.map +1 -0
  120. package/dist/code-language/languages/javascript.js +360 -0
  121. package/dist/code-language/languages/javascript.js.map +1 -0
  122. package/dist/code-language/languages/json.d.ts +4 -0
  123. package/dist/code-language/languages/json.d.ts.map +1 -0
  124. package/dist/code-language/languages/json.js +68 -0
  125. package/dist/code-language/languages/json.js.map +1 -0
  126. package/dist/code-language/languages/shell.d.ts +4 -0
  127. package/dist/code-language/languages/shell.d.ts.map +1 -0
  128. package/dist/code-language/languages/shell.js +189 -0
  129. package/dist/code-language/languages/shell.js.map +1 -0
  130. package/dist/code-language/languages/sql.d.ts +11 -0
  131. package/dist/code-language/languages/sql.d.ts.map +1 -0
  132. package/dist/code-language/languages/sql.js +133 -0
  133. package/dist/code-language/languages/sql.js.map +1 -0
  134. package/dist/code-language/lezer.d.ts +24 -0
  135. package/dist/code-language/lezer.d.ts.map +1 -0
  136. package/dist/code-language/lezer.js +148 -0
  137. package/dist/code-language/lezer.js.map +1 -0
  138. package/dist/code-language/registry.d.ts +19 -0
  139. package/dist/code-language/registry.d.ts.map +1 -0
  140. package/dist/code-language/registry.js +56 -0
  141. package/dist/code-language/registry.js.map +1 -0
  142. package/dist/code-language/runs.d.ts +35 -0
  143. package/dist/code-language/runs.d.ts.map +1 -0
  144. package/dist/code-language/runs.js +88 -0
  145. package/dist/code-language/runs.js.map +1 -0
  146. package/dist/code-language/stream.d.ts +70 -0
  147. package/dist/code-language/stream.d.ts.map +1 -0
  148. package/dist/code-language/stream.js +243 -0
  149. package/dist/code-language/stream.js.map +1 -0
  150. package/dist/code-language/textmate.d.ts +27 -0
  151. package/dist/code-language/textmate.d.ts.map +1 -0
  152. package/dist/code-language/textmate.js +86 -0
  153. package/dist/code-language/textmate.js.map +1 -0
  154. package/dist/code-language/theme.d.ts +26 -0
  155. package/dist/code-language/theme.d.ts.map +1 -0
  156. package/dist/code-language/theme.js +108 -0
  157. package/dist/code-language/theme.js.map +1 -0
  158. package/dist/code-language/timers.d.ts +7 -0
  159. package/dist/code-language/timers.d.ts.map +1 -0
  160. package/dist/code-language/timers.js +22 -0
  161. package/dist/code-language/timers.js.map +1 -0
  162. package/dist/code-language/types.d.ts +173 -0
  163. package/dist/code-language/types.d.ts.map +1 -0
  164. package/dist/code-language/types.js +41 -0
  165. package/dist/code-language/types.js.map +1 -0
  166. package/dist/codeblock/index.d.ts +69 -0
  167. package/dist/codeblock/index.d.ts.map +1 -0
  168. package/dist/codeblock/index.js +85 -0
  169. package/dist/codeblock/index.js.map +1 -0
  170. package/dist/color-picker/ColorField.d.ts +39 -0
  171. package/dist/color-picker/ColorField.d.ts.map +1 -0
  172. package/dist/color-picker/ColorField.js +239 -0
  173. package/dist/color-picker/ColorField.js.map +1 -0
  174. package/dist/color-picker/ColorPicker.d.ts +109 -0
  175. package/dist/color-picker/ColorPicker.d.ts.map +1 -0
  176. package/dist/color-picker/ColorPicker.js +757 -0
  177. package/dist/color-picker/ColorPicker.js.map +1 -0
  178. package/dist/color-picker/color.d.ts +105 -0
  179. package/dist/color-picker/color.d.ts.map +1 -0
  180. package/dist/color-picker/color.js +313 -0
  181. package/dist/color-picker/color.js.map +1 -0
  182. package/dist/color-picker/index.d.ts +8 -0
  183. package/dist/color-picker/index.d.ts.map +1 -0
  184. package/dist/color-picker/index.js +19 -0
  185. package/dist/color-picker/index.js.map +1 -0
  186. package/dist/desktop-calendar/eds.d.ts +102 -0
  187. package/dist/desktop-calendar/eds.d.ts.map +1 -0
  188. package/dist/desktop-calendar/eds.js +356 -0
  189. package/dist/desktop-calendar/eds.js.map +1 -0
  190. package/dist/desktop-calendar/ical.d.ts +63 -0
  191. package/dist/desktop-calendar/ical.d.ts.map +1 -0
  192. package/dist/desktop-calendar/ical.js +57 -0
  193. package/dist/desktop-calendar/ical.js.map +1 -0
  194. package/dist/desktop-calendar/index.d.ts +72 -0
  195. package/dist/desktop-calendar/index.d.ts.map +1 -0
  196. package/dist/desktop-calendar/index.js +213 -0
  197. package/dist/desktop-calendar/index.js.map +1 -0
  198. package/dist/embed/client.d.ts +121 -0
  199. package/dist/embed/client.d.ts.map +1 -0
  200. package/dist/embed/client.js +203 -0
  201. package/dist/embed/client.js.map +1 -0
  202. package/dist/embed/host.d.ts +96 -0
  203. package/dist/embed/host.d.ts.map +1 -0
  204. package/dist/embed/host.js +266 -0
  205. package/dist/embed/host.js.map +1 -0
  206. package/dist/embed/index.d.ts +5 -0
  207. package/dist/embed/index.d.ts.map +1 -0
  208. package/dist/embed/index.js +13 -0
  209. package/dist/embed/index.js.map +1 -0
  210. package/dist/embed/timers.d.ts +6 -0
  211. package/dist/embed/timers.d.ts.map +1 -0
  212. package/dist/embed/timers.js +16 -0
  213. package/dist/embed/timers.js.map +1 -0
  214. package/dist/flow/draw.d.ts +45 -0
  215. package/dist/flow/draw.d.ts.map +1 -0
  216. package/dist/flow/draw.js +295 -0
  217. package/dist/flow/draw.js.map +1 -0
  218. package/dist/flow/index.d.ts +64 -0
  219. package/dist/flow/index.d.ts.map +1 -0
  220. package/dist/flow/index.js +306 -0
  221. package/dist/flow/index.js.map +1 -0
  222. package/dist/flow/model.d.ts +158 -0
  223. package/dist/flow/model.d.ts.map +1 -0
  224. package/dist/flow/model.js +566 -0
  225. package/dist/flow/model.js.map +1 -0
  226. package/dist/flow/node.d.ts +429 -0
  227. package/dist/flow/node.d.ts.map +1 -0
  228. package/dist/flow/node.js +3025 -0
  229. package/dist/flow/node.js.map +1 -0
  230. package/dist/flow/paths.d.ts +43 -0
  231. package/dist/flow/paths.d.ts.map +1 -0
  232. package/dist/flow/paths.js +327 -0
  233. package/dist/flow/paths.js.map +1 -0
  234. package/dist/flow/types.d.ts +561 -0
  235. package/dist/flow/types.d.ts.map +1 -0
  236. package/dist/flow/types.js +2 -0
  237. package/dist/flow/types.js.map +1 -0
  238. package/dist/formula/hx.d.ts +24 -0
  239. package/dist/formula/hx.d.ts.map +1 -0
  240. package/dist/formula/hx.js +25 -0
  241. package/dist/formula/hx.js.map +1 -0
  242. package/dist/formula/index.d.ts +74 -0
  243. package/dist/formula/index.d.ts.map +1 -0
  244. package/dist/formula/index.js +155 -0
  245. package/dist/formula/index.js.map +1 -0
  246. package/dist/formula/katex.d.ts +78 -0
  247. package/dist/formula/katex.d.ts.map +1 -0
  248. package/dist/formula/katex.js +130 -0
  249. package/dist/formula/katex.js.map +1 -0
  250. package/dist/formula/layout.d.ts +103 -0
  251. package/dist/formula/layout.d.ts.map +1 -0
  252. package/dist/formula/layout.js +716 -0
  253. package/dist/formula/layout.js.map +1 -0
  254. package/dist/formula/node.d.ts +50 -0
  255. package/dist/formula/node.d.ts.map +1 -0
  256. package/dist/formula/node.js +351 -0
  257. package/dist/formula/node.js.map +1 -0
  258. package/dist/html/controls.d.ts +48 -0
  259. package/dist/html/controls.d.ts.map +1 -0
  260. package/dist/html/controls.js +195 -0
  261. package/dist/html/controls.js.map +1 -0
  262. package/dist/html/css/cascade.d.ts +51 -0
  263. package/dist/html/css/cascade.d.ts.map +1 -0
  264. package/dist/html/css/cascade.js +552 -0
  265. package/dist/html/css/cascade.js.map +1 -0
  266. package/dist/html/css/parse.d.ts +74 -0
  267. package/dist/html/css/parse.d.ts.map +1 -0
  268. package/dist/html/css/parse.js +464 -0
  269. package/dist/html/css/parse.js.map +1 -0
  270. package/dist/html/css/style.d.ts +142 -0
  271. package/dist/html/css/style.d.ts.map +1 -0
  272. package/dist/html/css/style.js +1145 -0
  273. package/dist/html/css/style.js.map +1 -0
  274. package/dist/html/css/ua.d.ts +5 -0
  275. package/dist/html/css/ua.d.ts.map +1 -0
  276. package/dist/html/css/ua.js +171 -0
  277. package/dist/html/css/ua.js.map +1 -0
  278. package/dist/html/css/values.d.ts +78 -0
  279. package/dist/html/css/values.d.ts.map +1 -0
  280. package/dist/html/css/values.js +330 -0
  281. package/dist/html/css/values.js.map +1 -0
  282. package/dist/html/dom.d.ts +112 -0
  283. package/dist/html/dom.d.ts.map +1 -0
  284. package/dist/html/dom.js +374 -0
  285. package/dist/html/dom.js.map +1 -0
  286. package/dist/html/hx.d.ts +24 -0
  287. package/dist/html/hx.d.ts.map +1 -0
  288. package/dist/html/hx.js +29 -0
  289. package/dist/html/hx.js.map +1 -0
  290. package/dist/html/index.d.ts +137 -0
  291. package/dist/html/index.d.ts.map +1 -0
  292. package/dist/html/index.js +339 -0
  293. package/dist/html/index.js.map +1 -0
  294. package/dist/html/layout/block.d.ts +58 -0
  295. package/dist/html/layout/block.d.ts.map +1 -0
  296. package/dist/html/layout/block.js +724 -0
  297. package/dist/html/layout/block.js.map +1 -0
  298. package/dist/html/layout/boxes.d.ts +261 -0
  299. package/dist/html/layout/boxes.d.ts.map +1 -0
  300. package/dist/html/layout/boxes.js +725 -0
  301. package/dist/html/layout/boxes.js.map +1 -0
  302. package/dist/html/layout/flex.d.ts +16 -0
  303. package/dist/html/layout/flex.d.ts.map +1 -0
  304. package/dist/html/layout/flex.js +242 -0
  305. package/dist/html/layout/flex.js.map +1 -0
  306. package/dist/html/layout/floats.d.ts +50 -0
  307. package/dist/html/layout/floats.d.ts.map +1 -0
  308. package/dist/html/layout/floats.js +110 -0
  309. package/dist/html/layout/floats.js.map +1 -0
  310. package/dist/html/layout/inline.d.ts +44 -0
  311. package/dist/html/layout/inline.d.ts.map +1 -0
  312. package/dist/html/layout/inline.js +700 -0
  313. package/dist/html/layout/inline.js.map +1 -0
  314. package/dist/html/layout/table.d.ts +5 -0
  315. package/dist/html/layout/table.d.ts.map +1 -0
  316. package/dist/html/layout/table.js +340 -0
  317. package/dist/html/layout/table.js.map +1 -0
  318. package/dist/html/node.d.ts +149 -0
  319. package/dist/html/node.d.ts.map +1 -0
  320. package/dist/html/node.js +861 -0
  321. package/dist/html/node.js.map +1 -0
  322. package/dist/html/paint.d.ts +48 -0
  323. package/dist/html/paint.d.ts.map +1 -0
  324. package/dist/html/paint.js +495 -0
  325. package/dist/html/paint.js.map +1 -0
  326. package/dist/html/resources.d.ts +48 -0
  327. package/dist/html/resources.d.ts.map +1 -0
  328. package/dist/html/resources.js +156 -0
  329. package/dist/html/resources.js.map +1 -0
  330. package/dist/index.d.ts +48 -0
  331. package/dist/index.d.ts.map +1 -0
  332. package/dist/index.js +92 -0
  333. package/dist/index.js.map +1 -0
  334. package/dist/internal/heights.d.ts +88 -0
  335. package/dist/internal/heights.d.ts.map +1 -0
  336. package/dist/internal/heights.js +203 -0
  337. package/dist/internal/heights.js.map +1 -0
  338. package/dist/internal/hx.d.ts +24 -0
  339. package/dist/internal/hx.d.ts.map +1 -0
  340. package/dist/internal/hx.js +27 -0
  341. package/dist/internal/hx.js.map +1 -0
  342. package/dist/internal/scroll.d.ts +62 -0
  343. package/dist/internal/scroll.d.ts.map +1 -0
  344. package/dist/internal/scroll.js +224 -0
  345. package/dist/internal/scroll.js.map +1 -0
  346. package/dist/internal/text.d.ts +6 -0
  347. package/dist/internal/text.d.ts.map +1 -0
  348. package/dist/internal/text.js +44 -0
  349. package/dist/internal/text.js.map +1 -0
  350. package/dist/internal/timers.d.ts +8 -0
  351. package/dist/internal/timers.d.ts.map +1 -0
  352. package/dist/internal/timers.js +22 -0
  353. package/dist/internal/timers.js.map +1 -0
  354. package/dist/internal/widget.d.ts +40 -0
  355. package/dist/internal/widget.d.ts.map +1 -0
  356. package/dist/internal/widget.js +44 -0
  357. package/dist/internal/widget.js.map +1 -0
  358. package/dist/markdown/ast.d.ts +126 -0
  359. package/dist/markdown/ast.d.ts.map +1 -0
  360. package/dist/markdown/ast.js +8 -0
  361. package/dist/markdown/ast.js.map +1 -0
  362. package/dist/markdown/hx.d.ts +24 -0
  363. package/dist/markdown/hx.d.ts.map +1 -0
  364. package/dist/markdown/hx.js +25 -0
  365. package/dist/markdown/hx.js.map +1 -0
  366. package/dist/markdown/index.d.ts +90 -0
  367. package/dist/markdown/index.d.ts.map +1 -0
  368. package/dist/markdown/index.js +413 -0
  369. package/dist/markdown/index.js.map +1 -0
  370. package/dist/markdown/parse.d.ts +8 -0
  371. package/dist/markdown/parse.d.ts.map +1 -0
  372. package/dist/markdown/parse.js +911 -0
  373. package/dist/markdown/parse.js.map +1 -0
  374. package/dist/markdown/spans.d.ts +20 -0
  375. package/dist/markdown/spans.d.ts.map +1 -0
  376. package/dist/markdown/spans.js +96 -0
  377. package/dist/markdown/spans.js.map +1 -0
  378. package/dist/media-player/backends.d.ts +64 -0
  379. package/dist/media-player/backends.d.ts.map +1 -0
  380. package/dist/media-player/backends.js +110 -0
  381. package/dist/media-player/backends.js.map +1 -0
  382. package/dist/media-player/control.d.ts +40 -0
  383. package/dist/media-player/control.d.ts.map +1 -0
  384. package/dist/media-player/control.js +44 -0
  385. package/dist/media-player/control.js.map +1 -0
  386. package/dist/media-player/hx.d.ts +24 -0
  387. package/dist/media-player/hx.d.ts.map +1 -0
  388. package/dist/media-player/hx.js +25 -0
  389. package/dist/media-player/hx.js.map +1 -0
  390. package/dist/media-player/index.d.ts +107 -0
  391. package/dist/media-player/index.d.ts.map +1 -0
  392. package/dist/media-player/index.js +219 -0
  393. package/dist/media-player/index.js.map +1 -0
  394. package/dist/media-player/mpv.d.ts +4 -0
  395. package/dist/media-player/mpv.d.ts.map +1 -0
  396. package/dist/media-player/mpv.js +120 -0
  397. package/dist/media-player/mpv.js.map +1 -0
  398. package/dist/media-player/vlc.d.ts +8 -0
  399. package/dist/media-player/vlc.d.ts.map +1 -0
  400. package/dist/media-player/vlc.js +83 -0
  401. package/dist/media-player/vlc.js.map +1 -0
  402. package/dist/richtext/index.d.ts +19 -0
  403. package/dist/richtext/index.d.ts.map +1 -0
  404. package/dist/richtext/index.js +4 -0
  405. package/dist/richtext/index.js.map +1 -0
  406. package/dist/richtext/links.d.ts +12 -0
  407. package/dist/richtext/links.d.ts.map +1 -0
  408. package/dist/richtext/links.js +64 -0
  409. package/dist/richtext/links.js.map +1 -0
  410. package/dist/richtext/menu.d.ts +11 -0
  411. package/dist/richtext/menu.d.ts.map +1 -0
  412. package/dist/richtext/menu.js +43 -0
  413. package/dist/richtext/menu.js.map +1 -0
  414. package/dist/richtext/node.d.ts +151 -0
  415. package/dist/richtext/node.d.ts.map +1 -0
  416. package/dist/richtext/node.js +255 -0
  417. package/dist/richtext/node.js.map +1 -0
  418. package/dist/richtext/runs.d.ts +92 -0
  419. package/dist/richtext/runs.d.ts.map +1 -0
  420. package/dist/richtext/runs.js +158 -0
  421. package/dist/richtext/runs.js.map +1 -0
  422. package/dist/table/hx.d.ts +24 -0
  423. package/dist/table/hx.d.ts.map +1 -0
  424. package/dist/table/hx.js +25 -0
  425. package/dist/table/hx.js.map +1 -0
  426. package/dist/table/index.d.ts +169 -0
  427. package/dist/table/index.d.ts.map +1 -0
  428. package/dist/table/index.js +890 -0
  429. package/dist/table/index.js.map +1 -0
  430. package/dist/table/rows.d.ts +136 -0
  431. package/dist/table/rows.d.ts.map +1 -0
  432. package/dist/table/rows.js +146 -0
  433. package/dist/table/rows.js.map +1 -0
  434. package/dist/terminal/backends.d.ts +105 -0
  435. package/dist/terminal/backends.d.ts.map +1 -0
  436. package/dist/terminal/backends.js +185 -0
  437. package/dist/terminal/backends.js.map +1 -0
  438. package/dist/terminal/hx.d.ts +24 -0
  439. package/dist/terminal/hx.d.ts.map +1 -0
  440. package/dist/terminal/hx.js +25 -0
  441. package/dist/terminal/hx.js.map +1 -0
  442. package/dist/terminal/index.d.ts +160 -0
  443. package/dist/terminal/index.d.ts.map +1 -0
  444. package/dist/terminal/index.js +344 -0
  445. package/dist/terminal/index.js.map +1 -0
  446. package/dist/terminal/title.d.ts +24 -0
  447. package/dist/terminal/title.d.ts.map +1 -0
  448. package/dist/terminal/title.js +129 -0
  449. package/dist/terminal/title.js.map +1 -0
  450. package/dist/terminal/vt/colors.d.ts +63 -0
  451. package/dist/terminal/vt/colors.d.ts.map +1 -0
  452. package/dist/terminal/vt/colors.js +203 -0
  453. package/dist/terminal/vt/colors.js.map +1 -0
  454. package/dist/terminal/vt/diff.d.ts +117 -0
  455. package/dist/terminal/vt/diff.d.ts.map +1 -0
  456. package/dist/terminal/vt/diff.js +358 -0
  457. package/dist/terminal/vt/diff.js.map +1 -0
  458. package/dist/terminal/vt/fonts.d.ts +92 -0
  459. package/dist/terminal/vt/fonts.d.ts.map +1 -0
  460. package/dist/terminal/vt/fonts.js +178 -0
  461. package/dist/terminal/vt/fonts.js.map +1 -0
  462. package/dist/terminal/vt/index.d.ts +78 -0
  463. package/dist/terminal/vt/index.d.ts.map +1 -0
  464. package/dist/terminal/vt/index.js +312 -0
  465. package/dist/terminal/vt/index.js.map +1 -0
  466. package/dist/terminal/vt/keys.d.ts +74 -0
  467. package/dist/terminal/vt/keys.d.ts.map +1 -0
  468. package/dist/terminal/vt/keys.js +309 -0
  469. package/dist/terminal/vt/keys.js.map +1 -0
  470. package/dist/terminal/vt/mouse.d.ts +44 -0
  471. package/dist/terminal/vt/mouse.d.ts.map +1 -0
  472. package/dist/terminal/vt/mouse.js +106 -0
  473. package/dist/terminal/vt/mouse.js.map +1 -0
  474. package/dist/terminal/vt/node.d.ts +246 -0
  475. package/dist/terminal/vt/node.d.ts.map +1 -0
  476. package/dist/terminal/vt/node.js +1068 -0
  477. package/dist/terminal/vt/node.js.map +1 -0
  478. package/dist/terminal/vt/pty.d.ts +81 -0
  479. package/dist/terminal/vt/pty.d.ts.map +1 -0
  480. package/dist/terminal/vt/pty.js +201 -0
  481. package/dist/terminal/vt/pty.js.map +1 -0
  482. package/dist/terminal/vt/renderer.d.ts +179 -0
  483. package/dist/terminal/vt/renderer.d.ts.map +1 -0
  484. package/dist/terminal/vt/renderer.js +357 -0
  485. package/dist/terminal/vt/renderer.js.map +1 -0
  486. package/dist/terminal/vt/timers.d.ts +6 -0
  487. package/dist/terminal/vt/timers.d.ts.map +1 -0
  488. package/dist/terminal/vt/timers.js +16 -0
  489. package/dist/terminal/vt/timers.js.map +1 -0
  490. package/dist/terminal/vt/xterm.d.ts +142 -0
  491. package/dist/terminal/vt/xterm.d.ts.map +1 -0
  492. package/dist/terminal/vt/xterm.js +32 -0
  493. package/dist/terminal/vt/xterm.js.map +1 -0
  494. package/dist/terminal-output/hx.d.ts +24 -0
  495. package/dist/terminal-output/hx.d.ts.map +1 -0
  496. package/dist/terminal-output/hx.js +25 -0
  497. package/dist/terminal-output/hx.js.map +1 -0
  498. package/dist/terminal-output/index.d.ts +92 -0
  499. package/dist/terminal-output/index.d.ts.map +1 -0
  500. package/dist/terminal-output/index.js +179 -0
  501. package/dist/terminal-output/index.js.map +1 -0
  502. package/dist/terminal-output/runs.d.ts +27 -0
  503. package/dist/terminal-output/runs.d.ts.map +1 -0
  504. package/dist/terminal-output/runs.js +66 -0
  505. package/dist/terminal-output/runs.js.map +1 -0
  506. package/dist/three/canvas.d.ts +46 -0
  507. package/dist/three/canvas.d.ts.map +1 -0
  508. package/dist/three/canvas.js +305 -0
  509. package/dist/three/canvas.js.map +1 -0
  510. package/dist/three/events.d.ts +64 -0
  511. package/dist/three/events.d.ts.map +1 -0
  512. package/dist/three/events.js +146 -0
  513. package/dist/three/events.js.map +1 -0
  514. package/dist/three/geometries.d.ts +89 -0
  515. package/dist/three/geometries.d.ts.map +1 -0
  516. package/dist/three/geometries.js +345 -0
  517. package/dist/three/geometries.js.map +1 -0
  518. package/dist/three/globals.d.ts +7 -0
  519. package/dist/three/globals.d.ts.map +1 -0
  520. package/dist/three/globals.js +20 -0
  521. package/dist/three/globals.js.map +1 -0
  522. package/dist/three/hx.d.ts +9 -0
  523. package/dist/three/hx.d.ts.map +1 -0
  524. package/dist/three/hx.js +10 -0
  525. package/dist/three/hx.js.map +1 -0
  526. package/dist/three/index.d.ts +22 -0
  527. package/dist/three/index.d.ts.map +1 -0
  528. package/dist/three/index.js +24 -0
  529. package/dist/three/index.js.map +1 -0
  530. package/dist/three/jsx-dev-runtime.d.ts +19 -0
  531. package/dist/three/jsx-dev-runtime.d.ts.map +1 -0
  532. package/dist/three/jsx-dev-runtime.js +2 -0
  533. package/dist/three/jsx-dev-runtime.js.map +1 -0
  534. package/dist/three/jsx-runtime.d.ts +19 -0
  535. package/dist/three/jsx-runtime.d.ts.map +1 -0
  536. package/dist/three/jsx-runtime.js +2 -0
  537. package/dist/three/jsx-runtime.js.map +1 -0
  538. package/dist/three/jsx.d.ts +198 -0
  539. package/dist/three/jsx.d.ts.map +1 -0
  540. package/dist/three/jsx.js +2 -0
  541. package/dist/three/jsx.js.map +1 -0
  542. package/dist/three/materials.d.ts +125 -0
  543. package/dist/three/materials.d.ts.map +1 -0
  544. package/dist/three/materials.js +229 -0
  545. package/dist/three/materials.js.map +1 -0
  546. package/dist/three/math.d.ts +146 -0
  547. package/dist/three/math.d.ts.map +1 -0
  548. package/dist/three/math.js +464 -0
  549. package/dist/three/math.js.map +1 -0
  550. package/dist/three/objects.d.ts +185 -0
  551. package/dist/three/objects.d.ts.map +1 -0
  552. package/dist/three/objects.js +309 -0
  553. package/dist/three/objects.js.map +1 -0
  554. package/dist/three/passes.d.ts +54 -0
  555. package/dist/three/passes.d.ts.map +1 -0
  556. package/dist/three/passes.js +78 -0
  557. package/dist/three/passes.js.map +1 -0
  558. package/dist/three/postprocess.d.ts +85 -0
  559. package/dist/three/postprocess.d.ts.map +1 -0
  560. package/dist/three/postprocess.js +503 -0
  561. package/dist/three/postprocess.js.map +1 -0
  562. package/dist/three/raycast.d.ts +24 -0
  563. package/dist/three/raycast.d.ts.map +1 -0
  564. package/dist/three/raycast.js +138 -0
  565. package/dist/three/raycast.js.map +1 -0
  566. package/dist/three/reconciler.d.ts +48 -0
  567. package/dist/three/reconciler.d.ts.map +1 -0
  568. package/dist/three/reconciler.js +416 -0
  569. package/dist/three/reconciler.js.map +1 -0
  570. package/dist/three/renderer-direct.d.ts +102 -0
  571. package/dist/three/renderer-direct.d.ts.map +1 -0
  572. package/dist/three/renderer-direct.js +782 -0
  573. package/dist/three/renderer-direct.js.map +1 -0
  574. package/dist/three/renderer-indirect.d.ts +68 -0
  575. package/dist/three/renderer-indirect.d.ts.map +1 -0
  576. package/dist/three/renderer-indirect.js +438 -0
  577. package/dist/three/renderer-indirect.js.map +1 -0
  578. package/dist/three/store.d.ts +81 -0
  579. package/dist/three/store.d.ts.map +1 -0
  580. package/dist/three/store.js +110 -0
  581. package/dist/three/store.js.map +1 -0
  582. package/dist/timeline/hx.d.ts +18 -0
  583. package/dist/timeline/hx.d.ts.map +1 -0
  584. package/dist/timeline/hx.js +10 -0
  585. package/dist/timeline/hx.js.map +1 -0
  586. package/dist/timeline/index.d.ts +152 -0
  587. package/dist/timeline/index.d.ts.map +1 -0
  588. package/dist/timeline/index.js +383 -0
  589. package/dist/timeline/index.js.map +1 -0
  590. package/dist/tray-host/hx.d.ts +24 -0
  591. package/dist/tray-host/hx.d.ts.map +1 -0
  592. package/dist/tray-host/hx.js +25 -0
  593. package/dist/tray-host/hx.js.map +1 -0
  594. package/dist/tray-host/index.d.ts +110 -0
  595. package/dist/tray-host/index.d.ts.map +1 -0
  596. package/dist/tray-host/index.js +191 -0
  597. package/dist/tray-host/index.js.map +1 -0
  598. package/dist/tray-host/manager.d.ts +137 -0
  599. package/dist/tray-host/manager.d.ts.map +1 -0
  600. package/dist/tray-host/manager.js +462 -0
  601. package/dist/tray-host/manager.js.map +1 -0
  602. package/dist/tray-host/notify.d.ts +22 -0
  603. package/dist/tray-host/notify.d.ts.map +1 -0
  604. package/dist/tray-host/notify.js +74 -0
  605. package/dist/tray-host/notify.js.map +1 -0
  606. package/dist/tray-host/protocol.d.ts +106 -0
  607. package/dist/tray-host/protocol.d.ts.map +1 -0
  608. package/dist/tray-host/protocol.js +191 -0
  609. package/dist/tray-host/protocol.js.map +1 -0
  610. package/dist/tree/hx.d.ts +24 -0
  611. package/dist/tree/hx.d.ts.map +1 -0
  612. package/dist/tree/hx.js +25 -0
  613. package/dist/tree/hx.js.map +1 -0
  614. package/dist/tree/index.d.ts +221 -0
  615. package/dist/tree/index.d.ts.map +1 -0
  616. package/dist/tree/index.js +751 -0
  617. package/dist/tree/index.js.map +1 -0
  618. package/dist/tree/internal.d.ts +18 -0
  619. package/dist/tree/internal.d.ts.map +1 -0
  620. package/dist/tree/internal.js +66 -0
  621. package/dist/tree/internal.js.map +1 -0
  622. package/dist/tree/rows.d.ts +177 -0
  623. package/dist/tree/rows.d.ts.map +1 -0
  624. package/dist/tree/rows.js +179 -0
  625. package/dist/tree/rows.js.map +1 -0
  626. package/package.json +166 -12
  627. package/src/ansi/cast.ts +159 -0
  628. package/src/ansi/index.ts +53 -0
  629. package/src/ansi/palette.ts +226 -0
  630. package/src/ansi/parse.ts +780 -0
  631. package/src/ansi/sgr.ts +380 -0
  632. package/src/ansi/utf8.ts +84 -0
  633. package/src/calendar/Calendar.ts +744 -0
  634. package/src/calendar/DatePicker.ts +368 -0
  635. package/src/calendar/dates.ts +307 -0
  636. package/src/calendar/index.ts +51 -0
  637. package/src/charts/components.ts +864 -0
  638. package/src/charts/data.ts +776 -0
  639. package/src/charts/hx.ts +39 -0
  640. package/src/charts/index.ts +99 -0
  641. package/src/charts/node.ts +932 -0
  642. package/src/charts/render.ts +982 -0
  643. package/src/charts/scale.ts +214 -0
  644. package/src/charts/spec.ts +122 -0
  645. package/src/charts/timers.ts +24 -0
  646. package/src/code/hx.ts +51 -0
  647. package/src/code/index.ts +174 -0
  648. package/src/code-editor/completion.ts +161 -0
  649. package/src/code-editor/doc.ts +198 -0
  650. package/src/code-editor/hx.ts +26 -0
  651. package/src/code-editor/index.ts +615 -0
  652. package/src/code-editor/node.ts +1926 -0
  653. package/src/code-language/hljs.ts +302 -0
  654. package/src/code-language/index.ts +51 -0
  655. package/src/code-language/languages/glsl.ts +120 -0
  656. package/src/code-language/languages/javascript.ts +419 -0
  657. package/src/code-language/languages/json.ts +72 -0
  658. package/src/code-language/languages/shell.ts +221 -0
  659. package/src/code-language/languages/sql.ts +165 -0
  660. package/src/code-language/lezer.ts +190 -0
  661. package/src/code-language/registry.ts +66 -0
  662. package/src/code-language/runs.ts +128 -0
  663. package/src/code-language/stream.ts +306 -0
  664. package/src/code-language/textmate.ts +134 -0
  665. package/src/code-language/theme.ts +124 -0
  666. package/src/code-language/timers.ts +36 -0
  667. package/src/code-language/types.ts +252 -0
  668. package/src/codeblock/index.ts +146 -0
  669. package/src/color-picker/ColorField.ts +333 -0
  670. package/src/color-picker/ColorPicker.ts +1069 -0
  671. package/src/color-picker/color.ts +399 -0
  672. package/src/color-picker/index.ts +50 -0
  673. package/src/desktop-calendar/eds.ts +484 -0
  674. package/src/desktop-calendar/ical.ts +119 -0
  675. package/src/desktop-calendar/index.ts +287 -0
  676. package/src/embed/client.ts +311 -0
  677. package/src/embed/host.ts +432 -0
  678. package/src/embed/index.ts +33 -0
  679. package/src/embed/timers.ts +32 -0
  680. package/src/flow/draw.ts +418 -0
  681. package/src/flow/index.ts +473 -0
  682. package/src/flow/model.ts +687 -0
  683. package/src/flow/node.ts +3694 -0
  684. package/src/flow/paths.ts +403 -0
  685. package/src/flow/types.ts +634 -0
  686. package/src/formula/hx.ts +51 -0
  687. package/src/formula/index.ts +243 -0
  688. package/src/formula/katex.ts +209 -0
  689. package/src/formula/layout.ts +876 -0
  690. package/src/formula/node.ts +467 -0
  691. package/src/html/controls.ts +244 -0
  692. package/src/html/css/cascade.ts +606 -0
  693. package/src/html/css/parse.ts +500 -0
  694. package/src/html/css/style.ts +1371 -0
  695. package/src/html/css/ua.ts +174 -0
  696. package/src/html/css/values.ts +358 -0
  697. package/src/html/dom.ts +410 -0
  698. package/src/html/hx.ts +55 -0
  699. package/src/html/index.ts +545 -0
  700. package/src/html/layout/block.ts +876 -0
  701. package/src/html/layout/boxes.ts +981 -0
  702. package/src/html/layout/flex.ts +297 -0
  703. package/src/html/layout/floats.ts +125 -0
  704. package/src/html/layout/inline.ts +870 -0
  705. package/src/html/layout/table.ts +380 -0
  706. package/src/html/node.ts +967 -0
  707. package/src/html/paint.ts +605 -0
  708. package/src/html/resources.ts +214 -0
  709. package/src/index.ts +638 -0
  710. package/src/internal/heights.ts +222 -0
  711. package/src/internal/hx.ts +53 -0
  712. package/src/internal/scroll.ts +288 -0
  713. package/src/internal/text.ts +44 -0
  714. package/src/internal/timers.ts +44 -0
  715. package/src/internal/widget.ts +92 -0
  716. package/src/markdown/ast.ts +163 -0
  717. package/src/markdown/hx.ts +51 -0
  718. package/src/markdown/index.ts +686 -0
  719. package/src/markdown/parse.ts +1037 -0
  720. package/src/markdown/spans.ts +143 -0
  721. package/src/media-player/backends.ts +155 -0
  722. package/src/media-player/control.ts +70 -0
  723. package/src/media-player/hx.ts +51 -0
  724. package/src/media-player/index.ts +378 -0
  725. package/src/media-player/mpv.ts +146 -0
  726. package/src/media-player/vlc.ts +97 -0
  727. package/src/richtext/index.ts +42 -0
  728. package/src/richtext/links.ts +78 -0
  729. package/src/richtext/menu.ts +49 -0
  730. package/src/richtext/node.ts +406 -0
  731. package/src/richtext/runs.ts +253 -0
  732. package/src/table/hx.ts +51 -0
  733. package/src/table/index.ts +1270 -0
  734. package/src/table/rows.ts +275 -0
  735. package/src/terminal/backends.ts +242 -0
  736. package/src/terminal/hx.ts +51 -0
  737. package/src/terminal/index.ts +574 -0
  738. package/src/terminal/title.ts +172 -0
  739. package/src/terminal/vt/colors.ts +247 -0
  740. package/src/terminal/vt/diff.ts +467 -0
  741. package/src/terminal/vt/fonts.ts +233 -0
  742. package/src/terminal/vt/index.ts +443 -0
  743. package/src/terminal/vt/keys.ts +369 -0
  744. package/src/terminal/vt/mouse.ts +144 -0
  745. package/src/terminal/vt/node.ts +1242 -0
  746. package/src/terminal/vt/pty.ts +334 -0
  747. package/src/terminal/vt/renderer.ts +555 -0
  748. package/src/terminal/vt/timers.ts +31 -0
  749. package/src/terminal/vt/xterm.ts +193 -0
  750. package/src/terminal-output/hx.ts +51 -0
  751. package/src/terminal-output/index.ts +340 -0
  752. package/src/terminal-output/runs.ts +79 -0
  753. package/src/three/canvas.ts +451 -0
  754. package/src/three/events.ts +197 -0
  755. package/src/three/geometries.ts +429 -0
  756. package/src/three/globals.ts +34 -0
  757. package/src/three/hx.ts +22 -0
  758. package/src/three/index.ts +98 -0
  759. package/src/three/jsx-dev-runtime.ts +27 -0
  760. package/src/three/jsx-runtime.ts +38 -0
  761. package/src/three/jsx.ts +275 -0
  762. package/src/three/materials.ts +270 -0
  763. package/src/three/math.ts +585 -0
  764. package/src/three/objects.ts +397 -0
  765. package/src/three/passes.ts +90 -0
  766. package/src/three/postprocess.ts +677 -0
  767. package/src/three/raycast.ts +189 -0
  768. package/src/three/react-reconciler.d.ts +50 -0
  769. package/src/three/reconciler.ts +624 -0
  770. package/src/three/renderer-direct.ts +1055 -0
  771. package/src/three/renderer-indirect.ts +570 -0
  772. package/src/three/store.ts +207 -0
  773. package/src/timeline/hx.ts +31 -0
  774. package/src/timeline/index.ts +603 -0
  775. package/src/tray-host/hx.ts +51 -0
  776. package/src/tray-host/index.ts +331 -0
  777. package/src/tray-host/manager.ts +639 -0
  778. package/src/tray-host/notify.ts +102 -0
  779. package/src/tray-host/protocol.ts +235 -0
  780. package/src/tree/hx.ts +51 -0
  781. package/src/tree/index.ts +1127 -0
  782. package/src/tree/internal.ts +87 -0
  783. package/src/tree/rows.ts +334 -0
  784. package/src/index.d.ts +0 -2
  785. package/src/index.js +0 -9
  786. package/src/sparkline/index.d.ts +0 -29
  787. package/src/sparkline/index.js +0 -50
  788. package/src/sparkline/node.js +0 -72
@@ -0,0 +1,876 @@
1
+ // Block layout: the driver, and the formatting context everything else hangs
2
+ // off.
3
+ //
4
+ // Boxes are laid out into **absolute document coordinates** in one pass. The
5
+ // alternative — relative offsets resolved by a second walk — buys incremental
6
+ // relayout of a subtree, and it is not worth it here: paint, hit testing and
7
+ // the selection accessors all want absolute rectangles, and every one of them
8
+ // runs far more often than layout does. So layout writes what they read.
9
+ //
10
+ // Float coordinates are absolute for the same reason, which is what lets the
11
+ // inline pass ask "how wide is the line at this y" without knowing whose
12
+ // formatting context it is inside.
13
+ import { AUTO, isPct, resolve, resolveOrNull } from '../css/values.js';
14
+ import type { Len } from '../css/values.js';
15
+ import { Box } from './boxes.js';
16
+ import type { BoxTree, LineBox } from './boxes.js';
17
+ import { FloatContext } from './floats.js';
18
+ import { layoutInline } from './inline.js';
19
+ import type { FontsLike } from './inline.js';
20
+ import { layoutFlex } from './flex.js';
21
+ import { layoutTable } from './table.js';
22
+ import { computePaintBounds } from '../paint.js';
23
+
24
+ export interface LayoutContext {
25
+ fonts: FontsLike | null;
26
+ viewportWidth: number;
27
+ viewportHeight: number;
28
+ /** Out-of-flow boxes, collected in flow order and laid out afterwards —
29
+ * an absolutely positioned box may be positioned against an ancestor
30
+ * whose size is not known until its in-flow content has been laid out. */
31
+ positioned: { box: Box; containing: Box }[];
32
+ /**
33
+ * Lay a box and everything under it out at a width, at the origin.
34
+ *
35
+ * The recursion back into this file that `flex.ts` and `table.ts` need — a
36
+ * flex item contains blocks, a table cell contains anything at all — passed
37
+ * on the context rather than imported, because the cycle is genuine and the
38
+ * alternative is a module that registers itself at import time. This
39
+ * package's tree-shaking contract forbids exactly that (AGENTS.md, "no side
40
+ * effects at import time anywhere else"), and a field is cheaper than the
41
+ * exception would be.
42
+ */
43
+ layoutSubtree(box: Box, width: number): void;
44
+ }
45
+
46
+ export interface LayoutResult {
47
+ width: number;
48
+ height: number;
49
+ }
50
+
51
+ /** Lay the whole document out at a width. */
52
+ export function layoutDocument(
53
+ tree: BoxTree,
54
+ fonts: FontsLike | null,
55
+ viewportWidth: number,
56
+ viewportHeight: number,
57
+ ): LayoutResult {
58
+ const ctx: LayoutContext = {
59
+ fonts,
60
+ viewportWidth,
61
+ viewportHeight,
62
+ positioned: [],
63
+ layoutSubtree: (box, width) => layoutSubtree(box, ctx, width),
64
+ };
65
+ const root = tree.root;
66
+ root.x = 0;
67
+ root.y = 0;
68
+ root.width = viewportWidth;
69
+ // The root box stands in for `<body>` when the document has none (see
70
+ // `Cascade.rootStyle`), so it may carry a margin — and a margin on the
71
+ // initial containing block has nothing to collapse against and nothing to
72
+ // sit inside. Folding it into the padding is what a browser's body margin
73
+ // amounts to, and it keeps `contentX` the one thing layout reads.
74
+ resolveEdges(root, viewportWidth);
75
+ root.padTop += root.marginTop;
76
+ root.padRight += root.marginRight;
77
+ root.padBottom += root.marginBottom;
78
+ root.padLeft += root.marginLeft;
79
+ root.marginTop = 0;
80
+ root.marginRight = 0;
81
+ root.marginBottom = 0;
82
+ root.marginLeft = 0;
83
+
84
+ const contentWidth = Math.max(0, viewportWidth - root.horizontalExtra);
85
+ const floats = new FloatContext(root.contentX, root.contentX + contentWidth);
86
+ const flow = layoutChildren(root, ctx, floats, root.contentY, contentWidth);
87
+ const floatBottom =
88
+ floats.bottom === -Infinity ? 0 : floats.bottom - root.contentY;
89
+ root.height = Math.max(flow.height, floatBottom) + root.verticalExtra;
90
+
91
+ // Positioned boxes last, and in the order they were found, so a later one
92
+ // can be positioned against an earlier one's resolved rectangle.
93
+ for (let i = 0; i < ctx.positioned.length; i += 1) {
94
+ const { box, containing } = ctx.positioned[i];
95
+ layoutPositioned(box, containing, ctx);
96
+ }
97
+
98
+ // `position: relative` moves a box after everything else has been placed
99
+ // against where it *was* — which is the whole of what makes it relative —
100
+ // and the ink bounds are computed after that, so culling sees where boxes
101
+ // ended up rather than where they were laid out.
102
+ applyRelativeOffsets(root);
103
+ computePaintBounds(root);
104
+
105
+ let bottom = root.height;
106
+ for (const { box } of ctx.positioned) {
107
+ if (box.style.position !== 'fixed')
108
+ bottom = Math.max(bottom, box.y + box.height);
109
+ }
110
+ return { width: viewportWidth, height: bottom };
111
+ }
112
+
113
+ /**
114
+ * The collapsed value of two adjoining margins: the largest positive plus
115
+ * the most negative — CSS 8.3.1's rule, whole. Both-positive takes the max,
116
+ * both-negative the min, and a mixed pair genuinely adds, which is what
117
+ * makes a `-8px` pull work against a `40px` push and come out at `32`.
118
+ */
119
+ function collapseMargins(a: number, b: number): number {
120
+ return Math.max(0, Math.max(a, b)) + Math.min(0, Math.min(a, b));
121
+ }
122
+
123
+ /** What a box's children came to: their height, and the margin still hanging
124
+ * past the last of them when the box's own bottom edge does not stop it. */
125
+ interface FlowResult {
126
+ height: number;
127
+ hanging: number;
128
+ }
129
+
130
+ /**
131
+ * Lay out a box's children as a block formatting context's contents, or as
132
+ * one inline formatting context when they are all inline-level.
133
+ */
134
+ function layoutChildren(
135
+ box: Box,
136
+ ctx: LayoutContext,
137
+ floats: FloatContext,
138
+ contentTop: number,
139
+ contentWidth: number,
140
+ ): FlowResult {
141
+ const contentLeft = box.contentX;
142
+ if (establishesInlineContext(box)) {
143
+ const height = layoutInlineContent(
144
+ box,
145
+ ctx,
146
+ floats,
147
+ contentTop,
148
+ contentWidth,
149
+ contentLeft,
150
+ );
151
+ return { height, hanging: 0 };
152
+ }
153
+
154
+ let y = contentTop;
155
+ /** The margin left hanging by the previous sibling, for collapsing. */
156
+ let pendingMargin = 0;
157
+ let first = true;
158
+
159
+ for (const child of box.children) {
160
+ if (child.kind === 'text' && !child.text.trim()) continue;
161
+ if (child.outOfFlow) {
162
+ ctx.positioned.push({
163
+ box: child,
164
+ containing: containingBlockFor(child) ?? box,
165
+ });
166
+ continue;
167
+ }
168
+ if (child.isFloat) {
169
+ layoutFloat(child, ctx, floats, y + pendingMargin, contentWidth);
170
+ continue;
171
+ }
172
+
173
+ resolveEdges(child, contentWidth);
174
+ const top = child.marginTop;
175
+ const collapsed = first ? top : collapseMargins(pendingMargin, top);
176
+ let childY = y + collapsed;
177
+ const clearance = floats.clearance(child.style.clear);
178
+ if (clearance > -Infinity && clearance > childY) childY = clearance;
179
+
180
+ layoutBlockLevel(child, ctx, floats, contentLeft, childY, contentWidth);
181
+ y = child.y + child.height;
182
+ pendingMargin = child.marginBottom;
183
+ first = false;
184
+ }
185
+
186
+ // The last child's bottom margin collapses through the parent's bottom
187
+ // edge unless a border, padding, a specified height or a formatting
188
+ // context of its own stops it — which is why a `<div>` around a `<p>` is
189
+ // not 16px taller than the paragraph. The margin is not *lost*, though: it
190
+ // escapes, and the caller merges it into the box's own bottom margin so
191
+ // the next sibling still sees it. Dropping it here was the bug that made
192
+ // `<div><p>…</p></div><p>…</p>` set the two paragraphs solid.
193
+ if (
194
+ !first &&
195
+ !box.borderBottom &&
196
+ !box.padBottom &&
197
+ box.style.height === AUTO &&
198
+ !establishesBFC(box)
199
+ ) {
200
+ return { height: y - contentTop, hanging: pendingMargin };
201
+ }
202
+ return { height: y + pendingMargin - contentTop, hanging: 0 };
203
+ }
204
+
205
+ function layoutInlineContent(
206
+ box: Box,
207
+ ctx: LayoutContext,
208
+ floats: FloatContext,
209
+ contentTop: number,
210
+ contentWidth: number,
211
+ contentLeft: number,
212
+ ): number {
213
+ // Floats inside an inline context are placed before the lines are built,
214
+ // so the lines already know to avoid them.
215
+ for (const child of box.children) {
216
+ if (child.outOfFlow) {
217
+ ctx.positioned.push({
218
+ box: child,
219
+ containing: containingBlockFor(child) ?? box,
220
+ });
221
+ } else if (child.isFloat) {
222
+ layoutFloat(child, ctx, floats, contentTop, contentWidth);
223
+ }
224
+ }
225
+ // Atomics have to be sized before the line breaker can place them.
226
+ sizeAtomics(box, ctx, contentWidth);
227
+
228
+ const result = layoutInline(box, {
229
+ fonts: ctx.fonts,
230
+ width: contentWidth,
231
+ startY: contentTop,
232
+ floats,
233
+ originX: contentLeft,
234
+ });
235
+ // The inline pass works in content-box coordinates; move the result into
236
+ // document space now, so nothing below this line has to know the
237
+ // difference.
238
+ for (const line of result.lines) {
239
+ line.x += contentLeft;
240
+ line.y += contentTop;
241
+ for (const placed of line.atomics) {
242
+ placed.x += contentLeft;
243
+ placed.y += contentTop;
244
+ moveTo(placed.box, placed.x, placed.y + placed.box.marginTop);
245
+ }
246
+ for (const text of line.texts) {
247
+ text.drawX += contentLeft;
248
+ text.drawY += contentTop;
249
+ }
250
+ }
251
+ box.lines = result.lines;
252
+ return result.height;
253
+ }
254
+
255
+ /** Size every atomic in an inline context. */
256
+ function sizeAtomics(box: Box, ctx: LayoutContext, contentWidth: number): void {
257
+ for (const child of box.children) {
258
+ if (child.outOfFlow || child.isFloat) continue;
259
+ if (child.kind === 'inline') {
260
+ sizeAtomics(child, ctx, contentWidth);
261
+ continue;
262
+ }
263
+ if (child.kind === 'text' || child.kind === 'break') continue;
264
+ resolveEdges(child, contentWidth);
265
+ layoutAtomic(child, ctx, contentWidth);
266
+ }
267
+ }
268
+
269
+ /** An inline-level box that lays out as a block inside: `inline-block`, a
270
+ * replaced element, an `inline-table`. */
271
+ function layoutAtomic(
272
+ box: Box,
273
+ ctx: LayoutContext,
274
+ availableWidth: number,
275
+ ): void {
276
+ if (box.kind === 'replaced') {
277
+ sizeReplaced(box, availableWidth);
278
+ return;
279
+ }
280
+ const width = shrinkToFitWidth(box, ctx, availableWidth);
281
+ layoutInternals(box, ctx, width, 0, 0);
282
+ }
283
+
284
+ function layoutBlockLevel(
285
+ box: Box,
286
+ ctx: LayoutContext,
287
+ outerFloats: FloatContext,
288
+ contentLeft: number,
289
+ y: number,
290
+ containingWidth: number,
291
+ ): void {
292
+ resolveEdges(box, containingWidth);
293
+
294
+ if (box.kind === 'replaced') {
295
+ sizeReplaced(box, containingWidth);
296
+ placeBlock(box, contentLeft, y, containingWidth);
297
+ return;
298
+ }
299
+
300
+ const width = blockWidth(box, containingWidth);
301
+ box.width = width;
302
+ placeBlock(box, contentLeft, y, containingWidth);
303
+ layoutInternals(box, ctx, width, box.x, box.y, outerFloats);
304
+ }
305
+
306
+ /**
307
+ * Lay a box out at a width and report the widest thing it drew.
308
+ *
309
+ * This is what a table column asks twice — once unbounded for max-content,
310
+ * once at a hair's width for min-content — and it exists rather than the
311
+ * caller reading `box.width` because a `width: auto` box laid out unbounded
312
+ * *is* unbounded: it fills its containing block, and its containing block was
313
+ * `Infinity`. The answer has to come from what the content came to, which is
314
+ * exactly what `intrinsicWidth` walks.
315
+ */
316
+ export function measureIntrinsicWidth(
317
+ box: Box,
318
+ ctx: LayoutContext,
319
+ available: number,
320
+ ): number {
321
+ ctx.layoutSubtree(box, available);
322
+ const specified = box.style.width;
323
+ if (specified !== AUTO && Number.isFinite(box.width)) return box.width;
324
+ return intrinsicWidth(box) + box.horizontalExtra;
325
+ }
326
+
327
+ /**
328
+ * Lay a box and everything under it out at a width, at the origin — what
329
+ * `LayoutContext.layoutSubtree` hands to `flex.ts` and `table.ts`, and what
330
+ * the shrink-to-fit probe uses. A replaced box is sized rather than laid out,
331
+ * because there is nothing inside it to lay out.
332
+ */
333
+ function layoutSubtree(box: Box, ctx: LayoutContext, width: number): void {
334
+ resolveEdges(box, Number.isFinite(width) ? width : 0);
335
+ if (box.kind === 'replaced') {
336
+ sizeReplaced(box, width);
337
+ box.x = 0;
338
+ box.y = 0;
339
+ return;
340
+ }
341
+ const borderBox = Number.isFinite(width)
342
+ ? clampWidth(box, width, width)
343
+ : Infinity;
344
+ layoutInternals(box, ctx, borderBox, 0, 0);
345
+ }
346
+
347
+ /**
348
+ * Lay a box's inside out and give it a height. `outerFloats` is the parent's
349
+ * float context, passed only when this box does *not* establish one of its
350
+ * own — which is the difference between text flowing beside a float that
351
+ * started in an earlier sibling and text that starts below it.
352
+ */
353
+ function layoutInternals(
354
+ box: Box,
355
+ ctx: LayoutContext,
356
+ borderBoxWidth: number,
357
+ x: number,
358
+ y: number,
359
+ outerFloats?: FloatContext,
360
+ ): void {
361
+ box.x = x;
362
+ box.y = y;
363
+ box.width = borderBoxWidth;
364
+ const contentWidth = box.contentWidth;
365
+
366
+ if (box.kind === 'flex') {
367
+ const height = layoutFlex(box, ctx, contentWidth);
368
+ finishHeight(box, height);
369
+ return;
370
+ }
371
+ if (box.kind === 'table') {
372
+ const height = layoutTable(box, ctx, contentWidth);
373
+ finishHeight(box, height);
374
+ return;
375
+ }
376
+
377
+ const ownFloats = establishesBFC(box) || !outerFloats;
378
+ const floats = ownFloats
379
+ ? new FloatContext(box.contentX, box.contentX + contentWidth)
380
+ : outerFloats;
381
+ const flow = layoutChildren(box, ctx, floats, box.contentY, contentWidth);
382
+ // A box that establishes a formatting context contains its own floats, so
383
+ // it has to be at least as tall as they are. One that does not, does not —
384
+ // that is the classic "collapsed parent" every author has met.
385
+ const withFloats = ownFloats
386
+ ? Math.max(
387
+ flow.height,
388
+ floats.bottom === -Infinity ? 0 : floats.bottom - box.contentY,
389
+ )
390
+ : flow.height;
391
+ finishHeight(box, withFloats);
392
+ // The margin that escaped through this box's bottom edge becomes part of
393
+ // its own: the parent's flow loop reads `child.marginBottom` for the next
394
+ // sibling's collapse, which is exactly where an escaped margin goes.
395
+ if (flow.hanging) {
396
+ box.marginBottom = collapseMargins(box.marginBottom, flow.hanging);
397
+ }
398
+ if (box.markerText) layoutMarker(box, ctx);
399
+ }
400
+
401
+ /** The first line box anywhere under a box, in layout order. */
402
+ function firstLineIn(box: Box): LineBox | null {
403
+ if (box.lines?.length) return box.lines[0];
404
+ for (const child of box.children) {
405
+ if (child.outOfFlow || child.isFloat) continue;
406
+ const found = firstLineIn(child);
407
+ if (found) return found;
408
+ }
409
+ return null;
410
+ }
411
+
412
+ /**
413
+ * A list item's marker.
414
+ *
415
+ * `outside` — the default, and what `<ul>`'s padding leaves room for — sits
416
+ * in the padding to the left of the content, right-aligned against it so a
417
+ * list numbered past 9 stays lined up. `inside` sits at the content edge and
418
+ * the text does not reserve room for it, which is what the keyword means.
419
+ *
420
+ * The marker is laid out here rather than being a box because it is not
421
+ * content: it must not join the selection, or copying a list would paste a
422
+ * bullet before every line.
423
+ */
424
+ function layoutMarker(box: Box, ctx: LayoutContext): void {
425
+ const fonts = ctx.fonts;
426
+ if (!fonts) return;
427
+ const style = box.style;
428
+ const layout = fonts.layout(
429
+ [
430
+ {
431
+ text: box.markerText,
432
+ family: style.fontFamily,
433
+ size: style.fontSize,
434
+ color: style.color,
435
+ },
436
+ ],
437
+ { family: style.fontFamily, size: style.fontSize, color: style.color },
438
+ {},
439
+ );
440
+ box.markerLayout = layout;
441
+ const gap = Math.round(style.fontSize * 0.4);
442
+ // The marker sits on the first line of the item's *content*, which is not
443
+ // always the item's own: an `<li>` holding a paragraph, or one holding text
444
+ // and a nested list, has its inline content in an anonymous block. Looking
445
+ // only at `box.lines` puts the marker of every such item at the content
446
+ // top, which reads as a missing bullet rather than a misplaced one.
447
+ const first = firstLineIn(box);
448
+ const baselineY = first ? first.y + first.baseline : box.contentY;
449
+ const own = layout.lines[0];
450
+ box.markerY = baselineY - (own ? own.baseline : style.fontSize);
451
+ box.markerX =
452
+ style.listStylePosition === 'inside'
453
+ ? box.contentX
454
+ : box.contentX - gap - layout.width;
455
+ }
456
+
457
+ function finishHeight(box: Box, contentHeight: number): void {
458
+ const specified = resolveOrNull(box.style.height, NaN);
459
+ const height = specified ?? contentHeight;
460
+ const borderBox =
461
+ box.style.boxSizing === 'border-box' && specified !== null
462
+ ? Math.max(height, box.verticalExtra)
463
+ : height + box.verticalExtra;
464
+ box.height = clampHeight(box, borderBox);
465
+ }
466
+
467
+ function clampHeight(box: Box, height: number): number {
468
+ let out = height;
469
+ const min = resolveOrNull(box.style.minHeight, NaN);
470
+ const max =
471
+ box.style.maxHeight === 'none'
472
+ ? null
473
+ : resolveOrNull(box.style.maxHeight, NaN);
474
+ if (max !== null)
475
+ out = Math.min(
476
+ out,
477
+ max + (box.style.boxSizing === 'border-box' ? 0 : box.verticalExtra),
478
+ );
479
+ if (min !== null)
480
+ out = Math.max(
481
+ out,
482
+ min + (box.style.boxSizing === 'border-box' ? 0 : box.verticalExtra),
483
+ );
484
+ return Math.max(0, out);
485
+ }
486
+
487
+ /** Place a block-level box horizontally, honouring `margin: auto`. */
488
+ function placeBlock(
489
+ box: Box,
490
+ contentLeft: number,
491
+ y: number,
492
+ containingWidth: number,
493
+ ): void {
494
+ const style = box.style;
495
+ const leftAuto = style.marginLeft === AUTO;
496
+ const rightAuto = style.marginRight === AUTO;
497
+ const slack = containingWidth - box.width - box.marginLeft - box.marginRight;
498
+ let left = contentLeft + box.marginLeft;
499
+ if (slack > 0) {
500
+ if (leftAuto && rightAuto) left = contentLeft + slack / 2 + box.marginLeft;
501
+ else if (leftAuto) left = contentLeft + slack + box.marginLeft;
502
+ }
503
+ box.x = left;
504
+ box.y = y;
505
+ }
506
+
507
+ /** The border-box width of an in-flow block-level box. */
508
+ function blockWidth(box: Box, containingWidth: number): number {
509
+ const style = box.style;
510
+ const available = containingWidth - box.marginLeft - box.marginRight;
511
+ if (style.width === AUTO) {
512
+ return clampWidth(box, Math.max(0, available), containingWidth);
513
+ }
514
+ const specified = resolve(style.width, containingWidth, 0);
515
+ const borderBox =
516
+ style.boxSizing === 'border-box'
517
+ ? Math.max(specified, box.horizontalExtra)
518
+ : specified + box.horizontalExtra;
519
+ return clampWidth(box, borderBox, containingWidth);
520
+ }
521
+
522
+ function clampWidth(box: Box, width: number, containingWidth: number): number {
523
+ const style = box.style;
524
+ const extra = style.boxSizing === 'border-box' ? 0 : box.horizontalExtra;
525
+ let out = width;
526
+ const max =
527
+ style.maxWidth === 'none'
528
+ ? null
529
+ : resolveOrNull(style.maxWidth, containingWidth);
530
+ if (max !== null) out = Math.min(out, max + extra);
531
+ const min = resolveOrNull(style.minWidth, containingWidth);
532
+ if (min !== null) out = Math.max(out, min + extra);
533
+ return Math.max(0, out);
534
+ }
535
+
536
+ /**
537
+ * Shrink-to-fit: the width a float, an inline-block or a positioned box with
538
+ * `width: auto` takes.
539
+ *
540
+ * CSS says `min(max(preferred-minimum, available), preferred)`, where the two
541
+ * preferred widths are the max-content and min-content sizes. This computes
542
+ * the max-content size by laying the box out unconstrained and skips the
543
+ * min-content one, which costs a second full pass and only changes the answer
544
+ * when a single unbreakable word is wider than the space — where the box
545
+ * overflows either way. The measured pass is thrown away; the caller lays the
546
+ * box out again at the width this returns.
547
+ */
548
+ function shrinkToFitWidth(
549
+ box: Box,
550
+ ctx: LayoutContext,
551
+ available: number,
552
+ ): number {
553
+ const style = box.style;
554
+ if (style.width !== AUTO) {
555
+ const specified = resolve(style.width, available, 0);
556
+ const borderBox =
557
+ style.boxSizing === 'border-box'
558
+ ? Math.max(specified, box.horizontalExtra)
559
+ : specified + box.horizontalExtra;
560
+ return clampWidth(box, borderBox, available);
561
+ }
562
+ const probe = new FloatContext(0, Infinity);
563
+ const saved = box.lines;
564
+ layoutInternals(box, ctx, Infinity, 0, 0, probe);
565
+ const preferred = intrinsicWidth(box) + box.horizontalExtra;
566
+ box.lines = saved;
567
+ return clampWidth(
568
+ box,
569
+ Math.min(Math.max(preferred, 0), available),
570
+ available,
571
+ );
572
+ }
573
+
574
+ /**
575
+ * The widest thing a laid-out box drew — its max-content width.
576
+ *
577
+ * A block child laid out at an unbounded width *has* an unbounded width (a
578
+ * `width: auto` block fills its containing block, and its containing block
579
+ * was `Infinity`), so its own width says nothing and only what it drew does.
580
+ * Skipping the non-finite ones is what stops the probe from answering
581
+ * `Infinity` for every box that contains a paragraph.
582
+ */
583
+ function intrinsicWidth(box: Box): number {
584
+ let widest = 0;
585
+ if (box.lines) {
586
+ for (const line of box.lines) widest = Math.max(widest, line.width);
587
+ }
588
+ for (const child of box.children) {
589
+ if (child.kind === 'text' || child.kind === 'break') continue;
590
+ if (child.outOfFlow) continue;
591
+ const margins = child.marginLeft + child.marginRight;
592
+ const inner = intrinsicWidth(child) + child.horizontalExtra + margins;
593
+ const own = Number.isFinite(child.width) ? child.width + margins : 0;
594
+ widest = Math.max(widest, inner, own);
595
+ }
596
+ return widest;
597
+ }
598
+
599
+ /** A replaced box's size: the style wins, then the attributes, then the
600
+ * intrinsic size, and an aspect ratio is kept when only one axis is given. */
601
+ function sizeReplaced(box: Box, containingWidth: number): void {
602
+ const style = box.style;
603
+ const intrinsicW = box.intrinsicWidth || 0;
604
+ const intrinsicH = box.intrinsicHeight || 0;
605
+ const ratio = intrinsicW > 0 && intrinsicH > 0 ? intrinsicH / intrinsicW : 0;
606
+
607
+ let width = resolveOrNull(style.width, containingWidth);
608
+ let height = resolveOrNull(style.height, NaN);
609
+ if (width === null && height === null) {
610
+ width = intrinsicW;
611
+ height = intrinsicH;
612
+ } else if (width === null) {
613
+ width = ratio ? (height as number) / ratio : intrinsicW;
614
+ } else if (height === null) {
615
+ height = ratio ? width * ratio : intrinsicH;
616
+ }
617
+
618
+ const contentW = Math.max(0, width ?? 0);
619
+ const contentH = Math.max(0, height ?? 0);
620
+ const borderBoxW =
621
+ style.boxSizing === 'border-box'
622
+ ? Math.max(contentW, box.horizontalExtra)
623
+ : contentW + box.horizontalExtra;
624
+ const borderBoxH =
625
+ style.boxSizing === 'border-box'
626
+ ? Math.max(contentH, box.verticalExtra)
627
+ : contentH + box.verticalExtra;
628
+ box.width = clampWidth(box, borderBoxW, containingWidth);
629
+ box.height = clampHeight(box, borderBoxH);
630
+ // `hr` has no intrinsic size and its whole appearance is its border, so a
631
+ // zero content height is the right answer rather than a missing one.
632
+ if (box.replaced === 'hr' && box.style.height === AUTO) {
633
+ box.height = box.verticalExtra;
634
+ }
635
+ }
636
+
637
+ /** Place and size a float, and register it with the formatting context. */
638
+ function layoutFloat(
639
+ box: Box,
640
+ ctx: LayoutContext,
641
+ floats: FloatContext,
642
+ y: number,
643
+ containingWidth: number,
644
+ ): void {
645
+ resolveEdges(box, containingWidth);
646
+ if (box.kind === 'replaced') sizeReplaced(box, containingWidth);
647
+ else {
648
+ const width = shrinkToFitWidth(box, ctx, containingWidth);
649
+ layoutInternals(box, ctx, width, 0, 0);
650
+ }
651
+ const outerWidth = box.width + box.marginLeft + box.marginRight;
652
+ const clearance = floats.clearance(box.style.clear);
653
+ const from = Math.max(y, clearance === -Infinity ? y : clearance);
654
+ const top = floats.placeAt(
655
+ from,
656
+ outerWidth,
657
+ box.style.float === 'right' ? 'right' : 'left',
658
+ );
659
+ const band = floats.bandAt(top, 1);
660
+ const x =
661
+ box.style.float === 'right'
662
+ ? band.right - outerWidth + box.marginLeft
663
+ : band.left + box.marginLeft;
664
+ moveTo(box, x, top + box.marginTop);
665
+ floats.add({
666
+ left: x - box.marginLeft,
667
+ right: x - box.marginLeft + outerWidth,
668
+ top,
669
+ bottom: top + box.height + box.marginTop + box.marginBottom,
670
+ side: box.style.float === 'right' ? 'right' : 'left',
671
+ });
672
+ }
673
+
674
+ /**
675
+ * An absolutely positioned box, against its containing block.
676
+ *
677
+ * The static position — where the box would have been in flow — is not
678
+ * tracked: a box with neither `top` nor `bottom` is placed at its containing
679
+ * block's content top rather than where its markup sat. That is the one
680
+ * deliberate simplification in positioning, and it is invisible for the
681
+ * overwhelmingly common `position: absolute` with an explicit offset, which
682
+ * is how a badge, a tooltip and an overlay are all written.
683
+ */
684
+ function layoutPositioned(box: Box, containing: Box, ctx: LayoutContext): void {
685
+ const cbWidth = containing.contentWidth;
686
+ const cbHeight = containing.contentHeight;
687
+ const cbX = containing.contentX;
688
+ const cbY = containing.contentY;
689
+ resolveEdges(box, cbWidth);
690
+
691
+ const style = box.style;
692
+ const left = resolveOrNull(style.left, cbWidth);
693
+ const right = resolveOrNull(style.right, cbWidth);
694
+ const top = resolveOrNull(style.top, cbHeight);
695
+ const bottom = resolveOrNull(style.bottom, cbHeight);
696
+
697
+ let width: number;
698
+ if (style.width !== AUTO) {
699
+ width = blockWidth(box, cbWidth);
700
+ } else if (left !== null && right !== null) {
701
+ width = Math.max(
702
+ 0,
703
+ cbWidth - left - right - box.marginLeft - box.marginRight,
704
+ );
705
+ } else {
706
+ width = shrinkToFitWidth(box, ctx, cbWidth);
707
+ }
708
+
709
+ if (box.kind === 'replaced') sizeReplaced(box, cbWidth);
710
+ else layoutInternals(box, ctx, width, 0, 0);
711
+
712
+ const x =
713
+ left !== null
714
+ ? cbX + left + box.marginLeft
715
+ : right !== null
716
+ ? cbX + cbWidth - right - box.width - box.marginRight
717
+ : cbX;
718
+ const y =
719
+ top !== null
720
+ ? cbY + top + box.marginTop
721
+ : bottom !== null
722
+ ? cbY + cbHeight - bottom - box.height - box.marginBottom
723
+ : cbY;
724
+ moveTo(box, x, y);
725
+ }
726
+
727
+ /** The nearest positioned ancestor, or null for the initial containing
728
+ * block. Walks the box tree rather than the DOM, so an anonymous box in
729
+ * between is transparent — which is what the spec means by "the nearest
730
+ * positioned ancestor". */
731
+ function containingBlockFor(box: Box): Box | null {
732
+ let node = box.parent;
733
+ while (node) {
734
+ if (node.style.position !== 'static' || node.parent === null) return node;
735
+ node = node.parent;
736
+ }
737
+ return null;
738
+ }
739
+
740
+ /** Move a box and everything under it, keeping the subtree's shape. */
741
+ export function moveTo(box: Box, x: number, y: number): void {
742
+ translate(box, x - box.x, y - box.y);
743
+ }
744
+
745
+ function translate(box: Box, dx: number, dy: number): void {
746
+ if (!dx && !dy) return;
747
+ box.x += dx;
748
+ box.y += dy;
749
+ if (box.lines) {
750
+ for (const line of box.lines) {
751
+ line.x += dx;
752
+ line.y += dy;
753
+ for (const text of line.texts) {
754
+ text.drawX += dx;
755
+ text.drawY += dy;
756
+ }
757
+ for (const placed of line.atomics) {
758
+ placed.x += dx;
759
+ placed.y += dy;
760
+ }
761
+ }
762
+ }
763
+ for (const child of box.children) translate(child, dx, dy);
764
+ }
765
+
766
+ /** Resolve the margin, border and padding edges against a containing width.
767
+ * Percentages on *every* one of them are of the containing block's width,
768
+ * vertical padding included — which surprises everyone once. */
769
+ export function resolveEdges(box: Box, containingWidth: number): void {
770
+ const style = box.style;
771
+ box.borderTop =
772
+ style.borderTopStyle === 'none' || style.borderTopStyle === 'hidden'
773
+ ? 0
774
+ : style.borderTopWidth;
775
+ box.borderRight =
776
+ style.borderRightStyle === 'none' || style.borderRightStyle === 'hidden'
777
+ ? 0
778
+ : style.borderRightWidth;
779
+ box.borderBottom =
780
+ style.borderBottomStyle === 'none' || style.borderBottomStyle === 'hidden'
781
+ ? 0
782
+ : style.borderBottomWidth;
783
+ box.borderLeft =
784
+ style.borderLeftStyle === 'none' || style.borderLeftStyle === 'hidden'
785
+ ? 0
786
+ : style.borderLeftWidth;
787
+ box.padTop = edge(style.paddingTop, containingWidth);
788
+ box.padRight = edge(style.paddingRight, containingWidth);
789
+ box.padBottom = edge(style.paddingBottom, containingWidth);
790
+ box.padLeft = edge(style.paddingLeft, containingWidth);
791
+ box.marginTop = edge(style.marginTop, containingWidth);
792
+ box.marginRight = edge(style.marginRight, containingWidth);
793
+ box.marginBottom = edge(style.marginBottom, containingWidth);
794
+ box.marginLeft = edge(style.marginLeft, containingWidth);
795
+ }
796
+
797
+ function edge(len: Len, containingWidth: number): number {
798
+ if (len === AUTO) return 0;
799
+ if (isPct(len))
800
+ return Number.isFinite(containingWidth)
801
+ ? (len.pct / 100) * containingWidth
802
+ : 0;
803
+ return len;
804
+ }
805
+
806
+ /** Whether every in-flow child is inline-level, which is what makes this box
807
+ * an inline formatting context rather than a block one. */
808
+ function establishesInlineContext(box: Box): boolean {
809
+ if (box.kind === 'table' || box.kind === 'flex') return false;
810
+ let sawInline = false;
811
+ for (const child of box.children) {
812
+ if (child.outOfFlow || child.isFloat) continue;
813
+ switch (child.kind) {
814
+ case 'text':
815
+ case 'inline':
816
+ case 'break':
817
+ sawInline = true;
818
+ break;
819
+ case 'replaced':
820
+ sawInline = true;
821
+ break;
822
+ default:
823
+ if (isInlineLevel(child)) sawInline = true;
824
+ else return false;
825
+ break;
826
+ }
827
+ }
828
+ return sawInline;
829
+ }
830
+
831
+ function isInlineLevel(box: Box): boolean {
832
+ const d = box.style.display;
833
+ return (
834
+ d === 'inline' ||
835
+ d === 'inline-block' ||
836
+ d === 'inline-flex' ||
837
+ d === 'inline-table'
838
+ );
839
+ }
840
+
841
+ /** Whether a box establishes a block formatting context — contains its own
842
+ * floats, and does not collapse margins through its edges. */
843
+ export function establishesBFC(box: Box): boolean {
844
+ const style = box.style;
845
+ if (style.overflowX !== 'visible' || style.overflowY !== 'visible')
846
+ return true;
847
+ if (style.float !== 'none') return true;
848
+ if (style.position === 'absolute' || style.position === 'fixed') return true;
849
+ if (
850
+ style.display === 'inline-block' ||
851
+ style.display === 'flex' ||
852
+ style.display === 'inline-flex'
853
+ ) {
854
+ return true;
855
+ }
856
+ if (box.kind === 'table-cell' || box.kind === 'table') return true;
857
+ return box.parent === null;
858
+ }
859
+
860
+ /** What a box's `position: relative` offset moves it by, applied after
861
+ * layout so it does not affect anything else's position — which is the
862
+ * whole of what makes it *relative*. */
863
+ export function applyRelativeOffsets(box: Box): void {
864
+ for (const child of box.children) applyRelativeOffsets(child);
865
+ const style = box.style;
866
+ if (style.position !== 'relative' && style.position !== 'sticky') return;
867
+ const parentWidth = box.parent ? box.parent.contentWidth : 0;
868
+ const parentHeight = box.parent ? box.parent.contentHeight : 0;
869
+ const left = resolveOrNull(style.left, parentWidth);
870
+ const right = resolveOrNull(style.right, parentWidth);
871
+ const top = resolveOrNull(style.top, parentHeight);
872
+ const bottom = resolveOrNull(style.bottom, parentHeight);
873
+ const dx = left ?? (right !== null ? -right : 0);
874
+ const dy = top ?? (bottom !== null ? -bottom : 0);
875
+ translate(box, dx, dy);
876
+ }