html2canvas-pro 2.1.0 → 2.2.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 (266) hide show
  1. package/dist/html2canvas-pro.esm.js +10226 -10526
  2. package/dist/html2canvas-pro.esm.js.map +1 -1
  3. package/dist/html2canvas-pro.js +10869 -11171
  4. package/dist/html2canvas-pro.js.map +1 -1
  5. package/dist/html2canvas-pro.min.js +8 -8
  6. package/dist/lib/config.js +0 -22
  7. package/dist/lib/core/cache-storage.js +3 -40
  8. package/dist/lib/core/constants.js +25 -0
  9. package/dist/lib/core/context.js +1 -0
  10. package/dist/lib/core/features.js +3 -2
  11. package/dist/lib/core/validator.js +3 -3
  12. package/dist/lib/css/grouped/background-styles.js +36 -0
  13. package/dist/lib/css/grouped/border-styles.js +75 -0
  14. package/dist/lib/css/grouped/font-styles.js +93 -0
  15. package/dist/lib/css/grouped/layout-styles.js +127 -0
  16. package/dist/lib/css/index.js +74 -46
  17. package/dist/lib/css/layout/text.js +7 -6
  18. package/dist/lib/css/property-descriptors/background-blend-mode.js +41 -0
  19. package/dist/lib/css/property-descriptors/border-image-repeat.js +42 -0
  20. package/dist/lib/css/property-descriptors/border-image-slice.js +45 -0
  21. package/dist/lib/css/property-descriptors/border-image-source.js +21 -0
  22. package/dist/lib/css/property-descriptors/border-radius.js +1 -1
  23. package/dist/lib/css/property-descriptors/box-decoration-break.js +18 -0
  24. package/dist/lib/css/property-descriptors/counter-increment.js +17 -12
  25. package/dist/lib/css/property-descriptors/counter-reset.js +4 -12
  26. package/dist/lib/css/property-descriptors/filter.js +76 -0
  27. package/dist/lib/css/property-descriptors/font-variant-ligatures.js +34 -0
  28. package/dist/lib/css/property-descriptors/object-fit.js +1 -1
  29. package/dist/lib/css/property-descriptors/object-position.js +42 -0
  30. package/dist/lib/css/property-descriptors/visibility.js +1 -1
  31. package/dist/lib/css/property-descriptors/zoom.js +18 -0
  32. package/dist/lib/css/syntax/parser.js +0 -1
  33. package/dist/lib/css/types/color.js +5 -1
  34. package/dist/lib/css/types/functions/repeating-linear-gradient.js +9 -0
  35. package/dist/lib/css/types/image.js +12 -2
  36. package/dist/lib/css/types/length-percentage.js +6 -2
  37. package/dist/lib/css/types/safe-eval.js +80 -0
  38. package/dist/lib/dom/document-cloner.js +23 -163
  39. package/dist/lib/dom/slot-cloner.js +176 -0
  40. package/dist/lib/index.js +1 -17
  41. package/dist/lib/render/canvas/background-renderer.js +169 -30
  42. package/dist/lib/render/canvas/border-image-renderer.js +153 -0
  43. package/dist/lib/render/canvas/canvas-renderer.js +39 -190
  44. package/dist/lib/render/canvas/content-renderer.js +202 -0
  45. package/dist/lib/render/canvas/effects-renderer.js +3 -0
  46. package/dist/lib/render/canvas/foreignobject-renderer.js +5 -1
  47. package/dist/lib/render/canvas/text/text-decoration-renderer.js +99 -0
  48. package/dist/lib/render/canvas/text-renderer.js +100 -224
  49. package/dist/lib/render/effects.js +38 -3
  50. package/dist/lib/render/object-fit.js +19 -15
  51. package/dist/lib/render/stacking-context.js +11 -0
  52. package/dist/types/config.d.ts +0 -10
  53. package/dist/types/core/cache-storage.d.ts +0 -24
  54. package/dist/types/core/constants.d.ts +22 -0
  55. package/dist/types/core/context.d.ts +3 -0
  56. package/dist/types/core/performance-monitor.d.ts +4 -4
  57. package/dist/types/core/validator.d.ts +6 -8
  58. package/dist/types/css/grouped/background-styles.d.ts +16 -0
  59. package/dist/types/css/grouped/border-styles.d.ts +31 -0
  60. package/dist/types/css/grouped/font-styles.d.ts +35 -0
  61. package/dist/types/css/grouped/layout-styles.d.ts +46 -0
  62. package/dist/types/css/index.d.ts +30 -0
  63. package/dist/types/css/property-descriptors/background-blend-mode.d.ts +23 -0
  64. package/dist/types/css/property-descriptors/border-image-repeat.d.ts +12 -0
  65. package/dist/types/css/property-descriptors/border-image-slice.d.ts +10 -0
  66. package/dist/types/css/property-descriptors/border-image-source.d.ts +4 -0
  67. package/dist/types/css/property-descriptors/box-decoration-break.d.ts +6 -0
  68. package/dist/types/css/property-descriptors/counter-increment.d.ts +3 -0
  69. package/dist/types/css/property-descriptors/filter.d.ts +3 -0
  70. package/dist/types/css/property-descriptors/font-variant-ligatures.d.ts +14 -0
  71. package/dist/types/css/property-descriptors/object-position.d.ts +4 -0
  72. package/dist/types/css/property-descriptors/zoom.d.ts +3 -0
  73. package/dist/types/css/types/functions/repeating-linear-gradient.d.ts +4 -0
  74. package/dist/types/css/types/image.d.ts +4 -2
  75. package/dist/types/css/types/safe-eval.d.ts +8 -0
  76. package/dist/types/dom/document-cloner.d.ts +3 -44
  77. package/dist/types/dom/slot-cloner.d.ts +66 -0
  78. package/dist/types/index.d.ts +3 -7
  79. package/dist/types/options.d.ts +11 -0
  80. package/dist/types/render/canvas/background-renderer.d.ts +23 -0
  81. package/dist/types/render/canvas/border-image-renderer.d.ts +18 -0
  82. package/dist/types/render/canvas/canvas-renderer.d.ts +1 -0
  83. package/dist/types/render/canvas/content-renderer.d.ts +44 -0
  84. package/dist/types/render/canvas/text/text-decoration-renderer.d.ts +18 -0
  85. package/dist/types/render/canvas/text-renderer.d.ts +12 -1
  86. package/dist/types/render/effects.d.ts +12 -2
  87. package/dist/types/render/object-fit.d.ts +2 -1
  88. package/dist/types/render/renderer-interface.d.ts +11 -9
  89. package/package.json +7 -20
  90. package/dist/lib/dom/replaced-elements/pseudo-elements.js +0 -0
  91. package/dist/lib/invariant.js +0 -9
  92. package/dist/types/dom/replaced-elements/pseudo-elements.d.ts +0 -0
  93. package/dist/types/invariant.d.ts +0 -1
  94. package/src/__tests__/index.ts +0 -99
  95. package/src/config.ts +0 -107
  96. package/src/core/__mocks__/cache-storage.ts +0 -1
  97. package/src/core/__mocks__/context.ts +0 -19
  98. package/src/core/__mocks__/features.ts +0 -8
  99. package/src/core/__mocks__/logger.ts +0 -17
  100. package/src/core/__tests__/cache-storage.test.ts +0 -205
  101. package/src/core/__tests__/cache-storage.ts +0 -278
  102. package/src/core/__tests__/logger.ts +0 -29
  103. package/src/core/__tests__/validator.ts +0 -359
  104. package/src/core/bitwise.ts +0 -1
  105. package/src/core/cache-storage.ts +0 -315
  106. package/src/core/context.ts +0 -31
  107. package/src/core/debugger.ts +0 -32
  108. package/src/core/features.ts +0 -222
  109. package/src/core/logger.ts +0 -64
  110. package/src/core/origin-checker.ts +0 -57
  111. package/src/core/performance-monitor.ts +0 -241
  112. package/src/core/render-element.ts +0 -272
  113. package/src/core/util.ts +0 -1
  114. package/src/core/validator.ts +0 -593
  115. package/src/css/index.ts +0 -427
  116. package/src/css/layout/__mocks__/bounds.ts +0 -6
  117. package/src/css/layout/bounds.ts +0 -79
  118. package/src/css/layout/text.ts +0 -161
  119. package/src/css/property-descriptor.ts +0 -49
  120. package/src/css/property-descriptors/__tests__/background-tests.ts +0 -65
  121. package/src/css/property-descriptors/__tests__/clip-path.test.ts +0 -280
  122. package/src/css/property-descriptors/__tests__/font-family.ts +0 -25
  123. package/src/css/property-descriptors/__tests__/image-rendering-integration.test.ts +0 -153
  124. package/src/css/property-descriptors/__tests__/image-rendering-performance.test.ts +0 -175
  125. package/src/css/property-descriptors/__tests__/image-rendering.test.ts +0 -72
  126. package/src/css/property-descriptors/__tests__/paint-order.ts +0 -87
  127. package/src/css/property-descriptors/__tests__/text-shadow.ts +0 -94
  128. package/src/css/property-descriptors/__tests__/transform-tests.ts +0 -18
  129. package/src/css/property-descriptors/background-clip.ts +0 -30
  130. package/src/css/property-descriptors/background-color.ts +0 -9
  131. package/src/css/property-descriptors/background-image.ts +0 -27
  132. package/src/css/property-descriptors/background-origin.ts +0 -31
  133. package/src/css/property-descriptors/background-position.ts +0 -38
  134. package/src/css/property-descriptors/background-repeat.ts +0 -44
  135. package/src/css/property-descriptors/background-size.ts +0 -27
  136. package/src/css/property-descriptors/border-color.ts +0 -13
  137. package/src/css/property-descriptors/border-radius.ts +0 -19
  138. package/src/css/property-descriptors/border-style.ts +0 -34
  139. package/src/css/property-descriptors/border-width.ts +0 -20
  140. package/src/css/property-descriptors/box-shadow.ts +0 -60
  141. package/src/css/property-descriptors/clip-path.ts +0 -271
  142. package/src/css/property-descriptors/color.ts +0 -9
  143. package/src/css/property-descriptors/content.ts +0 -26
  144. package/src/css/property-descriptors/counter-increment.ts +0 -43
  145. package/src/css/property-descriptors/counter-reset.ts +0 -36
  146. package/src/css/property-descriptors/direction.ts +0 -23
  147. package/src/css/property-descriptors/display.ts +0 -117
  148. package/src/css/property-descriptors/duration.ts +0 -14
  149. package/src/css/property-descriptors/float.ts +0 -29
  150. package/src/css/property-descriptors/font-family.ts +0 -38
  151. package/src/css/property-descriptors/font-size.ts +0 -9
  152. package/src/css/property-descriptors/font-style.ts +0 -25
  153. package/src/css/property-descriptors/font-variant.ts +0 -12
  154. package/src/css/property-descriptors/font-weight.ts +0 -26
  155. package/src/css/property-descriptors/image-rendering.ts +0 -33
  156. package/src/css/property-descriptors/letter-spacing.ts +0 -25
  157. package/src/css/property-descriptors/line-break.ts +0 -22
  158. package/src/css/property-descriptors/line-height.ts +0 -22
  159. package/src/css/property-descriptors/list-style-image.ts +0 -19
  160. package/src/css/property-descriptors/list-style-position.ts +0 -22
  161. package/src/css/property-descriptors/list-style-type.ts +0 -179
  162. package/src/css/property-descriptors/margin.ts +0 -13
  163. package/src/css/property-descriptors/mix-blend-mode.ts +0 -35
  164. package/src/css/property-descriptors/object-fit.ts +0 -39
  165. package/src/css/property-descriptors/opacity.ts +0 -15
  166. package/src/css/property-descriptors/overflow-wrap.ts +0 -22
  167. package/src/css/property-descriptors/overflow.ts +0 -34
  168. package/src/css/property-descriptors/padding.ts +0 -14
  169. package/src/css/property-descriptors/paint-order.ts +0 -42
  170. package/src/css/property-descriptors/position.ts +0 -30
  171. package/src/css/property-descriptors/quotes.ts +0 -57
  172. package/src/css/property-descriptors/rotate.ts +0 -34
  173. package/src/css/property-descriptors/text-align.ts +0 -26
  174. package/src/css/property-descriptors/text-decoration-color.ts +0 -9
  175. package/src/css/property-descriptors/text-decoration-line.ts +0 -38
  176. package/src/css/property-descriptors/text-decoration-style.ts +0 -32
  177. package/src/css/property-descriptors/text-decoration-thickness.ts +0 -30
  178. package/src/css/property-descriptors/text-overflow.ts +0 -23
  179. package/src/css/property-descriptors/text-shadow.ts +0 -52
  180. package/src/css/property-descriptors/text-transform.ts +0 -27
  181. package/src/css/property-descriptors/text-underline-offset.ts +0 -27
  182. package/src/css/property-descriptors/transform-origin.ts +0 -29
  183. package/src/css/property-descriptors/transform.ts +0 -74
  184. package/src/css/property-descriptors/visibility.ts +0 -25
  185. package/src/css/property-descriptors/webkit-line-clamp.ts +0 -30
  186. package/src/css/property-descriptors/webkit-text-stroke-color.ts +0 -8
  187. package/src/css/property-descriptors/webkit-text-stroke-width.ts +0 -15
  188. package/src/css/property-descriptors/word-break.ts +0 -25
  189. package/src/css/property-descriptors/writing-mode.ts +0 -37
  190. package/src/css/property-descriptors/z-index.ts +0 -27
  191. package/src/css/syntax/__tests__/tokernizer-tests.ts +0 -29
  192. package/src/css/syntax/parser.ts +0 -188
  193. package/src/css/syntax/tokenizer.ts +0 -822
  194. package/src/css/type-descriptor.ts +0 -7
  195. package/src/css/types/__tests__/color-tests.ts +0 -147
  196. package/src/css/types/__tests__/image-tests.ts +0 -239
  197. package/src/css/types/angle.ts +0 -86
  198. package/src/css/types/color-math.ts +0 -22
  199. package/src/css/types/color-spaces/a98.ts +0 -86
  200. package/src/css/types/color-spaces/p3.ts +0 -92
  201. package/src/css/types/color-spaces/pro-photo.ts +0 -87
  202. package/src/css/types/color-spaces/rec2020.ts +0 -90
  203. package/src/css/types/color-spaces/srgb.ts +0 -87
  204. package/src/css/types/color-utilities.ts +0 -452
  205. package/src/css/types/color.ts +0 -485
  206. package/src/css/types/functions/-prefix-linear-gradient.ts +0 -35
  207. package/src/css/types/functions/-prefix-radial-gradient.ts +0 -106
  208. package/src/css/types/functions/-webkit-gradient.ts +0 -69
  209. package/src/css/types/functions/__tests__/radial-gradient.ts +0 -69
  210. package/src/css/types/functions/counter.ts +0 -511
  211. package/src/css/types/functions/gradient.ts +0 -206
  212. package/src/css/types/functions/linear-gradient.ts +0 -28
  213. package/src/css/types/functions/radial-gradient.ts +0 -101
  214. package/src/css/types/image.ts +0 -120
  215. package/src/css/types/index.ts +0 -1
  216. package/src/css/types/length-percentage.ts +0 -137
  217. package/src/css/types/length.ts +0 -7
  218. package/src/css/types/time.ts +0 -20
  219. package/src/dom/__mocks__/document-cloner.ts +0 -22
  220. package/src/dom/__tests__/dom-normalizer.test.ts +0 -133
  221. package/src/dom/__tests__/element-container.test.ts +0 -129
  222. package/src/dom/document-cloner.ts +0 -929
  223. package/src/dom/dom-normalizer.ts +0 -133
  224. package/src/dom/element-container.ts +0 -75
  225. package/src/dom/elements/li-element-container.ts +0 -10
  226. package/src/dom/elements/ol-element-container.ts +0 -12
  227. package/src/dom/elements/select-element-container.ts +0 -10
  228. package/src/dom/elements/textarea-element-container.ts +0 -9
  229. package/src/dom/node-parser.ts +0 -177
  230. package/src/dom/node-type-guards.ts +0 -70
  231. package/src/dom/replaced-elements/canvas-element-container.ts +0 -15
  232. package/src/dom/replaced-elements/iframe-element-container.ts +0 -55
  233. package/src/dom/replaced-elements/image-element-container.ts +0 -16
  234. package/src/dom/replaced-elements/index.ts +0 -5
  235. package/src/dom/replaced-elements/input-element-container.ts +0 -105
  236. package/src/dom/replaced-elements/pseudo-elements.ts +0 -0
  237. package/src/dom/replaced-elements/svg-element-container.ts +0 -23
  238. package/src/dom/text-container.ts +0 -42
  239. package/src/global.d.ts +0 -19
  240. package/src/index.ts +0 -82
  241. package/src/invariant.ts +0 -5
  242. package/src/options.ts +0 -55
  243. package/src/render/__tests__/object-fit.test.ts +0 -85
  244. package/src/render/background.ts +0 -298
  245. package/src/render/bezier-curve.ts +0 -47
  246. package/src/render/border.ts +0 -165
  247. package/src/render/bound-curves.ts +0 -388
  248. package/src/render/box-sizing.ts +0 -31
  249. package/src/render/canvas/__tests__/background-renderer.test.ts +0 -72
  250. package/src/render/canvas/__tests__/border-renderer.test.ts +0 -24
  251. package/src/render/canvas/__tests__/effects-renderer.test.ts +0 -32
  252. package/src/render/canvas/__tests__/text-renderer.test.ts +0 -471
  253. package/src/render/canvas/background-renderer.ts +0 -271
  254. package/src/render/canvas/border-renderer.ts +0 -224
  255. package/src/render/canvas/canvas-path.ts +0 -31
  256. package/src/render/canvas/canvas-renderer.ts +0 -641
  257. package/src/render/canvas/effects-renderer.ts +0 -130
  258. package/src/render/canvas/foreignobject-renderer.ts +0 -53
  259. package/src/render/canvas/text-renderer.ts +0 -700
  260. package/src/render/effects.ts +0 -75
  261. package/src/render/font-metrics.ts +0 -72
  262. package/src/render/object-fit.ts +0 -100
  263. package/src/render/path.ts +0 -37
  264. package/src/render/renderer-interface.ts +0 -28
  265. package/src/render/stacking-context.ts +0 -386
  266. package/src/render/vector.ts +0 -19
