html2canvas-pro 2.1.0 → 2.1.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 (186) hide show
  1. package/dist/html2canvas-pro.esm.js +21 -7
  2. package/dist/html2canvas-pro.esm.js.map +1 -1
  3. package/dist/html2canvas-pro.js +21 -7
  4. package/dist/html2canvas-pro.js.map +1 -1
  5. package/dist/html2canvas-pro.min.js +3 -3
  6. package/dist/lib/core/cache-storage.js +2 -2
  7. package/dist/lib/core/features.js +2 -2
  8. package/dist/lib/render/canvas/background-renderer.js +6 -0
  9. package/dist/lib/render/canvas/canvas-renderer.js +5 -1
  10. package/dist/lib/render/canvas/foreignobject-renderer.js +5 -1
  11. package/package.json +3 -11
  12. package/dist/lib/invariant.js +0 -9
  13. package/dist/types/invariant.d.ts +0 -1
  14. package/src/__tests__/index.ts +0 -99
  15. package/src/config.ts +0 -107
  16. package/src/core/__mocks__/cache-storage.ts +0 -1
  17. package/src/core/__mocks__/context.ts +0 -19
  18. package/src/core/__mocks__/features.ts +0 -8
  19. package/src/core/__mocks__/logger.ts +0 -17
  20. package/src/core/__tests__/cache-storage.test.ts +0 -205
  21. package/src/core/__tests__/cache-storage.ts +0 -278
  22. package/src/core/__tests__/logger.ts +0 -29
  23. package/src/core/__tests__/validator.ts +0 -359
  24. package/src/core/bitwise.ts +0 -1
  25. package/src/core/cache-storage.ts +0 -315
  26. package/src/core/context.ts +0 -31
  27. package/src/core/debugger.ts +0 -32
  28. package/src/core/features.ts +0 -222
  29. package/src/core/logger.ts +0 -64
  30. package/src/core/origin-checker.ts +0 -57
  31. package/src/core/performance-monitor.ts +0 -241
  32. package/src/core/render-element.ts +0 -272
  33. package/src/core/util.ts +0 -1
  34. package/src/core/validator.ts +0 -593
  35. package/src/css/index.ts +0 -427
  36. package/src/css/layout/__mocks__/bounds.ts +0 -6
  37. package/src/css/layout/bounds.ts +0 -79
  38. package/src/css/layout/text.ts +0 -161
  39. package/src/css/property-descriptor.ts +0 -49
  40. package/src/css/property-descriptors/__tests__/background-tests.ts +0 -65
  41. package/src/css/property-descriptors/__tests__/clip-path.test.ts +0 -280
  42. package/src/css/property-descriptors/__tests__/font-family.ts +0 -25
  43. package/src/css/property-descriptors/__tests__/image-rendering-integration.test.ts +0 -153
  44. package/src/css/property-descriptors/__tests__/image-rendering-performance.test.ts +0 -175
  45. package/src/css/property-descriptors/__tests__/image-rendering.test.ts +0 -72
  46. package/src/css/property-descriptors/__tests__/paint-order.ts +0 -87
  47. package/src/css/property-descriptors/__tests__/text-shadow.ts +0 -94
  48. package/src/css/property-descriptors/__tests__/transform-tests.ts +0 -18
  49. package/src/css/property-descriptors/background-clip.ts +0 -30
  50. package/src/css/property-descriptors/background-color.ts +0 -9
  51. package/src/css/property-descriptors/background-image.ts +0 -27
  52. package/src/css/property-descriptors/background-origin.ts +0 -31
  53. package/src/css/property-descriptors/background-position.ts +0 -38
  54. package/src/css/property-descriptors/background-repeat.ts +0 -44
  55. package/src/css/property-descriptors/background-size.ts +0 -27
  56. package/src/css/property-descriptors/border-color.ts +0 -13
  57. package/src/css/property-descriptors/border-radius.ts +0 -19
  58. package/src/css/property-descriptors/border-style.ts +0 -34
  59. package/src/css/property-descriptors/border-width.ts +0 -20
  60. package/src/css/property-descriptors/box-shadow.ts +0 -60
  61. package/src/css/property-descriptors/clip-path.ts +0 -271
  62. package/src/css/property-descriptors/color.ts +0 -9
  63. package/src/css/property-descriptors/content.ts +0 -26
  64. package/src/css/property-descriptors/counter-increment.ts +0 -43
  65. package/src/css/property-descriptors/counter-reset.ts +0 -36
  66. package/src/css/property-descriptors/direction.ts +0 -23
  67. package/src/css/property-descriptors/display.ts +0 -117
  68. package/src/css/property-descriptors/duration.ts +0 -14
  69. package/src/css/property-descriptors/float.ts +0 -29
  70. package/src/css/property-descriptors/font-family.ts +0 -38
  71. package/src/css/property-descriptors/font-size.ts +0 -9
  72. package/src/css/property-descriptors/font-style.ts +0 -25
  73. package/src/css/property-descriptors/font-variant.ts +0 -12
  74. package/src/css/property-descriptors/font-weight.ts +0 -26
  75. package/src/css/property-descriptors/image-rendering.ts +0 -33
  76. package/src/css/property-descriptors/letter-spacing.ts +0 -25
  77. package/src/css/property-descriptors/line-break.ts +0 -22
  78. package/src/css/property-descriptors/line-height.ts +0 -22
  79. package/src/css/property-descriptors/list-style-image.ts +0 -19
  80. package/src/css/property-descriptors/list-style-position.ts +0 -22
  81. package/src/css/property-descriptors/list-style-type.ts +0 -179
  82. package/src/css/property-descriptors/margin.ts +0 -13
  83. package/src/css/property-descriptors/mix-blend-mode.ts +0 -35
  84. package/src/css/property-descriptors/object-fit.ts +0 -39
  85. package/src/css/property-descriptors/opacity.ts +0 -15
  86. package/src/css/property-descriptors/overflow-wrap.ts +0 -22
  87. package/src/css/property-descriptors/overflow.ts +0 -34
  88. package/src/css/property-descriptors/padding.ts +0 -14
  89. package/src/css/property-descriptors/paint-order.ts +0 -42
  90. package/src/css/property-descriptors/position.ts +0 -30
  91. package/src/css/property-descriptors/quotes.ts +0 -57
  92. package/src/css/property-descriptors/rotate.ts +0 -34
  93. package/src/css/property-descriptors/text-align.ts +0 -26
  94. package/src/css/property-descriptors/text-decoration-color.ts +0 -9
  95. package/src/css/property-descriptors/text-decoration-line.ts +0 -38
  96. package/src/css/property-descriptors/text-decoration-style.ts +0 -32
  97. package/src/css/property-descriptors/text-decoration-thickness.ts +0 -30
  98. package/src/css/property-descriptors/text-overflow.ts +0 -23
  99. package/src/css/property-descriptors/text-shadow.ts +0 -52
  100. package/src/css/property-descriptors/text-transform.ts +0 -27
  101. package/src/css/property-descriptors/text-underline-offset.ts +0 -27
  102. package/src/css/property-descriptors/transform-origin.ts +0 -29
  103. package/src/css/property-descriptors/transform.ts +0 -74
  104. package/src/css/property-descriptors/visibility.ts +0 -25
  105. package/src/css/property-descriptors/webkit-line-clamp.ts +0 -30
  106. package/src/css/property-descriptors/webkit-text-stroke-color.ts +0 -8
  107. package/src/css/property-descriptors/webkit-text-stroke-width.ts +0 -15
  108. package/src/css/property-descriptors/word-break.ts +0 -25
  109. package/src/css/property-descriptors/writing-mode.ts +0 -37
  110. package/src/css/property-descriptors/z-index.ts +0 -27
  111. package/src/css/syntax/__tests__/tokernizer-tests.ts +0 -29
  112. package/src/css/syntax/parser.ts +0 -188
  113. package/src/css/syntax/tokenizer.ts +0 -822
  114. package/src/css/type-descriptor.ts +0 -7
  115. package/src/css/types/__tests__/color-tests.ts +0 -147
  116. package/src/css/types/__tests__/image-tests.ts +0 -239
  117. package/src/css/types/angle.ts +0 -86
  118. package/src/css/types/color-math.ts +0 -22
  119. package/src/css/types/color-spaces/a98.ts +0 -86
  120. package/src/css/types/color-spaces/p3.ts +0 -92
  121. package/src/css/types/color-spaces/pro-photo.ts +0 -87
  122. package/src/css/types/color-spaces/rec2020.ts +0 -90
  123. package/src/css/types/color-spaces/srgb.ts +0 -87
  124. package/src/css/types/color-utilities.ts +0 -452
  125. package/src/css/types/color.ts +0 -485
  126. package/src/css/types/functions/-prefix-linear-gradient.ts +0 -35
  127. package/src/css/types/functions/-prefix-radial-gradient.ts +0 -106
  128. package/src/css/types/functions/-webkit-gradient.ts +0 -69
  129. package/src/css/types/functions/__tests__/radial-gradient.ts +0 -69
  130. package/src/css/types/functions/counter.ts +0 -511
  131. package/src/css/types/functions/gradient.ts +0 -206
  132. package/src/css/types/functions/linear-gradient.ts +0 -28
  133. package/src/css/types/functions/radial-gradient.ts +0 -101
  134. package/src/css/types/image.ts +0 -120
  135. package/src/css/types/index.ts +0 -1
  136. package/src/css/types/length-percentage.ts +0 -137
  137. package/src/css/types/length.ts +0 -7
  138. package/src/css/types/time.ts +0 -20
  139. package/src/dom/__mocks__/document-cloner.ts +0 -22
  140. package/src/dom/__tests__/dom-normalizer.test.ts +0 -133
  141. package/src/dom/__tests__/element-container.test.ts +0 -129
  142. package/src/dom/document-cloner.ts +0 -929
  143. package/src/dom/dom-normalizer.ts +0 -133
  144. package/src/dom/element-container.ts +0 -75
  145. package/src/dom/elements/li-element-container.ts +0 -10
  146. package/src/dom/elements/ol-element-container.ts +0 -12
  147. package/src/dom/elements/select-element-container.ts +0 -10
  148. package/src/dom/elements/textarea-element-container.ts +0 -9
  149. package/src/dom/node-parser.ts +0 -177
  150. package/src/dom/node-type-guards.ts +0 -70
  151. package/src/dom/replaced-elements/canvas-element-container.ts +0 -15
  152. package/src/dom/replaced-elements/iframe-element-container.ts +0 -55
  153. package/src/dom/replaced-elements/image-element-container.ts +0 -16
  154. package/src/dom/replaced-elements/index.ts +0 -5
  155. package/src/dom/replaced-elements/input-element-container.ts +0 -105
  156. package/src/dom/replaced-elements/pseudo-elements.ts +0 -0
  157. package/src/dom/replaced-elements/svg-element-container.ts +0 -23
  158. package/src/dom/text-container.ts +0 -42
  159. package/src/global.d.ts +0 -19
  160. package/src/index.ts +0 -82
  161. package/src/invariant.ts +0 -5
  162. package/src/options.ts +0 -55
  163. package/src/render/__tests__/object-fit.test.ts +0 -85
  164. package/src/render/background.ts +0 -298
  165. package/src/render/bezier-curve.ts +0 -47
  166. package/src/render/border.ts +0 -165
  167. package/src/render/bound-curves.ts +0 -388
  168. package/src/render/box-sizing.ts +0 -31
  169. package/src/render/canvas/__tests__/background-renderer.test.ts +0 -72
  170. package/src/render/canvas/__tests__/border-renderer.test.ts +0 -24
  171. package/src/render/canvas/__tests__/effects-renderer.test.ts +0 -32
  172. package/src/render/canvas/__tests__/text-renderer.test.ts +0 -471
  173. package/src/render/canvas/background-renderer.ts +0 -271
  174. package/src/render/canvas/border-renderer.ts +0 -224
  175. package/src/render/canvas/canvas-path.ts +0 -31
  176. package/src/render/canvas/canvas-renderer.ts +0 -641
  177. package/src/render/canvas/effects-renderer.ts +0 -130
  178. package/src/render/canvas/foreignobject-renderer.ts +0 -53
  179. package/src/render/canvas/text-renderer.ts +0 -700
  180. package/src/render/effects.ts +0 -75
  181. package/src/render/font-metrics.ts +0 -72
  182. package/src/render/object-fit.ts +0 -100
  183. package/src/render/path.ts +0 -37
  184. package/src/render/renderer-interface.ts +0 -28
  185. package/src/render/stacking-context.ts +0 -386
  186. package/src/render/vector.ts +0 -19
