html2canvas-pro 2.4.4 → 2.5.0

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 (228) hide show
  1. package/README.md +115 -13
  2. package/dist/html2canvas-pro.cjs +3246 -1601
  3. package/dist/html2canvas-pro.cjs.map +1 -1
  4. package/dist/html2canvas-pro.esm.js +3246 -1601
  5. package/dist/html2canvas-pro.esm.js.map +1 -1
  6. package/dist/html2canvas-pro.js +3242 -1597
  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 +4 -1
  10. package/dist/types/core/context.d.ts +10 -1
  11. package/dist/types/core/render-element.d.ts +11 -0
  12. package/dist/types/core/util.d.ts +6 -0
  13. package/dist/types/css/index.d.ts +77 -46
  14. package/dist/types/css/parse.d.ts +15 -0
  15. package/dist/types/css/property-descriptors/accent-color.d.ts +5 -0
  16. package/dist/types/css/property-descriptors/backdrop-filter.d.ts +9 -0
  17. package/dist/types/css/property-descriptors/background-blend-mode.d.ts +16 -16
  18. package/dist/types/css/property-descriptors/border-image-width.d.ts +36 -0
  19. package/dist/types/css/property-descriptors/clip-path.d.ts +16 -2
  20. package/dist/types/css/property-descriptors/isolation.d.ts +6 -0
  21. package/dist/types/css/property-descriptors/mask.d.ts +25 -0
  22. package/dist/types/css/property-descriptors/mix-blend-mode.d.ts +16 -16
  23. package/dist/types/css/property-descriptors/outline.d.ts +15 -0
  24. package/dist/types/css/property-descriptors/text-emphasis.d.ts +22 -0
  25. package/dist/types/css/property-descriptors/text-shadow.d.ts +1 -1
  26. package/dist/types/css/property-descriptors/webkit-box-reflect.d.ts +19 -0
  27. package/dist/types/css/property-descriptors/webkit-text-fill-color.d.ts +9 -0
  28. package/dist/types/css/syntax/token-constants.d.ts +1 -1
  29. package/dist/types/css/types/color-math.d.ts +7 -1
  30. package/dist/types/css/types/color-spaces/a98.d.ts +2 -1
  31. package/dist/types/css/types/color-spaces/p3.d.ts +5 -4
  32. package/dist/types/css/types/color-spaces/pro-photo.d.ts +5 -4
  33. package/dist/types/css/types/color-spaces/rec2020.d.ts +5 -4
  34. package/dist/types/css/types/color-spaces/srgb.d.ts +5 -4
  35. package/dist/types/css/types/color-utilities.d.ts +11 -11
  36. package/dist/types/css/types/color.d.ts +1 -0
  37. package/dist/types/css/types/functions/conic-gradient.d.ts +11 -0
  38. package/dist/types/css/types/functions/image-set.d.ts +11 -0
  39. package/dist/types/css/types/functions/repeating-radial-gradient.d.ts +8 -0
  40. package/dist/types/css/types/image.d.ts +15 -2
  41. package/dist/types/css/types/safe-eval.d.ts +0 -6
  42. package/dist/types/dom/copy-css-styles.d.ts +8 -0
  43. package/dist/types/dom/document-cloner.d.ts +3 -13
  44. package/dist/types/dom/iframe-mount.d.ts +37 -0
  45. package/dist/types/dom/pseudo-content.d.ts +33 -0
  46. package/dist/types/dom/replaced-elements/iframe-element-container.d.ts +2 -2
  47. package/dist/types/options.d.ts +8 -2
  48. package/dist/types/render/canvas/background-renderer.d.ts +19 -0
  49. package/dist/types/render/canvas/border-image-renderer.d.ts +50 -1
  50. package/dist/types/render/canvas/box-shadow-geometry.d.ts +3 -0
  51. package/dist/types/render/canvas/box-shadow-painter.d.ts +13 -0
  52. package/dist/types/render/canvas/box-shadow-transform.d.ts +16 -0
  53. package/dist/types/render/canvas/canvas-renderer.d.ts +21 -15
  54. package/dist/types/render/canvas/mask-renderer.d.ts +36 -0
  55. package/dist/types/render/canvas/text-clip-renderer.d.ts +36 -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 +39 -40
  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/canvas-path.js +0 -25
  213. package/dist/lib/render/canvas/canvas-renderer.js +0 -633
  214. package/dist/lib/render/canvas/content-renderer.js +0 -270
  215. package/dist/lib/render/canvas/effects-renderer.js +0 -171
  216. package/dist/lib/render/canvas/filter-surface.js +0 -270
  217. package/dist/lib/render/canvas/font-utils.js +0 -46
  218. package/dist/lib/render/canvas/foreignobject-renderer.js +0 -38
  219. package/dist/lib/render/canvas/surface-bounds.js +0 -64
  220. package/dist/lib/render/canvas/text/text-decoration-renderer.js +0 -99
  221. package/dist/lib/render/canvas/text-renderer.js +0 -486
  222. package/dist/lib/render/effects.js +0 -231
  223. package/dist/lib/render/font-metrics.js +0 -53
  224. package/dist/lib/render/object-fit.js +0 -91
  225. package/dist/lib/render/path.js +0 -26
  226. package/dist/lib/render/renderer-interface.js +0 -2
  227. package/dist/lib/render/stacking-context.js +0 -341
  228. package/dist/lib/render/vector.js +0 -16
