html2canvas-pro 2.5.0 → 2.5.2

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 (56) hide show
  1. package/README.md +14 -2
  2. package/dist/html2canvas-pro.cjs +2198 -1536
  3. package/dist/html2canvas-pro.cjs.map +1 -1
  4. package/dist/html2canvas-pro.esm.js +2198 -1536
  5. package/dist/html2canvas-pro.esm.js.map +1 -1
  6. package/dist/html2canvas-pro.js +2202 -1537
  7. package/dist/html2canvas-pro.js.map +1 -1
  8. package/dist/html2canvas-pro.min.js +6 -5
  9. package/dist/types/core/cache-storage.d.ts +24 -2
  10. package/dist/types/core/constants.d.ts +11 -0
  11. package/dist/types/core/context.d.ts +9 -1
  12. package/dist/types/core/features.d.ts +9 -5
  13. package/dist/types/core/logger.d.ts +0 -3
  14. package/dist/types/core/origin-checker.d.ts +7 -4
  15. package/dist/types/core/validator.d.ts +0 -2
  16. package/dist/types/css/grouped/background-styles.d.ts +4 -0
  17. package/dist/types/css/grouped/border-styles.d.ts +4 -0
  18. package/dist/types/css/grouped/font-styles.d.ts +4 -0
  19. package/dist/types/css/grouped/layout-styles.d.ts +4 -0
  20. package/dist/types/css/index.d.ts +4 -0
  21. package/dist/types/css/property-descriptor.d.ts +11 -3
  22. package/dist/types/css/property-descriptors/scale.d.ts +9 -0
  23. package/dist/types/css/property-descriptors/translate.d.ts +10 -0
  24. package/dist/types/css/syntax/tokenizer.d.ts +8 -0
  25. package/dist/types/css/types/color-utilities.d.ts +21 -0
  26. package/dist/types/css/types/functions/color-mix.d.ts +17 -0
  27. package/dist/types/css/types/functions/conic-gradient.d.ts +6 -0
  28. package/dist/types/css/types/image.d.ts +4 -2
  29. package/dist/types/dom/adopted-styles.d.ts +23 -0
  30. package/dist/types/dom/document-cloner.d.ts +12 -0
  31. package/dist/types/dom/dom-normalizer.d.ts +2 -0
  32. package/dist/types/dom/elements/li-element-container.d.ts +2 -2
  33. package/dist/types/dom/elements/ol-element-container.d.ts +2 -2
  34. package/dist/types/dom/elements/select-element-container.d.ts +2 -2
  35. package/dist/types/dom/elements/textarea-element-container.d.ts +2 -2
  36. package/dist/types/dom/iframe-mount.d.ts +17 -0
  37. package/dist/types/dom/node-parser.d.ts +2 -2
  38. package/dist/types/dom/replaced-elements/canvas-element-container.d.ts +2 -2
  39. package/dist/types/dom/replaced-elements/iframe-element-container.d.ts +2 -2
  40. package/dist/types/dom/replaced-elements/image-element-container.d.ts +2 -2
  41. package/dist/types/dom/replaced-elements/input-element-container.d.ts +3 -3
  42. package/dist/types/dom/replaced-elements/svg-element-container.d.ts +2 -2
  43. package/dist/types/dom/slot-cloner.d.ts +10 -0
  44. package/dist/types/options.d.ts +24 -0
  45. package/dist/types/render/canvas/background-renderer.d.ts +9 -0
  46. package/dist/types/render/canvas/border-image-renderer.d.ts +7 -0
  47. package/dist/types/render/canvas/canvas-renderer.d.ts +10 -3
  48. package/dist/types/render/canvas/effects-renderer.d.ts +8 -0
  49. package/dist/types/render/canvas/filter-surface.d.ts +37 -11
  50. package/dist/types/render/canvas/gradient-rasterizer.d.ts +53 -0
  51. package/dist/types/render/canvas/mask-renderer.d.ts +5 -2
  52. package/dist/types/render/canvas/text-clip-renderer.d.ts +24 -5
  53. package/dist/types/render/canvas/text-renderer.d.ts +1 -0
  54. package/package.json +11 -33
  55. package/dist/types/render/font-metrics.d.ts +0 -11
  56. package/dist/types/render/renderer-interface.d.ts +0 -28
