pagyra-js 0.0.20 → 0.0.21

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 (286) hide show
  1. package/README.md +55 -0
  2. package/dist/assets/fonts/licenses/selawik/SIL Open Font License.txt +43 -0
  3. package/dist/assets/fonts/ttf/arimo/Arimo-Bold.ttf +0 -0
  4. package/dist/assets/fonts/ttf/arimo/Arimo-BoldItalic.ttf +0 -0
  5. package/dist/assets/fonts/ttf/arimo/Arimo-Italic.ttf +0 -0
  6. package/dist/assets/fonts/ttf/arimo/Arimo-Regular.ttf +0 -0
  7. package/dist/assets/fonts/ttf/cinzeldecorative/CinzelDecorative-Black.ttf +0 -0
  8. package/dist/assets/fonts/ttf/cinzeldecorative/CinzelDecorative-Bold.ttf +0 -0
  9. package/dist/assets/fonts/ttf/cinzeldecorative/CinzelDecorative-Regular.ttf +0 -0
  10. package/dist/assets/fonts/ttf/dejavu/DejaVuSans.ttf +0 -0
  11. package/dist/assets/fonts/ttf/firecode/FiraCode-Bold.ttf +0 -0
  12. package/dist/assets/fonts/ttf/firecode/FiraCode-Light.ttf +0 -0
  13. package/dist/assets/fonts/ttf/firecode/FiraCode-Medium.ttf +0 -0
  14. package/dist/assets/fonts/ttf/firecode/FiraCode-Regular.ttf +0 -0
  15. package/dist/assets/fonts/ttf/firecode/FiraCode-SemiBold.ttf +0 -0
  16. package/dist/assets/fonts/ttf/notoemoji/NotoEmoji-Bold.ttf +0 -0
  17. package/dist/assets/fonts/ttf/notoemoji/NotoEmoji-Light.ttf +0 -0
  18. package/dist/assets/fonts/ttf/notoemoji/NotoEmoji-Medium.ttf +0 -0
  19. package/dist/assets/fonts/ttf/notoemoji/NotoEmoji-Regular.ttf +0 -0
  20. package/dist/assets/fonts/ttf/notoemoji/NotoEmoji-SemiBold.ttf +0 -0
  21. package/dist/assets/fonts/ttf/notosans/NotoSans-Regular.ttf +0 -0
  22. package/dist/assets/fonts/ttf/roboto/Roboto-Bold.ttf +0 -0
  23. package/dist/assets/fonts/ttf/roboto/Roboto-BoldItalic.ttf +0 -0
  24. package/dist/assets/fonts/ttf/roboto/Roboto-Italic.ttf +0 -0
  25. package/dist/assets/fonts/ttf/roboto/Roboto-Regular.ttf +0 -0
  26. package/dist/assets/fonts/ttf/selawik/selawk.ttf +0 -0
  27. package/dist/assets/fonts/ttf/selawik/selawkb.ttf +0 -0
  28. package/dist/assets/fonts/ttf/selawik/selawkl.ttf +0 -0
  29. package/dist/assets/fonts/ttf/selawik/selawksb.ttf +0 -0
  30. package/dist/assets/fonts/ttf/selawik/selawksl.ttf +0 -0
  31. package/dist/assets/fonts/ttf/stixtwomath/STIXTwoMath-Regular.ttf +0 -0
  32. package/dist/assets/fonts/ttf/tinos/Tinos-Bold.ttf +0 -0
  33. package/dist/assets/fonts/ttf/tinos/Tinos-BoldItalic.ttf +0 -0
  34. package/dist/assets/fonts/ttf/tinos/Tinos-Italic.ttf +0 -0
  35. package/dist/assets/fonts/ttf/tinos/Tinos-Regular.ttf +0 -0
  36. package/dist/assets/fonts/woff/lato/lato-latin-400-italic.woff +0 -0
  37. package/dist/assets/fonts/woff/lato/lato-latin-400-normal.woff +0 -0
  38. package/dist/assets/fonts/woff/lato/lato-latin-700-italic.woff +0 -0
  39. package/dist/assets/fonts/woff/lato/lato-latin-700-normal.woff +0 -0
  40. package/dist/assets/fonts/woff2/caveat/Caveat-Bold.woff2 +0 -0
  41. package/dist/assets/fonts/woff2/caveat/Caveat-Regular.woff2 +0 -0
  42. package/dist/assets/fonts/woff2/lato/lato-latin-400-italic.woff2 +0 -0
  43. package/dist/assets/fonts/woff2/lato/lato-latin-400-normal.woff2 +0 -0
  44. package/dist/assets/fonts/woff2/lato/lato-latin-700-italic.woff2 +0 -0
  45. package/dist/assets/fonts/woff2/lato/lato-latin-700-normal.woff2 +0 -0
  46. package/dist/browser/pagyra.min.js +34 -34
  47. package/dist/browser/pagyra.min.js.map +4 -4
  48. package/dist/playground/server.js +2 -0
  49. package/dist/src/css/compute-style/base-options.d.ts +7 -0
  50. package/dist/src/css/compute-style/base-options.js +24 -0
  51. package/dist/src/css/compute-style/declarations.d.ts +10 -0
  52. package/dist/src/css/compute-style/declarations.js +77 -0
  53. package/dist/src/css/compute-style/decoration.d.ts +8 -0
  54. package/dist/src/css/compute-style/decoration.js +55 -0
  55. package/dist/src/css/compute-style/defaults.d.ts +3 -0
  56. package/dist/src/css/compute-style/defaults.js +34 -0
  57. package/dist/src/css/compute-style/display.d.ts +3 -0
  58. package/dist/src/css/compute-style/display.js +85 -0
  59. package/dist/src/css/compute-style/float.d.ts +2 -0
  60. package/dist/src/css/compute-style/float.js +13 -0
  61. package/dist/src/css/compute-style/font.d.ts +12 -0
  62. package/dist/src/css/compute-style/font.js +57 -0
  63. package/dist/src/css/compute-style/overrides.d.ts +3 -0
  64. package/dist/src/css/compute-style/overrides.js +241 -0
  65. package/dist/src/css/compute-style.d.ts +2 -0
  66. package/dist/src/css/compute-style.js +34 -487
  67. package/dist/src/css/enums.d.ts +4 -0
  68. package/dist/src/css/enums.js +5 -0
  69. package/dist/src/css/layout-property-resolver.js +30 -18
  70. package/dist/src/css/length.d.ts +26 -2
  71. package/dist/src/css/length.js +48 -0
  72. package/dist/src/css/parsers/background-parser.js +1 -1
  73. package/dist/src/css/parsers/calc-parser.d.ts +2 -0
  74. package/dist/src/css/parsers/calc-parser.js +310 -0
  75. package/dist/src/css/parsers/content-parser.d.ts +2 -1
  76. package/dist/src/css/parsers/content-parser.js +7 -2
  77. package/dist/src/css/parsers/dimension-parser.js +37 -18
  78. package/dist/src/css/parsers/display-flex-parser.d.ts +4 -0
  79. package/dist/src/css/parsers/display-flex-parser.js +97 -0
  80. package/dist/src/css/parsers/filter-parser.d.ts +14 -0
  81. package/dist/src/css/parsers/filter-parser.js +255 -0
  82. package/dist/src/css/parsers/grid-parser-extended.d.ts +1 -0
  83. package/dist/src/css/parsers/grid-parser-extended.js +40 -1
  84. package/dist/src/css/parsers/grid-parser.d.ts +5 -2
  85. package/dist/src/css/parsers/grid-parser.js +71 -7
  86. package/dist/src/css/parsers/length-parser.d.ts +8 -3
  87. package/dist/src/css/parsers/length-parser.js +45 -2
  88. package/dist/src/css/parsers/margin-block-parser.js +3 -3
  89. package/dist/src/css/parsers/margin-parser.js +3 -3
  90. package/dist/src/css/parsers/padding-block-parser.js +3 -3
  91. package/dist/src/css/parsers/padding-inline-parser.js +3 -3
  92. package/dist/src/css/parsers/padding-parser.js +6 -6
  93. package/dist/src/css/parsers/position-parser.js +2 -22
  94. package/dist/src/css/parsers/register-parsers.js +29 -2
  95. package/dist/src/css/parsers/word-break-parser.d.ts +2 -0
  96. package/dist/src/css/parsers/word-break-parser.js +23 -0
  97. package/dist/src/css/properties/grid.d.ts +16 -2
  98. package/dist/src/css/properties/layout.d.ts +3 -1
  99. package/dist/src/css/properties/layout.js +1 -1
  100. package/dist/src/css/properties/misc.d.ts +5 -0
  101. package/dist/src/css/properties/typography.d.ts +3 -0
  102. package/dist/src/css/properties/visual.d.ts +36 -0
  103. package/dist/src/css/shorthands/box-shorthand.d.ts +2 -2
  104. package/dist/src/css/style-inheritance.d.ts +2 -1
  105. package/dist/src/css/style-inheritance.js +1 -0
  106. package/dist/src/css/style.d.ts +30 -10
  107. package/dist/src/css/style.js +8 -1
  108. package/dist/src/css/ua-defaults/base-defaults.d.ts +1 -0
  109. package/dist/src/css/ua-defaults/base-defaults.js +10 -1
  110. package/dist/src/css/ua-defaults/element-defaults.js +0 -2
  111. package/dist/src/html/css/parse-css.d.ts +2 -0
  112. package/dist/src/html/css/parse-css.js +32 -3
  113. package/dist/src/html/dom-converter/background-images.d.ts +3 -0
  114. package/dist/src/html/dom-converter/background-images.js +88 -0
  115. package/dist/src/html/dom-converter/convert-dom-node.d.ts +5 -0
  116. package/dist/src/html/dom-converter/convert-dom-node.js +81 -0
  117. package/dist/src/html/dom-converter/handlers/br-handler.d.ts +2 -0
  118. package/dist/src/html/dom-converter/handlers/br-handler.js +20 -0
  119. package/dist/src/html/dom-converter/handlers/form-control-handler.d.ts +2 -0
  120. package/dist/src/html/dom-converter/handlers/form-control-handler.js +28 -0
  121. package/dist/src/html/dom-converter/handlers/img-handler.d.ts +2 -0
  122. package/dist/src/html/dom-converter/handlers/img-handler.js +4 -0
  123. package/dist/src/html/dom-converter/handlers/index.d.ts +4 -0
  124. package/dist/src/html/dom-converter/handlers/index.js +19 -0
  125. package/dist/src/html/dom-converter/handlers/svg-handler.d.ts +2 -0
  126. package/dist/src/html/dom-converter/handlers/svg-handler.js +32 -0
  127. package/dist/src/html/dom-converter/handlers/types.d.ts +12 -0
  128. package/dist/src/html/dom-converter/handlers/types.js +2 -0
  129. package/dist/src/html/dom-converter/helpers.d.ts +7 -0
  130. package/dist/src/html/dom-converter/helpers.js +35 -0
  131. package/dist/src/html/dom-converter/index.d.ts +1 -0
  132. package/dist/src/html/dom-converter/index.js +1 -0
  133. package/dist/src/html/dom-converter/pseudo-elements.d.ts +6 -0
  134. package/dist/src/html/dom-converter/pseudo-elements.js +48 -0
  135. package/dist/src/html/dom-converter/text.d.ts +15 -0
  136. package/dist/src/html/dom-converter/text.js +170 -0
  137. package/dist/src/html/dom-converter.d.ts +1 -5
  138. package/dist/src/html/dom-converter.js +1 -417
  139. package/dist/src/html/image-converter.d.ts +5 -0
  140. package/dist/src/html-to-pdf/document-css.d.ts +14 -0
  141. package/dist/src/html-to-pdf/document-css.js +45 -0
  142. package/dist/src/html-to-pdf/fonts.d.ts +16 -0
  143. package/dist/src/html-to-pdf/fonts.js +74 -0
  144. package/dist/src/html-to-pdf/header-footer.d.ts +14 -0
  145. package/dist/src/html-to-pdf/header-footer.js +101 -0
  146. package/dist/src/html-to-pdf/html-parser.d.ts +6 -0
  147. package/dist/src/html-to-pdf/html-parser.js +81 -0
  148. package/dist/src/html-to-pdf/index.d.ts +3 -0
  149. package/dist/src/html-to-pdf/index.js +2 -0
  150. package/dist/src/html-to-pdf/layout-build.d.ts +37 -0
  151. package/dist/src/html-to-pdf/layout-build.js +73 -0
  152. package/dist/src/html-to-pdf/prepare-html-render.d.ts +2 -0
  153. package/dist/src/html-to-pdf/prepare-html-render.js +121 -0
  154. package/dist/src/html-to-pdf/render-finalize.d.ts +15 -0
  155. package/dist/src/html-to-pdf/render-finalize.js +27 -0
  156. package/dist/src/html-to-pdf/render-html-to-pdf.d.ts +3 -0
  157. package/dist/src/html-to-pdf/render-html-to-pdf.js +25 -0
  158. package/dist/src/html-to-pdf/resource-loader.d.ts +6 -0
  159. package/dist/src/html-to-pdf/resource-loader.js +120 -0
  160. package/dist/src/html-to-pdf/types.d.ts +38 -0
  161. package/dist/src/html-to-pdf/types.js +2 -0
  162. package/dist/src/html-to-pdf.d.ts +1 -37
  163. package/dist/src/html-to-pdf.js +1 -537
  164. package/dist/src/image/js-png-backend.d.ts +7 -0
  165. package/dist/src/image/js-png-backend.js +9 -0
  166. package/dist/src/image/png-backend.d.ts +5 -0
  167. package/dist/src/image/png-backend.js +1 -0
  168. package/dist/src/image/png-wasm-loader.d.ts +5 -0
  169. package/dist/src/image/png-wasm-loader.js +59 -0
  170. package/dist/src/image/wasm/png_decoder_wasm.d.ts +8 -0
  171. package/dist/src/image/wasm/png_decoder_wasm.js +24 -0
  172. package/dist/src/image/wasm/png_decoder_wasm_bg.js +16 -0
  173. package/dist/src/image/wasm-png-backend.d.ts +6 -0
  174. package/dist/src/image/wasm-png-backend.js +17 -0
  175. package/dist/src/layout/counter.d.ts +1 -2
  176. package/dist/src/layout/counter.js +18 -18
  177. package/dist/src/layout/inline/inline-utils.d.ts +1 -1
  178. package/dist/src/layout/inline/inline-utils.js +8 -7
  179. package/dist/src/layout/inline/layout.js +16 -3
  180. package/dist/src/layout/inline/run-placer.d.ts +1 -0
  181. package/dist/src/layout/inline/run-placer.js +2 -10
  182. package/dist/src/layout/pipeline/out-of-flow-manager.js +25 -1
  183. package/dist/src/layout/strategies/block.js +35 -24
  184. package/dist/src/layout/strategies/flex.js +305 -61
  185. package/dist/src/layout/strategies/form.d.ts +2 -0
  186. package/dist/src/layout/strategies/form.js +38 -13
  187. package/dist/src/layout/strategies/grid.js +166 -29
  188. package/dist/src/layout/strategies/image.js +53 -27
  189. package/dist/src/layout/strategies/inline.js +26 -21
  190. package/dist/src/layout/strategies/table.js +26 -18
  191. package/dist/src/layout/utils/content-measurer.d.ts +1 -1
  192. package/dist/src/layout/utils/content-measurer.js +8 -7
  193. package/dist/src/layout/utils/floats.d.ts +1 -0
  194. package/dist/src/layout/utils/floats.js +14 -12
  195. package/dist/src/layout/utils/margin.d.ts +4 -4
  196. package/dist/src/layout/utils/margin.js +20 -16
  197. package/dist/src/layout/utils/node-math.d.ts +12 -6
  198. package/dist/src/layout/utils/node-math.js +71 -41
  199. package/dist/src/layout/utils/sizing.js +2 -1
  200. package/dist/src/pdf/font-subset/font-registry.d.ts +6 -0
  201. package/dist/src/pdf/font-subset/font-registry.js +30 -2
  202. package/dist/src/pdf/header-footer-renderer.js +12 -1
  203. package/dist/src/pdf/layout-tree-builder.js +5 -1
  204. package/dist/src/pdf/page-painter.js +13 -0
  205. package/dist/src/pdf/pagination.js +2 -2
  206. package/dist/src/pdf/renderer/box-painter.js +28 -3
  207. package/dist/src/pdf/renderer/page-paint.js +11 -3
  208. package/dist/src/pdf/renderers/radius-utils.js +31 -38
  209. package/dist/src/pdf/renderers/shape-renderer.js +1 -1
  210. package/dist/src/pdf/renderers/shape-utils.js +1 -1
  211. package/dist/src/pdf/renderers/text-renderer.d.ts +9 -1
  212. package/dist/src/pdf/renderers/text-renderer.js +36 -2
  213. package/dist/src/pdf/stacking/build-stacking-contexts.js +1 -2
  214. package/dist/src/pdf/stacking/resolve-paint-order.d.ts +5 -6
  215. package/dist/src/pdf/stacking/resolve-paint-order.js +29 -9
  216. package/dist/src/pdf/stacking/types.d.ts +14 -0
  217. package/dist/src/pdf/svg/shape-renderer.js +47 -20
  218. package/dist/src/pdf/types.d.ts +7 -1
  219. package/dist/src/pdf/utils/border-radius-utils.js +31 -38
  220. package/dist/src/pdf/utils/color-utils.js +17 -2
  221. package/dist/src/pdf/utils/filter-utils.d.ts +29 -0
  222. package/dist/src/pdf/utils/filter-utils.js +85 -0
  223. package/dist/src/pdf/utils/node-text-run-factory.js +1 -1
  224. package/dist/src/pdf/utils/text-layout-adjuster.d.ts +0 -8
  225. package/dist/src/pdf/utils/text-layout-adjuster.js +12 -9
  226. package/dist/src/units/units.d.ts +1 -1
  227. package/dist/tests/css/box-sizing.spec.d.ts +1 -0
  228. package/dist/tests/css/box-sizing.spec.js +46 -0
  229. package/dist/tests/css/calc-parser.spec.d.ts +1 -0
  230. package/dist/tests/css/calc-parser.spec.js +68 -0
  231. package/dist/tests/css/container-query-units.spec.d.ts +1 -0
  232. package/dist/tests/css/container-query-units.spec.js +64 -0
  233. package/dist/tests/css/content-parser.spec.js +13 -0
  234. package/dist/tests/css/filter-parser.spec.d.ts +1 -0
  235. package/dist/tests/css/filter-parser.spec.js +116 -0
  236. package/dist/tests/css/flex-shorthand.spec.d.ts +1 -0
  237. package/dist/tests/css/flex-shorthand.spec.js +45 -0
  238. package/dist/tests/css/grid-clamp.spec.d.ts +1 -0
  239. package/dist/tests/css/grid-clamp.spec.js +82 -0
  240. package/dist/tests/css/parse-css-pseudo.spec.d.ts +1 -0
  241. package/dist/tests/css/parse-css-pseudo.spec.js +26 -0
  242. package/dist/tests/helpers/render-utils.d.ts +18 -2
  243. package/dist/tests/helpers/render-utils.js +25 -12
  244. package/dist/tests/html/dom-converter-pseudo-elements.spec.d.ts +1 -0
  245. package/dist/tests/html/dom-converter-pseudo-elements.spec.js +33 -0
  246. package/dist/tests/html/dom-converter-text.spec.d.ts +1 -0
  247. package/dist/tests/html/dom-converter-text.spec.js +67 -0
  248. package/dist/tests/image/png-backend.spec.d.ts +1 -0
  249. package/dist/tests/image/png-backend.spec.js +34 -0
  250. package/dist/tests/layout/box-sizing.spec.d.ts +1 -0
  251. package/dist/tests/layout/box-sizing.spec.js +75 -0
  252. package/dist/tests/layout/calc-padding.spec.d.ts +1 -0
  253. package/dist/tests/layout/calc-padding.spec.js +19 -0
  254. package/dist/tests/layout/container-query-units.spec.d.ts +1 -0
  255. package/dist/tests/layout/container-query-units.spec.js +24 -0
  256. package/dist/tests/layout/flex-auto-height.spec.d.ts +1 -0
  257. package/dist/tests/layout/flex-auto-height.spec.js +35 -0
  258. package/dist/tests/layout/flex-wrap-cards.spec.d.ts +1 -0
  259. package/dist/tests/layout/flex-wrap-cards.spec.js +16 -0
  260. package/dist/tests/layout/flex-wrap-grow-align-content.spec.d.ts +1 -0
  261. package/dist/tests/layout/flex-wrap-grow-align-content.spec.js +20 -0
  262. package/dist/tests/layout/grid-clamp-gap.spec.d.ts +1 -0
  263. package/dist/tests/layout/grid-clamp-gap.spec.js +22 -0
  264. package/dist/tests/layout/inline-fragments.spec.js +38 -0
  265. package/dist/tests/layout/paged-body-margin.spec.d.ts +1 -0
  266. package/dist/tests/layout/paged-body-margin.spec.js +92 -0
  267. package/dist/tests/layout/pseudo-counters-generated-content.spec.d.ts +1 -0
  268. package/dist/tests/layout/pseudo-counters-generated-content.spec.js +51 -0
  269. package/dist/tests/layout/responsive-clamp-grid-parity.spec.d.ts +1 -0
  270. package/dist/tests/layout/responsive-clamp-grid-parity.spec.js +75 -0
  271. package/dist/tests/layout/run-placer-baseline.spec.js +13 -11
  272. package/dist/tests/pdf/backdrop-filter-noop.spec.d.ts +1 -0
  273. package/dist/tests/pdf/backdrop-filter-noop.spec.js +140 -0
  274. package/dist/tests/pdf/filter-drop-shadow.spec.d.ts +1 -0
  275. package/dist/tests/pdf/filter-drop-shadow.spec.js +74 -0
  276. package/dist/tests/pdf/filter-opacity.spec.d.ts +1 -0
  277. package/dist/tests/pdf/filter-opacity.spec.js +30 -0
  278. package/dist/tests/pdf/font-subset-registry-key.spec.d.ts +1 -0
  279. package/dist/tests/pdf/font-subset-registry-key.spec.js +66 -0
  280. package/dist/tests/pdf/selawik-opt-in.spec.d.ts +1 -0
  281. package/dist/tests/pdf/selawik-opt-in.spec.js +106 -0
  282. package/dist/tests/pdf/system-ui-fallback-subset-regression.spec.d.ts +1 -0
  283. package/dist/tests/pdf/system-ui-fallback-subset-regression.spec.js +39 -0
  284. package/dist/tests/pdf/text-renderer-fallback.spec.js +55 -0
  285. package/dist/tests/pdf/text-transform-matrix.spec.js +8 -7
  286. package/package.json +2 -2
