html2canvas-pro 2.4.5 → 2.5.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 (231) hide show
  1. package/README.md +117 -13
  2. package/dist/html2canvas-pro.cjs +3425 -1677
  3. package/dist/html2canvas-pro.cjs.map +1 -1
  4. package/dist/html2canvas-pro.esm.js +3425 -1677
  5. package/dist/html2canvas-pro.esm.js.map +1 -1
  6. package/dist/html2canvas-pro.js +3479 -1731
  7. package/dist/html2canvas-pro.js.map +1 -1
  8. package/dist/html2canvas-pro.min.js +5 -5
  9. package/dist/types/core/cache-storage.d.ts +22 -1
  10. package/dist/types/core/context.d.ts +10 -1
  11. package/dist/types/core/logger.d.ts +0 -3
  12. package/dist/types/core/render-element.d.ts +11 -0
  13. package/dist/types/core/util.d.ts +6 -0
  14. package/dist/types/css/index.d.ts +77 -46
  15. package/dist/types/css/parse.d.ts +15 -0
  16. package/dist/types/css/property-descriptors/accent-color.d.ts +5 -0
  17. package/dist/types/css/property-descriptors/backdrop-filter.d.ts +9 -0
  18. package/dist/types/css/property-descriptors/background-blend-mode.d.ts +16 -16
  19. package/dist/types/css/property-descriptors/border-image-width.d.ts +36 -0
  20. package/dist/types/css/property-descriptors/clip-path.d.ts +16 -2
  21. package/dist/types/css/property-descriptors/isolation.d.ts +6 -0
  22. package/dist/types/css/property-descriptors/mask.d.ts +25 -0
  23. package/dist/types/css/property-descriptors/mix-blend-mode.d.ts +16 -16
  24. package/dist/types/css/property-descriptors/outline.d.ts +15 -0
  25. package/dist/types/css/property-descriptors/text-emphasis.d.ts +22 -0
  26. package/dist/types/css/property-descriptors/text-shadow.d.ts +1 -1
  27. package/dist/types/css/property-descriptors/webkit-box-reflect.d.ts +19 -0
  28. package/dist/types/css/property-descriptors/webkit-text-fill-color.d.ts +9 -0
  29. package/dist/types/css/syntax/token-constants.d.ts +1 -1
  30. package/dist/types/css/types/color-math.d.ts +7 -1
  31. package/dist/types/css/types/color-spaces/a98.d.ts +2 -1
  32. package/dist/types/css/types/color-spaces/p3.d.ts +5 -4
  33. package/dist/types/css/types/color-spaces/pro-photo.d.ts +5 -4
  34. package/dist/types/css/types/color-spaces/rec2020.d.ts +5 -4
  35. package/dist/types/css/types/color-spaces/srgb.d.ts +5 -4
  36. package/dist/types/css/types/color-utilities.d.ts +11 -11
  37. package/dist/types/css/types/color.d.ts +1 -0
  38. package/dist/types/css/types/functions/conic-gradient.d.ts +17 -0
  39. package/dist/types/css/types/functions/image-set.d.ts +11 -0
  40. package/dist/types/css/types/functions/repeating-radial-gradient.d.ts +8 -0
  41. package/dist/types/css/types/image.d.ts +17 -2
  42. package/dist/types/css/types/safe-eval.d.ts +0 -6
  43. package/dist/types/dom/copy-css-styles.d.ts +8 -0
  44. package/dist/types/dom/document-cloner.d.ts +3 -13
  45. package/dist/types/dom/iframe-mount.d.ts +37 -0
  46. package/dist/types/dom/pseudo-content.d.ts +33 -0
  47. package/dist/types/dom/replaced-elements/iframe-element-container.d.ts +2 -2
  48. package/dist/types/dom/replaced-elements/input-element-container.d.ts +1 -1
  49. package/dist/types/options.d.ts +8 -2
  50. package/dist/types/render/canvas/background-renderer.d.ts +28 -0
  51. package/dist/types/render/canvas/border-image-renderer.d.ts +50 -1
  52. package/dist/types/render/canvas/canvas-renderer.d.ts +29 -15
  53. package/dist/types/render/canvas/effects-renderer.d.ts +8 -0
  54. package/dist/types/render/canvas/mask-renderer.d.ts +36 -0
  55. package/dist/types/render/canvas/text-clip-renderer.d.ts +56 -0
  56. package/dist/types/render/canvas/text-renderer.d.ts +22 -0
  57. package/dist/types/render/stacking-context.d.ts +4 -1
  58. package/package.json +41 -42
  59. package/dist/lib/config.js +0 -49
  60. package/dist/lib/core/abort-helper.js +0 -20
  61. package/dist/lib/core/background-parser.js +0 -41
  62. package/dist/lib/core/bitwise.js +0 -5
  63. package/dist/lib/core/cache-storage.js +0 -283
  64. package/dist/lib/core/config-assembler.js +0 -88
  65. package/dist/lib/core/constants.js +0 -25
  66. package/dist/lib/core/context.js +0 -19
  67. package/dist/lib/core/debugger.js +0 -27
  68. package/dist/lib/core/features.js +0 -190
  69. package/dist/lib/core/logger.js +0 -56
  70. package/dist/lib/core/lru-map.js +0 -66
  71. package/dist/lib/core/origin-checker.js +0 -53
  72. package/dist/lib/core/performance-monitor.js +0 -185
  73. package/dist/lib/core/render-element.js +0 -131
  74. package/dist/lib/core/util.js +0 -4
  75. package/dist/lib/core/validator.js +0 -500
  76. package/dist/lib/css/grouped/background-styles.js +0 -36
  77. package/dist/lib/css/grouped/border-styles.js +0 -75
  78. package/dist/lib/css/grouped/font-styles.js +0 -93
  79. package/dist/lib/css/grouped/layout-styles.js +0 -127
  80. package/dist/lib/css/index.js +0 -339
  81. package/dist/lib/css/layout/bounds.js +0 -52
  82. package/dist/lib/css/layout/text.js +0 -133
  83. package/dist/lib/css/property-descriptor.js +0 -2
  84. package/dist/lib/css/property-descriptors/background-blend-mode.js +0 -41
  85. package/dist/lib/css/property-descriptors/background-clip.js +0 -25
  86. package/dist/lib/css/property-descriptors/background-color.js +0 -10
  87. package/dist/lib/css/property-descriptors/background-image.js +0 -24
  88. package/dist/lib/css/property-descriptors/background-origin.js +0 -23
  89. package/dist/lib/css/property-descriptors/background-position.js +0 -19
  90. package/dist/lib/css/property-descriptors/background-repeat.js +0 -33
  91. package/dist/lib/css/property-descriptors/background-size.js +0 -23
  92. package/dist/lib/css/property-descriptors/border-color.js +0 -14
  93. package/dist/lib/css/property-descriptors/border-image-repeat.js +0 -42
  94. package/dist/lib/css/property-descriptors/border-image-slice.js +0 -45
  95. package/dist/lib/css/property-descriptors/border-image-source.js +0 -22
  96. package/dist/lib/css/property-descriptors/border-radius.js +0 -15
  97. package/dist/lib/css/property-descriptors/border-style.js +0 -26
  98. package/dist/lib/css/property-descriptors/border-width.js +0 -20
  99. package/dist/lib/css/property-descriptors/box-decoration-break.js +0 -18
  100. package/dist/lib/css/property-descriptors/box-shadow.js +0 -54
  101. package/dist/lib/css/property-descriptors/clip-path.js +0 -189
  102. package/dist/lib/css/property-descriptors/color.js +0 -10
  103. package/dist/lib/css/property-descriptors/content.js +0 -19
  104. package/dist/lib/css/property-descriptors/counter-increment.js +0 -35
  105. package/dist/lib/css/property-descriptors/counter-reset.js +0 -18
  106. package/dist/lib/css/property-descriptors/direction.js +0 -18
  107. package/dist/lib/css/property-descriptors/display.js +0 -81
  108. package/dist/lib/css/property-descriptors/duration.js +0 -14
  109. package/dist/lib/css/property-descriptors/filter.js +0 -86
  110. package/dist/lib/css/property-descriptors/float.js +0 -22
  111. package/dist/lib/css/property-descriptors/font-family.js +0 -47
  112. package/dist/lib/css/property-descriptors/font-size.js +0 -10
  113. package/dist/lib/css/property-descriptors/font-style.js +0 -20
  114. package/dist/lib/css/property-descriptors/font-variant-ligatures.js +0 -34
  115. package/dist/lib/css/property-descriptors/font-variant.js +0 -13
  116. package/dist/lib/css/property-descriptors/font-weight.js +0 -25
  117. package/dist/lib/css/property-descriptors/image-rendering.js +0 -33
  118. package/dist/lib/css/property-descriptors/letter-spacing.js +0 -21
  119. package/dist/lib/css/property-descriptors/line-break.js +0 -23
  120. package/dist/lib/css/property-descriptors/line-height.js +0 -24
  121. package/dist/lib/css/property-descriptors/list-style-image.js +0 -17
  122. package/dist/lib/css/property-descriptors/list-style-position.js +0 -18
  123. package/dist/lib/css/property-descriptors/list-style-type.js +0 -122
  124. package/dist/lib/css/property-descriptors/margin.js +0 -13
  125. package/dist/lib/css/property-descriptors/mix-blend-mode.js +0 -31
  126. package/dist/lib/css/property-descriptors/object-fit.js +0 -28
  127. package/dist/lib/css/property-descriptors/object-position.js +0 -42
  128. package/dist/lib/css/property-descriptors/opacity.js +0 -16
  129. package/dist/lib/css/property-descriptors/overflow-wrap.js +0 -18
  130. package/dist/lib/css/property-descriptors/overflow.js +0 -27
  131. package/dist/lib/css/property-descriptors/padding.js +0 -14
  132. package/dist/lib/css/property-descriptors/paint-order.js +0 -33
  133. package/dist/lib/css/property-descriptors/position.js +0 -22
  134. package/dist/lib/css/property-descriptors/quotes.js +0 -41
  135. package/dist/lib/css/property-descriptors/rotate.js +0 -27
  136. package/dist/lib/css/property-descriptors/text-align.js +0 -21
  137. package/dist/lib/css/property-descriptors/text-decoration-color.js +0 -10
  138. package/dist/lib/css/property-descriptors/text-decoration-line.js +0 -28
  139. package/dist/lib/css/property-descriptors/text-decoration-style.js +0 -24
  140. package/dist/lib/css/property-descriptors/text-decoration-thickness.js +0 -26
  141. package/dist/lib/css/property-descriptors/text-overflow.js +0 -18
  142. package/dist/lib/css/property-descriptors/text-shadow.js +0 -46
  143. package/dist/lib/css/property-descriptors/text-transform.js +0 -20
  144. package/dist/lib/css/property-descriptors/text-underline-offset.js +0 -23
  145. package/dist/lib/css/property-descriptors/transform-origin.js +0 -24
  146. package/dist/lib/css/property-descriptors/transform.js +0 -57
  147. package/dist/lib/css/property-descriptors/visibility.js +0 -20
  148. package/dist/lib/css/property-descriptors/webkit-line-clamp.js +0 -26
  149. package/dist/lib/css/property-descriptors/webkit-text-stroke-color.js +0 -10
  150. package/dist/lib/css/property-descriptors/webkit-text-stroke-width.js +0 -16
  151. package/dist/lib/css/property-descriptors/white-space.js +0 -32
  152. package/dist/lib/css/property-descriptors/word-break.js +0 -26
  153. package/dist/lib/css/property-descriptors/writing-mode.js +0 -28
  154. package/dist/lib/css/property-descriptors/z-index.js +0 -19
  155. package/dist/lib/css/property-descriptors/zoom.js +0 -18
  156. package/dist/lib/css/syntax/parser.js +0 -141
  157. package/dist/lib/css/syntax/token-constants.js +0 -214
  158. package/dist/lib/css/syntax/token-singletons.js +0 -36
  159. package/dist/lib/css/syntax/token-types.js +0 -10
  160. package/dist/lib/css/syntax/tokenizer.js +0 -502
  161. package/dist/lib/css/type-descriptor.js +0 -2
  162. package/dist/lib/css/types/angle.js +0 -80
  163. package/dist/lib/css/types/color-math.js +0 -25
  164. package/dist/lib/css/types/color-spaces/a98.js +0 -78
  165. package/dist/lib/css/types/color-spaces/p3.js +0 -86
  166. package/dist/lib/css/types/color-spaces/pro-photo.js +0 -83
  167. package/dist/lib/css/types/color-spaces/rec2020.js +0 -85
  168. package/dist/lib/css/types/color-spaces/srgb.js +0 -79
  169. package/dist/lib/css/types/color-utilities.js +0 -342
  170. package/dist/lib/css/types/color.js +0 -400
  171. package/dist/lib/css/types/functions/-prefix-linear-gradient.js +0 -32
  172. package/dist/lib/css/types/functions/-prefix-radial-gradient.js +0 -83
  173. package/dist/lib/css/types/functions/-webkit-gradient.js +0 -59
  174. package/dist/lib/css/types/functions/counter.js +0 -367
  175. package/dist/lib/css/types/functions/gradient.js +0 -163
  176. package/dist/lib/css/types/functions/linear-gradient.js +0 -27
  177. package/dist/lib/css/types/functions/radial-gradient.js +0 -90
  178. package/dist/lib/css/types/functions/repeating-linear-gradient.js +0 -9
  179. package/dist/lib/css/types/image.js +0 -62
  180. package/dist/lib/css/types/index.js +0 -2
  181. package/dist/lib/css/types/length-percentage.js +0 -197
  182. package/dist/lib/css/types/length.js +0 -5
  183. package/dist/lib/css/types/safe-eval.js +0 -80
  184. package/dist/lib/css/types/time.js +0 -17
  185. package/dist/lib/dom/document-cloner.js +0 -618
  186. package/dist/lib/dom/dom-normalizer.js +0 -115
  187. package/dist/lib/dom/element-container.js +0 -71
  188. package/dist/lib/dom/elements/li-element-container.js +0 -11
  189. package/dist/lib/dom/elements/ol-element-container.js +0 -12
  190. package/dist/lib/dom/elements/select-element-container.js +0 -12
  191. package/dist/lib/dom/elements/textarea-element-container.js +0 -11
  192. package/dist/lib/dom/node-parser.js +0 -125
  193. package/dist/lib/dom/node-type-guards.js +0 -81
  194. package/dist/lib/dom/replaced-elements/canvas-element-container.js +0 -13
  195. package/dist/lib/dom/replaced-elements/iframe-element-container.js +0 -38
  196. package/dist/lib/dom/replaced-elements/image-element-container.js +0 -14
  197. package/dist/lib/dom/replaced-elements/index.js +0 -2
  198. package/dist/lib/dom/replaced-elements/input-element-container.js +0 -89
  199. package/dist/lib/dom/replaced-elements/svg-element-container.js +0 -57
  200. package/dist/lib/dom/slot-cloner.js +0 -176
  201. package/dist/lib/dom/text-container.js +0 -35
  202. package/dist/lib/index.js +0 -49
  203. package/dist/lib/options.js +0 -2
  204. package/dist/lib/render/background.js +0 -188
  205. package/dist/lib/render/bezier-curve.js +0 -34
  206. package/dist/lib/render/border.js +0 -104
  207. package/dist/lib/render/bound-curves.js +0 -188
  208. package/dist/lib/render/box-sizing.js +0 -20
  209. package/dist/lib/render/canvas/background-renderer.js +0 -338
  210. package/dist/lib/render/canvas/border-image-renderer.js +0 -153
  211. package/dist/lib/render/canvas/border-renderer.js +0 -184
  212. package/dist/lib/render/canvas/box-shadow-geometry.js +0 -52
  213. package/dist/lib/render/canvas/box-shadow-painter.js +0 -194
  214. package/dist/lib/render/canvas/box-shadow-transform.js +0 -42
  215. package/dist/lib/render/canvas/canvas-path.js +0 -25
  216. package/dist/lib/render/canvas/canvas-renderer.js +0 -610
  217. package/dist/lib/render/canvas/content-renderer.js +0 -270
  218. package/dist/lib/render/canvas/effects-renderer.js +0 -171
  219. package/dist/lib/render/canvas/filter-surface.js +0 -270
  220. package/dist/lib/render/canvas/font-utils.js +0 -46
  221. package/dist/lib/render/canvas/foreignobject-renderer.js +0 -38
  222. package/dist/lib/render/canvas/surface-bounds.js +0 -64
  223. package/dist/lib/render/canvas/text/text-decoration-renderer.js +0 -99
  224. package/dist/lib/render/canvas/text-renderer.js +0 -486
  225. package/dist/lib/render/effects.js +0 -231
  226. package/dist/lib/render/font-metrics.js +0 -53
  227. package/dist/lib/render/object-fit.js +0 -91
  228. package/dist/lib/render/path.js +0 -26
  229. package/dist/lib/render/renderer-interface.js +0 -2
  230. package/dist/lib/render/stacking-context.js +0 -341
  231. package/dist/lib/render/vector.js +0 -16