@@ -7,6 +7,19 @@ import { Validator } from './core/validator';
7
7
  *
8
8
  * Combines clone, window, render, and context configuration into a single
9
9
  * options object. All properties are optional.
10
+ *
11
+ * The full surface is composed from these interfaces (each documented where
12
+ * it is declared):
13
+ * - {@link CloneOptions} — `ignoreElements`, `onclone`, `allowTaint`,
14
+ * `iframeContainer` (src/dom/document-cloner.ts)
15
+ * - {@link WindowOptions} — `scrollX`, `scrollY`, `windowWidth`,
16
+ * `windowHeight` (src/dom/document-cloner.ts)
17
+ * - {@link RenderOptions} — `scale`, `canvas`, `x`, `y`, `width`, `height`
18
+ * (src/render/canvas/canvas-renderer.ts)
19
+ * - {@link ContextOptions} — `logging`, `cache`, `onError`, plus the
20
+ * `ResourceOptions` it extends: `imageTimeout`, `useCORS`, `proxy`,
21
+ * `customIsSameOrigin`, `maxCacheSize` (src/core/context.ts and
22
+ * src/core/cache-storage.ts)
10
23
  */
11
24
  export type Options = CloneOptions & WindowOptions & RenderOptions & ContextOptions & {
12
25
  /** Background color for the resulting canvas. Use `null` for transparent. */
@@ -15,6 +28,14 @@ export type Options = CloneOptions & WindowOptions & RenderOptions & ContextOpti
15
28
  foreignObjectRendering: boolean;
16
29
  /** Whether to remove the cloned iframe after rendering. @default true */
17
30
  removeContainer?: boolean;
31
+ /**
32
+ * Normalize the cloned DOM before parsing: disable CSS animations and
33
+ * replace active transforms with identity values so element bounds are
34
+ * measured in layout space. Set to `false` to keep animation/transform
35
+ * state intact during capture.
36
+ * @default true
37
+ */
38
+ normalizeDom?: boolean;
18
39
  /** CSP nonce for inline style elements. */
19
40
  cspNonce?: string;
20
41
  /** Custom input validator. */
@@ -51,6 +72,9 @@ export type Options = CloneOptions & WindowOptions & RenderOptions & ContextOpti
51
72
  /**
52
73
  * Called when a resource fails to load (image, font, iframe, etc.).
53
74
  * The render continues — this is a notification hook, not an abort.
75
+ * Image/proxy load failures are reported exactly once, by the
76
+ * resource cache at load time; iframe content failures are reported
77
+ * by the iframe container.
54
78
  */
55
79
  onError?: (error: Error) => void;
56
80
  /**
@@ -85,6 +85,15 @@ export declare class BackgroundRenderer {
85
85
  * CSS `from <angle>`.
86
86
  */
87
87
  private renderConicGradient;
88
+ /**
89
+ * Render a repeating conic gradient background.
90
+ *
91
+ * Canvas conic gradient stops span the full 2π sweep as [0, 1], so the
92
+ * one-cycle stop list is stacked k·period + s for k = 0..cycles-1 over the
93
+ * whole sweep — the same periodic-stop stacking the repeating linear and
94
+ * radial renderers use along their gradient lines.
95
+ */
96
+ private renderRepeatingConicGradient;
88
97
  /**
89
98
  * Render a repeating pattern with offset
90
99
  *
@@ -64,4 +64,11 @@ export declare class BorderImageRenderer {
64
64
  renderBorderImage(bounds: Bounds, image: HTMLImageElement, slice: BorderImageSlice, repeat: BorderImageRepeat, borderTopWidth: number, borderRightWidth: number, borderBottomWidth: number, borderLeftWidth: number, outset?: BorderImageSides): void;
65
65
  private drawRegion;
66
66
  private drawRepeatedEdge;
67
+ /**
68
+ * Draw the center region of the border image, tiling each axis per its
69
+ * border-image-repeat keyword (stretch spans the whole axis, repeat
70
+ * tiles at source size with the overflow cropped, round scales the tile
71
+ * to divide the axis evenly).
72
+ */
73
+ private drawCenterRegion;
67
74
  }