@@ -0,0 +1,59 @@
1
+ let wasmModule = null;
2
+ let initPromise = null;
3
+ let loadFailed = false;
4
+ async function loadWasmModule() {
5
+ if (wasmModule) {
6
+ return wasmModule;
7
+ }
8
+ if (loadFailed) {
9
+ throw new Error("WASM PNG decoder not available (build failed)");
10
+ }
11
+ if (initPromise) {
12
+ return initPromise;
13
+ }
14
+ initPromise = (async () => {
15
+ try {
16
+ const wasmPath = new URL("./wasm/png_decoder_wasm.js", import.meta.url).pathname;
17
+ const wasm = await import(wasmPath);
18
+ if (wasm.decode_png_rgba.toString().includes("throw new Error")) {
19
+ loadFailed = true;
20
+ initPromise = null;
21
+ throw new Error("WASM stub detected");
22
+ }
23
+ await wasm.default();
24
+ wasmModule = wasm;
25
+ return wasm;
26
+ }
27
+ catch (error) {
28
+ loadFailed = true;
29
+ initPromise = null;
30
+ throw new Error(`WASM PNG decoder init failed: ${error instanceof Error ? error.message : String(error)}`);
31
+ }
32
+ })();
33
+ return initPromise;
34
+ }
35
+ export class PngWasmLoader {
36
+ static async getOrInit() {
37
+ return loadWasmModule();
38
+ }
39
+ static async isAvailable() {
40
+ if (wasmModule) {
41
+ return true;
42
+ }
43
+ if (loadFailed) {
44
+ return false;
45
+ }
46
+ try {
47
+ await loadWasmModule();
48
+ return true;
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }
54
+ static reset() {
55
+ wasmModule = null;
56
+ initPromise = null;
57
+ loadFailed = false;
58
+ }
59
+ }
@@ -0,0 +1,8 @@
1
+ // Stub TypeScript types for WASM module
2
+ export default function init(): Promise<void>;
3
+ export function init(): Promise<void>;
4
+ export function decode_png_rgba(
5
+ buffer: Uint8Array,
6
+ targetWidth?: number,
7
+ targetHeight?: number,
8
+ ): { width: number; height: number; data: Uint8Array };
@@ -0,0 +1,24 @@
1
+ // Stub WASM module for development (fallback to JS decoder)
2
+ // Replace with real WASM build when toolchain is available
3
+
4
+ let initialized = false;
5
+
6
+ async function init() {
7
+ if (initialized) return;
8
+
9
+ try {
10
+ const wasmPath = new URL("./png_decoder_wasm.js", import.meta.url).pathname;
11
+ const wasm = await import(wasmPath);
12
+ await wasm.default();
13
+ initialized = true;
14
+ } catch {
15
+ initialized = false;
16
+ }
17
+ }
18
+
19
+ function decode_png_rgba(buffer, targetWidth, targetHeight) {
20
+ throw new Error("WASM PNG decoder not built. Run 'npm run build:wasm' or use pngBackend: 'js'");
21
+ }
22
+
23
+ export default init;
24
+ export { init, decode_png_rgba };
@@ -0,0 +1,16 @@
1
+ // Stub WASM module for development (fallback to JS decoder)
2
+ // Replace with real WASM build when toolchain is available
3
+
4
+ let initialized = false;
5
+
6
+ async function init() {
7
+ if (initialized) return;
8
+ initialized = true;
9
+ }
10
+
11
+ function decode_png_rgba(buffer, targetWidth, targetHeight) {
12
+ throw new Error("WASM PNG decoder not built. Run 'npm run build:wasm' or use pngBackend: 'js'");
13
+ }
14
+
15
+ export default init;
16
+ export { init, decode_png_rgba };
@@ -0,0 +1,6 @@
1
+ import type { ImageInfo } from "./types.js";
2
+ import type { ImageDecodeOptions } from "./types.js";
3
+ import type { PngBackend } from "./png-backend.js";
4
+ export declare class WasmPngBackend implements PngBackend {
5
+ decode(buffer: ArrayBuffer, options?: ImageDecodeOptions): Promise<ImageInfo>;
6
+ }
@@ -0,0 +1,17 @@
1
+ import { PngWasmLoader } from "./png-wasm-loader.js";
2
+ export class WasmPngBackend {
3
+ async decode(buffer, options) {
4
+ const wasm = await PngWasmLoader.getOrInit();
5
+ const targetWidth = options?.maxWidth;
6
+ const targetHeight = options?.maxHeight;
7
+ const result = wasm.decode_png_rgba(new Uint8Array(buffer), targetWidth, targetHeight);
8
+ return {
9
+ width: result.width,
10
+ height: result.height,
11
+ format: "png",
12
+ channels: 4,
13
+ bitsPerChannel: 8,
14
+ data: result.data.buffer,
15
+ };
16
+ }
17
+ }
@@ -31,8 +31,7 @@ export interface CounterIncrement {
31
31
  readonly value: number;
32
32
  }
33
33
  export interface CounterContext {
34
- getScopeId(): string;
35
- getCounter(name: string): number;
34
+ getCounter(name: string, scopeId: string | null): number;
36
35
  registerScope(parentScopeId: string | null): string;
37
36
  resetCounter(name: string, value: number, scopeId: string): void;
38
37
  incrementCounter(name: string, value: number, scopeId: string): void;
@@ -1,6 +1,5 @@
1
1
  // src/layout/counter.ts
2
2
  let scopeCounter = 0;
3
- let globalCounter = 0;
4
3
  /**
5
4
  * Create a new counter scope
6
5
  */
@@ -39,23 +38,23 @@ export function createCounterContext() {
39
38
  }
40
39
  return 0;
41
40
  }
42
- return {
43
- getScopeId() {
44
- return `global-${++globalCounter}`;
45
- },
46
- getCounter(name) {
47
- // Get from the innermost active scope
48
- let currentScopeId = null;
49
- for (const [sid, parentId] of scopeHierarchy) {
50
- if (parentId === null) {
51
- currentScopeId = sid;
52
- }
41
+ function findScopeWithCounter(scopeId, name) {
42
+ let currentScopeId = scopeId;
43
+ while (currentScopeId !== null) {
44
+ const scopeCounters = counters.get(currentScopeId);
45
+ if (scopeCounters && scopeCounters.has(name)) {
46
+ return currentScopeId;
53
47
  }
54
- if (!currentScopeId) {
55
- // No scopes active, use global counter
56
- return getEffectiveValue("global", name);
48
+ currentScopeId = scopeHierarchy.get(currentScopeId) ?? null;
49
+ }
50
+ return null;
51
+ }
52
+ return {
53
+ getCounter(name, scopeId) {
54
+ if (!scopeId) {
55
+ return 0;
57
56
  }
58
- return getEffectiveValue(currentScopeId, name);
57
+ return getEffectiveValue(scopeId, name);
59
58
  },
60
59
  registerScope(parentScopeId) {
61
60
  const scope = createScope(parentScopeId ? scopes.get(parentScopeId) ?? null : null);
@@ -69,8 +68,9 @@ export function createCounterContext() {
69
68
  scopeCounters.set(name, value);
70
69
  },
71
70
  incrementCounter(name, value, scopeId) {
72
- ensureCounter(scopeId, name);
73
- const scopeCounters = counters.get(scopeId);
71
+ const targetScopeId = findScopeWithCounter(scopeId, name) ?? scopeId;
72
+ ensureCounter(targetScopeId, name);
73
+ const scopeCounters = counters.get(targetScopeId);
74
74
  const current = scopeCounters.get(name) ?? 0;
75
75
  scopeCounters.set(name, current + value);
76
76
  },
@@ -22,7 +22,7 @@ export declare function collectInlineParticipants(node: LayoutNode): LayoutNode[
22
22
  * Calculates the inline extent (start and end positions) of a node within its container.
23
23
  * Includes margins, borders, and padding in the calculation.
24
24
  */
25
- export declare function inlineExtentWithinContainer(node: LayoutNode, referenceWidth: number): {
25
+ export declare function inlineExtentWithinContainer(node: LayoutNode, referenceWidth: number, containerHeight?: number): {
26
26
  start: number;
27
27
  end: number;
28
28
  };
@@ -70,13 +70,14 @@ export function collectInlineParticipants(node) {
70
70
  * Calculates the inline extent (start and end positions) of a node within its container.
71
71
  * Includes margins, borders, and padding in the calculation.
72
72
  */
73
- export function inlineExtentWithinContainer(node, referenceWidth) {
74
- const marginLeft = resolveLength(node.style.marginLeft, referenceWidth, { auto: "zero" });
75
- const marginRight = resolveLength(node.style.marginRight, referenceWidth, { auto: "zero" });
76
- const paddingLeft = resolveLength(node.style.paddingLeft, referenceWidth, { auto: "zero" });
77
- const paddingRight = resolveLength(node.style.paddingRight, referenceWidth, { auto: "zero" });
78
- const borderLeft = resolveLength(node.style.borderLeft, referenceWidth, { auto: "zero" });
79
- const borderRight = resolveLength(node.style.borderRight, referenceWidth, { auto: "zero" });
73
+ export function inlineExtentWithinContainer(node, referenceWidth, containerHeight = referenceWidth) {
74
+ const containerRefs = { containerWidth: referenceWidth, containerHeight };
75
+ const marginLeft = resolveLength(node.style.marginLeft, referenceWidth, { auto: "zero", ...containerRefs });
76
+ const marginRight = resolveLength(node.style.marginRight, referenceWidth, { auto: "zero", ...containerRefs });
77
+ const paddingLeft = resolveLength(node.style.paddingLeft, referenceWidth, { auto: "zero", ...containerRefs });
78
+ const paddingRight = resolveLength(node.style.paddingRight, referenceWidth, { auto: "zero", ...containerRefs });
79
+ const borderLeft = resolveLength(node.style.borderLeft, referenceWidth, { auto: "zero", ...containerRefs });
80
+ const borderRight = resolveLength(node.style.borderRight, referenceWidth, { auto: "zero", ...containerRefs });
80
81
  const marginStart = node.box.x - paddingLeft - borderLeft - marginLeft;
81
82
  const width = node.box.contentWidth + paddingLeft + paddingRight + borderLeft + borderRight + marginLeft + marginRight;
82
83
  return {
@@ -8,9 +8,13 @@ import { resolveInlineTextAlign, shouldLayoutInlineChildren, collectInlinePartic
8
8
  import { getAlignmentStrategy } from "./text-alignment.js";
9
9
  import { BoundingBoxCalculator } from "./bounding-box-calculator.js";
10
10
  import { RunPlacer } from "./run-placer.js";
11
+ import { calculateBaseline } from "./font-baseline-calculator.js";
11
12
  import { createLayoutDebug } from "../debug.js";
13
+ import { containingBlock } from "../utils/node-math.js";
12
14
  export function layoutInlineFormattingContext(options) {
13
15
  const { container, inlineNodes, context, floatContext, contentX, contentWidth } = options;
16
+ const cb = containingBlock(container, context.env.viewport);
17
+ const containerRefs = { containerWidth: cb.width, containerHeight: cb.height };
14
18
  container.establishesIFC = true;
15
19
  const textAlign = container.style.display === Display.Inline
16
20
  ? undefined
@@ -18,7 +22,7 @@ export function layoutInlineFormattingContext(options) {
18
22
  const alignmentStrategy = getAlignmentStrategy(textAlign);
19
23
  const shouldApplyTextIndent = container.style.display !== Display.Inline;
20
24
  const resolvedTextIndent = shouldApplyTextIndent
21
- ? resolveLength(container.style.textIndent, contentWidth, { auto: "zero" })
25
+ ? resolveLength(container.style.textIndent, contentWidth, { auto: "zero", ...containerRefs })
22
26
  : 0;
23
27
  let firstLineTextIndentPending = shouldApplyTextIndent && resolvedTextIndent !== 0;
24
28
  const layoutCallback = (node, width, ctx) => layoutInlineChildrenIfNeeded(node, width, ctx);
@@ -34,6 +38,13 @@ export function layoutInlineFormattingContext(options) {
34
38
  const runPlacer = new RunPlacer(context.env.fontEmbedder);
35
39
  const placeRunsForLine = (parts, isLastLine) => {
36
40
  const offsetShift = alignmentStrategy.calculateOffset(parts.reduce((max, part) => Math.max(max, part.offset + part.item.width), 0), Math.max(availableWidth, 0));
41
+ // Compute a shared baseline from the container's font (CSS "strut")
42
+ const strutFontSize = container.style.fontSize ?? 16;
43
+ const strutFontFamily = container.style.fontFamily ?? "sans-serif";
44
+ const strutFontWeight = container.style.fontWeight ?? 400;
45
+ const strutFontStyle = container.style.fontStyle ?? "normal";
46
+ const strutMetrics = context.env.fontEmbedder?.getMetrics(strutFontFamily, strutFontWeight, strutFontStyle);
47
+ const lineBaseline = calculateBaseline(lineTop, strutFontSize, lineHeight, strutMetrics);
37
48
  runPlacer.placeRunsForLine(parts, {
38
49
  lineTop,
39
50
  lineHeight,
@@ -44,6 +55,7 @@ export function layoutInlineFormattingContext(options) {
44
55
  isLastLine,
45
56
  contentX,
46
57
  inlineOffsetStart: inlineOffset.start,
58
+ lineBaseline,
47
59
  });
48
60
  };
49
61
  const commitLine = (isLastLine) => {
@@ -118,7 +130,8 @@ export function layoutInlineFormattingContext(options) {
118
130
  // Text items
119
131
  if (workingItem.kind === "word" && workingItem.width > remaining) {
120
132
  const mode = workingItem.style?.overflowWrap ?? "normal";
121
- if (mode !== "normal" && remaining > 0) {
133
+ const wb = workingItem.style?.wordBreak ?? "normal";
134
+ if ((mode !== "normal" || wb === "break-all" || wb === "break-word") && remaining > 0) {
122
135
  const [head, tail] = splitWordItemToken(workingItem, remaining);
123
136
  if (head) {
124
137
  lineParts.push({ item: head, offset: cursorX });
@@ -220,7 +233,7 @@ function layoutInlineChildrenIfNeeded(node, containerWidth, context) {
220
233
  const contentHeight = Math.max(result.newCursorY, floatBottom);
221
234
  let maxInlineEnd = 0;
222
235
  for (const child of inlineChildren) {
223
- const extent = inlineExtentWithinContainer(child, containerWidth);
236
+ const extent = inlineExtentWithinContainer(child, containerWidth, containerWidth);
224
237
  maxInlineEnd = Math.max(maxInlineEnd, extent.end);
225
238
  }
226
239
  node.box.x = savedX;
@@ -14,6 +14,7 @@ export interface LineContext {
14
14
  isLastLine: boolean;
15
15
  contentX: number;
16
16
  inlineOffsetStart: number;
17
+ lineBaseline: number;
17
18
  }
18
19
  /**
19
20
  * Responsible for placing text runs and box items on lines.
@@ -1,7 +1,6 @@
1
1
  import { LayoutNode } from "../../dom/node.js";
2
2
  import { isBoxItem } from "./types.js";
3
3
  import { placeInlineItem } from "./layout.js";
4
- import { calculateBaseline } from "./font-baseline-calculator.js";
5
4
  /**
6
5
  * Responsible for placing text runs and box items on lines.
7
6
  * Tracks runs per node and handles both text and inline-block layouts.
@@ -42,15 +41,8 @@ export class RunPlacer {
42
41
  if (!node || !part.item.text) {
43
42
  continue;
44
43
  }
45
- // Calculate baseline based on the item's fontSize and lineHeight
46
- const fontSize = part.item.style?.fontSize ?? 16;
47
- const itemLineHeight = part.item.lineHeight ?? lineHeight;
48
- // Use calculateBaseline with font metrics when available
49
- const fontFamily = part.item.style?.fontFamily ?? "sans-serif";
50
- const fontWeight = part.item.style?.fontWeight ?? 400;
51
- const fontStyle = part.item.style?.fontStyle ?? "normal";
52
- const fontMetrics = this.fontEmbedder?.getMetrics(fontFamily, fontWeight, fontStyle);
53
- const lineBaseline = calculateBaseline(lineTop, fontSize, itemLineHeight, fontMetrics);
44
+ // Use the shared line baseline computed from the container's strut
45
+ const lineBaseline = lineContext.lineBaseline;
54
46
  const startX = lineStartX + part.offset;
55
47
  const run = {
56
48
  lineIndex,
@@ -18,11 +18,12 @@ export class DefaultOutOfFlowManager {
18
18
  const cb = containingBlock(node, env.viewport);
19
19
  const widthRef = cb.width;
20
20
  const heightRef = cb.height;
21
+ const containerRefs = { containerWidth: widthRef, containerHeight: heightRef };
21
22
  const resolveInset = (value, reference) => {
22
23
  if (value === undefined || isAutoLength(value)) {
23
24
  return undefined;
24
25
  }
25
- return resolveLength(value, reference, { auto: "zero" });
26
+ return resolveLength(value, reference, { auto: "zero", ...containerRefs });
26
27
  };
27
28
  const left = resolveInset(node.style.left, widthRef);
28
29
  const right = resolveInset(node.style.right, widthRef);
@@ -46,7 +47,30 @@ export class DefaultOutOfFlowManager {
46
47
  else if (bottom !== undefined) {
47
48
  y = cb.y + cb.height - measuredHeight - bottom;
48
49
  }
50
+ const deltaX = x - node.box.x;
51
+ const deltaY = y - node.box.y;
49
52
  node.box.x = x;
50
53
  node.box.y = y;
54
+ // Offset all descendants so their coordinates stay consistent
55
+ // with the repositioned parent (children were laid out relative
56
+ // to the old position).
57
+ if (deltaX !== 0 || deltaY !== 0) {
58
+ offsetDescendants(node, deltaX, deltaY);
59
+ }
51
60
  }
52
61
  }
62
+ function offsetDescendants(node, deltaX, deltaY) {
63
+ node.walk((desc) => {
64
+ if (desc !== node) {
65
+ desc.box.x += deltaX;
66
+ desc.box.y += deltaY;
67
+ }
68
+ desc.box.baseline += deltaY;
69
+ if (desc.inlineRuns && desc.inlineRuns.length > 0) {
70
+ for (const run of desc.inlineRuns) {
71
+ run.startX += deltaX;
72
+ run.baseline += deltaY;
73
+ }
74
+ }
75
+ });
76
+ }
@@ -1,6 +1,6 @@
1
1
  import { LayoutNode } from "../../dom/node.js";
2
2
  import { Display, FloatMode } from "../../css/enums.js";
3
- import { containingBlock, establishesBFC, horizontalNonContent, horizontalMargin, inFlow, resolveBlockAutoMargins, resolveWidthBlock, verticalNonContent, } from "../utils/node-math.js";
3
+ import { adjustForBoxSizing, applyMinHeight, containingBlock, establishesBFC, horizontalNonContent, horizontalMargin, inFlow, resolveBlockAutoMargins, resolveWidthBlock, verticalNonContent, } from "../utils/node-math.js";
4
4
  import { resolveLength } from "../../css/length.js";
5
5
  import { canCollapseMarginEnd, canCollapseMarginStart, collapsedGapBetween, effectiveMarginBottom, effectiveMarginTop, findFirstMarginCollapsibleChild, findLastMarginCollapsibleChild, } from "../utils/margin.js";
6
6
  import { finalizeOverflow } from "../utils/overflow.js";
@@ -21,29 +21,30 @@ export class BlockLayoutStrategy {
21
21
  const layoutDebug = createLayoutDebug(context);
22
22
  const contentMeasurer = new ContentMeasurer(layoutDebug);
23
23
  const cb = containingBlock(node, context.env.viewport);
24
+ const containerRefs = { containerWidth: cb.width, containerHeight: cb.height };
24
25
  node.establishesBFC = establishesBFC(node);
25
- let contentWidth = resolveWidthBlock(node, cb.width);
26
+ let contentWidth = resolveWidthBlock(node, cb.width, cb.height);
26
27
  const debugTag = node.tagName ?? "(anonymous)";
27
28
  if (node.style.display === Display.InlineBlock) {
28
29
  layoutDebug(`[BlockLayout] start inline-block tag=${debugTag} style.width=${node.style.width} resolvedContentWidth=${contentWidth} cb.width=${cb.width}`);
29
30
  }
30
31
  const availableWidth = contentWidth;
31
32
  node.box.contentWidth = contentWidth;
32
- const horizontalExtras = horizontalNonContent(node, contentWidth);
33
- const horizontalMarginSize = horizontalMargin(node, contentWidth);
33
+ const horizontalExtras = horizontalNonContent(node, contentWidth, cb.height);
34
+ const horizontalMarginSize = horizontalMargin(node, contentWidth, cb.height);
34
35
  node.box.borderBoxWidth = contentWidth + horizontalExtras;
35
36
  node.box.marginBoxWidth = node.box.borderBoxWidth + horizontalMarginSize;
36
- const paddingLeft = resolveLength(node.style.paddingLeft, contentWidth, { auto: "zero" });
37
- const borderLeft = resolveLength(node.style.borderLeft, contentWidth, { auto: "zero" });
38
- const paddingTop = resolveLength(node.style.paddingTop, contentWidth, { auto: "zero" });
39
- const borderTop = resolveLength(node.style.borderTop, contentWidth, { auto: "zero" });
37
+ const paddingLeft = resolveLength(node.style.paddingLeft, contentWidth, { auto: "zero", ...containerRefs });
38
+ const borderLeft = resolveLength(node.style.borderLeft, contentWidth, { auto: "zero", ...containerRefs });
39
+ const paddingTop = resolveLength(node.style.paddingTop, contentWidth, { auto: "zero", ...containerRefs });
40
+ const borderTop = resolveLength(node.style.borderTop, contentWidth, { auto: "zero", ...containerRefs });
40
41
  const contentX = node.box.x + borderLeft + paddingLeft;
41
- const collapseTopWithChildren = canCollapseMarginStart(node, contentWidth);
42
- const collapseBottomWithChildren = canCollapseMarginEnd(node, contentWidth);
42
+ const collapseTopWithChildren = canCollapseMarginStart(node, contentWidth, cb.height);
43
+ const collapseBottomWithChildren = canCollapseMarginEnd(node, contentWidth, cb.height);
43
44
  const firstCollapsibleChild = collapseTopWithChildren ? findFirstMarginCollapsibleChild(node) : undefined;
44
45
  const lastCollapsibleChild = collapseBottomWithChildren ? findLastMarginCollapsibleChild(node) : undefined;
45
- const topCollapseAmount = collapseTopWithChildren && firstCollapsibleChild ? effectiveMarginTop(firstCollapsibleChild, contentWidth) : 0;
46
- const bottomCollapseAmount = collapseBottomWithChildren && lastCollapsibleChild ? effectiveMarginBottom(lastCollapsibleChild, contentWidth) : 0;
46
+ const topCollapseAmount = collapseTopWithChildren && firstCollapsibleChild ? effectiveMarginTop(firstCollapsibleChild, contentWidth, cb.height) : 0;
47
+ const bottomCollapseAmount = collapseBottomWithChildren && lastCollapsibleChild ? effectiveMarginBottom(lastCollapsibleChild, contentWidth, cb.height) : 0;
47
48
  let cursorY = node.box.y + paddingTop + borderTop;
48
49
  let previousBottomMargin = 0;
49
50
  const floatContext = new FloatContext();
@@ -61,6 +62,7 @@ export class BlockLayoutStrategy {
61
62
  context,
62
63
  contentX,
63
64
  contentWidth,
65
+ contentHeight: cb.height,
64
66
  startY: cursorY,
65
67
  });
66
68
  previousBottomMargin = 0;
@@ -94,10 +96,10 @@ export class BlockLayoutStrategy {
94
96
  index = lookahead - 1;
95
97
  continue;
96
98
  }
97
- const childMarginTopRaw = resolveLength(child.style.marginTop, contentWidth, { auto: "zero" });
98
- const childMarginBottomRaw = resolveLength(child.style.marginBottom, contentWidth, { auto: "zero" });
99
- const collapsedMarginTop = effectiveMarginTop(child, contentWidth);
100
- const collapsedMarginBottom = effectiveMarginBottom(child, contentWidth);
99
+ const childMarginTopRaw = resolveLength(child.style.marginTop, contentWidth, { auto: "zero", ...containerRefs });
100
+ const childMarginBottomRaw = resolveLength(child.style.marginBottom, contentWidth, { auto: "zero", ...containerRefs });
101
+ const collapsedMarginTop = effectiveMarginTop(child, contentWidth, cb.height);
102
+ const collapsedMarginBottom = effectiveMarginBottom(child, contentWidth, cb.height);
101
103
  let gap = collapsedGapBetween(previousBottomMargin, collapsedMarginTop, node.establishesBFC);
102
104
  if (collapseTopWithChildren && child === firstCollapsibleChild) {
103
105
  gap -= topCollapseAmount;
@@ -105,7 +107,7 @@ export class BlockLayoutStrategy {
105
107
  child.box.x = contentX;
106
108
  child.box.y = cursorY + gap;
107
109
  context.layoutChild(child);
108
- const { marginLeft: usedMarginLeft, marginRight: usedMarginRight } = resolveBlockAutoMargins(contentWidth, child.box.borderBoxWidth, child.style.marginLeft, child.style.marginRight);
110
+ const { marginLeft: usedMarginLeft, marginRight: usedMarginRight } = resolveBlockAutoMargins(contentWidth, child.box.borderBoxWidth, child.style.marginLeft, child.style.marginRight, cb.height);
109
111
  child.box.usedMarginLeft = usedMarginLeft;
110
112
  child.box.usedMarginRight = usedMarginRight;
111
113
  const deltaX = usedMarginLeft;
@@ -122,14 +124,21 @@ export class BlockLayoutStrategy {
122
124
  previousBottomMargin = 0;
123
125
  }
124
126
  }
125
- const measurement = contentMeasurer.measureInFlowWidth(node, contentWidth, contentX);
127
+ // When the parent cannot collapse its bottom margin with children
128
+ // (e.g. it has border-bottom or padding-bottom), the last child's
129
+ // bottom margin is contained inside the parent and must be included
130
+ // in the content height.
131
+ if (!collapseBottomWithChildren && previousBottomMargin !== 0) {
132
+ cursorY += previousBottomMargin;
133
+ }
134
+ const measurement = contentMeasurer.measureInFlowWidth(node, contentWidth, contentX, cb.height);
126
135
  if (Number.isFinite(measurement.width)) {
127
136
  const intrinsicWidth = Math.max(0, measurement.width);
128
137
  node.box.scrollWidth = Math.max(node.box.scrollWidth, intrinsicWidth);
129
138
  if (node.style.display === Display.InlineBlock && node.style.width === "auto") {
130
- const minWidth = node.style.minWidth !== undefined ? resolveLength(node.style.minWidth, cb.width, { auto: "zero" }) : undefined;
139
+ const minWidth = node.style.minWidth !== undefined ? resolveLength(node.style.minWidth, cb.width, { auto: "zero", ...containerRefs }) : undefined;
131
140
  const maxWidth = node.style.maxWidth !== undefined
132
- ? resolveLength(node.style.maxWidth, cb.width, { auto: "reference" })
141
+ ? resolveLength(node.style.maxWidth, cb.width, { auto: "reference", ...containerRefs })
133
142
  : undefined;
134
143
  let targetContentWidth = intrinsicWidth;
135
144
  targetContentWidth = Math.min(targetContentWidth, availableWidth);
@@ -162,14 +171,16 @@ export class BlockLayoutStrategy {
162
171
  const effectiveCursor = Math.max(cursorY, floatBottom);
163
172
  node.box.contentHeight = Math.max(0, effectiveCursor - (node.box.y + borderTop) - paddingTop);
164
173
  if (node.style.height !== "auto") {
165
- node.box.contentHeight = resolveLength(node.style.height, cb.height, { auto: "zero" });
174
+ const vertExtras = verticalNonContent(node, cb.height, cb.width);
175
+ node.box.contentHeight = adjustForBoxSizing(resolveLength(node.style.height, cb.height, { auto: "zero", ...containerRefs }), node.style.boxSizing, vertExtras);
166
176
  }
167
- const verticalExtras = verticalNonContent(node, contentWidth);
177
+ const verticalExtras = verticalNonContent(node, cb.height, cb.width);
178
+ node.box.contentHeight = applyMinHeight(node.box.contentHeight, node, cb.height, verticalExtras, containerRefs);
168
179
  node.box.borderBoxHeight = node.box.contentHeight + verticalExtras;
169
180
  node.box.marginBoxHeight =
170
181
  node.box.borderBoxHeight +
171
- resolveLength(node.style.marginTop, contentWidth, { auto: "zero" }) +
172
- resolveLength(node.style.marginBottom, contentWidth, { auto: "zero" });
182
+ resolveLength(node.style.marginTop, cb.height, { auto: "zero", ...containerRefs }) +
183
+ resolveLength(node.style.marginBottom, cb.height, { auto: "zero", ...containerRefs });
173
184
  finalizeOverflow(node);
174
185
  }
175
186
  }