html2canvas-pro 1.6.7 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/README.md +1 -0
  2. package/demo/image-smoothing-demo.html +256 -0
  3. package/demo/refactoring-test.html +602 -0
  4. package/dist/html2canvas-pro.esm.js +3391 -1491
  5. package/dist/html2canvas-pro.esm.js.map +1 -1
  6. package/dist/html2canvas-pro.js +3394 -1490
  7. package/dist/html2canvas-pro.js.map +1 -1
  8. package/dist/html2canvas-pro.min.js +5 -4
  9. package/dist/lib/__tests__/index.js +8 -2
  10. package/dist/lib/__tests__/index.js.map +1 -1
  11. package/dist/lib/config.js +72 -0
  12. package/dist/lib/config.js.map +1 -0
  13. package/dist/lib/core/__tests__/cache-storage.js +6 -3
  14. package/dist/lib/core/__tests__/cache-storage.js.map +1 -1
  15. package/dist/lib/core/__tests__/cache-storage.test.js +158 -0
  16. package/dist/lib/core/__tests__/cache-storage.test.js.map +1 -0
  17. package/dist/lib/core/__tests__/validator.js +296 -0
  18. package/dist/lib/core/__tests__/validator.js.map +1 -0
  19. package/dist/lib/core/cache-storage.js +130 -11
  20. package/dist/lib/core/cache-storage.js.map +1 -1
  21. package/dist/lib/core/context.js +5 -2
  22. package/dist/lib/core/context.js.map +1 -1
  23. package/dist/lib/core/debugger.js +3 -0
  24. package/dist/lib/core/debugger.js.map +1 -1
  25. package/dist/lib/core/origin-checker.js +54 -0
  26. package/dist/lib/core/origin-checker.js.map +1 -0
  27. package/dist/lib/core/performance-monitor.js +208 -0
  28. package/dist/lib/core/performance-monitor.js.map +1 -0
  29. package/dist/lib/core/validator.js +501 -0
  30. package/dist/lib/core/validator.js.map +1 -0
  31. package/dist/lib/css/index.js +4 -0
  32. package/dist/lib/css/index.js.map +1 -1
  33. package/dist/lib/css/property-descriptors/__tests__/background-tests.js +7 -1
  34. package/dist/lib/css/property-descriptors/__tests__/background-tests.js.map +1 -1
  35. package/dist/lib/css/property-descriptors/__tests__/clip-path.test.js +273 -0
  36. package/dist/lib/css/property-descriptors/__tests__/clip-path.test.js.map +1 -0
  37. package/dist/lib/css/property-descriptors/__tests__/image-rendering-integration.test.js +142 -0
  38. package/dist/lib/css/property-descriptors/__tests__/image-rendering-integration.test.js.map +1 -0
  39. package/dist/lib/css/property-descriptors/__tests__/image-rendering-performance.test.js +167 -0
  40. package/dist/lib/css/property-descriptors/__tests__/image-rendering-performance.test.js.map +1 -0
  41. package/dist/lib/css/property-descriptors/__tests__/image-rendering.test.js +61 -0
  42. package/dist/lib/css/property-descriptors/__tests__/image-rendering.test.js.map +1 -0
  43. package/dist/lib/css/property-descriptors/clip-path.js +190 -0
  44. package/dist/lib/css/property-descriptors/clip-path.js.map +1 -0
  45. package/dist/lib/css/property-descriptors/image-rendering.js +34 -0
  46. package/dist/lib/css/property-descriptors/image-rendering.js.map +1 -0
  47. package/dist/lib/css/types/__tests__/image-tests.js +7 -1
  48. package/dist/lib/css/types/__tests__/image-tests.js.map +1 -1
  49. package/dist/lib/css/types/color-math.js +26 -0
  50. package/dist/lib/css/types/color-math.js.map +1 -0
  51. package/dist/lib/css/types/color-spaces/srgb.js +6 -6
  52. package/dist/lib/css/types/color-spaces/srgb.js.map +1 -1
  53. package/dist/lib/css/types/color-utilities.js +13 -22
  54. package/dist/lib/css/types/color-utilities.js.map +1 -1
  55. package/dist/lib/dom/__tests__/dom-normalizer.test.js +113 -0
  56. package/dist/lib/dom/__tests__/dom-normalizer.test.js.map +1 -0
  57. package/dist/lib/dom/__tests__/element-container.test.js +109 -0
  58. package/dist/lib/dom/__tests__/element-container.test.js.map +1 -0
  59. package/dist/lib/dom/document-cloner.js +3 -3
  60. package/dist/lib/dom/document-cloner.js.map +1 -1
  61. package/dist/lib/dom/dom-normalizer.js +116 -0
  62. package/dist/lib/dom/dom-normalizer.js.map +1 -0
  63. package/dist/lib/dom/element-container.js +32 -15
  64. package/dist/lib/dom/element-container.js.map +1 -1
  65. package/dist/lib/dom/node-parser.js +16 -20
  66. package/dist/lib/dom/node-parser.js.map +1 -1
  67. package/dist/lib/dom/node-type-guards.js +44 -0
  68. package/dist/lib/dom/node-type-guards.js.map +1 -0
  69. package/dist/lib/dom/replaced-elements/iframe-element-container.js +5 -4
  70. package/dist/lib/dom/replaced-elements/iframe-element-container.js.map +1 -1
  71. package/dist/lib/index.js +148 -41
  72. package/dist/lib/index.js.map +1 -1
  73. package/dist/lib/render/canvas/__tests__/background-renderer.test.js +65 -0
  74. package/dist/lib/render/canvas/__tests__/background-renderer.test.js.map +1 -0
  75. package/dist/lib/render/canvas/__tests__/border-renderer.test.js +23 -0
  76. package/dist/lib/render/canvas/__tests__/border-renderer.test.js.map +1 -0
  77. package/dist/lib/render/canvas/__tests__/effects-renderer.test.js +30 -0
  78. package/dist/lib/render/canvas/__tests__/effects-renderer.test.js.map +1 -0
  79. package/dist/lib/render/canvas/__tests__/text-renderer.test.js +310 -0
  80. package/dist/lib/render/canvas/__tests__/text-renderer.test.js.map +1 -0
  81. package/dist/lib/render/canvas/background-renderer.js +222 -0
  82. package/dist/lib/render/canvas/background-renderer.js.map +1 -0
  83. package/dist/lib/render/canvas/border-renderer.js +185 -0
  84. package/dist/lib/render/canvas/border-renderer.js.map +1 -0
  85. package/dist/lib/render/canvas/canvas-renderer.js +61 -689
  86. package/dist/lib/render/canvas/canvas-renderer.js.map +1 -1
  87. package/dist/lib/render/canvas/effects-renderer.js +94 -0
  88. package/dist/lib/render/canvas/effects-renderer.js.map +1 -0
  89. package/dist/lib/render/canvas/text-renderer.js +575 -0
  90. package/dist/lib/render/canvas/text-renderer.js.map +1 -0
  91. package/dist/lib/render/effects.js +17 -1
  92. package/dist/lib/render/effects.js.map +1 -1
  93. package/dist/lib/render/renderer-interface.js +3 -0
  94. package/dist/lib/render/renderer-interface.js.map +1 -0
  95. package/dist/lib/render/stacking-context.js +131 -0
  96. package/dist/lib/render/stacking-context.js.map +1 -1
  97. package/dist/types/config.d.ts +54 -0
  98. package/dist/types/core/__tests__/cache-storage.test.d.ts +1 -0
  99. package/dist/types/core/__tests__/validator.d.ts +1 -0
  100. package/dist/types/core/cache-storage.d.ts +42 -1
  101. package/dist/types/core/context.d.ts +5 -1
  102. package/dist/types/core/origin-checker.d.ts +33 -0
  103. package/dist/types/core/performance-monitor.d.ts +131 -0
  104. package/dist/types/core/validator.d.ts +132 -0
  105. package/dist/types/css/index.d.ts +4 -0
  106. package/dist/types/css/property-descriptors/__tests__/clip-path.test.d.ts +1 -0
  107. package/dist/types/css/property-descriptors/__tests__/image-rendering-integration.test.d.ts +1 -0
  108. package/dist/types/css/property-descriptors/__tests__/image-rendering-performance.test.d.ts +1 -0
  109. package/dist/types/css/property-descriptors/__tests__/image-rendering.test.d.ts +1 -0
  110. package/dist/types/css/property-descriptors/clip-path.d.ts +62 -0
  111. package/dist/types/css/property-descriptors/image-rendering.d.ts +8 -0
  112. package/dist/types/css/types/color-math.d.ts +12 -0
  113. package/dist/types/css/types/color-utilities.d.ts +2 -3
  114. package/dist/types/dom/__tests__/dom-normalizer.test.d.ts +1 -0
  115. package/dist/types/dom/__tests__/element-container.test.d.ts +1 -0
  116. package/dist/types/dom/dom-normalizer.d.ts +62 -0
  117. package/dist/types/dom/element-container.d.ts +20 -1
  118. package/dist/types/dom/node-parser.d.ts +2 -7
  119. package/dist/types/dom/node-type-guards.d.ts +33 -0
  120. package/dist/types/dom/replaced-elements/iframe-element-container.d.ts +4 -1
  121. package/dist/types/index.d.ts +48 -3
  122. package/dist/types/render/canvas/__tests__/background-renderer.test.d.ts +1 -0
  123. package/dist/types/render/canvas/__tests__/border-renderer.test.d.ts +1 -0
  124. package/dist/types/render/canvas/__tests__/effects-renderer.test.d.ts +1 -0
  125. package/dist/types/render/canvas/__tests__/text-renderer.test.d.ts +1 -0
  126. package/dist/types/render/canvas/background-renderer.d.ts +87 -0
  127. package/dist/types/render/canvas/border-renderer.d.ts +67 -0
  128. package/dist/types/render/canvas/canvas-renderer.d.ts +19 -23
  129. package/dist/types/render/canvas/effects-renderer.d.ts +65 -0
  130. package/dist/types/render/canvas/text-renderer.d.ts +75 -0
  131. package/dist/types/render/effects.d.ts +15 -1
  132. package/dist/types/render/renderer-interface.d.ts +26 -0
  133. package/package.json +2 -1
