html2canvas-pro 2.4.5 → 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 +3058 -1607
  3. package/dist/html2canvas-pro.cjs.map +1 -1
  4. package/dist/html2canvas-pro.esm.js +3058 -1607
  5. package/dist/html2canvas-pro.esm.js.map +1 -1
  6. package/dist/html2canvas-pro.js +3055 -1604
  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/canvas-renderer.d.ts +21 -15
  51. package/dist/types/render/canvas/mask-renderer.d.ts +36 -0
  52. package/dist/types/render/canvas/text-clip-renderer.d.ts +36 -0
  53. package/dist/types/render/canvas/text-renderer.d.ts +22 -0
  54. package/dist/types/render/stacking-context.d.ts +4 -1
  55. package/package.json +39 -40
  56. package/dist/lib/config.js +0 -49
  57. package/dist/lib/core/abort-helper.js +0 -20
  58. package/dist/lib/core/background-parser.js +0 -41
  59. package/dist/lib/core/bitwise.js +0 -5
  60. package/dist/lib/core/cache-storage.js +0 -283
  61. package/dist/lib/core/config-assembler.js +0 -88
  62. package/dist/lib/core/constants.js +0 -25
  63. package/dist/lib/core/context.js +0 -19
  64. package/dist/lib/core/debugger.js +0 -27
  65. package/dist/lib/core/features.js +0 -190
  66. package/dist/lib/core/logger.js +0 -56
  67. package/dist/lib/core/lru-map.js +0 -66
  68. package/dist/lib/core/origin-checker.js +0 -53
  69. package/dist/lib/core/performance-monitor.js +0 -185
  70. package/dist/lib/core/render-element.js +0 -131
  71. package/dist/lib/core/util.js +0 -4
  72. package/dist/lib/core/validator.js +0 -500
  73. package/dist/lib/css/grouped/background-styles.js +0 -36
  74. package/dist/lib/css/grouped/border-styles.js +0 -75
  75. package/dist/lib/css/grouped/font-styles.js +0 -93
  76. package/dist/lib/css/grouped/layout-styles.js +0 -127
  77. package/dist/lib/css/index.js +0 -339
  78. package/dist/lib/css/layout/bounds.js +0 -52
  79. package/dist/lib/css/layout/text.js +0 -133
  80. package/dist/lib/css/property-descriptor.js +0 -2
  81. package/dist/lib/css/property-descriptors/background-blend-mode.js +0 -41
  82. package/dist/lib/css/property-descriptors/background-clip.js +0 -25
  83. package/dist/lib/css/property-descriptors/background-color.js +0 -10
  84. package/dist/lib/css/property-descriptors/background-image.js +0 -24
  85. package/dist/lib/css/property-descriptors/background-origin.js +0 -23
  86. package/dist/lib/css/property-descriptors/background-position.js +0 -19
  87. package/dist/lib/css/property-descriptors/background-repeat.js +0 -33
  88. package/dist/lib/css/property-descriptors/background-size.js +0 -23
  89. package/dist/lib/css/property-descriptors/border-color.js +0 -14
  90. package/dist/lib/css/property-descriptors/border-image-repeat.js +0 -42
  91. package/dist/lib/css/property-descriptors/border-image-slice.js +0 -45
  92. package/dist/lib/css/property-descriptors/border-image-source.js +0 -22
  93. package/dist/lib/css/property-descriptors/border-radius.js +0 -15
  94. package/dist/lib/css/property-descriptors/border-style.js +0 -26
  95. package/dist/lib/css/property-descriptors/border-width.js +0 -20
  96. package/dist/lib/css/property-descriptors/box-decoration-break.js +0 -18
  97. package/dist/lib/css/property-descriptors/box-shadow.js +0 -54
  98. package/dist/lib/css/property-descriptors/clip-path.js +0 -189
  99. package/dist/lib/css/property-descriptors/color.js +0 -10
  100. package/dist/lib/css/property-descriptors/content.js +0 -19
  101. package/dist/lib/css/property-descriptors/counter-increment.js +0 -35
  102. package/dist/lib/css/property-descriptors/counter-reset.js +0 -18
  103. package/dist/lib/css/property-descriptors/direction.js +0 -18
  104. package/dist/lib/css/property-descriptors/display.js +0 -81
  105. package/dist/lib/css/property-descriptors/duration.js +0 -14
  106. package/dist/lib/css/property-descriptors/filter.js +0 -86
  107. package/dist/lib/css/property-descriptors/float.js +0 -22
  108. package/dist/lib/css/property-descriptors/font-family.js +0 -47
  109. package/dist/lib/css/property-descriptors/font-size.js +0 -10
  110. package/dist/lib/css/property-descriptors/font-style.js +0 -20
  111. package/dist/lib/css/property-descriptors/font-variant-ligatures.js +0 -34
  112. package/dist/lib/css/property-descriptors/font-variant.js +0 -13
  113. package/dist/lib/css/property-descriptors/font-weight.js +0 -25
  114. package/dist/lib/css/property-descriptors/image-rendering.js +0 -33
  115. package/dist/lib/css/property-descriptors/letter-spacing.js +0 -21
  116. package/dist/lib/css/property-descriptors/line-break.js +0 -23
  117. package/dist/lib/css/property-descriptors/line-height.js +0 -24
  118. package/dist/lib/css/property-descriptors/list-style-image.js +0 -17
  119. package/dist/lib/css/property-descriptors/list-style-position.js +0 -18
  120. package/dist/lib/css/property-descriptors/list-style-type.js +0 -122
  121. package/dist/lib/css/property-descriptors/margin.js +0 -13
  122. package/dist/lib/css/property-descriptors/mix-blend-mode.js +0 -31
  123. package/dist/lib/css/property-descriptors/object-fit.js +0 -28
  124. package/dist/lib/css/property-descriptors/object-position.js +0 -42
  125. package/dist/lib/css/property-descriptors/opacity.js +0 -16
  126. package/dist/lib/css/property-descriptors/overflow-wrap.js +0 -18
  127. package/dist/lib/css/property-descriptors/overflow.js +0 -27
  128. package/dist/lib/css/property-descriptors/padding.js +0 -14
  129. package/dist/lib/css/property-descriptors/paint-order.js +0 -33
  130. package/dist/lib/css/property-descriptors/position.js +0 -22
  131. package/dist/lib/css/property-descriptors/quotes.js +0 -41
  132. package/dist/lib/css/property-descriptors/rotate.js +0 -27
  133. package/dist/lib/css/property-descriptors/text-align.js +0 -21
  134. package/dist/lib/css/property-descriptors/text-decoration-color.js +0 -10
  135. package/dist/lib/css/property-descriptors/text-decoration-line.js +0 -28
  136. package/dist/lib/css/property-descriptors/text-decoration-style.js +0 -24
  137. package/dist/lib/css/property-descriptors/text-decoration-thickness.js +0 -26
  138. package/dist/lib/css/property-descriptors/text-overflow.js +0 -18
  139. package/dist/lib/css/property-descriptors/text-shadow.js +0 -46
  140. package/dist/lib/css/property-descriptors/text-transform.js +0 -20
  141. package/dist/lib/css/property-descriptors/text-underline-offset.js +0 -23
  142. package/dist/lib/css/property-descriptors/transform-origin.js +0 -24
  143. package/dist/lib/css/property-descriptors/transform.js +0 -57
  144. package/dist/lib/css/property-descriptors/visibility.js +0 -20
  145. package/dist/lib/css/property-descriptors/webkit-line-clamp.js +0 -26
  146. package/dist/lib/css/property-descriptors/webkit-text-stroke-color.js +0 -10
  147. package/dist/lib/css/property-descriptors/webkit-text-stroke-width.js +0 -16
  148. package/dist/lib/css/property-descriptors/white-space.js +0 -32
  149. package/dist/lib/css/property-descriptors/word-break.js +0 -26
  150. package/dist/lib/css/property-descriptors/writing-mode.js +0 -28
  151. package/dist/lib/css/property-descriptors/z-index.js +0 -19
  152. package/dist/lib/css/property-descriptors/zoom.js +0 -18
  153. package/dist/lib/css/syntax/parser.js +0 -141
  154. package/dist/lib/css/syntax/token-constants.js +0 -214
  155. package/dist/lib/css/syntax/token-singletons.js +0 -36
  156. package/dist/lib/css/syntax/token-types.js +0 -10
  157. package/dist/lib/css/syntax/tokenizer.js +0 -502
  158. package/dist/lib/css/type-descriptor.js +0 -2
  159. package/dist/lib/css/types/angle.js +0 -80
  160. package/dist/lib/css/types/color-math.js +0 -25
  161. package/dist/lib/css/types/color-spaces/a98.js +0 -78
  162. package/dist/lib/css/types/color-spaces/p3.js +0 -86
  163. package/dist/lib/css/types/color-spaces/pro-photo.js +0 -83
  164. package/dist/lib/css/types/color-spaces/rec2020.js +0 -85
  165. package/dist/lib/css/types/color-spaces/srgb.js +0 -79
  166. package/dist/lib/css/types/color-utilities.js +0 -342
  167. package/dist/lib/css/types/color.js +0 -400
  168. package/dist/lib/css/types/functions/-prefix-linear-gradient.js +0 -32
  169. package/dist/lib/css/types/functions/-prefix-radial-gradient.js +0 -83
  170. package/dist/lib/css/types/functions/-webkit-gradient.js +0 -59
  171. package/dist/lib/css/types/functions/counter.js +0 -367
  172. package/dist/lib/css/types/functions/gradient.js +0 -163
  173. package/dist/lib/css/types/functions/linear-gradient.js +0 -27
  174. package/dist/lib/css/types/functions/radial-gradient.js +0 -90
  175. package/dist/lib/css/types/functions/repeating-linear-gradient.js +0 -9
  176. package/dist/lib/css/types/image.js +0 -62
  177. package/dist/lib/css/types/index.js +0 -2
  178. package/dist/lib/css/types/length-percentage.js +0 -197
  179. package/dist/lib/css/types/length.js +0 -5
  180. package/dist/lib/css/types/safe-eval.js +0 -80
  181. package/dist/lib/css/types/time.js +0 -17
  182. package/dist/lib/dom/document-cloner.js +0 -618
  183. package/dist/lib/dom/dom-normalizer.js +0 -115
  184. package/dist/lib/dom/element-container.js +0 -71
  185. package/dist/lib/dom/elements/li-element-container.js +0 -11
  186. package/dist/lib/dom/elements/ol-element-container.js +0 -12
  187. package/dist/lib/dom/elements/select-element-container.js +0 -12
  188. package/dist/lib/dom/elements/textarea-element-container.js +0 -11
  189. package/dist/lib/dom/node-parser.js +0 -125
  190. package/dist/lib/dom/node-type-guards.js +0 -81
  191. package/dist/lib/dom/replaced-elements/canvas-element-container.js +0 -13
  192. package/dist/lib/dom/replaced-elements/iframe-element-container.js +0 -38
  193. package/dist/lib/dom/replaced-elements/image-element-container.js +0 -14
  194. package/dist/lib/dom/replaced-elements/index.js +0 -2
  195. package/dist/lib/dom/replaced-elements/input-element-container.js +0 -89
  196. package/dist/lib/dom/replaced-elements/svg-element-container.js +0 -57
  197. package/dist/lib/dom/slot-cloner.js +0 -176
  198. package/dist/lib/dom/text-container.js +0 -35
  199. package/dist/lib/index.js +0 -49
  200. package/dist/lib/options.js +0 -2
  201. package/dist/lib/render/background.js +0 -188
  202. package/dist/lib/render/bezier-curve.js +0 -34
  203. package/dist/lib/render/border.js +0 -104
  204. package/dist/lib/render/bound-curves.js +0 -188
  205. package/dist/lib/render/box-sizing.js +0 -20
  206. package/dist/lib/render/canvas/background-renderer.js +0 -338
  207. package/dist/lib/render/canvas/border-image-renderer.js +0 -153
  208. package/dist/lib/render/canvas/border-renderer.js +0 -184
  209. package/dist/lib/render/canvas/box-shadow-geometry.js +0 -52
  210. package/dist/lib/render/canvas/box-shadow-painter.js +0 -194
  211. package/dist/lib/render/canvas/box-shadow-transform.js +0 -42
  212. package/dist/lib/render/canvas/canvas-path.js +0 -25
  213. package/dist/lib/render/canvas/canvas-renderer.js +0 -610
  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;