@@ -71,7 +71,6 @@ export declare class CanvasRenderer {
71
71
  renderReplacedElement(container: ReplacedElementContainer, curves: BoundCurves, image: HTMLImageElement | HTMLCanvasElement): void;
72
72
  renderNodeContent(paint: ElementPaint): Promise<void>;
73
73
  renderStackContent(stack: StackingContext): Promise<void>;
74
- mask(paths: Path[]): void;
75
74
  path(paths: Path[]): void;
76
75
  formatPath(paths: Path[]): void;
77
76
  private renderSurfaceBoxShadow;
@@ -81,10 +80,18 @@ export declare class CanvasRenderer {
81
80
  * offset outwards. Outlines paint atop content and do not affect layout.
82
81
  */
83
82
  private renderOutline;
83
+ /**
84
+ * Rasterise a gradient border-image-source across the border image area.
85
+ * CSS allows any <image> as the border-image source; gradients are painted
86
+ * over the whole border-image box and then sliced by the regular 9-slice
87
+ * pipeline, matching browser behaviour for `border-image: linear-gradient()`.
88
+ * Returns null when the gradient could not be painted.
89
+ */
90
+ private rasterizeGradientSource;
84
91
  /**
85
92
  * Filter the already-painted content beneath the element's border box and
86
- * paint the result back, approximating CSS backdrop-filter for the
87
- * blur/drop-shadow subset supported by parseSimpleFilter.
93
+ * paint the result back, approximating CSS backdrop-filter for the chain
94
+ * subset the filter surface backends support.
88
95
  */
89
96
  private renderBackdropFilter;
90
97
  render(element: ElementContainer): Promise<HTMLCanvasElement>;
@@ -16,6 +16,13 @@ import { Path } from '../path';
16
16
  */
17
17
  export interface EffectsRendererDependencies {
18
18
  ctx: CanvasRenderingContext2D;
19
+ /**
20
+ * Device-pixel ratio of the bound context. Canvas shadow metrics
21
+ * (offset/blur) live in device space, unaffected by the context
22
+ * transform, so drop-shadow() blur must be scaled like the offsets.
23
+ * Defaults to 1.
24
+ */
25
+ scale?: number;
19
26
  }
20
27
  /**
21
28
  * Path callback for clip effects
@@ -57,6 +64,7 @@ export interface EffectsPathCallback {
57
64
  export declare class EffectsRenderer {
58
65
  private readonly ctx;
59
66
  private readonly pathCallback;
67
+ private readonly scale;
60
68
  private readonly activeEffects;
61
69
  /** Whether a canvas state save was performed for the current batch. */
62
70
  private didSave;
@@ -1,17 +1,43 @@
1
1
  export declare class FilterSurfaceError extends Error {
2
2
  }
3
3
  export declare const releaseSurface: (canvas: HTMLCanvasElement) => void;
4
- export interface SimpleFilter {
4
+ /**
5
+ * A parsed CSS filter chain. Functions keep their declaration order — CSS
6
+ * applies them left to right, and the native canvas backend reproduces that
7
+ * order exactly. Chains containing functions the backends cannot express
8
+ * (url() references, unknown functions) fail parsing and stay on the legacy
9
+ * renderer, where ctx.filter receives the full string natively.
10
+ */
11
+ export type FilterFunction = {
12
+ kind: 'blur';
13
+ value: number;
14
+ } | {
15
+ kind: 'drop-shadow';
16
+ x: number;
17
+ y: number;
5
18
  blur: number;
6
- shadow?: {
7
- x: number;
8
- y: number;
9
- blur: number;
10
- color: string;
11
- };
19
+ color: string;
20
+ } | {
21
+ kind: 'unitless';
22
+ name: UnitlessFilterName;
23
+ value: number;
24
+ };
25
+ export type UnitlessFilterName = 'brightness' | 'contrast' | 'grayscale' | 'hue-rotate' | 'invert' | 'opacity' | 'saturate' | 'sepia';
26
+ export interface ParsedFilter {
27
+ functions: FilterFunction[];
12
28
  }
13
- export declare function parseSimpleFilter(value: string | null): SimpleFilter | null;
14
- export declare function filterOutset(filter: SimpleFilter): number;
29
+ export declare function parseFilterChain(value: string | null): ParsedFilter | null;
30
+ /**
31
+ * Render the chain as a canvas ctx.filter string, scaling all device-space
32
+ * lengths (blur radii, shadow offsets) by the capture scale. Unitless
33
+ * functions and hue angles are scale-invariant.
34
+ */
35
+ export declare const nativeFilterString: (filter: ParsedFilter, scale: number) => string;
36
+ /**
37
+ * Outset (in CSS pixels) a surface must grow so blur/shadow spillover is not
38
+ * cropped. Unitless functions never spread beyond the bounds. Consecutive
39
+ * blurs compound, so their radii sum.
40
+ */
41
+ export declare function filterOutset(filter: ParsedFilter): number;
15
42
  export declare function supportsNativeFilters(owner?: Document): boolean;
16
- export declare function renderFilterSurface(source: HTMLCanvasElement, filter: SimpleFilter, opacity: number, scale: number, signal?: AbortSignal): Promise<HTMLCanvasElement>;
17
- export declare function renderSvgFilterSurface(source: HTMLCanvasElement, { blur, shadow }: SimpleFilter, opacity: number, scale: number, signal?: AbortSignal): Promise<HTMLCanvasElement>;
43
+ export declare function renderFilterSurface(source: HTMLCanvasElement, filter: ParsedFilter, opacity: number, scale: number, signal?: AbortSignal): Promise<HTMLCanvasElement>;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Shared gradient rasterisation primitives.
3
+ *
4
+ * Canvas 2D has no repeating gradients and no native elliptical radial
5
+ * gradients, so every gradient painter (background, mask, border-image) needs
6
+ * the same two building blocks:
7
+ *
8
+ * 1. periodic stop stacking — the one-cycle stop list re-added k·period + s
9
+ * for k = 0..cycles-1, clamped to the [0, 1] gradient range;
10
+ * 2. ellipse rasterisation — a circle of radius rx scaled vertically by
11
+ * ry / rx, painted on a 2rx × 2ry offscreen canvas.
12
+ *
13
+ * Centralising them keeps the subtle invariants in one place:
14
+ * - stop positions are normalised against rx (the canvas gradient radius),
15
+ * NOT the diameter — normalising against the diameter halves every
16
+ * absolute-px stop;
17
+ * - the fill must cover the pre-scale circle (fillRect of the rx*2 square),
18
+ * not the post-scale ellipse box — a user-space (2rx × 2ry) rect shrinks
19
+ * vertically under the y-scale and clips the ellipse whenever ry < rx;
20
+ * - outside the ending shape a radial gradient continues with its last
21
+ * colour, which callers must paint across the full area first.
22
+ */
23
+ import { UnprocessedGradientColorStop, GradientColorStop } from '../../css/types/image';
24
+ export interface StringColorStop {
25
+ stop: number;
26
+ color: string;
27
+ }
28
+ /**
29
+ * Stack the one-cycle stop list periodically across [0, 1]. Returns null for
30
+ * a degenerate period (all stops clamped to one point) — CSS renders the
31
+ * last colour across the whole area in that case, and callers should paint
32
+ * the last colour instead of stacking.
33
+ */
34
+ export declare const stackRepeatingStops: (processed: GradientColorStop[]) => StringColorStop[] | null;
35
+ /** Map parsed stops to string-colour stops clamped into the canvas [0, 1] range. */
36
+ export declare const toCanvasStops: (processed: GradientColorStop[]) => StringColorStop[];
37
+ export interface RasterizedRadialGradient {
38
+ /** 2rx × 2ry device-pixel canvas holding the gradient ellipse. */
39
+ canvas: HTMLCanvasElement;
40
+ /** Colour beyond the ending shape (the last stop's colour). */
41
+ lastColor: string;
42
+ rx: number;
43
+ ry: number;
44
+ }
45
+ /**
46
+ * Rasterise a radial gradient's ending-shape ellipse to an offscreen canvas.
47
+ *
48
+ * The ellipse is a circle of radius rx scaled vertically by ry / rx around
49
+ * the canvas centre, so the offscreen canvas is the ellipse's full 2rx × 2ry
50
+ * bounding box and callers draw it at (centre - rx, centre - ry). Handles the
51
+ * repeating variant by stacking stops across the [0, 1] gradient range.
52
+ */
53
+ export declare const rasterizeRadialGradient: (ownerDocument: Document, rx: number, ry: number, stops: UnprocessedGradientColorStop[], repeating?: boolean) => RasterizedRadialGradient | null;
@@ -10,8 +10,11 @@
10
10
  * always fills the whole area — a mask surface is about alpha coverage, not
11
11
  * about what is visible underneath.
12
12
  *
13
- * Limitations (v1): repeating gradients render their base cycle; mask-mode is
14
- * alpha-only; layers composite with source-over (≈ the default `add`).
13
+ * Gradient layers share the rasterisation primitives of the background
14
+ * renderer (gradient-rasterizer.ts): repeating gradients stack their stop
15
+ * cycles, and the area beyond a radial gradient's ending shape keeps the
16
+ * last stop's colour. Limitations (v1): mask-mode is alpha-only; layers
17
+ * composite with source-over (≈ the spec-default `add`).
15
18
  */
16
19
  import { ICSSImage } from '../../css/types/image';
17
20
  import { LengthPercentage } from '../../css/types/length-percentage';
@@ -9,8 +9,15 @@
9
9
  * Extracted from CanvasRenderer to keep paint orchestration separate from
10
10
  * this self-contained compositing algorithm.
11
11
  *
12
- * The offscreen canvas uses CSS-pixel dimensions (not device-pixel) because the
13
- * background renderer handles scaling internally via BackgroundRenderer options.
12
+ * The offscreen and mask canvases are backed at device-pixel resolution
13
+ * (bounds × scale) with their contexts scaled to CSS pixels, so the
14
+ * composite back onto the main canvas maps 1:1 onto the backing store and
15
+ * stays sharp at devicePixelRatio > 1.
16
+ *
17
+ * Matching browser paint order for clipped text:
18
+ * - text shadows render *beneath* the clipped background (silhouettes in
19
+ * the shadow colour), they are not part of the clip region;
20
+ * - -webkit-text-stroke is part of the clip region (fill ∪ stroke band).
14
21
  */
15
22
  import { ElementPaint } from '../stacking-context';
16
23
  import { CSSParsedDeclaration } from '../../css';
@@ -19,18 +26,30 @@ export interface TextClipRendererDependencies {
19
26
  /** Main canvas context the clipped background is composited onto. */
20
27
  ctx: CanvasRenderingContext2D;
21
28
  context: Context;
29
+ /** Device-pixel ratio shared with the main renderer. */
30
+ scale: number;
22
31
  /** Font builder shared with the text renderer so both use identical fonts. */
23
32
  createFontStyle: (styles: CSSParsedDeclaration) => string[];
24
33
  }
25
34
  export declare class TextClipRenderer {
26
35
  private readonly ctx;
27
36
  private readonly context;
37
+ private readonly scale;
28
38
  private readonly createFontStyle;
29
39
  constructor(deps: TextClipRendererDependencies);
30
40
  render(paint: ElementPaint): Promise<void>;
41
+ private createLayer;
42
+ private createGlyphLayer;
43
+ /**
44
+ * Draw one text bound onto a glyph layer, splitting into per-glyph draws
45
+ * when letter-spacing is in effect so the layout matches the main text
46
+ * renderer. Vertical writing modes fall back to a single draw call.
47
+ */
48
+ private drawGlyphs;
31
49
  /**
32
- * Render text glyphs one-by-one as a mask, applying letter-spacing between characters.
33
- * This ensures the mask matches how the text renderer lays out the characters.
50
+ * Paint the text-shadow silhouettes for every glyph, one canvas per
51
+ * shadow, returned front-to-back (the last shadow sits deepest). Returns
52
+ * null when the element has no text shadows.
34
53
  */
35
- private renderTextMaskWithLetterSpacing;
54
+ private renderShadowSilhouettes;
36
55
  }
@@ -25,6 +25,7 @@ export interface TextRendererDependencies {
25
25
  };
26
26
  }
27
27
  export declare const hasCJKCharacters: (text: string) => boolean;
28
+ export declare const getTextStrokeLineJoin: () => CanvasLineJoin;
28
29
  /**
29
30
  * Text Renderer
30
31
  *
package/package.json CHANGED
@@ -19,7 +19,7 @@
19
19
  "default": "./dist/html2canvas-pro.esm.js"
20
20
  }
21
21
  },
22
- "version": "2.5.0",
22
+ "version": "2.5.2",
23
23
  "author": {
24
24
  "name": "yorickshan",
25
25
  "email": "yorickshan@gmail.com",
@@ -31,7 +31,7 @@
31
31
  "screenshot"
32
32
  ],
33
33
  "engines": {
34
- "node": ">=16.0.0"
34
+ "node": ">=24.0.0"
35
35
  },
36
36
  "homepage": "https://yorickshan.github.io/html2canvas-pro/",
37
37
  "repository": {
@@ -41,27 +41,18 @@
41
41
  "devDependencies": {
42
42
  "@commitlint/cli": "^21.2.3",
43
43
  "@commitlint/config-conventional": "^21.2.3",
44
- "@types/chai": "^5.2.3",
45
44
  "@types/express": "^5.0.6",
46
- "@types/karma": "^6.3.9",
47
- "@types/mocha": "^10.0.10",
48
45
  "@types/node": "^26.6.3",
49
- "@types/platform": "^1.3.6",
50
46
  "@types/pngjs": "^6.0.5",
51
47
  "@types/serve-index": "^1.9.4",
52
48
  "@typescript-eslint/eslint-plugin": "^8.70.1",
53
49
  "@typescript-eslint/parser": "^8.70.1",
54
50
  "@typescript/native": "npm:typescript@^7.0.2",
55
51
  "@vitest/coverage-v8": "^5.0.2",
56
- "appium-ios-simulator": "^8.2.8",
57
- "base64-arraybuffer": "1.0.2",
58
52
  "body-parser": "^2.3.0",
59
- "chai": "6.2.2",
60
- "change-case": "^5.4.4",
61
53
  "conventional-changelog": "^8.1.3",
62
54
  "conventional-changelog-conventionalcommits": "^10.4.0",
63
55
  "cors": "^2.8.6",
64
- "cz-conventional-changelog": "^3.3.0",
65
56
  "eslint": "^10.11.0",
66
57
  "eslint-config-prettier": "^10.1.8",
67
58
  "eslint-plugin-prettier": "^5.5.6",
@@ -70,23 +61,11 @@
70
61
  "glob": "^13.0.6",
71
62
  "husky": "^9.1.7",
72
63
  "jsdom": "^30.1.1",
73
- "karma": "^6.4.4",
74
- "karma-chrome-launcher": "^3.2.0",
75
- "karma-edge-launcher": "^0.4.2",
76
- "karma-firefox-launcher": "^2.1.3",
77
- "karma-ie-launcher": "^1.0.0",
78
- "karma-junit-reporter": "^2.0.1",
79
- "karma-mocha": "^2.0.1",
80
- "karma-safarinative-launcher": "^1.1.0",
81
64
  "lint-staged": "^17.6.0",
82
- "mocha": "^12.0.2",
83
- "node-simctl": "^8.2.9",
84
65
  "pixelmatch": "^7.2.0",
85
- "platform": "^1.3.6",
86
66
  "playwright": "1.63.0",
87
67
  "pngjs": "^7.0.0",
88
68
  "prettier": "^3.9.9",
89
- "puppeteer": "^25.12.0",
90
69
  "rimraf": "^6.1.3",
91
70
  "rolldown": "^1.2.11",
92
71
  "serve-index": "^1.9.2",
@@ -99,10 +78,7 @@
99
78
  "vitest": "^5.0.2",
100
79
  "yargs": "^18.2.0"
101
80
  },
102
- "dependencies": {
103
- "css-line-break": "^2.1.0",
104
- "text-segmentation": "^1.0.3"
105
- },
81
+ "dependencies": {},
106
82
  "lint-staged": {
107
83
  "{src,tests}/**/*.ts": [
108
84
  "prettier --write",
@@ -111,20 +87,19 @@
111
87
  },
112
88
  "scripts": {
113
89
  "prebuild": "rimraf dist/ && rimraf build/ && mkdir -p dist && mkdir -p build",
114
- "build": "tsc -p tsconfig.build.json && rolldown -c rolldown.config.ts && pnpm build:create-reftest-list && rolldown -c tests/rolldown.testrunner.config.ts && node scripts/bundle-filter-surface.mjs",
90
+ "build": "tsc -p tsconfig.build.json && rolldown -c rolldown.config.ts && pnpm build:create-reftest-list && node scripts/bundle-filter-surface.mjs",
115
91
  "build:testrunner": "rolldown -c tests/rolldown.testrunner.config.ts",
116
92
  "build:reftest-result-list": "tsx scripts/create-reftest-result-list.ts",
117
93
  "build:create-reftest-list": "tsx scripts/create-reftest-list.ts tests/reftests/ignore.txt build/reftests.js",
118
94
  "release": "sh scripts/version-upgrade.sh",
119
95
  "format": "prettier --write \"{src,tests,scripts}/**/*.ts\"",
120
- "lint": "eslint src/**/*.ts --max-warnings 0",
121
- "test": "pnpm lint && pnpm unittest && pnpm karma",
96
+ "lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" \"scripts/**/*.ts\" \"scripts/**/*.mjs\" --max-warnings 0",
97
+ "test": "pnpm lint && pnpm unittest && pnpm reftests:pw",
122
98
  "unittest": "vitest run",
123
99
  "unittest:coverage": "vitest run --coverage",
124
100
  "bench:css-parse": "tsx scripts/benchmarks/css-parse.bench.ts",
101
+ "bench:render": "node scripts/benchmarks/render.bench.mjs",
125
102
  "reftests-diff": "mkdir -p tmp/snapshots && vitest run --config vitest.reftest.config.ts",
126
- "prekarma": "node scripts/ensure-karma-prereqs.mjs",
127
- "karma": "tsx tests/karma",
128
103
  "watch": "rolldown -w",
129
104
  "watch:unittest": "vitest",
130
105
  "start": "tsx tests/server --port=8080 --cors=8081",
@@ -133,6 +108,9 @@
133
108
  "docs:build": "vitepress build docs",
134
109
  "docs:preview": "vitepress preview docs",
135
110
  "docs:api": "typedoc",
136
- "docs:api:watch": "typedoc --watch"
111
+ "docs:api:watch": "typedoc --watch",
112
+ "reftests:pw": "tsx tests/reftests-playwright.ts",
113
+ "reftests": "pnpm reftests:pw",
114
+ "prebrowser": "node scripts/ensure-browser-prereqs.mjs"
137
115
  }
138
116
  }
