pagyra-js 0.0.19 → 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.
- package/README.md +55 -0
- package/dist/assets/fonts/licenses/selawik/SIL Open Font License.txt +43 -0
- package/dist/assets/fonts/ttf/arimo/Arimo-Bold.ttf +0 -0
- package/dist/assets/fonts/ttf/arimo/Arimo-BoldItalic.ttf +0 -0
- package/dist/assets/fonts/ttf/arimo/Arimo-Italic.ttf +0 -0
- package/dist/assets/fonts/ttf/arimo/Arimo-Regular.ttf +0 -0
- package/dist/assets/fonts/ttf/cinzeldecorative/CinzelDecorative-Black.ttf +0 -0
- package/dist/assets/fonts/ttf/cinzeldecorative/CinzelDecorative-Bold.ttf +0 -0
- package/dist/assets/fonts/ttf/cinzeldecorative/CinzelDecorative-Regular.ttf +0 -0
- package/dist/assets/fonts/ttf/dejavu/DejaVuSans.ttf +0 -0
- package/dist/assets/fonts/ttf/firecode/FiraCode-Bold.ttf +0 -0
- package/dist/assets/fonts/ttf/firecode/FiraCode-Light.ttf +0 -0
- package/dist/assets/fonts/ttf/firecode/FiraCode-Medium.ttf +0 -0
- package/dist/assets/fonts/ttf/firecode/FiraCode-Regular.ttf +0 -0
- package/dist/assets/fonts/ttf/firecode/FiraCode-SemiBold.ttf +0 -0
- package/dist/assets/fonts/ttf/notoemoji/NotoEmoji-Bold.ttf +0 -0
- package/dist/assets/fonts/ttf/notoemoji/NotoEmoji-Light.ttf +0 -0
- package/dist/assets/fonts/ttf/notoemoji/NotoEmoji-Medium.ttf +0 -0
- package/dist/assets/fonts/ttf/notoemoji/NotoEmoji-Regular.ttf +0 -0
- package/dist/assets/fonts/ttf/notoemoji/NotoEmoji-SemiBold.ttf +0 -0
- package/dist/assets/fonts/ttf/notosans/NotoSans-Regular.ttf +0 -0
- package/dist/assets/fonts/ttf/roboto/Roboto-Bold.ttf +0 -0
- package/dist/assets/fonts/ttf/roboto/Roboto-BoldItalic.ttf +0 -0
- package/dist/assets/fonts/ttf/roboto/Roboto-Italic.ttf +0 -0
- package/dist/assets/fonts/ttf/roboto/Roboto-Regular.ttf +0 -0
- package/dist/assets/fonts/ttf/selawik/selawk.ttf +0 -0
- package/dist/assets/fonts/ttf/selawik/selawkb.ttf +0 -0
- package/dist/assets/fonts/ttf/selawik/selawkl.ttf +0 -0
- package/dist/assets/fonts/ttf/selawik/selawksb.ttf +0 -0
- package/dist/assets/fonts/ttf/selawik/selawksl.ttf +0 -0
- package/dist/assets/fonts/ttf/stixtwomath/STIXTwoMath-Regular.ttf +0 -0
- package/dist/assets/fonts/ttf/tinos/Tinos-Bold.ttf +0 -0
- package/dist/assets/fonts/ttf/tinos/Tinos-BoldItalic.ttf +0 -0
- package/dist/assets/fonts/ttf/tinos/Tinos-Italic.ttf +0 -0
- package/dist/assets/fonts/ttf/tinos/Tinos-Regular.ttf +0 -0
- package/dist/assets/fonts/woff/lato/lato-latin-400-italic.woff +0 -0
- package/dist/assets/fonts/woff/lato/lato-latin-400-normal.woff +0 -0
- package/dist/assets/fonts/woff/lato/lato-latin-700-italic.woff +0 -0
- package/dist/assets/fonts/woff/lato/lato-latin-700-normal.woff +0 -0
- package/dist/assets/fonts/woff2/caveat/Caveat-Bold.woff2 +0 -0
- package/dist/assets/fonts/woff2/caveat/Caveat-Regular.woff2 +0 -0
- package/dist/assets/fonts/woff2/lato/lato-latin-400-italic.woff2 +0 -0
- package/dist/assets/fonts/woff2/lato/lato-latin-400-normal.woff2 +0 -0
- package/dist/assets/fonts/woff2/lato/lato-latin-700-italic.woff2 +0 -0
- package/dist/assets/fonts/woff2/lato/lato-latin-700-normal.woff2 +0 -0
- package/dist/browser/pagyra.min.js +34 -34
- package/dist/browser/pagyra.min.js.map +4 -4
- package/dist/playground/server.js +2 -0
- package/dist/src/css/compute-style/base-options.d.ts +7 -0
- package/dist/src/css/compute-style/base-options.js +24 -0
- package/dist/src/css/compute-style/declarations.d.ts +10 -0
- package/dist/src/css/compute-style/declarations.js +77 -0
- package/dist/src/css/compute-style/decoration.d.ts +8 -0
- package/dist/src/css/compute-style/decoration.js +55 -0
- package/dist/src/css/compute-style/defaults.d.ts +3 -0
- package/dist/src/css/compute-style/defaults.js +34 -0
- package/dist/src/css/compute-style/display.d.ts +3 -0
- package/dist/src/css/compute-style/display.js +85 -0
- package/dist/src/css/compute-style/float.d.ts +2 -0
- package/dist/src/css/compute-style/float.js +13 -0
- package/dist/src/css/compute-style/font.d.ts +12 -0
- package/dist/src/css/compute-style/font.js +57 -0
- package/dist/src/css/compute-style/overrides.d.ts +3 -0
- package/dist/src/css/compute-style/overrides.js +241 -0
- package/dist/src/css/compute-style.d.ts +2 -0
- package/dist/src/css/compute-style.js +34 -487
- package/dist/src/css/enums.d.ts +4 -0
- package/dist/src/css/enums.js +5 -0
- package/dist/src/css/layout-property-resolver.js +30 -18
- package/dist/src/css/length.d.ts +26 -2
- package/dist/src/css/length.js +48 -0
- package/dist/src/css/parsers/background-parser.js +1 -1
- package/dist/src/css/parsers/calc-parser.d.ts +2 -0
- package/dist/src/css/parsers/calc-parser.js +310 -0
- package/dist/src/css/parsers/content-parser.d.ts +2 -1
- package/dist/src/css/parsers/content-parser.js +7 -2
- package/dist/src/css/parsers/dimension-parser.js +37 -18
- package/dist/src/css/parsers/display-flex-parser.d.ts +4 -0
- package/dist/src/css/parsers/display-flex-parser.js +97 -0
- package/dist/src/css/parsers/filter-parser.d.ts +14 -0
- package/dist/src/css/parsers/filter-parser.js +255 -0
- package/dist/src/css/parsers/grid-parser-extended.d.ts +1 -0
- package/dist/src/css/parsers/grid-parser-extended.js +40 -1
- package/dist/src/css/parsers/grid-parser.d.ts +5 -2
- package/dist/src/css/parsers/grid-parser.js +71 -7
- package/dist/src/css/parsers/length-parser.d.ts +8 -3
- package/dist/src/css/parsers/length-parser.js +45 -2
- package/dist/src/css/parsers/margin-block-parser.js +3 -3
- package/dist/src/css/parsers/margin-parser.js +3 -3
- package/dist/src/css/parsers/padding-block-parser.js +3 -3
- package/dist/src/css/parsers/padding-inline-parser.js +3 -3
- package/dist/src/css/parsers/padding-parser.js +6 -6
- package/dist/src/css/parsers/position-parser.js +2 -22
- package/dist/src/css/parsers/register-parsers.js +29 -2
- package/dist/src/css/parsers/word-break-parser.d.ts +2 -0
- package/dist/src/css/parsers/word-break-parser.js +23 -0
- package/dist/src/css/properties/grid.d.ts +16 -2
- package/dist/src/css/properties/layout.d.ts +3 -1
- package/dist/src/css/properties/layout.js +1 -1
- package/dist/src/css/properties/misc.d.ts +5 -0
- package/dist/src/css/properties/typography.d.ts +3 -0
- package/dist/src/css/properties/visual.d.ts +36 -0
- package/dist/src/css/shorthands/box-shorthand.d.ts +2 -2
- package/dist/src/css/style-inheritance.d.ts +2 -1
- package/dist/src/css/style-inheritance.js +1 -0
- package/dist/src/css/style.d.ts +30 -10
- package/dist/src/css/style.js +8 -1
- package/dist/src/css/ua-defaults/base-defaults.d.ts +1 -0
- package/dist/src/css/ua-defaults/base-defaults.js +10 -1
- package/dist/src/css/ua-defaults/element-defaults.js +0 -2
- package/dist/src/html/css/parse-css.d.ts +2 -0
- package/dist/src/html/css/parse-css.js +32 -3
- package/dist/src/html/dom-converter/background-images.d.ts +3 -0
- package/dist/src/html/dom-converter/background-images.js +88 -0
- package/dist/src/html/dom-converter/convert-dom-node.d.ts +5 -0
- package/dist/src/html/dom-converter/convert-dom-node.js +81 -0
- package/dist/src/html/dom-converter/handlers/br-handler.d.ts +2 -0
- package/dist/src/html/dom-converter/handlers/br-handler.js +20 -0
- package/dist/src/html/dom-converter/handlers/form-control-handler.d.ts +2 -0
- package/dist/src/html/dom-converter/handlers/form-control-handler.js +28 -0
- package/dist/src/html/dom-converter/handlers/img-handler.d.ts +2 -0
- package/dist/src/html/dom-converter/handlers/img-handler.js +4 -0
- package/dist/src/html/dom-converter/handlers/index.d.ts +4 -0
- package/dist/src/html/dom-converter/handlers/index.js +19 -0
- package/dist/src/html/dom-converter/handlers/svg-handler.d.ts +2 -0
- package/dist/src/html/dom-converter/handlers/svg-handler.js +32 -0
- package/dist/src/html/dom-converter/handlers/types.d.ts +12 -0
- package/dist/src/html/dom-converter/handlers/types.js +2 -0
- package/dist/src/html/dom-converter/helpers.d.ts +7 -0
- package/dist/src/html/dom-converter/helpers.js +35 -0
- package/dist/src/html/dom-converter/index.d.ts +1 -0
- package/dist/src/html/dom-converter/index.js +1 -0
- package/dist/src/html/dom-converter/pseudo-elements.d.ts +6 -0
- package/dist/src/html/dom-converter/pseudo-elements.js +48 -0
- package/dist/src/html/dom-converter/text.d.ts +15 -0
- package/dist/src/html/dom-converter/text.js +170 -0
- package/dist/src/html/dom-converter.d.ts +1 -5
- package/dist/src/html/dom-converter.js +1 -412
- package/dist/src/html/image-converter.d.ts +5 -0
- package/dist/src/html/image-converter.js +8 -3
- package/dist/src/html-to-pdf/document-css.d.ts +14 -0
- package/dist/src/html-to-pdf/document-css.js +45 -0
- package/dist/src/html-to-pdf/fonts.d.ts +16 -0
- package/dist/src/html-to-pdf/fonts.js +74 -0
- package/dist/src/html-to-pdf/header-footer.d.ts +14 -0
- package/dist/src/html-to-pdf/header-footer.js +101 -0
- package/dist/src/html-to-pdf/html-parser.d.ts +6 -0
- package/dist/src/html-to-pdf/html-parser.js +81 -0
- package/dist/src/html-to-pdf/index.d.ts +3 -0
- package/dist/src/html-to-pdf/index.js +2 -0
- package/dist/src/html-to-pdf/layout-build.d.ts +37 -0
- package/dist/src/html-to-pdf/layout-build.js +73 -0
- package/dist/src/html-to-pdf/prepare-html-render.d.ts +2 -0
- package/dist/src/html-to-pdf/prepare-html-render.js +121 -0
- package/dist/src/html-to-pdf/render-finalize.d.ts +15 -0
- package/dist/src/html-to-pdf/render-finalize.js +27 -0
- package/dist/src/html-to-pdf/render-html-to-pdf.d.ts +3 -0
- package/dist/src/html-to-pdf/render-html-to-pdf.js +25 -0
- package/dist/src/html-to-pdf/resource-loader.d.ts +6 -0
- package/dist/src/html-to-pdf/resource-loader.js +120 -0
- package/dist/src/html-to-pdf/types.d.ts +38 -0
- package/dist/src/html-to-pdf/types.js +2 -0
- package/dist/src/html-to-pdf.d.ts +1 -37
- package/dist/src/html-to-pdf.js +1 -537
- package/dist/src/image/js-png-backend.d.ts +7 -0
- package/dist/src/image/js-png-backend.js +9 -0
- package/dist/src/image/png-backend.d.ts +5 -0
- package/dist/src/image/png-backend.js +1 -0
- package/dist/src/image/png-wasm-loader.d.ts +5 -0
- package/dist/src/image/png-wasm-loader.js +59 -0
- package/dist/src/image/wasm/png_decoder_wasm.d.ts +8 -0
- package/dist/src/image/wasm/png_decoder_wasm.js +24 -0
- package/dist/src/image/wasm/png_decoder_wasm_bg.js +16 -0
- package/dist/src/image/wasm-png-backend.d.ts +6 -0
- package/dist/src/image/wasm-png-backend.js +17 -0
- package/dist/src/layout/counter.d.ts +1 -2
- package/dist/src/layout/counter.js +18 -18
- package/dist/src/layout/inline/inline-utils.d.ts +1 -1
- package/dist/src/layout/inline/inline-utils.js +8 -7
- package/dist/src/layout/inline/layout.js +16 -3
- package/dist/src/layout/inline/run-placer.d.ts +1 -0
- package/dist/src/layout/inline/run-placer.js +2 -10
- package/dist/src/layout/pipeline/out-of-flow-manager.js +25 -1
- package/dist/src/layout/strategies/block.js +35 -24
- package/dist/src/layout/strategies/flex.js +305 -61
- package/dist/src/layout/strategies/form.d.ts +2 -0
- package/dist/src/layout/strategies/form.js +38 -13
- package/dist/src/layout/strategies/grid.js +166 -29
- package/dist/src/layout/strategies/image.js +53 -27
- package/dist/src/layout/strategies/inline.js +26 -21
- package/dist/src/layout/strategies/table.js +26 -18
- package/dist/src/layout/utils/content-measurer.d.ts +1 -1
- package/dist/src/layout/utils/content-measurer.js +8 -7
- package/dist/src/layout/utils/floats.d.ts +1 -0
- package/dist/src/layout/utils/floats.js +14 -12
- package/dist/src/layout/utils/margin.d.ts +4 -4
- package/dist/src/layout/utils/margin.js +20 -16
- package/dist/src/layout/utils/node-math.d.ts +12 -6
- package/dist/src/layout/utils/node-math.js +71 -41
- package/dist/src/layout/utils/sizing.js +2 -1
- package/dist/src/pdf/font-subset/font-registry.d.ts +6 -0
- package/dist/src/pdf/font-subset/font-registry.js +30 -2
- package/dist/src/pdf/header-footer-painter.d.ts +2 -0
- package/dist/src/pdf/header-footer-painter.js +52 -4
- package/dist/src/pdf/header-footer-renderer.js +12 -1
- package/dist/src/pdf/layout-tree-builder.js +5 -1
- package/dist/src/pdf/page-painter.js +13 -0
- package/dist/src/pdf/pagination.js +2 -2
- package/dist/src/pdf/renderer/box-painter.js +28 -3
- package/dist/src/pdf/renderer/page-paint.js +12 -3
- package/dist/src/pdf/renderers/radius-utils.js +31 -38
- package/dist/src/pdf/renderers/shape-renderer.js +1 -1
- package/dist/src/pdf/renderers/shape-utils.js +1 -1
- package/dist/src/pdf/renderers/text-renderer.d.ts +9 -1
- package/dist/src/pdf/renderers/text-renderer.js +36 -2
- package/dist/src/pdf/stacking/build-stacking-contexts.js +1 -2
- package/dist/src/pdf/stacking/resolve-paint-order.d.ts +5 -6
- package/dist/src/pdf/stacking/resolve-paint-order.js +29 -9
- package/dist/src/pdf/stacking/types.d.ts +14 -0
- package/dist/src/pdf/svg/shape-renderer.js +47 -20
- package/dist/src/pdf/types.d.ts +7 -1
- package/dist/src/pdf/utils/border-radius-utils.js +31 -38
- package/dist/src/pdf/utils/color-utils.js +17 -2
- package/dist/src/pdf/utils/filter-utils.d.ts +29 -0
- package/dist/src/pdf/utils/filter-utils.js +85 -0
- package/dist/src/pdf/utils/node-text-run-factory.js +1 -1
- package/dist/src/pdf/utils/text-layout-adjuster.d.ts +0 -8
- package/dist/src/pdf/utils/text-layout-adjuster.js +12 -9
- package/dist/src/shim/css-browser.d.ts +14 -9
- package/dist/src/shim/css-browser.js +50 -39
- package/dist/src/units/units.d.ts +1 -1
- package/dist/tests/css/box-sizing.spec.d.ts +1 -0
- package/dist/tests/css/box-sizing.spec.js +46 -0
- package/dist/tests/css/calc-parser.spec.d.ts +1 -0
- package/dist/tests/css/calc-parser.spec.js +68 -0
- package/dist/tests/css/container-query-units.spec.d.ts +1 -0
- package/dist/tests/css/container-query-units.spec.js +64 -0
- package/dist/tests/css/content-parser.spec.js +13 -0
- package/dist/tests/css/filter-parser.spec.d.ts +1 -0
- package/dist/tests/css/filter-parser.spec.js +116 -0
- package/dist/tests/css/flex-shorthand.spec.d.ts +1 -0
- package/dist/tests/css/flex-shorthand.spec.js +45 -0
- package/dist/tests/css/grid-clamp.spec.d.ts +1 -0
- package/dist/tests/css/grid-clamp.spec.js +82 -0
- package/dist/tests/css/parse-css-pseudo.spec.d.ts +1 -0
- package/dist/tests/css/parse-css-pseudo.spec.js +26 -0
- package/dist/tests/helpers/render-utils.d.ts +18 -2
- package/dist/tests/helpers/render-utils.js +25 -12
- package/dist/tests/html/dom-converter-pseudo-elements.spec.d.ts +1 -0
- package/dist/tests/html/dom-converter-pseudo-elements.spec.js +33 -0
- package/dist/tests/html/dom-converter-text.spec.d.ts +1 -0
- package/dist/tests/html/dom-converter-text.spec.js +67 -0
- package/dist/tests/image/png-backend.spec.d.ts +1 -0
- package/dist/tests/image/png-backend.spec.js +34 -0
- package/dist/tests/layout/box-sizing.spec.d.ts +1 -0
- package/dist/tests/layout/box-sizing.spec.js +75 -0
- package/dist/tests/layout/calc-padding.spec.d.ts +1 -0
- package/dist/tests/layout/calc-padding.spec.js +19 -0
- package/dist/tests/layout/container-query-units.spec.d.ts +1 -0
- package/dist/tests/layout/container-query-units.spec.js +24 -0
- package/dist/tests/layout/flex-auto-height.spec.d.ts +1 -0
- package/dist/tests/layout/flex-auto-height.spec.js +35 -0
- package/dist/tests/layout/flex-wrap-cards.spec.d.ts +1 -0
- package/dist/tests/layout/flex-wrap-cards.spec.js +16 -0
- package/dist/tests/layout/flex-wrap-grow-align-content.spec.d.ts +1 -0
- package/dist/tests/layout/flex-wrap-grow-align-content.spec.js +20 -0
- package/dist/tests/layout/grid-clamp-gap.spec.d.ts +1 -0
- package/dist/tests/layout/grid-clamp-gap.spec.js +22 -0
- package/dist/tests/layout/inline-fragments.spec.js +38 -0
- package/dist/tests/layout/paged-body-margin.spec.d.ts +1 -0
- package/dist/tests/layout/paged-body-margin.spec.js +92 -0
- package/dist/tests/layout/pseudo-counters-generated-content.spec.d.ts +1 -0
- package/dist/tests/layout/pseudo-counters-generated-content.spec.js +51 -0
- package/dist/tests/layout/responsive-clamp-grid-parity.spec.d.ts +1 -0
- package/dist/tests/layout/responsive-clamp-grid-parity.spec.js +75 -0
- package/dist/tests/layout/run-placer-baseline.spec.js +13 -11
- package/dist/tests/pdf/backdrop-filter-noop.spec.d.ts +1 -0
- package/dist/tests/pdf/backdrop-filter-noop.spec.js +140 -0
- package/dist/tests/pdf/filter-drop-shadow.spec.d.ts +1 -0
- package/dist/tests/pdf/filter-drop-shadow.spec.js +74 -0
- package/dist/tests/pdf/filter-opacity.spec.d.ts +1 -0
- package/dist/tests/pdf/filter-opacity.spec.js +30 -0
- package/dist/tests/pdf/font-subset-registry-key.spec.d.ts +1 -0
- package/dist/tests/pdf/font-subset-registry-key.spec.js +66 -0
- package/dist/tests/pdf/header-footer-clip-overflow.spec.d.ts +1 -0
- package/dist/tests/pdf/header-footer-clip-overflow.spec.js +45 -0
- package/dist/tests/pdf/selawik-opt-in.spec.d.ts +1 -0
- package/dist/tests/pdf/selawik-opt-in.spec.js +106 -0
- package/dist/tests/pdf/system-ui-fallback-subset-regression.spec.d.ts +1 -0
- package/dist/tests/pdf/system-ui-fallback-subset-regression.spec.js +39 -0
- package/dist/tests/pdf/text-renderer-fallback.spec.js +55 -0
- package/dist/tests/pdf/text-transform-matrix.spec.js +8 -7
- 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
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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(
|
|
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
|
-
|
|
73
|
-
|
|
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
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
const
|
|
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
|
-
|
|
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;
|
|
@@ -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
|
-
//
|
|
46
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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,
|
|
172
|
-
resolveLength(node.style.marginBottom,
|
|
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
|
}
|