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,206 +0,0 @@
1
- import { CSSValue } from '../../syntax/parser';
2
- import {
3
- CSSRadialExtent,
4
- CSSRadialGradientImage,
5
- CSSRadialShape,
6
- GradientColorStop,
7
- GradientCorner,
8
- UnprocessedGradientColorStop
9
- } from '../image';
10
- import { color as colorType } from '../color';
11
- import { getAbsoluteValue, HUNDRED_PERCENT, isLengthPercentage, ZERO_LENGTH } from '../length-percentage';
12
- import { Context } from '../../../core/context';
13
-
14
- export const parseColorStop = (context: Context, args: CSSValue[]): UnprocessedGradientColorStop => {
15
- const color = colorType.parse(context, args[0]);
16
- const stop = args[1];
17
- return stop && isLengthPercentage(stop) ? { color, stop } : { color, stop: null };
18
- };
19
-
20
- export const processColorStops = (stops: UnprocessedGradientColorStop[], lineLength: number): GradientColorStop[] => {
21
- const first = stops[0];
22
- const last = stops[stops.length - 1];
23
- if (first.stop === null) {
24
- first.stop = ZERO_LENGTH;
25
- }
26
-
27
- if (last.stop === null) {
28
- last.stop = HUNDRED_PERCENT;
29
- }
30
-
31
- const processStops: (number | null)[] = [];
32
- let previous = 0;
33
- for (let i = 0; i < stops.length; i++) {
34
- const stop = stops[i].stop;
35
- if (stop !== null) {
36
- const absoluteValue = getAbsoluteValue(stop, lineLength);
37
- if (absoluteValue > previous) {
38
- processStops.push(absoluteValue);
39
- } else {
40
- processStops.push(previous);
41
- }
42
- previous = absoluteValue;
43
- } else {
44
- processStops.push(null);
45
- }
46
- }
47
-
48
- let gapBegin = null;
49
- for (let i = 0; i < processStops.length; i++) {
50
- const stop = processStops[i];
51
- if (stop === null) {
52
- if (gapBegin === null) {
53
- gapBegin = i;
54
- }
55
- } else if (gapBegin !== null) {
56
- const gapLength = i - gapBegin;
57
- const beforeGap = processStops[gapBegin - 1] as number;
58
- const gapValue = (stop - beforeGap) / (gapLength + 1);
59
- for (let g = 1; g <= gapLength; g++) {
60
- processStops[gapBegin + g - 1] = gapValue * g;
61
- }
62
- gapBegin = null;
63
- }
64
- }
65
-
66
- return stops.map(({ color }, i) => {
67
- return { color, stop: Math.max(Math.min(1, (processStops[i] as number) / lineLength), 0) };
68
- });
69
- };
70
-
71
- const getAngleFromCorner = (corner: GradientCorner, width: number, height: number): number => {
72
- const centerX = width / 2;
73
- const centerY = height / 2;
74
- const x = getAbsoluteValue(corner[0], width) - centerX;
75
- const y = centerY - getAbsoluteValue(corner[1], height);
76
-
77
- return (Math.atan2(y, x) + Math.PI * 2) % (Math.PI * 2);
78
- };
79
-
80
- export const calculateGradientDirection = (
81
- angle: number | GradientCorner,
82
- width: number,
83
- height: number
84
- ): [number, number, number, number, number] => {
85
- const radian = typeof angle === 'number' ? angle : getAngleFromCorner(angle, width, height);
86
-
87
- const lineLength = Math.abs(width * Math.sin(radian)) + Math.abs(height * Math.cos(radian));
88
-
89
- const halfWidth = width / 2;
90
- const halfHeight = height / 2;
91
- const halfLineLength = lineLength / 2;
92
-
93
- const yDiff = Math.sin(radian - Math.PI / 2) * halfLineLength;
94
- const xDiff = Math.cos(radian - Math.PI / 2) * halfLineLength;
95
-
96
- return [lineLength, halfWidth - xDiff, halfWidth + xDiff, halfHeight - yDiff, halfHeight + yDiff];
97
- };
98
-
99
- const distance = (a: number, b: number): number => Math.sqrt(a * a + b * b);
100
-
101
- const findCorner = (width: number, height: number, x: number, y: number, closest: boolean): [number, number] => {
102
- const corners = [
103
- [0, 0],
104
- [0, height],
105
- [width, 0],
106
- [width, height]
107
- ];
108
-
109
- return corners.reduce(
110
- (stat, corner) => {
111
- const [cx, cy] = corner;
112
- const d = distance(x - cx, y - cy);
113
- if (closest ? d < stat.optimumDistance : d > stat.optimumDistance) {
114
- return {
115
- optimumCorner: corner,
116
- optimumDistance: d
117
- };
118
- }
119
-
120
- return stat;
121
- },
122
- {
123
- optimumDistance: closest ? Infinity : -Infinity,
124
- optimumCorner: null
125
- }
126
- ).optimumCorner as [number, number];
127
- };
128
-
129
- export const calculateRadius = (
130
- gradient: CSSRadialGradientImage,
131
- x: number,
132
- y: number,
133
- width: number,
134
- height: number
135
- ): [number, number] => {
136
- let rx = 0;
137
- let ry = 0;
138
-
139
- switch (gradient.size) {
140
- case CSSRadialExtent.CLOSEST_SIDE:
141
- // The ending shape is sized so that that it exactly meets the side of the gradient box closest to the gradient’s center.
142
- // If the shape is an ellipse, it exactly meets the closest side in each dimension.
143
- if (gradient.shape === CSSRadialShape.CIRCLE) {
144
- rx = ry = Math.min(Math.abs(x), Math.abs(x - width), Math.abs(y), Math.abs(y - height));
145
- } else if (gradient.shape === CSSRadialShape.ELLIPSE) {
146
- rx = Math.min(Math.abs(x), Math.abs(x - width));
147
- ry = Math.min(Math.abs(y), Math.abs(y - height));
148
- }
149
- break;
150
-
151
- case CSSRadialExtent.CLOSEST_CORNER:
152
- // The ending shape is sized so that that it passes through the corner of the gradient box closest to the gradient’s center.
153
- // If the shape is an ellipse, the ending shape is given the same aspect-ratio it would have if closest-side were specified.
154
- if (gradient.shape === CSSRadialShape.CIRCLE) {
155
- rx = ry = Math.min(
156
- distance(x, y),
157
- distance(x, y - height),
158
- distance(x - width, y),
159
- distance(x - width, y - height)
160
- );
161
- } else if (gradient.shape === CSSRadialShape.ELLIPSE) {
162
- // Compute the ratio ry/rx (which is to be the same as for "closest-side")
163
- const c = Math.min(Math.abs(y), Math.abs(y - height)) / Math.min(Math.abs(x), Math.abs(x - width));
164
- const [cx, cy] = findCorner(width, height, x, y, true);
165
- rx = distance(cx - x, (cy - y) / c);
166
- ry = c * rx;
167
- }
168
- break;
169
-
170
- case CSSRadialExtent.FARTHEST_SIDE:
171
- // Same as closest-side, except the ending shape is sized based on the farthest side(s)
172
- if (gradient.shape === CSSRadialShape.CIRCLE) {
173
- rx = ry = Math.max(Math.abs(x), Math.abs(x - width), Math.abs(y), Math.abs(y - height));
174
- } else if (gradient.shape === CSSRadialShape.ELLIPSE) {
175
- rx = Math.max(Math.abs(x), Math.abs(x - width));
176
- ry = Math.max(Math.abs(y), Math.abs(y - height));
177
- }
178
- break;
179
-
180
- case CSSRadialExtent.FARTHEST_CORNER:
181
- // Same as closest-corner, except the ending shape is sized based on the farthest corner.
182
- // If the shape is an ellipse, the ending shape is given the same aspect ratio it would have if farthest-side were specified.
183
- if (gradient.shape === CSSRadialShape.CIRCLE) {
184
- rx = ry = Math.max(
185
- distance(x, y),
186
- distance(x, y - height),
187
- distance(x - width, y),
188
- distance(x - width, y - height)
189
- );
190
- } else if (gradient.shape === CSSRadialShape.ELLIPSE) {
191
- // Compute the ratio ry/rx (which is to be the same as for "farthest-side")
192
- const c = Math.max(Math.abs(y), Math.abs(y - height)) / Math.max(Math.abs(x), Math.abs(x - width));
193
- const [cx, cy] = findCorner(width, height, x, y, false);
194
- rx = distance(cx - x, (cy - y) / c);
195
- ry = c * rx;
196
- }
197
- break;
198
- }
199
-
200
- if (Array.isArray(gradient.size)) {
201
- rx = getAbsoluteValue(gradient.size[0], width);
202
- ry = gradient.size.length === 2 ? getAbsoluteValue(gradient.size[1], height) : rx;
203
- }
204
-
205
- return [rx, ry];
206
- };
@@ -1,28 +0,0 @@
1
- import { CSSValue, parseFunctionArgs } from '../../syntax/parser';
2
- import { TokenType } from '../../syntax/tokenizer';
3
- import { isAngle, angle as angleType, parseNamedSide, deg } from '../angle';
4
- import { CSSImageType, CSSLinearGradientImage, GradientCorner, UnprocessedGradientColorStop } from '../image';
5
- import { parseColorStop } from './gradient';
6
- import { Context } from '../../../core/context';
7
-
8
- export const linearGradient = (context: Context, tokens: CSSValue[]): CSSLinearGradientImage => {
9
- let angle: number | GradientCorner = deg(180);
10
- const stops: UnprocessedGradientColorStop[] = [];
11
-
12
- parseFunctionArgs(tokens).forEach((arg, i) => {
13
- if (i === 0) {
14
- const firstToken = arg[0];
15
- if (firstToken.type === TokenType.IDENT_TOKEN && firstToken.value === 'to') {
16
- angle = parseNamedSide(arg);
17
- return;
18
- } else if (isAngle(firstToken)) {
19
- angle = angleType.parse(context, firstToken);
20
- return;
21
- }
22
- }
23
- const colorStop = parseColorStop(context, arg);
24
- stops.push(colorStop);
25
- });
26
-
27
- return { angle, stops, type: CSSImageType.LINEAR_GRADIENT };
28
- };
@@ -1,101 +0,0 @@
1
- import { CSSValue, isIdentToken, parseFunctionArgs } from '../../syntax/parser';
2
- import {
3
- CSSImageType,
4
- CSSRadialExtent,
5
- CSSRadialGradientImage,
6
- CSSRadialShape,
7
- CSSRadialSize,
8
- UnprocessedGradientColorStop
9
- } from '../image';
10
- import { parseColorStop } from './gradient';
11
- import {
12
- FIFTY_PERCENT,
13
- HUNDRED_PERCENT,
14
- isLengthPercentage,
15
- LengthPercentage,
16
- ZERO_LENGTH
17
- } from '../length-percentage';
18
- import { isLength } from '../length';
19
- import { Context } from '../../../core/context';
20
- export const CLOSEST_SIDE = 'closest-side';
21
- export const FARTHEST_SIDE = 'farthest-side';
22
- export const CLOSEST_CORNER = 'closest-corner';
23
- export const FARTHEST_CORNER = 'farthest-corner';
24
- export const CIRCLE = 'circle';
25
- export const ELLIPSE = 'ellipse';
26
- export const COVER = 'cover';
27
- export const CONTAIN = 'contain';
28
-
29
- export const radialGradient = (context: Context, tokens: CSSValue[]): CSSRadialGradientImage => {
30
- let shape: CSSRadialShape = CSSRadialShape.CIRCLE;
31
- let size: CSSRadialSize = CSSRadialExtent.FARTHEST_CORNER;
32
- const stops: UnprocessedGradientColorStop[] = [];
33
- const position: LengthPercentage[] = [];
34
- parseFunctionArgs(tokens).forEach((arg, i) => {
35
- let isColorStop = true;
36
- if (i === 0) {
37
- let isAtPosition = false;
38
- isColorStop = arg.reduce((acc, token) => {
39
- if (isAtPosition) {
40
- if (isIdentToken(token)) {
41
- switch (token.value) {
42
- case 'center':
43
- position.push(FIFTY_PERCENT);
44
- return acc;
45
- case 'top':
46
- case 'left':
47
- position.push(ZERO_LENGTH);
48
- return acc;
49
- case 'right':
50
- case 'bottom':
51
- position.push(HUNDRED_PERCENT);
52
- return acc;
53
- }
54
- } else if (isLengthPercentage(token) || isLength(token)) {
55
- position.push(token);
56
- }
57
- } else if (isIdentToken(token)) {
58
- switch (token.value) {
59
- case CIRCLE:
60
- shape = CSSRadialShape.CIRCLE;
61
- return false;
62
- case ELLIPSE:
63
- shape = CSSRadialShape.ELLIPSE;
64
- return false;
65
- case 'at':
66
- isAtPosition = true;
67
- return false;
68
- case CLOSEST_SIDE:
69
- size = CSSRadialExtent.CLOSEST_SIDE;
70
- return false;
71
- case COVER:
72
- case FARTHEST_SIDE:
73
- size = CSSRadialExtent.FARTHEST_SIDE;
74
- return false;
75
- case CONTAIN:
76
- case CLOSEST_CORNER:
77
- size = CSSRadialExtent.CLOSEST_CORNER;
78
- return false;
79
- case FARTHEST_CORNER:
80
- size = CSSRadialExtent.FARTHEST_CORNER;
81
- return false;
82
- }
83
- } else if (isLength(token) || isLengthPercentage(token)) {
84
- if (!Array.isArray(size)) {
85
- size = [];
86
- }
87
- size.push(token);
88
- return false;
89
- }
90
- return acc;
91
- }, isColorStop);
92
- }
93
-
94
- if (isColorStop) {
95
- const colorStop = parseColorStop(context, arg);
96
- stops.push(colorStop);
97
- }
98
- });
99
-
100
- return { size, shape, stops, position, type: CSSImageType.RADIAL_GRADIENT };
101
- };
@@ -1,120 +0,0 @@
1
- import { CSSValue } from '../syntax/parser';
2
- import { TokenType } from '../syntax/tokenizer';
3
- import { Color } from './color';
4
- import { linearGradient } from './functions/linear-gradient';
5
- import { prefixLinearGradient } from './functions/-prefix-linear-gradient';
6
- import { ITypeDescriptor } from '../type-descriptor';
7
- import { LengthPercentage } from './length-percentage';
8
- import { webkitGradient } from './functions/-webkit-gradient';
9
- import { radialGradient } from './functions/radial-gradient';
10
- import { prefixRadialGradient } from './functions/-prefix-radial-gradient';
11
- import { Context } from '../../core/context';
12
-
13
- export const enum CSSImageType {
14
- URL,
15
- LINEAR_GRADIENT,
16
- RADIAL_GRADIENT
17
- }
18
-
19
- export const isLinearGradient = (background: ICSSImage): background is CSSLinearGradientImage => {
20
- return background.type === CSSImageType.LINEAR_GRADIENT;
21
- };
22
-
23
- export const isRadialGradient = (background: ICSSImage): background is CSSRadialGradientImage => {
24
- return background.type === CSSImageType.RADIAL_GRADIENT;
25
- };
26
-
27
- export interface UnprocessedGradientColorStop {
28
- color: Color;
29
- stop: LengthPercentage | null;
30
- }
31
-
32
- export interface GradientColorStop {
33
- color: Color;
34
- stop: number;
35
- }
36
-
37
- export interface ICSSImage {
38
- type: CSSImageType;
39
- }
40
-
41
- export interface CSSURLImage extends ICSSImage {
42
- url: string;
43
- type: CSSImageType.URL;
44
- }
45
-
46
- // interface ICSSGeneratedImage extends ICSSImage {}
47
-
48
- export type GradientCorner = [LengthPercentage, LengthPercentage];
49
-
50
- interface ICSSGradientImage extends ICSSImage {
51
- stops: UnprocessedGradientColorStop[];
52
- }
53
-
54
- export interface CSSLinearGradientImage extends ICSSGradientImage {
55
- angle: number | GradientCorner;
56
- type: CSSImageType.LINEAR_GRADIENT;
57
- }
58
-
59
- export const enum CSSRadialShape {
60
- CIRCLE,
61
- ELLIPSE
62
- }
63
-
64
- export const enum CSSRadialExtent {
65
- CLOSEST_SIDE,
66
- FARTHEST_SIDE,
67
- CLOSEST_CORNER,
68
- FARTHEST_CORNER
69
- }
70
-
71
- export type CSSRadialSize = CSSRadialExtent | LengthPercentage[];
72
-
73
- export interface CSSRadialGradientImage extends ICSSGradientImage {
74
- type: CSSImageType.RADIAL_GRADIENT;
75
- shape: CSSRadialShape;
76
- size: CSSRadialSize;
77
- position: LengthPercentage[];
78
- }
79
-
80
- export const image: ITypeDescriptor<ICSSImage> = {
81
- name: 'image',
82
- parse: (context: Context, value: CSSValue): ICSSImage => {
83
- if (value.type === TokenType.URL_TOKEN) {
84
- const image: CSSURLImage = { url: value.value, type: CSSImageType.URL };
85
- context.cache.addImage(value.value);
86
- return image;
87
- }
88
-
89
- if (value.type === TokenType.FUNCTION) {
90
- const imageFunction = SUPPORTED_IMAGE_FUNCTIONS[value.name];
91
- if (typeof imageFunction === 'undefined') {
92
- throw new Error(`Attempting to parse an unsupported image function "${value.name}"`);
93
- }
94
- return imageFunction(context, value.values);
95
- }
96
-
97
- throw new Error(`Unsupported image type ${value.type}`);
98
- }
99
- };
100
-
101
- export function isSupportedImage(value: CSSValue): boolean {
102
- return (
103
- !(value.type === TokenType.IDENT_TOKEN && value.value === 'none') &&
104
- (value.type !== TokenType.FUNCTION || !!SUPPORTED_IMAGE_FUNCTIONS[value.name])
105
- );
106
- }
107
-
108
- const SUPPORTED_IMAGE_FUNCTIONS: Record<string, (context: Context, args: CSSValue[]) => ICSSImage> = {
109
- 'linear-gradient': linearGradient,
110
- '-moz-linear-gradient': prefixLinearGradient,
111
- '-ms-linear-gradient': prefixLinearGradient,
112
- '-o-linear-gradient': prefixLinearGradient,
113
- '-webkit-linear-gradient': prefixLinearGradient,
114
- 'radial-gradient': radialGradient,
115
- '-moz-radial-gradient': prefixRadialGradient,
116
- '-ms-radial-gradient': prefixRadialGradient,
117
- '-o-radial-gradient': prefixRadialGradient,
118
- '-webkit-radial-gradient': prefixRadialGradient,
119
- '-webkit-gradient': webkitGradient
120
- };
@@ -1 +0,0 @@
1
- export type CSSTypes = 'angle' | 'color' | 'image' | 'length' | 'length-percentage' | 'time';
@@ -1,137 +0,0 @@
1
- import { DimensionToken, FLAG_INTEGER, NumberValueToken, TokenType } from '../syntax/tokenizer';
2
- import { CSSValue, CSSFunction, isDimensionToken } from '../syntax/parser';
3
- import { isLength } from './length';
4
- export type LengthPercentage = DimensionToken | NumberValueToken;
5
- export type LengthPercentageTuple = [LengthPercentage] | [LengthPercentage, LengthPercentage];
6
-
7
- export const isLengthPercentage = (token: CSSValue): token is LengthPercentage =>
8
- token.type === TokenType.PERCENTAGE_TOKEN || isLength(token);
9
-
10
- /**
11
- * Check if a token is a calc() function
12
- */
13
- export const isCalcFunction = (token: CSSValue): token is CSSFunction =>
14
- token.type === TokenType.FUNCTION && token.name === 'calc';
15
-
16
- /**
17
- * Evaluate a calc() expression and convert to LengthPercentage token
18
- * Supports basic arithmetic: +, -, *, /
19
- * Note: Percentages in calc() are converted based on a context value
20
- */
21
- export const evaluateCalcToLengthPercentage = (calcToken: CSSFunction, contextValue = 0): LengthPercentage | null => {
22
- // Build expression string from tokens
23
- const buildExpression = (values: CSSValue[]): string | null => {
24
- let expression = '';
25
-
26
- for (const value of values) {
27
- if (value.type === TokenType.WHITESPACE_TOKEN) {
28
- continue;
29
- }
30
-
31
- if (value.type === TokenType.FUNCTION) {
32
- if (value.name === 'calc') {
33
- const nested = buildExpression(value.values);
34
- if (nested === null) return null;
35
- expression += `(${nested})`;
36
- } else {
37
- return null;
38
- }
39
- } else if (value.type === TokenType.NUMBER_TOKEN) {
40
- expression += value.number.toString();
41
- } else if (value.type === TokenType.DIMENSION_TOKEN) {
42
- // Convert units to px
43
- if (value.unit === 'px') {
44
- expression += value.number.toString();
45
- } else if (value.unit === 'rem' || value.unit === 'em') {
46
- expression += (value.number * 16).toString();
47
- } else {
48
- expression += value.number.toString();
49
- }
50
- } else if (value.type === TokenType.PERCENTAGE_TOKEN) {
51
- // Convert percentage to absolute value based on context
52
- expression += ((value.number / 100) * contextValue).toString();
53
- } else if (value.type === TokenType.DELIM_TOKEN) {
54
- const op = value.value;
55
- if (op === '+' || op === '-' || op === '*' || op === '/') {
56
- expression += ` ${op} `;
57
- } else if (op === '(') {
58
- expression += '(';
59
- } else if (op === ')') {
60
- expression += ')';
61
- }
62
- }
63
- }
64
-
65
- return expression;
66
- };
67
-
68
- try {
69
- const expression = buildExpression(calcToken.values);
70
- if (expression === null || expression.trim() === '') {
71
- return null;
72
- }
73
-
74
- // Evaluate the expression
75
- // Note: Using Function constructor (similar to color.ts line 185)
76
- const result = new Function('return ' + expression)();
77
-
78
- if (typeof result === 'number' && !isNaN(result)) {
79
- // Return as a number token in px
80
- return {
81
- type: TokenType.NUMBER_TOKEN,
82
- number: result,
83
- flags: FLAG_INTEGER
84
- };
85
- }
86
- } catch (e) {
87
- return null;
88
- }
89
-
90
- return null;
91
- };
92
- export const parseLengthPercentageTuple = (tokens: LengthPercentage[]): LengthPercentageTuple =>
93
- tokens.length > 1 ? [tokens[0], tokens[1]] : [tokens[0]];
94
- export const ZERO_LENGTH: NumberValueToken = {
95
- type: TokenType.NUMBER_TOKEN,
96
- number: 0,
97
- flags: FLAG_INTEGER
98
- };
99
-
100
- export const FIFTY_PERCENT: NumberValueToken = {
101
- type: TokenType.PERCENTAGE_TOKEN,
102
- number: 50,
103
- flags: FLAG_INTEGER
104
- };
105
-
106
- export const HUNDRED_PERCENT: NumberValueToken = {
107
- type: TokenType.PERCENTAGE_TOKEN,
108
- number: 100,
109
- flags: FLAG_INTEGER
110
- };
111
-
112
- export const getAbsoluteValueForTuple = (
113
- tuple: LengthPercentageTuple,
114
- width: number,
115
- height: number
116
- ): [number, number] => {
117
- const [x, y] = tuple;
118
- return [getAbsoluteValue(x, width), getAbsoluteValue(typeof y !== 'undefined' ? y : x, height)];
119
- };
120
- export const getAbsoluteValue = (token: LengthPercentage, parent: number): number => {
121
- if (token.type === TokenType.PERCENTAGE_TOKEN) {
122
- return (token.number / 100) * parent;
123
- }
124
-
125
- if (isDimensionToken(token)) {
126
- switch (token.unit) {
127
- case 'rem':
128
- case 'em':
129
- return 16 * token.number; // TODO use correct font-size
130
- case 'px':
131
- default:
132
- return token.number;
133
- }
134
- }
135
-
136
- return token.number;
137
- };
@@ -1,7 +0,0 @@
1
- import { CSSValue } from '../syntax/parser';
2
- import { DimensionToken, NumberValueToken, TokenType } from '../syntax/tokenizer';
3
-
4
- export type Length = DimensionToken | NumberValueToken;
5
-
6
- export const isLength = (token: CSSValue): token is Length =>
7
- token.type === TokenType.NUMBER_TOKEN || token.type === TokenType.DIMENSION_TOKEN;
@@ -1,20 +0,0 @@
1
- import { CSSValue } from '../syntax/parser';
2
- import { TokenType } from '../syntax/tokenizer';
3
- import { ITypeDescriptor } from '../type-descriptor';
4
- import { Context } from '../../core/context';
5
-
6
- export const time: ITypeDescriptor<number> = {
7
- name: 'time',
8
- parse: (_context: Context, value: CSSValue): number => {
9
- if (value.type === TokenType.DIMENSION_TOKEN) {
10
- switch (value.unit.toLowerCase()) {
11
- case 's':
12
- return 1000 * value.number;
13
- case 'ms':
14
- return value.number;
15
- }
16
- }
17
-
18
- throw new Error(`Unsupported time type`);
19
- }
20
- };
@@ -1,22 +0,0 @@
1
- export class DocumentCloner {
2
- clonedReferenceElement?: HTMLElement;
3
-
4
- constructor() {
5
- this.clonedReferenceElement = {
6
- ownerDocument: {
7
- defaultView: {
8
- pageXOffset: 12,
9
- pageYOffset: 34
10
- }
11
- }
12
- } as HTMLElement;
13
- }
14
-
15
- toIFrame(): Promise<HTMLIFrameElement> {
16
- return Promise.resolve({} as HTMLIFrameElement);
17
- }
18
-
19
- static destroy(): boolean {
20
- return true;
21
- }
22
- }