@@ -1,49 +0,0 @@
1
- import { CSSValue } from './syntax/parser';
2
- import { CSSTypes } from './types';
3
- import { Context } from '../core/context';
4
-
5
- export const enum PropertyDescriptorParsingType {
6
- VALUE,
7
- LIST,
8
- IDENT_VALUE,
9
- TYPE_VALUE,
10
- TOKEN_VALUE
11
- }
12
-
13
- export interface IPropertyDescriptor {
14
- name: string;
15
- type: PropertyDescriptorParsingType;
16
- initialValue: string;
17
- prefix: boolean;
18
- }
19
-
20
- export interface IPropertyIdentValueDescriptor<T> extends IPropertyDescriptor {
21
- type: PropertyDescriptorParsingType.IDENT_VALUE;
22
- parse: (context: Context, token: string) => T;
23
- }
24
-
25
- export interface IPropertyTypeValueDescriptor extends IPropertyDescriptor {
26
- type: PropertyDescriptorParsingType.TYPE_VALUE;
27
- format: CSSTypes;
28
- }
29
-
30
- export interface IPropertyValueDescriptor<T> extends IPropertyDescriptor {
31
- type: PropertyDescriptorParsingType.VALUE;
32
- parse: (context: Context, token: CSSValue) => T;
33
- }
34
-
35
- export interface IPropertyListDescriptor<T> extends IPropertyDescriptor {
36
- type: PropertyDescriptorParsingType.LIST;
37
- parse: (context: Context, tokens: CSSValue[]) => T;
38
- }
39
-
40
- export interface IPropertyTokenValueDescriptor extends IPropertyDescriptor {
41
- type: PropertyDescriptorParsingType.TOKEN_VALUE;
42
- }
43
-
44
- export type CSSPropertyDescriptor<T> =
45
- | IPropertyValueDescriptor<T>
46
- | IPropertyListDescriptor<T>
47
- | IPropertyIdentValueDescriptor<T>
48
- | IPropertyTypeValueDescriptor
49
- | IPropertyTokenValueDescriptor;
@@ -1,65 +0,0 @@
1
- import { deepStrictEqual } from 'assert';
2
- import { Parser } from '../../syntax/parser';
3
- import { backgroundImage } from '../background-image';
4
- import { CSSImageType } from '../../types/image';
5
- import { pack } from '../../types/color-utilities';
6
- import { deg } from '../../types/angle';
7
-
8
- vi.mock('../../../core/context');
9
- import { Context } from '../../../core/context';
10
-
11
- vi.mock('../../../core/features');
12
-
13
- const backgroundImageParse = (context: Context, value: string) =>
14
- backgroundImage.parse(context, Parser.parseValues(value));
15
-
16
- import { Html2CanvasConfig } from '../../../config';
17
-
18
- describe('property-descriptors', () => {
19
- let context: Context;
20
- beforeEach(() => {
21
- const mockWindow = {
22
- location: { href: 'http://example.com' },
23
- document: { createElement: () => ({ href: '' }) }
24
- } as any;
25
- const config = new Html2CanvasConfig({ window: mockWindow });
26
- context = new Context({} as any, {} as any, config);
27
- });
28
- describe('background-image', () => {
29
- it('none', () => {
30
- deepStrictEqual(backgroundImageParse(context, 'none'), []);
31
- expect(context.cache.addImage).not.toHaveBeenCalled();
32
- });
33
-
34
- it('url(test.jpg), url(test2.jpg)', () => {
35
- deepStrictEqual(
36
- backgroundImageParse(context, 'url(http://example.com/test.jpg), url(http://example.com/test2.jpg)'),
37
- [
38
- { url: 'http://example.com/test.jpg', type: CSSImageType.URL },
39
- { url: 'http://example.com/test2.jpg', type: CSSImageType.URL }
40
- ]
41
- );
42
- expect(context.cache.addImage).toHaveBeenCalledWith('http://example.com/test.jpg');
43
- expect(context.cache.addImage).toHaveBeenCalledWith('http://example.com/test2.jpg');
44
- });
45
-
46
- it(`linear-gradient(to bottom, rgba(255,255,0,0.5), rgba(0,0,255,0.5)), url('https://html2canvas.hertzen.com')`, () =>
47
- deepStrictEqual(
48
- backgroundImageParse(
49
- context,
50
- `linear-gradient(to bottom, rgba(255,255,0,0.5), rgba(0,0,255,0.5)), url('https://html2canvas.hertzen.com')`
51
- ),
52
- [
53
- {
54
- angle: deg(180),
55
- type: CSSImageType.LINEAR_GRADIENT,
56
- stops: [
57
- { color: pack(255, 255, 0, 0.5), stop: null },
58
- { color: pack(0, 0, 255, 0.5), stop: null }
59
- ]
60
- },
61
- { url: 'https://html2canvas.hertzen.com', type: CSSImageType.URL }
62
- ]
63
- ));
64
- });
65
- });
@@ -1,280 +0,0 @@
1
- import { strictEqual, deepStrictEqual, ok } from 'assert';
2
- import { Parser } from '../../syntax/parser';
3
- import { clipPath, CLIP_PATH_TYPE, ClipPathValue } from '../clip-path';
4
- import { LengthPercentage } from '../../types/length-percentage';
5
- import { TokenType } from '../../syntax/tokenizer';
6
-
7
- /** Helper that runs a CSS value string through the clipPath descriptor. */
8
- const parse = (css: string): ClipPathValue => {
9
- const token = Parser.parseValue(css);
10
- return clipPath.parse(null as any, token);
11
- };
12
-
13
- describe('clip-path property descriptor', () => {
14
- // ------------------------------------------------------------------ none
15
- describe('none / fallbacks', () => {
16
- it('should return NONE for "none"', () => {
17
- strictEqual(parse('none').type, CLIP_PATH_TYPE.NONE);
18
- });
19
-
20
- it('should return NONE for unknown ident', () => {
21
- strictEqual(parse('auto').type, CLIP_PATH_TYPE.NONE);
22
- });
23
-
24
- it('should return NONE for unsupported function', () => {
25
- // url() is not yet supported
26
- strictEqual(parse('url(#mask)').type, CLIP_PATH_TYPE.NONE);
27
- });
28
- });
29
-
30
- // ----------------------------------------------------------------- inset
31
- describe('inset()', () => {
32
- it('should parse a single length (all sides equal)', () => {
33
- const result = parse('inset(10px)');
34
- if (result.type !== CLIP_PATH_TYPE.INSET) throw new Error('wrong type');
35
- strictEqual(result.top.number, 10);
36
- strictEqual(result.right.number, 10);
37
- strictEqual(result.bottom.number, 10);
38
- strictEqual(result.left.number, 10);
39
- });
40
-
41
- it('should parse two values (top/bottom | left/right)', () => {
42
- const result = parse('inset(10px 20%)');
43
- if (result.type !== CLIP_PATH_TYPE.INSET) throw new Error('wrong type');
44
- strictEqual(result.top.number, 10);
45
- strictEqual(result.right.number, 20);
46
- strictEqual(result.bottom.number, 10);
47
- strictEqual(result.left.number, 20);
48
- });
49
-
50
- it('should parse four values', () => {
51
- const result = parse('inset(5px 10px 15px 20px)');
52
- if (result.type !== CLIP_PATH_TYPE.INSET) throw new Error('wrong type');
53
- strictEqual(result.top.number, 5);
54
- strictEqual(result.right.number, 10);
55
- strictEqual(result.bottom.number, 15);
56
- strictEqual(result.left.number, 20);
57
- });
58
-
59
- it('should parse three values (top | left/right | bottom)', () => {
60
- const result = parse('inset(5px 10px 15px)');
61
- if (result.type !== CLIP_PATH_TYPE.INSET) throw new Error('wrong type');
62
- strictEqual(result.top.number, 5);
63
- strictEqual(result.right.number, 10);
64
- strictEqual(result.bottom.number, 15);
65
- strictEqual(result.left.number, 10, 'left should mirror right');
66
- });
67
-
68
- it('should ignore the "round" clause', () => {
69
- const result = parse('inset(10px round 5px)');
70
- if (result.type !== CLIP_PATH_TYPE.INSET) throw new Error('wrong type');
71
- strictEqual(result.top.number, 10);
72
- });
73
-
74
- it('should parse percentage values', () => {
75
- const result = parse('inset(25%)');
76
- if (result.type !== CLIP_PATH_TYPE.INSET) throw new Error('wrong type');
77
- strictEqual(result.top.type, TokenType.PERCENTAGE_TOKEN);
78
- strictEqual(result.top.number, 25);
79
- });
80
-
81
- it('should parse overlapping insets (>50% each side) — clamping to 0 is done at render time', () => {
82
- // The parser stores the raw values; buildClipPathEffect clamps w/h to Math.max(0, …).
83
- const result = parse('inset(60%)');
84
- if (result.type !== CLIP_PATH_TYPE.INSET) throw new Error('wrong type');
85
- strictEqual(result.top.number, 60);
86
- strictEqual(result.right.number, 60);
87
- });
88
- });
89
-
90
- // ---------------------------------------------------------------- circle
91
- describe('circle()', () => {
92
- it('should default to closest-side radius and 50% 50% center', () => {
93
- const result = parse('circle()');
94
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
95
- strictEqual(result.radius, 'closest-side');
96
- strictEqual(result.cx.number, 50);
97
- strictEqual(result.cy.number, 50);
98
- });
99
-
100
- it('should parse a percentage radius', () => {
101
- const result = parse('circle(50%)');
102
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
103
- ok(result.radius !== 'closest-side' && result.radius !== 'farthest-side');
104
- strictEqual((result.radius as LengthPercentage).number, 50);
105
- });
106
-
107
- it('should parse closest-side keyword', () => {
108
- const result = parse('circle(closest-side)');
109
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
110
- strictEqual(result.radius, 'closest-side');
111
- });
112
-
113
- it('should parse farthest-side keyword', () => {
114
- const result = parse('circle(farthest-side)');
115
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
116
- strictEqual(result.radius, 'farthest-side');
117
- });
118
-
119
- it('should parse "at" position', () => {
120
- const result = parse('circle(50% at 30% 70%)');
121
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
122
- strictEqual(result.cx.number, 30);
123
- strictEqual(result.cy.number, 70);
124
- });
125
-
126
- it('should parse "at center" as 50% 50%', () => {
127
- const result = parse('circle(at center)');
128
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
129
- strictEqual(result.cx.number, 50);
130
- strictEqual(result.cy.number, 50);
131
- });
132
-
133
- it('should parse "at left top" as 0 0', () => {
134
- const result = parse('circle(at left top)');
135
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
136
- strictEqual(result.cx.number, 0);
137
- strictEqual(result.cy.number, 0);
138
- });
139
-
140
- it('should parse "at top" as cx=50% cy=0 (top is y-axis)', () => {
141
- const result = parse('circle(at top)');
142
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
143
- strictEqual(result.cx.number, 50, 'cx should default to 50% (center)');
144
- strictEqual(result.cy.number, 0, 'cy should be 0 (top)');
145
- });
146
-
147
- it('should parse "at bottom" as cx=50% cy=100%', () => {
148
- const result = parse('circle(at bottom)');
149
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
150
- strictEqual(result.cx.number, 50);
151
- strictEqual(result.cy.number, 100);
152
- });
153
-
154
- it('should parse "at right" as cx=100% cy=50%', () => {
155
- const result = parse('circle(at right)');
156
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
157
- strictEqual(result.cx.number, 100);
158
- strictEqual(result.cy.number, 50);
159
- });
160
-
161
- it('should parse "at top left" (reversed order) as cx=0 cy=0', () => {
162
- const result = parse('circle(at top left)');
163
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
164
- strictEqual(result.cx.number, 0);
165
- strictEqual(result.cy.number, 0);
166
- });
167
-
168
- it('should parse mixed "at top 30%" as cx=30% cy=0', () => {
169
- const result = parse('circle(at top 30%)');
170
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
171
- strictEqual(result.cx.number, 30, 'cx should be the length-percentage');
172
- strictEqual(result.cy.number, 0, 'cy should be 0 (top)');
173
- });
174
-
175
- it('should parse "at center 30%" as cx=50% cy=30%', () => {
176
- const result = parse('circle(at center 30%)');
177
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
178
- strictEqual(result.cx.number, 50);
179
- strictEqual(result.cy.number, 30);
180
- });
181
-
182
- it('should parse "at 30% center" as cx=30% cy=50%', () => {
183
- const result = parse('circle(at 30% center)');
184
- if (result.type !== CLIP_PATH_TYPE.CIRCLE) throw new Error('wrong type');
185
- strictEqual(result.cx.number, 30);
186
- strictEqual(result.cy.number, 50);
187
- });
188
- });
189
-
190
- // --------------------------------------------------------------- ellipse
191
- describe('ellipse()', () => {
192
- it('should default both radii to closest-side and center to 50% 50%', () => {
193
- const result = parse('ellipse()');
194
- if (result.type !== CLIP_PATH_TYPE.ELLIPSE) throw new Error('wrong type');
195
- strictEqual(result.rx, 'closest-side');
196
- strictEqual(result.ry, 'closest-side');
197
- strictEqual(result.cx.number, 50);
198
- strictEqual(result.cy.number, 50);
199
- });
200
-
201
- it('should parse two length-percentage radii', () => {
202
- const result = parse('ellipse(40% 30%)');
203
- if (result.type !== CLIP_PATH_TYPE.ELLIPSE) throw new Error('wrong type');
204
- ok(result.rx !== 'closest-side' && result.rx !== 'farthest-side');
205
- ok(result.ry !== 'closest-side' && result.ry !== 'farthest-side');
206
- strictEqual((result.rx as LengthPercentage).number, 40);
207
- strictEqual((result.ry as LengthPercentage).number, 30);
208
- });
209
-
210
- it('should parse radii and "at" position', () => {
211
- const result = parse('ellipse(40px 20px at 50% 50%)');
212
- if (result.type !== CLIP_PATH_TYPE.ELLIPSE) throw new Error('wrong type');
213
- strictEqual((result.rx as LengthPercentage).number, 40);
214
- strictEqual((result.ry as LengthPercentage).number, 20);
215
- strictEqual(result.cx.number, 50);
216
- strictEqual(result.cy.number, 50);
217
- });
218
- });
219
-
220
- // -------------------------------------------------------------- polygon
221
- describe('polygon()', () => {
222
- it('should parse a triangle', () => {
223
- const result = parse('polygon(0% 0%, 100% 0%, 50% 100%)');
224
- if (result.type !== CLIP_PATH_TYPE.POLYGON) throw new Error('wrong type');
225
- strictEqual(result.points.length, 3);
226
- strictEqual(result.points[0][0].number, 0);
227
- strictEqual(result.points[0][1].number, 0);
228
- strictEqual(result.points[1][0].number, 100);
229
- strictEqual(result.points[2][0].number, 50);
230
- });
231
-
232
- it('should skip a leading fill-rule keyword', () => {
233
- const result = parse('polygon(evenodd, 0% 0%, 100% 50%, 0% 100%)');
234
- if (result.type !== CLIP_PATH_TYPE.POLYGON) throw new Error('wrong type');
235
- strictEqual(result.points.length, 3);
236
- });
237
-
238
- it('should parse pixel coordinates', () => {
239
- const result = parse('polygon(10px 20px, 100px 20px, 100px 80px, 10px 80px)');
240
- if (result.type !== CLIP_PATH_TYPE.POLYGON) throw new Error('wrong type');
241
- strictEqual(result.points.length, 4);
242
- strictEqual(result.points[0][0].number, 10);
243
- strictEqual(result.points[0][1].number, 20);
244
- });
245
-
246
- it('should return empty points array for empty polygon', () => {
247
- const result = parse('polygon()');
248
- if (result.type !== CLIP_PATH_TYPE.POLYGON) throw new Error('wrong type');
249
- deepStrictEqual(result.points, []);
250
- });
251
- });
252
-
253
- // ------------------------------------------------------------------ path
254
- describe('path()', () => {
255
- it('should parse a valid SVG path string', () => {
256
- const result = parse("path('M 0 0 L 100 0 L 100 100 Z')");
257
- if (result.type !== CLIP_PATH_TYPE.PATH) throw new Error('wrong type');
258
- strictEqual(result.d, 'M 0 0 L 100 0 L 100 100 Z');
259
- });
260
-
261
- it('should return NONE when no string is provided', () => {
262
- strictEqual(parse('path()').type, CLIP_PATH_TYPE.NONE);
263
- });
264
- });
265
-
266
- // ---------------------------------------- initial value / descriptor meta
267
- describe('descriptor metadata', () => {
268
- it('should have name "clip-path"', () => {
269
- strictEqual(clipPath.name, 'clip-path');
270
- });
271
-
272
- it('should have initial value "none"', () => {
273
- strictEqual(clipPath.initialValue, 'none');
274
- });
275
-
276
- it('should not require vendor prefix', () => {
277
- strictEqual(clipPath.prefix, false);
278
- });
279
- });
280
- });
@@ -1,25 +0,0 @@
1
- import { deepEqual } from 'assert';
2
- import { Parser } from '../../syntax/parser';
3
- import { fontFamily } from '../font-family';
4
- import { Context } from '../../../core/context';
5
-
6
- const fontFamilyParse = (value: string) => fontFamily.parse({} as Context, Parser.parseValues(value));
7
-
8
- describe('property-descriptors', () => {
9
- describe('font-family', () => {
10
- it('sans-serif', () => deepEqual(fontFamilyParse('sans-serif'), ['sans-serif']));
11
-
12
- it('great fonts 40 library', () =>
13
- deepEqual(fontFamilyParse('great fonts 40 library'), ["'great fonts 40 library'"]));
14
-
15
- it('preferred font, "quoted fallback font", font', () =>
16
- deepEqual(fontFamilyParse('preferred font, "quoted fallback font", font'), [
17
- "'preferred font'",
18
- "'quoted fallback font'",
19
- 'font'
20
- ]));
21
-
22
- it("'escaping test\\'s font'", () =>
23
- deepEqual(fontFamilyParse("'escaping test\\'s font'"), ["'escaping test's font'"]));
24
- });
25
- });
@@ -1,153 +0,0 @@
1
- import { IMAGE_RENDERING } from '../image-rendering';
2
-
3
- /**
4
- * Integration tests for image-rendering CSS property
5
- * Tests actual DOM and canvas rendering behavior
6
- */
7
- describe('image-rendering integration', () => {
8
- let container: HTMLDivElement;
9
- let canvas: HTMLCanvasElement;
10
- let ctx: CanvasRenderingContext2D | null = null;
11
-
12
- beforeEach(() => {
13
- // Create test DOM elements
14
- container = document.createElement('div');
15
- document.body.appendChild(container);
16
-
17
- // Create canvas for testing
18
- canvas = document.createElement('canvas');
19
- canvas.width = 100;
20
- canvas.height = 100;
21
- try {
22
- ctx = canvas.getContext('2d');
23
- } catch {
24
- // JSDOM does not implement getContext('2d') unless canvas npm package is installed
25
- ctx = null;
26
- }
27
- });
28
-
29
- afterEach(() => {
30
- // Cleanup
31
- if (container.parentNode) {
32
- container.parentNode.removeChild(container);
33
- }
34
- });
35
-
36
- describe('Canvas context imageSmoothingEnabled', () => {
37
- it('should default to true', () => {
38
- if (!ctx) return; // Skip if canvas not available
39
- expect(ctx.imageSmoothingEnabled).toBe(true);
40
- });
41
-
42
- it('should be settable to false', () => {
43
- if (!ctx) return; // Skip if canvas not available
44
- ctx.imageSmoothingEnabled = false;
45
- expect(ctx.imageSmoothingEnabled).toBe(false);
46
- });
47
-
48
- it('should be settable to true', () => {
49
- if (!ctx) return; // Skip if canvas not available
50
- ctx.imageSmoothingEnabled = false;
51
- ctx.imageSmoothingEnabled = true;
52
- expect(ctx.imageSmoothingEnabled).toBe(true);
53
- });
54
- });
55
-
56
- describe('Canvas context imageSmoothingQuality', () => {
57
- it('should accept "low" value', () => {
58
- if (!ctx) return; // Skip if canvas not available
59
- ctx.imageSmoothingQuality = 'low';
60
- expect(ctx.imageSmoothingQuality).toBe('low');
61
- });
62
-
63
- it('should accept "medium" value', () => {
64
- if (!ctx) return; // Skip if canvas not available
65
- ctx.imageSmoothingQuality = 'medium';
66
- expect(ctx.imageSmoothingQuality).toBe('medium');
67
- });
68
-
69
- it('should accept "high" value', () => {
70
- if (!ctx) return; // Skip if canvas not available
71
- ctx.imageSmoothingQuality = 'high';
72
- expect(ctx.imageSmoothingQuality).toBe('high');
73
- });
74
- });
75
-
76
- describe('CSS image-rendering property', () => {
77
- it('should apply pixelated style to img element', () => {
78
- const img = document.createElement('img');
79
- img.style.imageRendering = 'pixelated';
80
- container.appendChild(img);
81
- expect(img.style.imageRendering).toBe('pixelated');
82
- });
83
-
84
- it('should apply crisp-edges style to img element', () => {
85
- const img = document.createElement('img');
86
- img.style.imageRendering = 'crisp-edges';
87
- container.appendChild(img);
88
- expect(img.style.imageRendering).toBe('crisp-edges');
89
- });
90
-
91
- it('should apply smooth style to img element', () => {
92
- const img = document.createElement('img');
93
- img.style.imageRendering = 'smooth';
94
- container.appendChild(img);
95
- // Note: Some browsers may normalize this value
96
- expect(['smooth', 'auto', '']).toContain(img.style.imageRendering);
97
- });
98
- });
99
-
100
- describe('IMAGE_RENDERING enum values', () => {
101
- it('should have correct enum values', () => {
102
- expect(IMAGE_RENDERING.AUTO).toBe(0);
103
- expect(IMAGE_RENDERING.CRISP_EDGES).toBe(1);
104
- expect(IMAGE_RENDERING.PIXELATED).toBe(2);
105
- expect(IMAGE_RENDERING.SMOOTH).toBe(3);
106
- });
107
-
108
- it('should have distinct values', () => {
109
- const values = [
110
- IMAGE_RENDERING.AUTO,
111
- IMAGE_RENDERING.CRISP_EDGES,
112
- IMAGE_RENDERING.PIXELATED,
113
- IMAGE_RENDERING.SMOOTH
114
- ];
115
- const uniqueValues = new Set(values);
116
- expect(uniqueValues.size).toBe(values.length);
117
- });
118
- });
119
-
120
- describe('Smoothing state preservation', () => {
121
- it('should preserve and restore smoothing state', () => {
122
- if (!ctx) return; // Skip if canvas not available
123
- const originalState = ctx.imageSmoothingEnabled;
124
-
125
- // Save state
126
- ctx.save();
127
- ctx.imageSmoothingEnabled = false;
128
- expect(ctx.imageSmoothingEnabled).toBe(false);
129
-
130
- // Restore state
131
- ctx.restore();
132
- expect(ctx.imageSmoothingEnabled).toBe(originalState);
133
- });
134
-
135
- it('should handle multiple save/restore cycles', () => {
136
- if (!ctx) return; // Skip if canvas not available
137
- ctx.imageSmoothingEnabled = true;
138
- ctx.save();
139
-
140
- ctx.imageSmoothingEnabled = false;
141
- ctx.save();
142
-
143
- ctx.imageSmoothingEnabled = true;
144
- expect(ctx.imageSmoothingEnabled).toBe(true);
145
-
146
- ctx.restore();
147
- expect(ctx.imageSmoothingEnabled).toBe(false);
148
-
149
- ctx.restore();
150
- expect(ctx.imageSmoothingEnabled).toBe(true);
151
- });
152
- });
153
- });