@@ -1,270 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.releaseSurface = exports.FilterSurfaceError = void 0;
4
- exports.parseSimpleFilter = parseSimpleFilter;
5
- exports.filterOutset = filterOutset;
6
- exports.supportsNativeFilters = supportsNativeFilters;
7
- exports.renderFilterSurface = renderFilterSurface;
8
- exports.renderSvgFilterSurface = renderSvgFilterSurface;
9
- const effects_1 = require("../effects");
10
- const abort_helper_1 = require("../../core/abort-helper");
11
- // Only errors in the optional surface path are eligible for legacy fallback.
12
- class FilterSurfaceError extends Error {
13
- }
14
- exports.FilterSurfaceError = FilterSurfaceError;
15
- const releaseSurface = (canvas) => {
16
- canvas.width = canvas.height = 0;
17
- };
18
- exports.releaseSurface = releaseSurface;
19
- // This first renderer integration handles computed blur followed by one shadow.
20
- // Unsupported chains retain the existing renderer until general filter support lands.
21
- function parseSimpleFilter(value) {
22
- if (!value || value === 'none')
23
- return { blur: 0 };
24
- const effect = new effects_1.FilterEffect(value);
25
- const shadows = value.match(/drop-shadow\(/g) || [];
26
- if (shadows.length > 1 || (shadows.length === 1 && !effect.shadow))
27
- return null;
28
- const blur = effect.safeFilterString.match(/^blur\((\d+(?:\.\d+)?)px\)$/);
29
- if (effect.safeFilterString && !blur)
30
- return null;
31
- if (blur && shadows.length && value.indexOf('blur(') > value.indexOf('drop-shadow('))
32
- return null;
33
- return {
34
- blur: blur ? Number(blur[1]) : 0,
35
- shadow: effect.shadow
36
- ? {
37
- x: effect.shadow.offsetX,
38
- y: effect.shadow.offsetY,
39
- blur: effect.shadow.blur,
40
- color: effect.shadow.color
41
- }
42
- : undefined
43
- };
44
- }
45
- function filterOutset(filter) {
46
- return Math.ceil(3 * (filter.blur + (filter.shadow?.blur ?? 0)) +
47
- Math.max(Math.abs(filter.shadow?.x ?? 0), Math.abs(filter.shadow?.y ?? 0)));
48
- }
49
- function canvasLike(source) {
50
- const canvas = document.createElement('canvas');
51
- canvas.width = source.width;
52
- canvas.height = source.height;
53
- return canvas;
54
- }
55
- const decodeSurface = (image, signal) => new Promise((resolve, reject) => {
56
- const finish = (error) => {
57
- clearTimeout(timer);
58
- signal?.removeEventListener('abort', abort);
59
- if (error)
60
- reject(error);
61
- else
62
- resolve();
63
- };
64
- const abort = () => finish(new DOMException('The operation was aborted.', 'AbortError'));
65
- const timer = setTimeout(() => finish(new FilterSurfaceError('Filter surface image decode timed out')), 10000);
66
- signal?.addEventListener('abort', abort, { once: true });
67
- if (signal?.aborted)
68
- abort();
69
- else
70
- image.decode().then(() => finish(), () => finish(new FilterSurfaceError('Filter surface image decode failed')));
71
- });
72
- // Cache only a capability result, never raster storage. Separate Documents may use
73
- // different Canvas implementations (including embedded webviews and test realms).
74
- const canvasFilterSupport = new WeakMap();
75
- function supportsNativeFilters(owner = document) {
76
- const cached = canvasFilterSupport.get(owner);
77
- if (cached !== undefined)
78
- return cached;
79
- const source = owner.createElement('canvas');
80
- const target = owner.createElement('canvas');
81
- let supported = false;
82
- try {
83
- source.width = source.height = target.width = target.height = 32;
84
- const input = source.getContext('2d');
85
- const context = target.getContext('2d');
86
- // Check before assignment: on older WebKit assigning filter creates an
87
- // expando property, not a working implementation.
88
- if (input && context && 'filter' in context) {
89
- input.fillStyle = '#fff';
90
- input.fillRect(8, 8, 8, 8);
91
- context.filter = 'blur(2px)';
92
- context.drawImage(source, 0, 0);
93
- const blurred = context.getImageData(6, 12, 1, 1).data[3] > 0;
94
- context.clearRect(0, 0, 32, 32);
95
- context.filter = 'drop-shadow(12px 0px 0px rgba(255, 0, 0, 0.5))';
96
- context.drawImage(source, 0, 0);
97
- const shadow = context.getImageData(24, 12, 1, 1).data;
98
- supported = blurred && shadow[0] > 240 && shadow[1] < 10 && shadow[3] >= 126 && shadow[3] <= 129;
99
- }
100
- }
101
- catch {
102
- // Readback can itself be unavailable. Be conservative and retain SVG.
103
- }
104
- finally {
105
- (0, exports.releaseSurface)(source);
106
- (0, exports.releaseSurface)(target);
107
- }
108
- canvasFilterSupport.set(owner, supported);
109
- return supported;
110
- }
111
- function tryNativeFilterSurface(source, { blur, shadow }, opacity, scale, signal) {
112
- let filtered;
113
- let output;
114
- let complete = false;
115
- try {
116
- (0, abort_helper_1.throwIfAborted)(signal);
117
- filtered = canvasLike(source);
118
- const context = filtered.getContext('2d');
119
- if (!context || !('filter' in context))
120
- return null;
121
- const functions = [];
122
- if (blur)
123
- functions.push(`blur(${blur * scale}px)`);
124
- if (shadow)
125
- functions.push(`drop-shadow(${shadow.x * scale}px ${shadow.y * scale}px ${shadow.blur * scale}px ${shadow.color})`);
126
- context.filter = functions.join(' ');
127
- if (context.filter === 'none')
128
- return null;
129
- // Canvas applies globalAlpha before filtering. Filter the complete layer
130
- // at alpha 1, then composite opacity separately, including its shadow.
131
- context.drawImage(source, 0, 0);
132
- (0, abort_helper_1.throwIfAborted)(signal);
133
- output = canvasLike(source);
134
- const composite = output.getContext('2d');
135
- if (!composite)
136
- return null;
137
- composite.globalAlpha = opacity;
138
- composite.drawImage(filtered, 0, 0);
139
- (0, abort_helper_1.throwIfAborted)(signal);
140
- complete = true;
141
- return output;
142
- }
143
- catch {
144
- // A native allocation/draw failure may still succeed through SVG, but
145
- // cancellation must never silently degrade to a successful fallback.
146
- (0, abort_helper_1.throwIfAborted)(signal);
147
- return null;
148
- }
149
- finally {
150
- if (filtered)
151
- (0, exports.releaseSurface)(filtered);
152
- if (output && !complete)
153
- (0, exports.releaseSurface)(output);
154
- }
155
- }
156
- // Backend selection is internal; the public html2canvas options are unchanged.
157
- async function renderFilterSurface(source, filter, opacity, scale, signal) {
158
- (0, abort_helper_1.throwIfAborted)(signal);
159
- if ((filter.blur || filter.shadow) && supportsNativeFilters()) {
160
- const output = tryNativeFilterSurface(source, filter, opacity, scale, signal);
161
- if (output)
162
- return output;
163
- }
164
- return renderSvgFilterSurface(source, filter, opacity, scale, signal);
165
- }
166
- // Explicit SVG entry is internal and allows independent fallback benchmarks/tests.
167
- // No foreignObject or external image is used.
168
- async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale, signal) {
169
- (0, abort_helper_1.throwIfAborted)(signal);
170
- if (!blur && !shadow) {
171
- const output = canvasLike(source);
172
- const context = output.getContext('2d');
173
- if (!context) {
174
- (0, exports.releaseSurface)(output);
175
- throw new FilterSurfaceError('Filter surface canvas is unavailable');
176
- }
177
- context.globalAlpha = opacity;
178
- try {
179
- context.drawImage(source, 0, 0);
180
- return output;
181
- }
182
- catch {
183
- (0, exports.releaseSurface)(output);
184
- throw new FilterSurfaceError('Filter surface image cannot be drawn');
185
- }
186
- }
187
- const namespace = 'http://www.w3.org/2000/svg';
188
- const element = (tag, attributes = {}) => {
189
- const node = document.createElementNS(namespace, tag);
190
- Object.entries(attributes).forEach(([key, value]) => node.setAttribute(key, String(value)));
191
- return node;
192
- };
193
- const svg = element('svg', {
194
- width: source.width,
195
- height: source.height,
196
- viewBox: `0 0 ${source.width} ${source.height}`
197
- });
198
- const defs = element('defs');
199
- const filter = element('filter', {
200
- id: 'composited-filter',
201
- filterUnits: 'userSpaceOnUse',
202
- x: 0,
203
- y: 0,
204
- width: source.width,
205
- height: source.height,
206
- 'color-interpolation-filters': 'sRGB'
207
- });
208
- if (blur) {
209
- filter.appendChild(element('feGaussianBlur', { stdDeviation: blur * scale, result: 'blurred-source' }));
210
- }
211
- if (shadow) {
212
- // Explicit primitives avoid the narrower feDropShadow blur observed in WebKit.
213
- filter.appendChild(element('feGaussianBlur', {
214
- in: blur ? 'blurred-source' : 'SourceAlpha',
215
- stdDeviation: shadow.blur * scale
216
- }));
217
- filter.appendChild(element('feOffset', { dx: shadow.x * scale, dy: shadow.y * scale, result: 'offset-shadow' }));
218
- filter.appendChild(element('feFlood', { 'flood-color': shadow.color }));
219
- filter.appendChild(element('feComposite', { in2: 'offset-shadow', operator: 'in' }));
220
- const merge = element('feMerge');
221
- merge.appendChild(element('feMergeNode'));
222
- merge.appendChild(element('feMergeNode', { in: blur ? 'blurred-source' : 'SourceGraphic' }));
223
- filter.appendChild(merge);
224
- }
225
- defs.appendChild(filter);
226
- svg.appendChild(defs);
227
- let sourceUrl;
228
- try {
229
- sourceUrl = source.toDataURL('image/png');
230
- if (sourceUrl === 'data:,')
231
- throw new Error('Canvas size is unsupported');
232
- }
233
- catch {
234
- // allowTaint may intentionally produce an unreadable canvas. Keep that
235
- // API behavior by letting the caller render the subtree on the old path.
236
- throw new FilterSurfaceError('Filter surface pixels cannot be serialized');
237
- }
238
- svg.appendChild(element('image', {
239
- width: source.width,
240
- height: source.height,
241
- href: sourceUrl,
242
- filter: 'url(#composited-filter)'
243
- }));
244
- const image = new Image();
245
- let output;
246
- try {
247
- image.src = `data:image/svg+xml,${encodeURIComponent(new XMLSerializer().serializeToString(svg))}`;
248
- await decodeSurface(image, signal);
249
- (0, abort_helper_1.throwIfAborted)(signal);
250
- output = canvasLike(source);
251
- const context = output.getContext('2d');
252
- if (!context)
253
- throw new FilterSurfaceError('Filter surface canvas is unavailable');
254
- context.globalAlpha = opacity;
255
- context.drawImage(image, 0, 0);
256
- return output;
257
- }
258
- catch (error) {
259
- if (output)
260
- (0, exports.releaseSurface)(output);
261
- if (signal?.aborted)
262
- (0, abort_helper_1.throwIfAborted)(signal);
263
- throw error instanceof FilterSurfaceError
264
- ? error
265
- : new FilterSurfaceError('Filter surface image cannot be drawn');
266
- }
267
- finally {
268
- image.removeAttribute('src');
269
- }
270
- }
@@ -1,46 +0,0 @@
1
- "use strict";
2
- /**
3
- * Font measurement utility
4
- *
5
- * Provides Canvas API-based font measurement that works correctly with webfonts
6
- * (which may not be loaded in the original document) and system fonts.
7
- *
8
- * Fallback chain:
9
- * 1. fontBoundingBoxAscent — font-level metric (Chrome 99+, FF 116+, Safari 17.4+)
10
- * 2. actualBoundingBoxAscent — glyph-level metric (widely supported)
11
- * 3. fallback value — coarse CSS fallback
12
- */
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.measureBaseline = exports.measureFontMetrics = void 0;
15
- const SAMPLE_TEXT = 'Mg'; // characters with both ascender and descender
16
- const isValidMetric = (value) => value !== undefined && !Number.isNaN(value);
17
- /**
18
- * Measure the baseline ascent and full font box for the currently set font.
19
- */
20
- const measureFontMetrics = (ctx, fallback) => {
21
- const tm = ctx.measureText(SAMPLE_TEXT);
22
- const fontMetrics = tm;
23
- const baseline = isValidMetric(fontMetrics.fontBoundingBoxAscent)
24
- ? fontMetrics.fontBoundingBoxAscent
25
- : isValidMetric(tm.actualBoundingBoxAscent)
26
- ? tm.actualBoundingBoxAscent
27
- : fallback;
28
- const height = isValidMetric(fontMetrics.fontBoundingBoxAscent) && isValidMetric(fontMetrics.fontBoundingBoxDescent)
29
- ? fontMetrics.fontBoundingBoxAscent + fontMetrics.fontBoundingBoxDescent
30
- : isValidMetric(tm.actualBoundingBoxAscent) && isValidMetric(tm.actualBoundingBoxDescent)
31
- ? tm.actualBoundingBoxAscent + tm.actualBoundingBoxDescent
32
- : fallback;
33
- return { baseline, height };
34
- };
35
- exports.measureFontMetrics = measureFontMetrics;
36
- /**
37
- * Measure the baseline ascent for the currently set font.
38
- *
39
- * @param ctx - Canvas 2D rendering context with ctx.font already set
40
- * @param fallback - Fallback value when no metrics are available (e.g. fontSize.number)
41
- * @returns The distance from the text baseline to the top of the bounding box
42
- */
43
- const measureBaseline = (ctx, fallback) => {
44
- return (0, exports.measureFontMetrics)(ctx, fallback).baseline;
45
- };
46
- exports.measureBaseline = measureBaseline;
@@ -1,38 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ForeignObjectRenderer = void 0;
4
- const features_1 = require("../../core/features");
5
- const color_utilities_1 = require("../../css/types/color-utilities");
6
- class ForeignObjectRenderer {
7
- constructor(context, options) {
8
- this.context = context;
9
- this.options = options;
10
- this.canvas = options.canvas ? options.canvas : document.createElement('canvas');
11
- const ctx = this.canvas.getContext('2d');
12
- if (!ctx) {
13
- throw new Error('Failed to get 2D rendering context from canvas');
14
- }
15
- this.ctx = ctx;
16
- this.canvas.width = Math.floor(options.width * options.scale);
17
- this.canvas.height = Math.floor(options.height * options.scale);
18
- this.canvas.style.width = `${options.width}px`;
19
- this.canvas.style.height = `${options.height}px`;
20
- this.ctx.scale(this.options.scale, this.options.scale);
21
- this.ctx.translate(-options.x, -options.y);
22
- this.context.logger.debug(`EXPERIMENTAL ForeignObject renderer initialized (${options.width}x${options.height} at ${options.x},${options.y}) with scale ${options.scale}`);
23
- }
24
- async render(element) {
25
- if (this.options.signal?.aborted) {
26
- throw new DOMException('The operation was aborted.', 'AbortError');
27
- }
28
- const svg = (0, features_1.createForeignObjectSVG)(this.options.width * this.options.scale, this.options.height * this.options.scale, this.options.scale, this.options.scale, element);
29
- const img = await (0, features_1.loadSerializedSVG)(svg);
30
- if (this.options.backgroundColor) {
31
- this.ctx.fillStyle = (0, color_utilities_1.asString)(this.options.backgroundColor);
32
- this.ctx.fillRect(0, 0, this.options.width * this.options.scale, this.options.height * this.options.scale);
33
- }
34
- this.ctx.drawImage(img, -this.options.x * this.options.scale, -this.options.y * this.options.scale);
35
- return this.canvas;
36
- }
37
- }
38
- exports.ForeignObjectRenderer = ForeignObjectRenderer;
@@ -1,64 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MAX_SURFACE_SIDE = exports.MAX_SURFACE_PIXELS = void 0;
4
- exports.reserveSurface = reserveSurface;
5
- exports.surfaceBounds = surfaceBounds;
6
- exports.cropSurface = cropSurface;
7
- const bounds_1 = require("../../css/layout/bounds");
8
- const length_percentage_1 = require("../../css/types/length-percentage");
9
- const filter_surface_1 = require("./filter-surface");
10
- // Budget backing stores across all active nested surfaces in one capture.
11
- // Reserve source, filtered output and decoded SVG/PNG rasters conservatively.
12
- // Browser encoder/decoder overhead and the caller's output canvas are separate.
13
- exports.MAX_SURFACE_PIXELS = 16 * 1024 * 1024;
14
- exports.MAX_SURFACE_SIDE = 8192;
15
- function reserveSurface(budget, width, height) {
16
- const pixels = width * height * 4;
17
- if (!Number.isFinite(pixels) ||
18
- width <= 0 ||
19
- height <= 0 ||
20
- width > exports.MAX_SURFACE_SIDE ||
21
- height > exports.MAX_SURFACE_SIDE ||
22
- budget.pixels + pixels > exports.MAX_SURFACE_PIXELS)
23
- return 0;
24
- budget.pixels += pixels;
25
- return pixels;
26
- }
27
- const expand = (b, margin) => b.add(-margin, -margin, margin * 2, margin * 2);
28
- const union = (a, b) => new bounds_1.Bounds(Math.min(a.left, b.left), Math.min(a.top, b.top), Math.max(a.left + a.width, b.left + b.width) - Math.min(a.left, b.left), Math.max(a.top + a.height, b.top + b.height) - Math.min(a.top, b.top));
29
- // Conservative paint bounds for the untransformed subtree supported by this path.
30
- // Include overflow descendants, text ink padding, box/text shadows and nested filters.
31
- function surfaceBounds(container) {
32
- const styles = container.styles;
33
- let bounds = container.bounds;
34
- for (const shadow of styles.boxShadow) {
35
- if (!shadow.inset) {
36
- const spread = Math.max(0, shadow.spread.number) + 3 * shadow.blur.number;
37
- bounds = union(bounds, expand(container.bounds.add(shadow.offsetX.number, shadow.offsetY.number, 0, 0), spread));
38
- }
39
- }
40
- for (const text of container.textNodes) {
41
- for (const part of text.textBounds) {
42
- const ink = expand(part.bounds, 2 * (0, length_percentage_1.getAbsoluteValue)(styles.fontSize, container.bounds.height) + styles.webkitTextStrokeWidth);
43
- bounds = union(bounds, ink);
44
- for (const shadow of styles.textShadow) {
45
- bounds = union(bounds, expand(ink.add(shadow.offsetX.number, shadow.offsetY.number, 0, 0), 3 * shadow.blur.number));
46
- }
47
- }
48
- }
49
- for (const child of container.elements) {
50
- if (child.styles.isVisible())
51
- bounds = union(bounds, surfaceBounds(child));
52
- }
53
- const filter = (0, filter_surface_1.parseSimpleFilter)(styles.filter);
54
- return expand(bounds, filter ? (0, filter_surface_1.filterOutset)(filter) : 0);
55
- }
56
- function cropSurface(bounds, viewport, margin, scale) {
57
- // Pixels just outside the destination still contribute through blur/shadow.
58
- const area = expand(viewport, margin);
59
- const left = Math.floor(Math.max(bounds.left, area.left) * scale) / scale;
60
- const top = Math.floor(Math.max(bounds.top, area.top) * scale) / scale;
61
- const right = Math.ceil(Math.min(bounds.left + bounds.width, area.left + area.width) * scale) / scale;
62
- const bottom = Math.ceil(Math.min(bounds.top + bounds.height, area.top + area.height) * scale) / scale;
63
- return new bounds_1.Bounds(left, top, Math.max(0, right - left), Math.max(0, bottom - top));
64
- }
@@ -1,99 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TextDecorationRenderer = void 0;
4
- const color_utilities_1 = require("../../../css/types/color-utilities");
5
- class TextDecorationRenderer {
6
- constructor(ctx) {
7
- this.ctx = ctx;
8
- }
9
- render(bounds, styles) {
10
- this.ctx.fillStyle = (0, color_utilities_1.asString)(styles.textDecorationColor || styles.color);
11
- let thickness = 1;
12
- if (typeof styles.textDecorationThickness === 'number') {
13
- thickness = styles.textDecorationThickness;
14
- }
15
- else if (styles.textDecorationThickness === 'from-font') {
16
- thickness = Math.max(1, Math.floor(styles.fontSize.number * 0.05));
17
- }
18
- let underlineOffset = 0;
19
- if (typeof styles.textUnderlineOffset === 'number') {
20
- underlineOffset = styles.textUnderlineOffset;
21
- }
22
- const decorationStyle = styles.textDecorationStyle;
23
- styles.textDecorationLine.forEach((line) => {
24
- let y = 0;
25
- switch (line) {
26
- case 1 /* TEXT_DECORATION_LINE.UNDERLINE */:
27
- y = bounds.top + bounds.height - thickness + underlineOffset;
28
- break;
29
- case 2 /* TEXT_DECORATION_LINE.OVERLINE */:
30
- y = bounds.top;
31
- break;
32
- case 3 /* TEXT_DECORATION_LINE.LINE_THROUGH */:
33
- y = bounds.top + (bounds.height / 2 - thickness / 2);
34
- break;
35
- default:
36
- return;
37
- }
38
- this.draw(bounds.left, y, bounds.width, thickness, decorationStyle);
39
- });
40
- }
41
- draw(x, y, width, thickness, style) {
42
- switch (style) {
43
- case 0 /* TEXT_DECORATION_STYLE.SOLID */:
44
- this.ctx.fillRect(x, y, width, thickness);
45
- break;
46
- case 1 /* TEXT_DECORATION_STYLE.DOUBLE */: {
47
- const gap = Math.max(1, thickness);
48
- this.ctx.fillRect(x, y, width, thickness);
49
- this.ctx.fillRect(x, y + thickness + gap, width, thickness);
50
- break;
51
- }
52
- case 2 /* TEXT_DECORATION_STYLE.DOTTED */:
53
- this.drawPattern(x, y, width, thickness, [thickness, thickness * 2]);
54
- break;
55
- case 3 /* TEXT_DECORATION_STYLE.DASHED */:
56
- this.drawPattern(x, y, width, thickness, [thickness * 3, thickness * 2]);
57
- break;
58
- case 4 /* TEXT_DECORATION_STYLE.WAVY */:
59
- this.drawWavy(x, y, width, thickness);
60
- break;
61
- default:
62
- this.ctx.fillRect(x, y, width, thickness);
63
- }
64
- }
65
- drawPattern(x, y, width, thickness, dash) {
66
- this.ctx.save();
67
- this.ctx.beginPath();
68
- this.ctx.setLineDash(dash);
69
- this.ctx.lineWidth = thickness;
70
- this.ctx.strokeStyle = this.ctx.fillStyle;
71
- this.ctx.moveTo(x, y + thickness / 2);
72
- this.ctx.lineTo(x + width, y + thickness / 2);
73
- this.ctx.stroke();
74
- this.ctx.restore();
75
- }
76
- drawWavy(x, y, width, thickness) {
77
- this.ctx.save();
78
- this.ctx.beginPath();
79
- this.ctx.lineWidth = thickness;
80
- this.ctx.strokeStyle = this.ctx.fillStyle;
81
- const amplitude = thickness * 2;
82
- const wavelength = thickness * 4;
83
- let currentX = x;
84
- this.ctx.moveTo(currentX, y + thickness / 2);
85
- while (currentX < x + width) {
86
- const nextX = Math.min(currentX + wavelength / 2, x + width);
87
- this.ctx.quadraticCurveTo(currentX + wavelength / 4, y + thickness / 2 - amplitude, nextX, y + thickness / 2);
88
- currentX = nextX;
89
- if (currentX < x + width) {
90
- const nextX2 = Math.min(currentX + wavelength / 2, x + width);
91
- this.ctx.quadraticCurveTo(currentX + wavelength / 4, y + thickness / 2 + amplitude, nextX2, y + thickness / 2);
92
- currentX = nextX2;
93
- }
94
- }
95
- this.ctx.stroke();
96
- this.ctx.restore();
97
- }
98
- }
99
- exports.TextDecorationRenderer = TextDecorationRenderer;