@@ -7,6 +7,7 @@ import { backgroundSize } from './property-descriptors/background-size';
7
7
  import { borderBottomLeftRadius, borderBottomRightRadius, borderTopLeftRadius, borderTopRightRadius } from './property-descriptors/border-radius';
8
8
  import { borderBottomStyle, borderLeftStyle, borderRightStyle, borderTopStyle } from './property-descriptors/border-style';
9
9
  import { borderBottomWidth, borderLeftWidth, borderRightWidth, borderTopWidth } from './property-descriptors/border-width';
10
+ import { ClipPathValue } from './property-descriptors/clip-path';
10
11
  import { direction } from './property-descriptors/direction';
11
12
  import { display } from './property-descriptors/display';
12
13
  import { float } from './property-descriptors/float';
@@ -51,6 +52,7 @@ import { webkitLineClamp } from './property-descriptors/webkit-line-clamp';
51
52
  import { Context } from '../core/context';
52
53
  import { objectFit } from './property-descriptors/object-fit';
53
54
  import { textOverflow } from './property-descriptors/text-overflow';
55
+ import { imageRendering } from './property-descriptors/image-rendering';
54
56
  export declare class CSSParsedDeclaration {
55
57
  animationDuration: ReturnType<typeof duration.parse>;
56
58
  backgroundClip: ReturnType<typeof backgroundClip.parse>;
@@ -77,6 +79,7 @@ export declare class CSSParsedDeclaration {
77
79
  borderBottomWidth: ReturnType<typeof borderBottomWidth.parse>;
78
80
  borderLeftWidth: ReturnType<typeof borderLeftWidth.parse>;
79
81
  boxShadow: ReturnType<typeof boxShadow.parse>;
82
+ clipPath: ClipPathValue;
80
83
  color: Color;
81
84
  direction: ReturnType<typeof direction.parse>;
82
85
  display: ReturnType<typeof display.parse>;
@@ -125,6 +128,7 @@ export declare class CSSParsedDeclaration {
125
128
  wordBreak: ReturnType<typeof wordBreak.parse>;
126
129
  zIndex: ReturnType<typeof zIndex.parse>;
127
130
  objectFit: ReturnType<typeof objectFit.parse>;
131
+ imageRendering: ReturnType<typeof imageRendering.parse>;
128
132
  constructor(context: Context, declaration: CSSStyleDeclaration);
129
133
  isVisible(): boolean;
130
134
  isTransparent(): boolean;
@@ -0,0 +1,62 @@
1
+ import { IPropertyValueDescriptor } from '../IPropertyDescriptor';
2
+ import { LengthPercentage } from '../types/length-percentage';
3
+ export declare const enum CLIP_PATH_TYPE {
4
+ NONE = 0,
5
+ INSET = 1,
6
+ CIRCLE = 2,
7
+ ELLIPSE = 3,
8
+ POLYGON = 4,
9
+ PATH = 5
10
+ }
11
+ /** Radius keyword or length-percentage for circle/ellipse. */
12
+ export type ShapeRadius = LengthPercentage | 'closest-side' | 'farthest-side';
13
+ export interface NoneClipPath {
14
+ type: CLIP_PATH_TYPE.NONE;
15
+ }
16
+ /**
17
+ * inset(top right bottom left [ round <border-radius> ]?)
18
+ * Amounts to cut from each side of the reference box.
19
+ */
20
+ export interface InsetClipPath {
21
+ type: CLIP_PATH_TYPE.INSET;
22
+ top: LengthPercentage;
23
+ right: LengthPercentage;
24
+ bottom: LengthPercentage;
25
+ left: LengthPercentage;
26
+ }
27
+ /**
28
+ * circle( [ <shape-radius> ]? [ at <position> ]? )
29
+ */
30
+ export interface CircleClipPath {
31
+ type: CLIP_PATH_TYPE.CIRCLE;
32
+ radius: ShapeRadius;
33
+ cx: LengthPercentage;
34
+ cy: LengthPercentage;
35
+ }
36
+ /**
37
+ * ellipse( [ <shape-radius>{2} ]? [ at <position> ]? )
38
+ */
39
+ export interface EllipseClipPath {
40
+ type: CLIP_PATH_TYPE.ELLIPSE;
41
+ rx: ShapeRadius;
42
+ ry: ShapeRadius;
43
+ cx: LengthPercentage;
44
+ cy: LengthPercentage;
45
+ }
46
+ /**
47
+ * polygon( [ <fill-rule>, ]? [ <length-percentage> <length-percentage> ]# )
48
+ */
49
+ export interface PolygonClipPath {
50
+ type: CLIP_PATH_TYPE.POLYGON;
51
+ points: [LengthPercentage, LengthPercentage][];
52
+ }
53
+ /**
54
+ * path( [ <fill-rule>, ]? <string> )
55
+ * The string contains SVG path data in the element's local coordinate space.
56
+ */
57
+ export interface PathClipPath {
58
+ type: CLIP_PATH_TYPE.PATH;
59
+ d: string;
60
+ }
61
+ export type ClipPathValue = NoneClipPath | InsetClipPath | CircleClipPath | EllipseClipPath | PolygonClipPath | PathClipPath;
62
+ export declare const clipPath: IPropertyValueDescriptor<ClipPathValue>;
@@ -0,0 +1,8 @@
1
+ import { IPropertyIdentValueDescriptor } from '../IPropertyDescriptor';
2
+ export declare enum IMAGE_RENDERING {
3
+ AUTO = 0,
4
+ CRISP_EDGES = 1,
5
+ PIXELATED = 2,
6
+ SMOOTH = 3
7
+ }
8
+ export declare const imageRendering: IPropertyIdentValueDescriptor<IMAGE_RENDERING>;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Color mathematics utilities
3
+ * Extracted to break circular dependency between srgb.ts and color-utilities.ts
4
+ */
5
+ /**
6
+ * Clamp a value between min and max
7
+ */
8
+ export declare const clamp: (value: number, min: number, max: number) => number;
9
+ /**
10
+ * Multiply two 3x3 matrices
11
+ */
12
+ export declare const multiplyMatrices: (A: number[], B: number[]) => [number, number, number];
@@ -1,13 +1,13 @@
1
1
  import { Context } from '../../core/context';
2
2
  import { CSSValue } from '../syntax/parser';
3
+ import { clamp, multiplyMatrices } from './color-math';
3
4
  type Color = number;
4
5
  export declare const isTransparent: (color: Color) => boolean;
5
6
  export declare const asString: (color: Color) => string;
6
7
  export declare const pack: (r: number, g: number, b: number, a: number) => Color;
7
8
  export declare const getTokenColorValue: (token: CSSValue, i: number) => number;
8
9
  export declare const isRelativeTransform: (tokens: CSSValue[]) => boolean;
9
- export declare const clamp: (value: number, min: number, max: number) => number;
10
- export declare const multiplyMatrices: (A: number[], B: number[]) => [number, number, number];
10
+ export { clamp, multiplyMatrices };
11
11
  export declare const packSrgb: (args: number[]) => number;
12
12
  export declare const packSrgbLinear: ([r, g, b, a]: [number, number, number, number]) => number;
13
13
  export declare const packXYZ: (args: number[]) => number;
@@ -105,4 +105,3 @@ export declare const convertXyz: (args: number[]) => number;
105
105
  * @param args
106
106
  */
107
107
  export declare const convertXyz50: (args: number[]) => number;
108
- export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,62 @@
1
+ /**
2
+ * DOM Normalizer
3
+ * Handles DOM side effects that need to happen before rendering
4
+ * Extracted from ElementContainer to follow SRP
5
+ */
6
+ import { CSSParsedDeclaration } from '../css';
7
+ /**
8
+ * Stored original styles for restoration
9
+ */
10
+ export interface OriginalStyles {
11
+ animationDuration?: string;
12
+ transform?: string;
13
+ rotate?: string;
14
+ }
15
+ /**
16
+ * Normalize element styles for accurate rendering
17
+ * This includes disabling animations and neutralizing transforms.
18
+ */
19
+ export declare class DOMNormalizer {
20
+ /**
21
+ * Normalize a single element and return original styles.
22
+ *
23
+ * ## Why we replace transforms with an identity value instead of "none"
24
+ *
25
+ * `getBoundingClientRect()` returns visual (post-transform) coordinates, so we
26
+ * must neutralize any active transform before measuring element bounds.
27
+ *
28
+ * The naive approach of setting `transform: none` (or `rotate: none`) has a
29
+ * critical side-effect: per **CSS Transforms Level 2**, an element whose
30
+ * `transform` is non-none automatically becomes the **containing block** for
31
+ * all of its `position: absolute` *and* `position: fixed` descendants.
32
+ * Setting it to `none` destroys that role, causing children to resolve their
33
+ * percentage dimensions and offsets against an unintended ancestor — which
34
+ * produces completely wrong bounds.
35
+ *
36
+ * Solution: instead of removing the transform, we replace it with a visually
37
+ * inert identity value:
38
+ *
39
+ * - `transform: scale(0.5)` → `transform: translate(0, 0)`
40
+ * - `translate(0, 0)` is an identity transform (no visual change, no layout shift).
41
+ * - `getBoundingClientRect()` returns the same layout-space coordinates as
42
+ * if there were no transform at all.
43
+ * - Because the value is still non-none, the element **remains a containing
44
+ * block** for both `position: absolute` and `position: fixed` descendants.
45
+ *
46
+ * - `rotate: 45deg` → `rotate: 0deg`
47
+ * - `0deg` is the identity rotation; `0deg ≠ none`, so the same containing-
48
+ * block guarantee holds.
49
+ *
50
+ * @param element - Element to normalize
51
+ * @param styles - Parsed CSS styles
52
+ * @returns Original styles map for restoration
53
+ */
54
+ static normalizeElement(element: Element, styles: CSSParsedDeclaration): OriginalStyles;
55
+ /**
56
+ * Restore element styles after rendering.
57
+ *
58
+ * @param element - Element to restore
59
+ * @param originalStyles - Original styles to restore
60
+ */
61
+ static restoreElement(element: Element, originalStyles: OriginalStyles): void;
62
+ }
@@ -8,6 +8,13 @@ export declare const enum FLAGS {
8
8
  IS_LIST_OWNER = 8,
9
9
  DEBUG_RENDER = 16
10
10
  }
11
+ export interface ElementContainerOptions {
12
+ /**
13
+ * Whether to normalize DOM (disable animations, reset transforms)
14
+ * Default: true for backward compatibility
15
+ */
16
+ normalizeDom?: boolean;
17
+ }
11
18
  export declare class ElementContainer {
12
19
  protected readonly context: Context;
13
20
  readonly styles: CSSParsedDeclaration;
@@ -15,5 +22,17 @@ export declare class ElementContainer {
15
22
  readonly elements: ElementContainer[];
16
23
  bounds: Bounds;
17
24
  flags: number;
18
- constructor(context: Context, element: Element);
25
+ private originalStyles?;
26
+ private originalElement?;
27
+ constructor(context: Context, element: Element, options?: ElementContainerOptions);
28
+ /**
29
+ * Restore original element styles (if normalized)
30
+ * Call this after rendering is complete to clean up DOM state
31
+ */
32
+ restore(): void;
33
+ /**
34
+ * Recursively restore all elements in the tree
35
+ * Call this on the root container after rendering is complete
36
+ */
37
+ restoreTree(): void;
19
38
  }
@@ -1,12 +1,8 @@
1
1
  import { ElementContainer } from './element-container';
2
2
  import { Context } from '../core/context';
3
+ import { isElementNode, isTextNode, isSVGElementNode, isHTMLElementNode, isLIElement, isOLElement, isCustomElement } from './node-type-guards';
4
+ export { isElementNode, isTextNode, isSVGElementNode, isHTMLElementNode, isLIElement, isOLElement, isCustomElement };
3
5
  export declare const parseTree: (context: Context, element: HTMLElement) => ElementContainer;
4
- export declare const isTextNode: (node: Node) => node is Text;
5
- export declare const isElementNode: (node: Node) => node is Element;
6
- export declare const isHTMLElementNode: (node: Node) => node is HTMLElement;
7
- export declare const isSVGElementNode: (element: Element) => element is SVGElement;
8
- export declare const isLIElement: (node: Element) => node is HTMLLIElement;
9
- export declare const isOLElement: (node: Element) => node is HTMLOListElement;
10
6
  export declare const isInputElement: (node: Element) => node is HTMLInputElement;
11
7
  export declare const isHTMLElement: (node: Element) => node is HTMLHtmlElement;
12
8
  export declare const isSVGElement: (node: Element) => node is SVGSVGElement;
@@ -20,4 +16,3 @@ export declare const isScriptElement: (node: Element) => node is HTMLScriptEleme
20
16
  export declare const isTextareaElement: (node: Element) => node is HTMLTextAreaElement;
21
17
  export declare const isSelectElement: (node: Element) => node is HTMLSelectElement;
22
18
  export declare const isSlotElement: (node: Element) => node is HTMLSlotElement;
23
- export declare const isCustomElement: (node: Element) => node is HTMLElement;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * DOM Node Type Guards
3
+ * Extracted to break circular dependencies
4
+ */
5
+ /**
6
+ * Check if node is an Element
7
+ */
8
+ export declare const isElementNode: (node: Node) => node is Element;
9
+ /**
10
+ * Check if node is a Text node
11
+ */
12
+ export declare const isTextNode: (node: Node) => node is Text;
13
+ /**
14
+ * Check if element is an SVG element
15
+ */
16
+ export declare const isSVGElementNode: (element: Element) => element is SVGElement;
17
+ /**
18
+ * Check if node is an HTML element
19
+ */
20
+ export declare const isHTMLElementNode: (node: Node) => node is HTMLElement;
21
+ /**
22
+ * Check if node is an LI element
23
+ */
24
+ export declare const isLIElement: (node: Element) => node is HTMLLIElement;
25
+ /**
26
+ * Check if node is an OL element
27
+ */
28
+ export declare const isOLElement: (node: Element) => node is HTMLOListElement;
29
+ /**
30
+ * Check if element is a custom element
31
+ * Custom elements must have a hyphen and cannot be SVG elements
32
+ */
33
+ export declare const isCustomElement: (element: Element) => element is HTMLElement;
@@ -1,11 +1,14 @@
1
1
  import { ElementContainer } from '../element-container';
2
2
  import { Color } from '../../css/types/color';
3
3
  import { Context } from '../../core/context';
4
+ type ParseTreeFunction = (context: Context, node: Node) => ElementContainer;
4
5
  export declare class IFrameElementContainer extends ElementContainer {
5
6
  src: string;
6
7
  width: number;
7
8
  height: number;
8
9
  tree?: ElementContainer;
9
10
  backgroundColor: Color;
10
- constructor(context: Context, iframe: HTMLIFrameElement);
11
+ private parseTreeFn?;
12
+ constructor(context: Context, iframe: HTMLIFrameElement, parseTreeFn?: ParseTreeFunction);
11
13
  }
14
+ export {};
@@ -1,15 +1,60 @@
1
1
  import { CloneOptions, WindowOptions } from './dom/document-cloner';
2
2
  import { RenderOptions } from './render/canvas/canvas-renderer';
3
3
  import { ContextOptions } from './core/context';
4
+ import { Html2CanvasConfig, ConfigOptions } from './config';
5
+ import { createDefaultValidator, Validator, ValidationResult } from './core/validator';
6
+ import { PerformanceMonitor } from './core/performance-monitor';
4
7
  export type Options = CloneOptions & WindowOptions & RenderOptions & ContextOptions & {
5
8
  backgroundColor: string | null;
6
9
  foreignObjectRendering: boolean;
7
10
  removeContainer?: boolean;
11
+ cspNonce?: string;
12
+ validator?: Validator;
13
+ skipValidation?: boolean;
14
+ enablePerformanceMonitoring?: boolean;
15
+ /**
16
+ * Enable/disable image smoothing (anti-aliasing) globally.
17
+ * - `false`: Pixel-perfect rendering for pixel art, sprites, and retro graphics
18
+ * - `true`: Smooth rendering for photos and high-quality images
19
+ * - CSS `image-rendering` property on individual elements takes precedence
20
+ * @default true (browser default)
21
+ * @example
22
+ * // Pixel art game screenshot
23
+ * html2canvas(element, { imageSmoothing: false, scale: 2 });
24
+ *
25
+ * // High-quality photo
26
+ * html2canvas(element, { imageSmoothing: true, imageSmoothingQuality: 'high' });
27
+ */
28
+ imageSmoothing?: boolean;
29
+ /**
30
+ * Image smoothing quality level when imageSmoothing is enabled.
31
+ * - `'low'`: Faster, lower quality (good for preview)
32
+ * - `'medium'`: Balanced (default in most browsers)
33
+ * - `'high'`: Slower, best quality (good for final export)
34
+ *
35
+ * Browser support: Chrome 54+, Firefox 94+, Safari 17+
36
+ * Falls back gracefully in older browsers.
37
+ * @default browser default (usually 'low' or 'medium')
38
+ */
39
+ imageSmoothingQuality?: 'low' | 'medium' | 'high';
8
40
  };
9
- declare const setCspNonce: (nonce: string) => void;
41
+ /**
42
+ * Main html2canvas function with improved configuration management
43
+ *
44
+ * @param element - Element to render
45
+ * @param options - Rendering options
46
+ * @param config - Optional configuration (for advanced use cases)
47
+ * @returns Promise resolving to rendered canvas
48
+ */
10
49
  declare const html2canvas: {
11
- (element: HTMLElement, options?: Partial<Options>): Promise<HTMLCanvasElement>;
50
+ (element: HTMLElement, options?: Partial<Options>, config?: Html2CanvasConfig): Promise<HTMLCanvasElement>;
12
51
  setCspNonce: (nonce: string) => void;
13
52
  };
53
+ /**
54
+ * Set CSP nonce for inline styles
55
+ * @deprecated Use options.cspNonce instead
56
+ */
57
+ declare const setCspNonce: (nonce: string) => void;
14
58
  export default html2canvas;
15
- export { html2canvas, setCspNonce };
59
+ export { html2canvas, setCspNonce, Html2CanvasConfig, ConfigOptions, Validator, ValidationResult, createDefaultValidator, PerformanceMonitor };
60
+ export { IMAGE_RENDERING } from './css/property-descriptors/image-rendering';
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Background Renderer
3
+ *
4
+ * Handles rendering of element backgrounds including:
5
+ * - Background colors
6
+ * - Background images (URL)
7
+ * - Linear gradients
8
+ * - Radial gradients
9
+ * - Background patterns and repeats
10
+ */
11
+ import { Context } from '../../core/context';
12
+ import { ElementContainer } from '../../dom/element-container';
13
+ /**
14
+ * Dependencies required for BackgroundRenderer
15
+ */
16
+ export interface BackgroundRendererDependencies {
17
+ ctx: CanvasRenderingContext2D;
18
+ context: Context;
19
+ canvas: HTMLCanvasElement;
20
+ options: {
21
+ width: number;
22
+ height: number;
23
+ scale: number;
24
+ };
25
+ }
26
+ /**
27
+ * Background Renderer
28
+ *
29
+ * Specialized renderer for element backgrounds.
30
+ * Extracted from CanvasRenderer to improve code organization and maintainability.
31
+ */
32
+ export declare class BackgroundRenderer {
33
+ private readonly ctx;
34
+ private readonly context;
35
+ private readonly canvas;
36
+ constructor(deps: BackgroundRendererDependencies);
37
+ /**
38
+ * Render background images for a container
39
+ * Supports URL images, linear gradients, and radial gradients
40
+ *
41
+ * @param container - Element container with background styles
42
+ */
43
+ renderBackgroundImage(container: ElementContainer): Promise<void>;
44
+ /**
45
+ * Render a URL-based background image
46
+ */
47
+ private renderBackgroundURLImage;
48
+ /**
49
+ * Render a linear gradient background
50
+ */
51
+ private renderLinearGradient;
52
+ /**
53
+ * Render a radial gradient background
54
+ */
55
+ private renderRadialGradient;
56
+ /**
57
+ * Render a repeating pattern with offset
58
+ *
59
+ * @param path - Path to fill
60
+ * @param pattern - Canvas pattern or gradient
61
+ * @param offsetX - X offset for pattern
62
+ * @param offsetY - Y offset for pattern
63
+ */
64
+ private renderRepeat;
65
+ /**
66
+ * Resize an image to target dimensions
67
+ *
68
+ * @param image - Source image
69
+ * @param width - Target width
70
+ * @param height - Target height
71
+ * @param imageRendering - CSS image-rendering property value
72
+ * @returns Resized canvas or original image
73
+ */
74
+ private resizeImage;
75
+ /**
76
+ * Create a canvas path from path array
77
+ *
78
+ * @param paths - Array of path points
79
+ */
80
+ private path;
81
+ /**
82
+ * Format path points into canvas path
83
+ *
84
+ * @param paths - Array of path points
85
+ */
86
+ private formatPath;
87
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Border Renderer
3
+ *
4
+ * Handles rendering of element borders including:
5
+ * - Solid borders
6
+ * - Double borders
7
+ * - Dashed borders
8
+ * - Dotted borders
9
+ */
10
+ import { Color } from '../../css/types/color';
11
+ import { BoundCurves } from '../bound-curves';
12
+ import { BORDER_STYLE } from '../../css/property-descriptors/border-style';
13
+ import { Path } from '../path';
14
+ /**
15
+ * Dependencies required for BorderRenderer
16
+ */
17
+ export interface BorderRendererDependencies {
18
+ ctx: CanvasRenderingContext2D;
19
+ }
20
+ /**
21
+ * Path creation callbacks
22
+ * The main CanvasRenderer retains path() and formatPath() methods,
23
+ * so we inject them as callbacks to avoid duplication
24
+ */
25
+ export interface PathCallbacks {
26
+ path(paths: Path[]): void;
27
+ formatPath(paths: Path[]): void;
28
+ }
29
+ /**
30
+ * Border Renderer
31
+ *
32
+ * Specialized renderer for element borders.
33
+ * Extracted from CanvasRenderer to improve code organization and maintainability.
34
+ */
35
+ export declare class BorderRenderer {
36
+ private readonly ctx;
37
+ private pathCallbacks;
38
+ constructor(deps: BorderRendererDependencies, pathCallbacks: PathCallbacks);
39
+ /**
40
+ * Render a solid border
41
+ *
42
+ * @param color - Border color
43
+ * @param side - Border side (0=top, 1=right, 2=bottom, 3=left)
44
+ * @param curvePoints - Border curve points
45
+ */
46
+ renderSolidBorder(color: Color, side: number, curvePoints: BoundCurves): Promise<void>;
47
+ /**
48
+ * Render a double border
49
+ * Falls back to solid border if width is too small
50
+ *
51
+ * @param color - Border color
52
+ * @param width - Border width
53
+ * @param side - Border side (0=top, 1=right, 2=bottom, 3=left)
54
+ * @param curvePoints - Border curve points
55
+ */
56
+ renderDoubleBorder(color: Color, width: number, side: number, curvePoints: BoundCurves): Promise<void>;
57
+ /**
58
+ * Render a dashed or dotted border
59
+ *
60
+ * @param color - Border color
61
+ * @param width - Border width
62
+ * @param side - Border side (0=top, 1=right, 2=bottom, 3=left)
63
+ * @param curvePoints - Border curve points
64
+ * @param style - Border style (DASHED or DOTTED)
65
+ */
66
+ renderDashedDottedBorder(color: Color, width: number, side: number, curvePoints: BoundCurves, style: BORDER_STYLE): Promise<void>;
67
+ }
@@ -1,19 +1,28 @@
1
1
  import { ElementPaint, StackingContext } from '../stacking-context';
2
2
  import { Color } from '../../css/types/color';
3
3
  import { ElementContainer } from '../../dom/element-container';
4
- import { BORDER_STYLE } from '../../css/property-descriptors/border-style';
5
- import { CSSParsedDeclaration } from '../../css';
6
- import { TextContainer } from '../../dom/text-container';
7
4
  import { Path } from '../path';
8
5
  import { BoundCurves } from '../bound-curves';
9
- import { TextBounds } from '../../css/layout/text';
10
6
  import { ReplacedElementContainer } from '../../dom/replaced-elements';
11
- import { IElementEffect } from '../effects';
12
- import { Bounds } from '../../css/layout/bounds';
13
7
  import { Renderer } from '../renderer';
14
8
  import { Context } from '../../core/context';
15
9
  export type RenderConfigurations = RenderOptions & {
16
10
  backgroundColor: Color | null;
11
+ /**
12
+ * Enable/disable image smoothing (anti-aliasing).
13
+ * When disabled, images are rendered with pixel-perfect sharpness (no interpolation).
14
+ * CSS `image-rendering` property on individual elements takes precedence.
15
+ * @default browser default (usually true)
16
+ */
17
+ imageSmoothing?: boolean;
18
+ /**
19
+ * Image smoothing quality level when imageSmoothing is enabled.
20
+ * Higher quality may be slower for large images.
21
+ * Only supported in modern browsers (Chrome 54+, Firefox 94+, Safari 17+).
22
+ * Falls back gracefully in older browsers.
23
+ * @default browser default
24
+ */
25
+ imageSmoothingQuality?: 'low' | 'medium' | 'high';
17
26
  };
18
27
  export interface RenderOptions {
19
28
  scale: number;
@@ -26,37 +35,24 @@ export interface RenderOptions {
26
35
  export declare class CanvasRenderer extends Renderer {
27
36
  canvas: HTMLCanvasElement;
28
37
  ctx: CanvasRenderingContext2D;
29
- private readonly _activeEffects;
30
38
  private readonly fontMetrics;
39
+ private readonly backgroundRenderer;
40
+ private readonly borderRenderer;
41
+ private readonly effectsRenderer;
42
+ private readonly textRenderer;
31
43
  constructor(context: Context, options: RenderConfigurations);
32
- applyEffects(effects: IElementEffect[]): void;
33
- applyEffect(effect: IElementEffect): void;
34
- popEffect(): void;
35
44
  renderStack(stack: StackingContext): Promise<void>;
36
45
  renderNode(paint: ElementPaint): Promise<void>;
37
- renderTextWithLetterSpacing(text: TextBounds, letterSpacing: number, baseline: number): void;
38
46
  /**
39
47
  * Helper method to render text with paint order support
40
48
  * Reduces code duplication in line-clamp and normal rendering
41
49
  */
42
- private renderTextBoundWithPaintOrder;
43
- private renderTextDecoration;
44
- private drawDecorationLine;
45
- private truncateTextWithEllipsis;
46
- private createFontStyle;
47
- renderTextNode(text: TextContainer, styles: CSSParsedDeclaration, containerBounds?: Bounds): Promise<void>;
48
50
  renderReplacedElement(container: ReplacedElementContainer, curves: BoundCurves, image: HTMLImageElement | HTMLCanvasElement): void;
49
51
  renderNodeContent(paint: ElementPaint): Promise<void>;
50
52
  renderStackContent(stack: StackingContext): Promise<void>;
51
53
  mask(paths: Path[]): void;
52
54
  path(paths: Path[]): void;
53
55
  formatPath(paths: Path[]): void;
54
- renderRepeat(path: Path[], pattern: CanvasPattern | CanvasGradient, offsetX: number, offsetY: number): void;
55
- resizeImage(image: HTMLImageElement, width: number, height: number): HTMLCanvasElement | HTMLImageElement;
56
- renderBackgroundImage(container: ElementContainer): Promise<void>;
57
- renderSolidBorder(color: Color, side: number, curvePoints: BoundCurves): Promise<void>;
58
- renderDoubleBorder(color: Color, width: number, side: number, curvePoints: BoundCurves): Promise<void>;
59
56
  renderNodeBackgroundAndBorders(paint: ElementPaint): Promise<void>;
60
- renderDashedDottedBorder(color: Color, width: number, side: number, curvePoints: BoundCurves, style: BORDER_STYLE): Promise<void>;
61
57
  render(element: ElementContainer): Promise<HTMLCanvasElement>;
62
58
  }