@@ -1,386 +0,0 @@
1
- import { ElementContainer } from '../dom/element-container';
2
- import { contains } from '../core/bitwise';
3
- import { BoundCurves, calculateBorderBoxPath, calculatePaddingBoxPath } from './bound-curves';
4
- import {
5
- BlendEffect,
6
- ClipEffect,
7
- ClipPathEffect,
8
- EffectTarget,
9
- IElementEffect,
10
- isClipEffect,
11
- OpacityEffect,
12
- TransformEffect
13
- } from './effects';
14
- import { Matrix } from '../css/property-descriptors/transform';
15
- import { OVERFLOW } from '../css/property-descriptors/overflow';
16
- import { equalPath } from './path';
17
- import { DISPLAY } from '../css/property-descriptors/display';
18
- import { OLElementContainer } from '../dom/elements/ol-element-container';
19
- import { LIElementContainer } from '../dom/elements/li-element-container';
20
- import { createCounterText } from '../css/types/functions/counter';
21
- import { POSITION } from '../css/property-descriptors/position';
22
- import { getAbsoluteValue } from '../css/types/length-percentage';
23
- import { Bounds } from '../css/layout/bounds';
24
- import { CLIP_PATH_TYPE, ClipPathValue, ShapeRadius } from '../css/property-descriptors/clip-path';
25
- import { MIX_BLEND_MODE } from '../css/property-descriptors/mix-blend-mode';
26
-
27
- export class StackingContext {
28
- element: ElementPaint;
29
- negativeZIndex: StackingContext[];
30
- zeroOrAutoZIndexOrTransformedOrOpacity: StackingContext[];
31
- positiveZIndex: StackingContext[];
32
- nonPositionedFloats: StackingContext[];
33
- nonPositionedInlineLevel: StackingContext[];
34
- inlineLevel: ElementPaint[];
35
- nonInlineLevel: ElementPaint[];
36
-
37
- constructor(container: ElementPaint) {
38
- this.element = container;
39
- this.inlineLevel = [];
40
- this.nonInlineLevel = [];
41
- this.negativeZIndex = [];
42
- this.zeroOrAutoZIndexOrTransformedOrOpacity = [];
43
- this.positiveZIndex = [];
44
- this.nonPositionedFloats = [];
45
- this.nonPositionedInlineLevel = [];
46
- }
47
- }
48
-
49
- export class ElementPaint {
50
- readonly effects: IElementEffect[] = [];
51
- readonly curves: BoundCurves;
52
- listValue?: string;
53
-
54
- constructor(
55
- readonly container: ElementContainer,
56
- readonly parent: ElementPaint | null
57
- ) {
58
- this.curves = new BoundCurves(this.container);
59
- if (this.container.styles.opacity < 1) {
60
- this.effects.push(new OpacityEffect(this.container.styles.opacity));
61
- }
62
-
63
- if (this.container.styles.rotate !== null) {
64
- const origin = this.container.styles.transformOrigin;
65
- const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
66
- const offsetY = this.container.bounds.top + getAbsoluteValue(origin[1], this.container.bounds.height);
67
- // Apply rotate property if present
68
- const angle = this.container.styles.rotate;
69
- const rad = (angle * Math.PI) / 180;
70
- const cos = Math.cos(rad);
71
- const sin = Math.sin(rad);
72
- const rotateMatrix: Matrix = [cos, sin, -sin, cos, 0, 0];
73
- this.effects.push(new TransformEffect(offsetX, offsetY, rotateMatrix));
74
- }
75
-
76
- if (this.container.styles.transform !== null) {
77
- const origin = this.container.styles.transformOrigin;
78
- const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
79
- const offsetY = this.container.bounds.top + getAbsoluteValue(origin[1], this.container.bounds.height);
80
- const matrix = this.container.styles.transform;
81
- this.effects.push(new TransformEffect(offsetX, offsetY, matrix));
82
- }
83
-
84
- if (hasOverflowClip(this.container.styles)) {
85
- const borderBox = calculateBorderBoxPath(this.curves);
86
- const paddingBox = calculatePaddingBoxPath(this.curves);
87
-
88
- if (equalPath(borderBox, paddingBox)) {
89
- this.effects.push(new ClipEffect(borderBox, EffectTarget.BACKGROUND_BORDERS | EffectTarget.CONTENT));
90
- } else {
91
- this.effects.push(new ClipEffect(borderBox, EffectTarget.BACKGROUND_BORDERS));
92
- this.effects.push(new ClipEffect(paddingBox, EffectTarget.CONTENT));
93
- }
94
- }
95
-
96
- if (this.container.styles.clipPath.type !== CLIP_PATH_TYPE.NONE) {
97
- const clipPathEffect = buildClipPathEffect(this.container.styles.clipPath, this.container.bounds);
98
- if (clipPathEffect) {
99
- this.effects.push(clipPathEffect);
100
- }
101
- }
102
-
103
- if (this.container.styles.mixBlendMode !== MIX_BLEND_MODE.NORMAL) {
104
- this.effects.push(new BlendEffect(this.container.styles.mixBlendMode as GlobalCompositeOperation));
105
- }
106
- }
107
-
108
- getEffects(target: EffectTarget): IElementEffect[] {
109
- let inFlow = [POSITION.ABSOLUTE, POSITION.FIXED].indexOf(this.container.styles.position) === -1;
110
- let parent = this.parent;
111
- const effects = this.effects.slice(0);
112
- while (parent) {
113
- const croplessEffects = parent.effects.filter((effect) => !isClipEffect(effect));
114
- if (inFlow || parent.container.styles.position !== POSITION.STATIC || !parent.parent) {
115
- inFlow = [POSITION.ABSOLUTE, POSITION.FIXED].indexOf(parent.container.styles.position) === -1;
116
- if (hasOverflowClip(parent.container.styles)) {
117
- const borderBox = calculateBorderBoxPath(parent.curves);
118
- const paddingBox = calculatePaddingBoxPath(parent.curves);
119
- if (!equalPath(borderBox, paddingBox)) {
120
- effects.unshift(
121
- new ClipEffect(paddingBox, EffectTarget.BACKGROUND_BORDERS | EffectTarget.CONTENT)
122
- );
123
- }
124
- }
125
- effects.unshift(...croplessEffects);
126
- } else {
127
- effects.unshift(...croplessEffects);
128
- }
129
-
130
- parent = parent.parent;
131
- }
132
-
133
- return effects.filter((effect) => contains(effect.target, target));
134
- }
135
- }
136
-
137
- const hasOverflowClip = (styles: ElementContainer['styles']): boolean =>
138
- styles.overflowX !== OVERFLOW.VISIBLE || styles.overflowY !== OVERFLOW.VISIBLE;
139
-
140
- /**
141
- * Resolve a `closest-side` or `farthest-side` shape-radius keyword to pixels
142
- * for a single axis. Used by both `circle()` (per-axis) and `ellipse()`.
143
- *
144
- * @param r - The ShapeRadius (keyword or length-percentage).
145
- * @param center - Absolute center coordinate on this axis (cx or cy).
146
- * @param start - Absolute start of the reference box on this axis.
147
- * @param end - Absolute end of the reference box on this axis.
148
- * @param dimRef - Reference dimension for resolving a length-percentage value.
149
- */
150
- const resolveAxisRadius = (r: ShapeRadius, center: number, start: number, end: number, dimRef: number): number => {
151
- if (r === 'closest-side') return Math.min(center - start, end - center);
152
- if (r === 'farthest-side') return Math.max(center - start, end - center);
153
- return getAbsoluteValue(r, dimRef);
154
- };
155
-
156
- /**
157
- * Convert a parsed ClipPathValue + element bounds into a ClipPathEffect whose
158
- * `applyClip` callback draws the clip shape directly onto the canvas context.
159
- *
160
- * All coordinates are computed in page-absolute space at construction time so
161
- * the callback itself is allocation-free and executes synchronously.
162
- */
163
- const buildClipPathEffect = (clipPath: ClipPathValue, bounds: Bounds): ClipPathEffect | null => {
164
- const { left: bLeft, top: bTop, width: bWidth, height: bHeight } = bounds;
165
-
166
- switch (clipPath.type) {
167
- case CLIP_PATH_TYPE.INSET: {
168
- const iLeft = getAbsoluteValue(clipPath.left, bWidth);
169
- const iTop = getAbsoluteValue(clipPath.top, bHeight);
170
- const x = bLeft + iLeft;
171
- const y = bTop + iTop;
172
- // Clamp to zero: per CSS spec, overlapping insets produce an empty shape.
173
- const w = Math.max(0, bWidth - iLeft - getAbsoluteValue(clipPath.right, bWidth));
174
- const h = Math.max(0, bHeight - iTop - getAbsoluteValue(clipPath.bottom, bHeight));
175
- return new ClipPathEffect((ctx) => {
176
- ctx.beginPath();
177
- ctx.rect(x, y, w, h);
178
- ctx.clip();
179
- });
180
- }
181
-
182
- case CLIP_PATH_TYPE.CIRCLE: {
183
- const cx = bLeft + getAbsoluteValue(clipPath.cx, bWidth);
184
- const cy = bTop + getAbsoluteValue(clipPath.cy, bHeight);
185
- let r: number;
186
- if (clipPath.radius === 'closest-side') {
187
- r = Math.min(cx - bLeft, cy - bTop, bLeft + bWidth - cx, bTop + bHeight - cy);
188
- } else if (clipPath.radius === 'farthest-side') {
189
- r = Math.max(cx - bLeft, cy - bTop, bLeft + bWidth - cx, bTop + bHeight - cy);
190
- } else {
191
- // Per CSS spec, percentage is relative to sqrt(w² + h²) / sqrt(2).
192
- r = getAbsoluteValue(clipPath.radius, Math.sqrt(bWidth * bWidth + bHeight * bHeight) / Math.SQRT2);
193
- }
194
- return new ClipPathEffect((ctx) => {
195
- ctx.beginPath();
196
- ctx.arc(cx, cy, Math.max(0, r), 0, Math.PI * 2);
197
- ctx.clip();
198
- });
199
- }
200
-
201
- case CLIP_PATH_TYPE.ELLIPSE: {
202
- const cx = bLeft + getAbsoluteValue(clipPath.cx, bWidth);
203
- const cy = bTop + getAbsoluteValue(clipPath.cy, bHeight);
204
- const rx = resolveAxisRadius(clipPath.rx, cx, bLeft, bLeft + bWidth, bWidth);
205
- const ry = resolveAxisRadius(clipPath.ry, cy, bTop, bTop + bHeight, bHeight);
206
- return new ClipPathEffect((ctx) => {
207
- ctx.beginPath();
208
- ctx.ellipse(cx, cy, Math.max(0, rx), Math.max(0, ry), 0, 0, Math.PI * 2);
209
- ctx.clip();
210
- });
211
- }
212
-
213
- case CLIP_PATH_TYPE.POLYGON: {
214
- // Pre-compute all vertices in page-absolute coordinates.
215
- const absPoints = clipPath.points.map(
216
- ([px, py]) =>
217
- [bLeft + getAbsoluteValue(px, bWidth), bTop + getAbsoluteValue(py, bHeight)] as [number, number]
218
- );
219
- return new ClipPathEffect((ctx) => {
220
- ctx.beginPath();
221
- if (absPoints.length > 0) {
222
- ctx.moveTo(absPoints[0][0], absPoints[0][1]);
223
- for (let i = 1; i < absPoints.length; i++) {
224
- ctx.lineTo(absPoints[i][0], absPoints[i][1]);
225
- }
226
- ctx.closePath();
227
- }
228
- // Calling clip() with an empty path (zero points) is intentional:
229
- // it clips the entire region to nothing, which is the correct
230
- // behaviour for a degenerate polygon() per the CSS spec.
231
- ctx.clip();
232
- });
233
- }
234
-
235
- case CLIP_PATH_TYPE.PATH: {
236
- // path() coordinates are in the element's local space (0,0 = element top-left).
237
- // We temporarily translate the canvas origin to the element's position, clip
238
- // with the Path2D, then restore only the transform matrix (not the clipping
239
- // region) via setTransform so the clip persists for the enclosing
240
- // ctx.save() / ctx.restore() pair managed by EffectsRenderer.
241
- //
242
- // When the element also has a CSS transform, that transform was already applied
243
- // by a preceding TransformEffect, so the path coordinates end up correctly in
244
- // the element's transformed local space — matching browser behaviour.
245
- const { d } = clipPath;
246
- let cachedPath: Path2D | null = null;
247
- return new ClipPathEffect((ctx) => {
248
- try {
249
- if (!cachedPath) {
250
- cachedPath = new Path2D(d);
251
- }
252
- const savedTransform = ctx.getTransform();
253
- ctx.translate(bLeft, bTop);
254
- ctx.clip(cachedPath);
255
- ctx.setTransform(savedTransform);
256
- } catch (_e) {
257
- // Path2D or getTransform/setTransform not supported in this environment.
258
- }
259
- });
260
- }
261
-
262
- case CLIP_PATH_TYPE.NONE:
263
- return null;
264
-
265
- default: {
266
- // Exhaustiveness guard: if a new CLIP_PATH_TYPE is added in the future
267
- // without a corresponding case above, TypeScript will raise a compile-time
268
- // error here rather than silently falling through.
269
- const _exhaustive: never = clipPath;
270
- void _exhaustive;
271
- return null;
272
- }
273
- }
274
- };
275
-
276
- const parseStackTree = (
277
- parent: ElementPaint,
278
- stackingContext: StackingContext,
279
- realStackingContext: StackingContext,
280
- listItems: ElementPaint[]
281
- ) => {
282
- parent.container.elements.forEach((child) => {
283
- const treatAsRealStackingContext = child.createsRealStackingContext;
284
- const createsStackingContext = child.createsStackingContext;
285
- const paintContainer = new ElementPaint(child, parent);
286
- if (contains(child.styles.display, DISPLAY.LIST_ITEM)) {
287
- listItems.push(paintContainer);
288
- }
289
-
290
- const listOwnerItems = child.isListOwner ? [] : listItems;
291
-
292
- if (treatAsRealStackingContext || createsStackingContext) {
293
- const parentStack =
294
- treatAsRealStackingContext || child.styles.isPositioned() ? realStackingContext : stackingContext;
295
-
296
- const stack = new StackingContext(paintContainer);
297
-
298
- if (child.styles.isPositioned() || child.styles.opacity < 1 || child.styles.isTransformed()) {
299
- const order = child.styles.zIndex.order;
300
- if (order < 0) {
301
- let index = 0;
302
-
303
- parentStack.negativeZIndex.some((current, i) => {
304
- if (order > current.element.container.styles.zIndex.order) {
305
- index = i;
306
- return false;
307
- } else if (index > 0) {
308
- return true;
309
- }
310
-
311
- return false;
312
- });
313
- parentStack.negativeZIndex.splice(index, 0, stack);
314
- } else if (order > 0) {
315
- let index = 0;
316
- parentStack.positiveZIndex.some((current, i) => {
317
- if (order >= current.element.container.styles.zIndex.order) {
318
- index = i + 1;
319
- return false;
320
- } else if (index > 0) {
321
- return true;
322
- }
323
-
324
- return false;
325
- });
326
- parentStack.positiveZIndex.splice(index, 0, stack);
327
- } else {
328
- parentStack.zeroOrAutoZIndexOrTransformedOrOpacity.push(stack);
329
- }
330
- } else {
331
- if (child.styles.isFloating()) {
332
- parentStack.nonPositionedFloats.push(stack);
333
- } else {
334
- parentStack.nonPositionedInlineLevel.push(stack);
335
- }
336
- }
337
-
338
- parseStackTree(
339
- paintContainer,
340
- stack,
341
- treatAsRealStackingContext ? stack : realStackingContext,
342
- listOwnerItems
343
- );
344
- } else {
345
- if (child.styles.isInlineLevel()) {
346
- stackingContext.inlineLevel.push(paintContainer);
347
- } else {
348
- stackingContext.nonInlineLevel.push(paintContainer);
349
- }
350
-
351
- parseStackTree(paintContainer, stackingContext, realStackingContext, listOwnerItems);
352
- }
353
-
354
- if (child.isListOwner) {
355
- processListItems(child, listOwnerItems);
356
- }
357
- });
358
- };
359
-
360
- const processListItems = (owner: ElementContainer, elements: ElementPaint[]) => {
361
- let numbering = owner instanceof OLElementContainer ? owner.start : 1;
362
- const reversed = owner instanceof OLElementContainer ? owner.reversed : false;
363
- for (let i = 0; i < elements.length; i++) {
364
- const item = elements[i];
365
- if (
366
- item.container instanceof LIElementContainer &&
367
- typeof item.container.value === 'number' &&
368
- item.container.value !== 0
369
- ) {
370
- numbering = item.container.value;
371
- }
372
-
373
- item.listValue = createCounterText(numbering, item.container.styles.listStyleType, true);
374
-
375
- numbering += reversed ? -1 : 1;
376
- }
377
- };
378
-
379
- export const parseStackingContexts = (container: ElementContainer): StackingContext => {
380
- const paintContainer = new ElementPaint(container, null);
381
- const root = new StackingContext(paintContainer);
382
- const listItems: ElementPaint[] = [];
383
- parseStackTree(paintContainer, root, root, listItems);
384
- processListItems(paintContainer.container, listItems);
385
- return root;
386
- };
@@ -1,19 +0,0 @@
1
- import { IPath, Path, PathType } from './path';
2
-
3
- export class Vector implements IPath {
4
- type: PathType;
5
- x: number;
6
- y: number;
7
-
8
- constructor(x: number, y: number) {
9
- this.type = PathType.VECTOR;
10
- this.x = x;
11
- this.y = y;
12
- }
13
-
14
- add(deltaX: number, deltaY: number): Vector {
15
- return new Vector(this.x + deltaX, this.y + deltaY);
16
- }
17
- }
18
-
19
- export const isVector = (path: Path): path is Vector => path.type === PathType.VECTOR;