@@ -1,56 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Logger = void 0;
4
- class Logger {
5
- constructor({ id, enabled }) {
6
- this.id = id;
7
- this.enabled = enabled;
8
- this.start = Date.now();
9
- }
10
- debug(...args) {
11
- if (this.enabled) {
12
- // eslint-disable-next-line no-console
13
- if (typeof window !== 'undefined' && window.console && typeof console.debug === 'function') {
14
- // eslint-disable-next-line no-console
15
- console.debug(this.id, `${this.getTime()}ms`, ...args);
16
- }
17
- else {
18
- this.info(...args);
19
- }
20
- }
21
- }
22
- getTime() {
23
- return Date.now() - this.start;
24
- }
25
- info(...args) {
26
- if (this.enabled) {
27
- // eslint-disable-next-line no-console
28
- if (typeof window !== 'undefined' && window.console && typeof console.info === 'function') {
29
- // eslint-disable-next-line no-console
30
- console.info(this.id, `${this.getTime()}ms`, ...args);
31
- }
32
- }
33
- }
34
- warn(...args) {
35
- if (this.enabled) {
36
- if (typeof window !== 'undefined' && window.console && typeof console.warn === 'function') {
37
- console.warn(this.id, `${this.getTime()}ms`, ...args);
38
- }
39
- else {
40
- this.info(...args);
41
- }
42
- }
43
- }
44
- error(...args) {
45
- if (this.enabled) {
46
- if (typeof window !== 'undefined' && window.console && typeof console.error === 'function') {
47
- console.error(this.id, `${this.getTime()}ms`, ...args);
48
- }
49
- else {
50
- this.info(...args);
51
- }
52
- }
53
- }
54
- }
55
- exports.Logger = Logger;
56
- Logger.instances = {};
@@ -1,66 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LRUMap = void 0;
4
- /**
5
- * Generic LRU (Least-Recently-Used) wrapper over a native `Map`.
6
- *
7
- * Both the CSS parse cache and the background pattern cache implement the
8
- * same LRU eviction pattern using Map's insertion-order guarantee. This
9
- * tiny utility centralises that logic so it can be reused without
10
- * duplication.
11
- *
12
- * Usage:
13
- * ```ts
14
- * const cache = new LRUMap<string, CanvasPattern>(50);
15
- * const entry = cache.get(key); // promotes if found, returns undefined otherwise
16
- * cache.set(key, value); // evicts oldest entry when at capacity
17
- * ```
18
- */
19
- class LRUMap {
20
- constructor(maxSize) {
21
- this.maxSize = maxSize;
22
- this._map = new Map();
23
- }
24
- /**
25
- * Get a value by key.
26
- * On cache hit the entry is promoted to the end of the Map (most-recently-used).
27
- * Returns `undefined` on miss.
28
- */
29
- get(key) {
30
- if (!this._map.has(key)) {
31
- return undefined;
32
- }
33
- // Delete-then-set promotes the entry to MRU position.
34
- const value = this._map.get(key);
35
- this._map.delete(key);
36
- this._map.set(key, value);
37
- return value;
38
- }
39
- /**
40
- * Insert or update a key-value pair.
41
- * If the key already exists it is moved to MRU position. If the map is
42
- * at capacity the least-recently-used entry (oldest insertion order) is
43
- * evicted before inserting.
44
- */
45
- set(key, value) {
46
- if (this._map.has(key)) {
47
- this._map.delete(key);
48
- }
49
- else if (this._map.size >= this.maxSize) {
50
- const oldestKey = this._map.keys().next().value;
51
- if (oldestKey !== undefined) {
52
- this._map.delete(oldestKey);
53
- }
54
- }
55
- this._map.set(key, value);
56
- }
57
- /** Current number of entries. */
58
- get size() {
59
- return this._map.size;
60
- }
61
- /** Remove all entries. */
62
- clear() {
63
- this._map.clear();
64
- }
65
- }
66
- exports.LRUMap = LRUMap;
@@ -1,53 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OriginChecker = void 0;
4
- /**
5
- * Origin Checker
6
- *
7
- * Provides origin checking functionality without global static state.
8
- * Each instance maintains its own anchor element and origin reference.
9
- *
10
- * Replaces the static methods in CacheStorage with instance-based approach.
11
- */
12
- class OriginChecker {
13
- constructor(window) {
14
- if (!window || !window.document) {
15
- throw new Error('Valid window object required for OriginChecker');
16
- }
17
- if (!window.location || !window.location.href) {
18
- throw new Error('Window object must have valid location');
19
- }
20
- this.link = window.document.createElement('a');
21
- this.origin = this.getOrigin(window.location.href);
22
- }
23
- /**
24
- * Get the origin (protocol + hostname + port) of a URL
25
- *
26
- * @param url - URL to parse
27
- * @returns Origin string (e.g., "https://example.com:8080")
28
- */
29
- getOrigin(url) {
30
- this.link.href = url;
31
- // IE9 hack: accessing href twice to ensure it's properly parsed
32
- this.link.href = this.link.href;
33
- return this.link.protocol + this.link.hostname + this.link.port;
34
- }
35
- /**
36
- * Check if a URL is from the same origin as the context
37
- *
38
- * @param src - URL to check
39
- * @returns true if same origin, false otherwise
40
- */
41
- isSameOrigin(src) {
42
- return this.getOrigin(src) === this.origin;
43
- }
44
- /**
45
- * Get the current context origin
46
- *
47
- * @returns The origin of the context window
48
- */
49
- getContextOrigin() {
50
- return this.origin;
51
- }
52
- }
53
- exports.OriginChecker = OriginChecker;
@@ -1,185 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PerformanceMonitor = void 0;
4
- /**
5
- * Performance Monitor
6
- *
7
- * Tracks performance metrics throughout the rendering pipeline.
8
- * Provides insights into where time is spent during rendering.
9
- *
10
- * Usage:
11
- * ```typescript
12
- * const monitor = new PerformanceMonitor(context);
13
- *
14
- * monitor.start('clone');
15
- * await cloneDocument();
16
- * monitor.end('clone');
17
- *
18
- * const summary = monitor.getSummary();
19
- * ```
20
- */
21
- class PerformanceMonitor {
22
- constructor(context, enabled = true) {
23
- this.context = context;
24
- this.activeMetrics = new Map();
25
- this.completedMetrics = [];
26
- this.enabled = enabled;
27
- // Fallback for environments without performance.now()
28
- this.getTime =
29
- typeof performance !== 'undefined' && typeof performance.now === 'function'
30
- ? () => performance.now()
31
- : () => Date.now();
32
- }
33
- /**
34
- * Start measuring a performance metric
35
- *
36
- * @param name - Unique name for this metric
37
- * @param metadata - Optional metadata to attach
38
- */
39
- start(name, metadata) {
40
- if (!this.enabled) {
41
- return;
42
- }
43
- if (this.activeMetrics.has(name)) {
44
- this.context?.logger.warn(`Performance metric '${name}' already started. Overwriting.`);
45
- }
46
- this.activeMetrics.set(name, {
47
- name,
48
- startTime: this.getTime(),
49
- metadata
50
- });
51
- }
52
- /**
53
- * End measuring a performance metric
54
- *
55
- * @param name - Name of the metric to end
56
- * @returns The completed metric, or undefined if not found
57
- */
58
- end(name) {
59
- if (!this.enabled) {
60
- return undefined;
61
- }
62
- const metric = this.activeMetrics.get(name);
63
- if (!metric) {
64
- this.context?.logger.warn(`Performance metric '${name}' not found. Was start() called?`);
65
- return undefined;
66
- }
67
- metric.endTime = this.getTime();
68
- metric.duration = metric.endTime - metric.startTime;
69
- this.completedMetrics.push(metric);
70
- this.activeMetrics.delete(name);
71
- this.context?.logger.debug(`⏱️ ${name}: ${metric.duration.toFixed(2)}ms`, metric.metadata);
72
- return metric;
73
- }
74
- /**
75
- * Measure a synchronous function
76
- *
77
- * @param name - Name for this measurement
78
- * @param fn - Function to measure
79
- * @param metadata - Optional metadata
80
- * @returns The function's return value
81
- */
82
- measure(name, fn, metadata) {
83
- this.start(name, metadata);
84
- try {
85
- const result = fn();
86
- this.end(name);
87
- return result;
88
- }
89
- catch (error) {
90
- this.end(name);
91
- throw error;
92
- }
93
- }
94
- /**
95
- * Measure an asynchronous function
96
- *
97
- * @param name - Name for this measurement
98
- * @param fn - Async function to measure
99
- * @param metadata - Optional metadata
100
- * @returns Promise resolving to the function's return value
101
- */
102
- async measureAsync(name, fn, metadata) {
103
- this.start(name, metadata);
104
- try {
105
- const result = await fn();
106
- this.end(name);
107
- return result;
108
- }
109
- catch (error) {
110
- this.end(name);
111
- throw error;
112
- }
113
- }
114
- /**
115
- * Get all completed metrics
116
- *
117
- * @returns Array of completed performance metrics
118
- */
119
- getMetrics() {
120
- return [...this.completedMetrics];
121
- }
122
- /**
123
- * Get a specific metric by name
124
- *
125
- * @param name - Metric name
126
- * @returns The metric, or undefined if not found
127
- */
128
- getMetric(name) {
129
- return this.completedMetrics.find((m) => m.name === name);
130
- }
131
- /**
132
- * Get performance summary
133
- *
134
- * @returns Aggregated performance data
135
- */
136
- getSummary() {
137
- const totalDuration = this.completedMetrics.reduce((sum, metric) => sum + (metric.duration || 0), 0);
138
- const breakdown = this.completedMetrics.map((metric) => ({
139
- name: metric.name,
140
- duration: metric.duration || 0,
141
- percentage: totalDuration > 0 ? (((metric.duration || 0) / totalDuration) * 100).toFixed(1) + '%' : '0%'
142
- }));
143
- return {
144
- totalDuration,
145
- metrics: this.getMetrics(),
146
- breakdown
147
- };
148
- }
149
- /**
150
- * Log performance summary to console
151
- */
152
- logSummary() {
153
- if (!this.enabled || this.completedMetrics.length === 0 || !this.context) {
154
- return;
155
- }
156
- const summary = this.getSummary();
157
- this.context.logger.info(`\n📊 Performance Summary (Total: ${summary.totalDuration.toFixed(2)}ms):`);
158
- summary.breakdown
159
- .sort((a, b) => b.duration - a.duration)
160
- .forEach((item) => {
161
- this.context.logger.info(` ${item.name.padEnd(20)} ${item.duration.toFixed(2).padStart(8)}ms ${item.percentage.padStart(6)}`);
162
- });
163
- }
164
- /**
165
- * Clear all metrics
166
- */
167
- clear() {
168
- this.activeMetrics.clear();
169
- this.completedMetrics.splice(0);
170
- }
171
- /**
172
- * Check if monitoring is enabled
173
- */
174
- isEnabled() {
175
- return this.enabled;
176
- }
177
- /**
178
- * Get active (uncompleted) metrics
179
- * Useful for debugging leaked measurements
180
- */
181
- getActiveMetrics() {
182
- return Array.from(this.activeMetrics.keys());
183
- }
184
- }
185
- exports.PerformanceMonitor = PerformanceMonitor;
@@ -1,131 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.renderElement = void 0;
4
- const bounds_1 = require("../css/layout/bounds");
5
- const color_1 = require("../css/types/color");
6
- const document_cloner_1 = require("../dom/document-cloner");
7
- const node_type_guards_1 = require("../dom/node-type-guards");
8
- const node_parser_1 = require("../dom/node-parser");
9
- const canvas_renderer_1 = require("../render/canvas/canvas-renderer");
10
- const foreignobject_renderer_1 = require("../render/canvas/foreignobject-renderer");
11
- const context_1 = require("./context");
12
- const validator_1 = require("./validator");
13
- const performance_monitor_1 = require("./performance-monitor");
14
- const abort_helper_1 = require("./abort-helper");
15
- const config_assembler_1 = require("./config-assembler");
16
- const background_parser_1 = require("./background-parser");
17
- const renderElement = async (element, opts, config) => {
18
- (0, config_assembler_1.coerceNumberOptions)(opts);
19
- // Input validation (unless explicitly skipped)
20
- if (!opts.skipValidation) {
21
- const validator = opts.validator || (0, validator_1.createDefaultValidator)();
22
- const elementValidation = validator.validateElement(element);
23
- if (!elementValidation.valid) {
24
- throw new Error(elementValidation.error);
25
- }
26
- const optionsValidation = validator.validateOptions(opts);
27
- if (!optionsValidation.valid) {
28
- throw new Error(`Invalid options: ${optionsValidation.error}`);
29
- }
30
- }
31
- if (!element || typeof element !== 'object') {
32
- throw new Error('Invalid element provided as first argument');
33
- }
34
- const ownerDocument = element.ownerDocument;
35
- if (!ownerDocument) {
36
- throw new Error(`Element is not attached to a Document`);
37
- }
38
- const defaultView = ownerDocument.defaultView;
39
- if (!defaultView) {
40
- throw new Error(`Document is not attached to a Window`);
41
- }
42
- const resourceOptions = (0, config_assembler_1.assembleResourceOptions)(opts);
43
- const contextOptions = (0, config_assembler_1.assembleContextOptions)(opts, config, resourceOptions);
44
- const windowOptions = (0, config_assembler_1.assembleWindowOptions)(opts, defaultView);
45
- const windowBounds = new bounds_1.Bounds(windowOptions.scrollX, windowOptions.scrollY, windowOptions.windowWidth, windowOptions.windowHeight);
46
- const context = new context_1.Context(contextOptions, windowBounds, config);
47
- const performanceMonitoring = opts.enablePerformanceMonitoring ?? opts.logging ?? false;
48
- const perfMonitor = new performance_monitor_1.PerformanceMonitor(context, performanceMonitoring);
49
- perfMonitor.start('total', {
50
- width: windowOptions.windowWidth,
51
- height: windowOptions.windowHeight
52
- });
53
- const signal = opts.signal;
54
- (0, abort_helper_1.throwIfAborted)(signal);
55
- const foreignObjectRendering = opts.foreignObjectRendering ?? false;
56
- const cloneOptions = (0, config_assembler_1.assembleCloneOptions)(opts, config, foreignObjectRendering);
57
- context.logger.debug(`Starting document clone with size ${windowBounds.width}x${windowBounds.height} scrolled to ${-windowBounds.left},${-windowBounds.top}`);
58
- perfMonitor.start('clone');
59
- const documentCloner = new document_cloner_1.DocumentCloner(context, element, cloneOptions);
60
- const clonedElement = documentCloner.clonedReferenceElement;
61
- if (!clonedElement) {
62
- throw new Error('Unable to find element in cloned iframe');
63
- }
64
- const container = await documentCloner.toIFrame(ownerDocument, windowBounds);
65
- perfMonitor.end('clone');
66
- if (signal?.aborted) {
67
- if (opts.removeContainer ?? true) {
68
- document_cloner_1.DocumentCloner.destroy(container);
69
- }
70
- (0, abort_helper_1.throwIfAborted)(signal);
71
- }
72
- const { width, height, left, top } = (0, node_type_guards_1.isBodyElement)(clonedElement) || (0, node_type_guards_1.isHTMLElement)(clonedElement)
73
- ? (0, bounds_1.parseDocumentSize)(clonedElement.ownerDocument)
74
- : (0, bounds_1.parseBounds)(context, clonedElement);
75
- const backgroundColor = (0, background_parser_1.parseBackgroundColor)(context, clonedElement, opts.backgroundColor);
76
- const renderOptions = (0, config_assembler_1.assembleRenderOptions)(opts, backgroundColor, left, top, width, height, defaultView.devicePixelRatio ?? 1);
77
- let canvas;
78
- let root;
79
- try {
80
- if (foreignObjectRendering) {
81
- context.logger.debug(`Document cloned, using foreign object rendering`);
82
- perfMonitor.start('render-foreignobject');
83
- const renderer = new foreignobject_renderer_1.ForeignObjectRenderer(context, renderOptions);
84
- canvas = await renderer.render(clonedElement);
85
- perfMonitor.end('render-foreignobject');
86
- }
87
- else {
88
- context.logger.debug(`Document cloned, element located at ${left},${top} with size ${width}x${height} using computed rendering`);
89
- context.logger.debug(`Starting DOM parsing`);
90
- perfMonitor.start('parse');
91
- (0, abort_helper_1.throwIfAborted)(signal);
92
- // Enter defer mode: collect all image URLs during parse without
93
- // starting individual loads. This avoids serialised loading in
94
- // DOM-traversal order.
95
- context.cache.startDefer();
96
- root = (0, node_parser_1.parseTree)(context, clonedElement);
97
- perfMonitor.end('parse');
98
- // Batch-preload all collected images in parallel before rendering.
99
- perfMonitor.start('preload');
100
- await context.cache.preloadAll();
101
- perfMonitor.end('preload');
102
- if (backgroundColor === root.styles.backgroundColor) {
103
- root.styles.backgroundColor = color_1.COLORS.TRANSPARENT;
104
- }
105
- context.logger.debug(`Starting renderer for element at ${renderOptions.x},${renderOptions.y} with size ${renderOptions.width}x${renderOptions.height}`);
106
- perfMonitor.start('render');
107
- (0, abort_helper_1.throwIfAborted)(signal);
108
- const renderer = new canvas_renderer_1.CanvasRenderer(context, renderOptions);
109
- canvas = await renderer.render(root);
110
- perfMonitor.end('render');
111
- }
112
- }
113
- finally {
114
- perfMonitor.start('cleanup');
115
- try {
116
- if (root)
117
- root.restoreTree();
118
- }
119
- finally {
120
- if (opts.removeContainer ?? true)
121
- document_cloner_1.DocumentCloner.destroy(container);
122
- perfMonitor.end('cleanup');
123
- }
124
- }
125
- perfMonitor.end('total');
126
- context.logger.debug(`Finished rendering`);
127
- if (performanceMonitoring)
128
- perfMonitor.logSummary();
129
- return canvas;
130
- };
131
- exports.renderElement = renderElement;
@@ -1,4 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SMALL_IMAGE = void 0;
4
- exports.SMALL_IMAGE = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';