@@ -1,11 +0,0 @@
1
- export interface FontMetric {
2
- baseline: number;
3
- middle: number;
4
- }
5
- export declare class FontMetrics {
6
- private readonly _data;
7
- private readonly _document;
8
- constructor(document: Document);
9
- private parseMetrics;
10
- getMetrics(fontFamily: string, fontSize: string): FontMetric;
11
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * Base interface for all specialized renderers.
3
- * Each renderer is responsible for rendering a specific aspect of an element.
4
- *
5
- * @internal This interface is a structural contract; prefer using concrete
6
- * renderer classes (BackgroundRenderer, BorderRenderer, etc.)
7
- * directly rather than relying on the generic IRenderer shape.
8
- */
9
- export interface IRenderer {
10
- render(...args: unknown[]): void | Promise<void>;
11
- }
12
- /**
13
- * Common dependencies required by renderers.
14
- * RenderConfigurations from canvas-renderer.ts provides a concrete type.
15
- */
16
- export interface RendererDependencies {
17
- ctx: CanvasRenderingContext2D;
18
- scale: number;
19
- options: Record<string, unknown>;
20
- }
21
- /**
22
- * Performance tracking for renderers.
23
- */
24
- export interface RenderMetrics {
25
- renderCount: number;
26
- totalTime: number;
27
- averageTime: number;
28
- }