html2canvas-pro 2.0.4 → 2.1.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 (632) hide show
  1. package/README.md +8 -6
  2. package/dist/html2canvas-pro.esm.js +10018 -9922
  3. package/dist/html2canvas-pro.esm.js.map +1 -1
  4. package/dist/html2canvas-pro.js +10017 -9922
  5. package/dist/html2canvas-pro.js.map +1 -1
  6. package/dist/html2canvas-pro.min.js +5 -5
  7. package/dist/lib/config.js +3 -4
  8. package/dist/lib/core/bitwise.js +0 -1
  9. package/dist/lib/core/cache-storage.js +34 -48
  10. package/dist/lib/core/context.js +0 -1
  11. package/dist/lib/core/debugger.js +0 -1
  12. package/dist/lib/core/features.js +0 -1
  13. package/dist/lib/core/logger.js +0 -1
  14. package/dist/lib/core/origin-checker.js +0 -1
  15. package/dist/lib/core/performance-monitor.js +1 -24
  16. package/dist/lib/core/render-element.js +210 -0
  17. package/dist/lib/core/util.js +0 -1
  18. package/dist/lib/core/validator.js +0 -1
  19. package/dist/lib/css/index.js +149 -90
  20. package/dist/lib/css/layout/bounds.js +0 -1
  21. package/dist/lib/css/layout/text.js +0 -1
  22. package/dist/lib/css/{ITypeDescriptor.js → property-descriptor.js} +0 -1
  23. package/dist/lib/css/property-descriptors/background-clip.js +0 -1
  24. package/dist/lib/css/property-descriptors/background-color.js +0 -1
  25. package/dist/lib/css/property-descriptors/background-image.js +0 -1
  26. package/dist/lib/css/property-descriptors/background-origin.js +0 -1
  27. package/dist/lib/css/property-descriptors/background-position.js +0 -1
  28. package/dist/lib/css/property-descriptors/background-repeat.js +0 -1
  29. package/dist/lib/css/property-descriptors/background-size.js +0 -1
  30. package/dist/lib/css/property-descriptors/border-color.js +0 -1
  31. package/dist/lib/css/property-descriptors/border-radius.js +0 -1
  32. package/dist/lib/css/property-descriptors/border-style.js +0 -1
  33. package/dist/lib/css/property-descriptors/border-width.js +0 -1
  34. package/dist/lib/css/property-descriptors/box-shadow.js +0 -1
  35. package/dist/lib/css/property-descriptors/clip-path.js +0 -1
  36. package/dist/lib/css/property-descriptors/color.js +0 -1
  37. package/dist/lib/css/property-descriptors/content.js +0 -1
  38. package/dist/lib/css/property-descriptors/counter-increment.js +0 -1
  39. package/dist/lib/css/property-descriptors/counter-reset.js +0 -1
  40. package/dist/lib/css/property-descriptors/direction.js +0 -1
  41. package/dist/lib/css/property-descriptors/display.js +0 -1
  42. package/dist/lib/css/property-descriptors/duration.js +0 -1
  43. package/dist/lib/css/property-descriptors/float.js +0 -1
  44. package/dist/lib/css/property-descriptors/font-family.js +0 -1
  45. package/dist/lib/css/property-descriptors/font-size.js +0 -1
  46. package/dist/lib/css/property-descriptors/font-style.js +0 -1
  47. package/dist/lib/css/property-descriptors/font-variant.js +0 -1
  48. package/dist/lib/css/property-descriptors/font-weight.js +0 -1
  49. package/dist/lib/css/property-descriptors/image-rendering.js +0 -1
  50. package/dist/lib/css/property-descriptors/letter-spacing.js +0 -1
  51. package/dist/lib/css/property-descriptors/line-break.js +0 -1
  52. package/dist/lib/css/property-descriptors/line-height.js +0 -1
  53. package/dist/lib/css/property-descriptors/list-style-image.js +0 -1
  54. package/dist/lib/css/property-descriptors/list-style-position.js +0 -1
  55. package/dist/lib/css/property-descriptors/list-style-type.js +0 -1
  56. package/dist/lib/css/property-descriptors/margin.js +0 -1
  57. package/dist/lib/css/property-descriptors/mix-blend-mode.js +31 -0
  58. package/dist/lib/css/property-descriptors/object-fit.js +0 -1
  59. package/dist/lib/css/property-descriptors/opacity.js +0 -1
  60. package/dist/lib/css/property-descriptors/overflow-wrap.js +0 -1
  61. package/dist/lib/css/property-descriptors/overflow.js +0 -1
  62. package/dist/lib/css/property-descriptors/padding.js +0 -1
  63. package/dist/lib/css/property-descriptors/paint-order.js +0 -1
  64. package/dist/lib/css/property-descriptors/position.js +0 -1
  65. package/dist/lib/css/property-descriptors/quotes.js +0 -1
  66. package/dist/lib/css/property-descriptors/rotate.js +0 -1
  67. package/dist/lib/css/property-descriptors/text-align.js +0 -1
  68. package/dist/lib/css/property-descriptors/text-decoration-color.js +0 -1
  69. package/dist/lib/css/property-descriptors/text-decoration-line.js +0 -1
  70. package/dist/lib/css/property-descriptors/text-decoration-style.js +0 -1
  71. package/dist/lib/css/property-descriptors/text-decoration-thickness.js +0 -1
  72. package/dist/lib/css/property-descriptors/text-overflow.js +0 -1
  73. package/dist/lib/css/property-descriptors/text-shadow.js +0 -1
  74. package/dist/lib/css/property-descriptors/text-transform.js +0 -1
  75. package/dist/lib/css/property-descriptors/text-underline-offset.js +0 -1
  76. package/dist/lib/css/property-descriptors/transform-origin.js +0 -1
  77. package/dist/lib/css/property-descriptors/transform.js +0 -1
  78. package/dist/lib/css/property-descriptors/visibility.js +0 -1
  79. package/dist/lib/css/property-descriptors/webkit-line-clamp.js +0 -1
  80. package/dist/lib/css/property-descriptors/webkit-text-stroke-color.js +0 -1
  81. package/dist/lib/css/property-descriptors/webkit-text-stroke-width.js +0 -1
  82. package/dist/lib/css/property-descriptors/word-break.js +0 -1
  83. package/dist/lib/css/property-descriptors/writing-mode.js +0 -1
  84. package/dist/lib/css/property-descriptors/z-index.js +0 -1
  85. package/dist/lib/css/syntax/parser.js +0 -1
  86. package/dist/lib/css/syntax/tokenizer.js +14 -1
  87. package/dist/lib/css/{IPropertyDescriptor.js → type-descriptor.js} +0 -1
  88. package/dist/lib/css/types/angle.js +0 -1
  89. package/dist/lib/css/types/color-math.js +0 -1
  90. package/dist/lib/css/types/color-spaces/a98.js +0 -1
  91. package/dist/lib/css/types/color-spaces/p3.js +0 -1
  92. package/dist/lib/css/types/color-spaces/pro-photo.js +0 -1
  93. package/dist/lib/css/types/color-spaces/rec2020.js +0 -1
  94. package/dist/lib/css/types/color-spaces/srgb.js +0 -1
  95. package/dist/lib/css/types/color-utilities.js +0 -1
  96. package/dist/lib/css/types/color.js +0 -1
  97. package/dist/lib/css/types/functions/-prefix-linear-gradient.js +0 -1
  98. package/dist/lib/css/types/functions/-prefix-radial-gradient.js +0 -1
  99. package/dist/lib/css/types/functions/-webkit-gradient.js +0 -1
  100. package/dist/lib/css/types/functions/counter.js +0 -1
  101. package/dist/lib/css/types/functions/gradient.js +0 -1
  102. package/dist/lib/css/types/functions/linear-gradient.js +0 -1
  103. package/dist/lib/css/types/functions/radial-gradient.js +0 -1
  104. package/dist/lib/css/types/image.js +0 -1
  105. package/dist/lib/css/types/index.js +0 -1
  106. package/dist/lib/css/types/length-percentage.js +0 -1
  107. package/dist/lib/css/types/length.js +0 -1
  108. package/dist/lib/css/types/time.js +0 -1
  109. package/dist/lib/dom/document-cloner.js +27 -22
  110. package/dist/lib/dom/dom-normalizer.js +0 -1
  111. package/dist/lib/dom/element-container.js +7 -6
  112. package/dist/lib/dom/elements/li-element-container.js +0 -1
  113. package/dist/lib/dom/elements/ol-element-container.js +0 -1
  114. package/dist/lib/dom/elements/select-element-container.js +0 -1
  115. package/dist/lib/dom/elements/textarea-element-container.js +0 -1
  116. package/dist/lib/dom/node-parser.js +37 -53
  117. package/dist/lib/dom/node-type-guards.js +62 -25
  118. package/dist/lib/dom/replaced-elements/canvas-element-container.js +0 -1
  119. package/dist/lib/dom/replaced-elements/iframe-element-container.js +0 -1
  120. package/dist/lib/dom/replaced-elements/image-element-container.js +0 -1
  121. package/dist/lib/dom/replaced-elements/index.js +0 -1
  122. package/dist/lib/dom/replaced-elements/input-element-container.js +0 -1
  123. package/dist/lib/dom/replaced-elements/pseudo-elements.js +0 -1
  124. package/dist/lib/dom/replaced-elements/svg-element-container.js +0 -1
  125. package/dist/lib/dom/text-container.js +0 -1
  126. package/dist/lib/index.js +32 -210
  127. package/dist/lib/invariant.js +0 -1
  128. package/dist/lib/options.js +2 -0
  129. package/dist/lib/render/background.js +0 -1
  130. package/dist/lib/render/bezier-curve.js +0 -1
  131. package/dist/lib/render/border.js +0 -1
  132. package/dist/lib/render/bound-curves.js +0 -1
  133. package/dist/lib/render/box-sizing.js +0 -1
  134. package/dist/lib/render/canvas/background-renderer.js +2 -24
  135. package/dist/lib/render/canvas/border-renderer.js +0 -1
  136. package/dist/lib/render/canvas/canvas-path.js +25 -0
  137. package/dist/lib/render/canvas/canvas-renderer.js +23 -96
  138. package/dist/lib/render/canvas/effects-renderer.js +3 -1
  139. package/dist/lib/render/canvas/foreignobject-renderer.js +8 -16
  140. package/dist/lib/render/canvas/text-renderer.js +61 -117
  141. package/dist/lib/render/effects.js +11 -2
  142. package/dist/lib/render/font-metrics.js +0 -1
  143. package/dist/lib/render/object-fit.js +87 -0
  144. package/dist/lib/render/path.js +0 -1
  145. package/dist/lib/render/renderer-interface.js +0 -1
  146. package/dist/lib/render/stacking-context.js +16 -8
  147. package/dist/lib/render/vector.js +0 -1
  148. package/dist/types/core/cache-storage.d.ts +5 -6
  149. package/dist/types/core/performance-monitor.d.ts +0 -11
  150. package/dist/types/core/render-element.d.ts +3 -0
  151. package/dist/types/css/index.d.ts +3 -0
  152. package/dist/types/css/property-descriptors/background-clip.d.ts +1 -1
  153. package/dist/types/css/property-descriptors/background-color.d.ts +1 -1
  154. package/dist/types/css/property-descriptors/background-image.d.ts +1 -1
  155. package/dist/types/css/property-descriptors/background-origin.d.ts +1 -1
  156. package/dist/types/css/property-descriptors/background-position.d.ts +1 -1
  157. package/dist/types/css/property-descriptors/background-repeat.d.ts +1 -1
  158. package/dist/types/css/property-descriptors/background-size.d.ts +1 -1
  159. package/dist/types/css/property-descriptors/border-color.d.ts +1 -1
  160. package/dist/types/css/property-descriptors/border-radius.d.ts +1 -1
  161. package/dist/types/css/property-descriptors/border-style.d.ts +1 -1
  162. package/dist/types/css/property-descriptors/border-width.d.ts +1 -1
  163. package/dist/types/css/property-descriptors/box-shadow.d.ts +1 -1
  164. package/dist/types/css/property-descriptors/clip-path.d.ts +1 -1
  165. package/dist/types/css/property-descriptors/color.d.ts +1 -1
  166. package/dist/types/css/property-descriptors/content.d.ts +1 -1
  167. package/dist/types/css/property-descriptors/counter-increment.d.ts +1 -1
  168. package/dist/types/css/property-descriptors/counter-reset.d.ts +1 -1
  169. package/dist/types/css/property-descriptors/direction.d.ts +1 -1
  170. package/dist/types/css/property-descriptors/display.d.ts +1 -1
  171. package/dist/types/css/property-descriptors/duration.d.ts +1 -1
  172. package/dist/types/css/property-descriptors/float.d.ts +1 -1
  173. package/dist/types/css/property-descriptors/font-family.d.ts +1 -1
  174. package/dist/types/css/property-descriptors/font-size.d.ts +1 -1
  175. package/dist/types/css/property-descriptors/font-style.d.ts +1 -1
  176. package/dist/types/css/property-descriptors/font-variant.d.ts +1 -1
  177. package/dist/types/css/property-descriptors/font-weight.d.ts +1 -1
  178. package/dist/types/css/property-descriptors/image-rendering.d.ts +1 -1
  179. package/dist/types/css/property-descriptors/letter-spacing.d.ts +1 -1
  180. package/dist/types/css/property-descriptors/line-break.d.ts +1 -1
  181. package/dist/types/css/property-descriptors/line-height.d.ts +1 -1
  182. package/dist/types/css/property-descriptors/list-style-image.d.ts +1 -1
  183. package/dist/types/css/property-descriptors/list-style-position.d.ts +1 -1
  184. package/dist/types/css/property-descriptors/list-style-type.d.ts +1 -1
  185. package/dist/types/css/property-descriptors/margin.d.ts +1 -1
  186. package/dist/types/css/property-descriptors/mix-blend-mode.d.ts +21 -0
  187. package/dist/types/css/property-descriptors/object-fit.d.ts +1 -1
  188. package/dist/types/css/property-descriptors/opacity.d.ts +1 -1
  189. package/dist/types/css/property-descriptors/overflow-wrap.d.ts +1 -1
  190. package/dist/types/css/property-descriptors/overflow.d.ts +1 -1
  191. package/dist/types/css/property-descriptors/padding.d.ts +1 -1
  192. package/dist/types/css/property-descriptors/paint-order.d.ts +1 -1
  193. package/dist/types/css/property-descriptors/position.d.ts +1 -1
  194. package/dist/types/css/property-descriptors/quotes.d.ts +1 -1
  195. package/dist/types/css/property-descriptors/rotate.d.ts +1 -1
  196. package/dist/types/css/property-descriptors/text-align.d.ts +1 -1
  197. package/dist/types/css/property-descriptors/text-decoration-color.d.ts +1 -1
  198. package/dist/types/css/property-descriptors/text-decoration-line.d.ts +1 -1
  199. package/dist/types/css/property-descriptors/text-decoration-style.d.ts +1 -1
  200. package/dist/types/css/property-descriptors/text-decoration-thickness.d.ts +1 -1
  201. package/dist/types/css/property-descriptors/text-overflow.d.ts +1 -1
  202. package/dist/types/css/property-descriptors/text-shadow.d.ts +1 -1
  203. package/dist/types/css/property-descriptors/text-transform.d.ts +1 -1
  204. package/dist/types/css/property-descriptors/text-underline-offset.d.ts +1 -1
  205. package/dist/types/css/property-descriptors/transform-origin.d.ts +1 -1
  206. package/dist/types/css/property-descriptors/transform.d.ts +1 -1
  207. package/dist/types/css/property-descriptors/visibility.d.ts +1 -1
  208. package/dist/types/css/property-descriptors/webkit-line-clamp.d.ts +1 -1
  209. package/dist/types/css/property-descriptors/webkit-text-stroke-color.d.ts +1 -1
  210. package/dist/types/css/property-descriptors/webkit-text-stroke-width.d.ts +1 -1
  211. package/dist/types/css/property-descriptors/word-break.d.ts +1 -1
  212. package/dist/types/css/property-descriptors/writing-mode.d.ts +1 -1
  213. package/dist/types/css/property-descriptors/z-index.d.ts +1 -1
  214. package/dist/types/css/syntax/tokenizer.d.ts +5 -0
  215. package/dist/types/css/types/angle.d.ts +1 -1
  216. package/dist/types/css/types/color.d.ts +1 -1
  217. package/dist/types/css/types/image.d.ts +1 -1
  218. package/dist/types/css/types/time.d.ts +1 -1
  219. package/dist/types/dom/element-container.d.ts +4 -11
  220. package/dist/types/dom/node-parser.d.ts +2 -15
  221. package/dist/types/dom/node-type-guards.d.ts +21 -22
  222. package/dist/types/index.d.ts +28 -48
  223. package/dist/types/options.d.ts +51 -0
  224. package/dist/types/render/canvas/background-renderer.d.ts +0 -6
  225. package/dist/types/render/canvas/canvas-path.d.ts +3 -0
  226. package/dist/types/render/canvas/canvas-renderer.d.ts +4 -2
  227. package/dist/types/render/canvas/foreignobject-renderer.d.ts +2 -3
  228. package/dist/types/render/canvas/text-renderer.d.ts +5 -0
  229. package/dist/types/render/effects.d.ts +9 -1
  230. package/dist/types/render/object-fit.d.ts +18 -0
  231. package/package.json +43 -35
  232. package/src/__tests__/index.ts +99 -0
  233. package/src/config.ts +107 -0
  234. package/src/core/__mocks__/cache-storage.ts +1 -0
  235. package/src/core/__mocks__/context.ts +19 -0
  236. package/{dist/lib/core/__mocks__/features.js → src/core/__mocks__/features.ts} +1 -5
  237. package/src/core/__mocks__/logger.ts +17 -0
  238. package/{dist/lib/core/__tests__/cache-storage.test.js → src/core/__tests__/cache-storage.test.ts} +95 -48
  239. package/{dist/lib/core/__tests__/cache-storage.js → src/core/__tests__/cache-storage.ts} +117 -64
  240. package/{dist/lib/core/__tests__/logger.js → src/core/__tests__/logger.ts} +10 -8
  241. package/{dist/lib/core/__tests__/validator.js → src/core/__tests__/validator.ts} +161 -98
  242. package/src/core/bitwise.ts +1 -0
  243. package/src/core/cache-storage.ts +315 -0
  244. package/src/core/context.ts +31 -0
  245. package/src/core/debugger.ts +32 -0
  246. package/src/core/features.ts +222 -0
  247. package/src/core/logger.ts +64 -0
  248. package/src/core/origin-checker.ts +57 -0
  249. package/src/core/performance-monitor.ts +241 -0
  250. package/src/core/render-element.ts +272 -0
  251. package/src/core/util.ts +1 -0
  252. package/src/core/validator.ts +593 -0
  253. package/src/css/index.ts +427 -0
  254. package/src/css/layout/__mocks__/bounds.ts +6 -0
  255. package/src/css/layout/bounds.ts +79 -0
  256. package/src/css/layout/text.ts +161 -0
  257. package/src/css/property-descriptor.ts +49 -0
  258. package/src/css/property-descriptors/__tests__/background-tests.ts +65 -0
  259. package/src/css/property-descriptors/__tests__/clip-path.test.ts +280 -0
  260. package/src/css/property-descriptors/__tests__/font-family.ts +25 -0
  261. package/src/css/property-descriptors/__tests__/image-rendering-integration.test.ts +153 -0
  262. package/{dist/lib/css/property-descriptors/__tests__/image-rendering-performance.test.js → src/css/property-descriptors/__tests__/image-rendering-performance.test.ts} +74 -66
  263. package/src/css/property-descriptors/__tests__/image-rendering.test.ts +72 -0
  264. package/src/css/property-descriptors/__tests__/paint-order.ts +87 -0
  265. package/src/css/property-descriptors/__tests__/text-shadow.ts +94 -0
  266. package/src/css/property-descriptors/__tests__/transform-tests.ts +18 -0
  267. package/src/css/property-descriptors/background-clip.ts +30 -0
  268. package/src/css/property-descriptors/background-color.ts +9 -0
  269. package/src/css/property-descriptors/background-image.ts +27 -0
  270. package/src/css/property-descriptors/background-origin.ts +31 -0
  271. package/src/css/property-descriptors/background-position.ts +38 -0
  272. package/src/css/property-descriptors/background-repeat.ts +44 -0
  273. package/src/css/property-descriptors/background-size.ts +27 -0
  274. package/src/css/property-descriptors/border-color.ts +13 -0
  275. package/src/css/property-descriptors/border-radius.ts +19 -0
  276. package/src/css/property-descriptors/border-style.ts +34 -0
  277. package/src/css/property-descriptors/border-width.ts +20 -0
  278. package/src/css/property-descriptors/box-shadow.ts +60 -0
  279. package/src/css/property-descriptors/clip-path.ts +271 -0
  280. package/src/css/property-descriptors/color.ts +9 -0
  281. package/src/css/property-descriptors/content.ts +26 -0
  282. package/src/css/property-descriptors/counter-increment.ts +43 -0
  283. package/src/css/property-descriptors/counter-reset.ts +36 -0
  284. package/src/css/property-descriptors/direction.ts +23 -0
  285. package/src/css/property-descriptors/display.ts +117 -0
  286. package/src/css/property-descriptors/duration.ts +14 -0
  287. package/src/css/property-descriptors/float.ts +29 -0
  288. package/src/css/property-descriptors/font-family.ts +38 -0
  289. package/src/css/property-descriptors/font-size.ts +9 -0
  290. package/src/css/property-descriptors/font-style.ts +25 -0
  291. package/src/css/property-descriptors/font-variant.ts +12 -0
  292. package/src/css/property-descriptors/font-weight.ts +26 -0
  293. package/src/css/property-descriptors/image-rendering.ts +33 -0
  294. package/src/css/property-descriptors/letter-spacing.ts +25 -0
  295. package/src/css/property-descriptors/line-break.ts +22 -0
  296. package/src/css/property-descriptors/line-height.ts +22 -0
  297. package/src/css/property-descriptors/list-style-image.ts +19 -0
  298. package/src/css/property-descriptors/list-style-position.ts +22 -0
  299. package/src/css/property-descriptors/list-style-type.ts +179 -0
  300. package/src/css/property-descriptors/margin.ts +13 -0
  301. package/src/css/property-descriptors/mix-blend-mode.ts +35 -0
  302. package/src/css/property-descriptors/object-fit.ts +39 -0
  303. package/src/css/property-descriptors/opacity.ts +15 -0
  304. package/src/css/property-descriptors/overflow-wrap.ts +22 -0
  305. package/src/css/property-descriptors/overflow.ts +34 -0
  306. package/src/css/property-descriptors/padding.ts +14 -0
  307. package/src/css/property-descriptors/paint-order.ts +42 -0
  308. package/src/css/property-descriptors/position.ts +30 -0
  309. package/src/css/property-descriptors/quotes.ts +57 -0
  310. package/src/css/property-descriptors/rotate.ts +34 -0
  311. package/src/css/property-descriptors/text-align.ts +26 -0
  312. package/src/css/property-descriptors/text-decoration-color.ts +9 -0
  313. package/src/css/property-descriptors/text-decoration-line.ts +38 -0
  314. package/src/css/property-descriptors/text-decoration-style.ts +32 -0
  315. package/src/css/property-descriptors/text-decoration-thickness.ts +30 -0
  316. package/src/css/property-descriptors/text-overflow.ts +23 -0
  317. package/src/css/property-descriptors/text-shadow.ts +52 -0
  318. package/src/css/property-descriptors/text-transform.ts +27 -0
  319. package/src/css/property-descriptors/text-underline-offset.ts +27 -0
  320. package/src/css/property-descriptors/transform-origin.ts +29 -0
  321. package/src/css/property-descriptors/transform.ts +74 -0
  322. package/src/css/property-descriptors/visibility.ts +25 -0
  323. package/src/css/property-descriptors/webkit-line-clamp.ts +30 -0
  324. package/src/css/property-descriptors/webkit-text-stroke-color.ts +8 -0
  325. package/src/css/property-descriptors/webkit-text-stroke-width.ts +15 -0
  326. package/src/css/property-descriptors/word-break.ts +25 -0
  327. package/src/css/property-descriptors/writing-mode.ts +37 -0
  328. package/src/css/property-descriptors/z-index.ts +27 -0
  329. package/src/css/syntax/__tests__/tokernizer-tests.ts +29 -0
  330. package/src/css/syntax/parser.ts +188 -0
  331. package/src/css/syntax/tokenizer.ts +822 -0
  332. package/src/css/type-descriptor.ts +7 -0
  333. package/src/css/types/__tests__/color-tests.ts +147 -0
  334. package/src/css/types/__tests__/image-tests.ts +239 -0
  335. package/src/css/types/angle.ts +86 -0
  336. package/src/css/types/color-math.ts +22 -0
  337. package/src/css/types/color-spaces/a98.ts +86 -0
  338. package/src/css/types/color-spaces/p3.ts +92 -0
  339. package/src/css/types/color-spaces/pro-photo.ts +87 -0
  340. package/src/css/types/color-spaces/rec2020.ts +90 -0
  341. package/src/css/types/color-spaces/srgb.ts +87 -0
  342. package/src/css/types/color-utilities.ts +452 -0
  343. package/src/css/types/color.ts +485 -0
  344. package/src/css/types/functions/-prefix-linear-gradient.ts +35 -0
  345. package/src/css/types/functions/-prefix-radial-gradient.ts +106 -0
  346. package/src/css/types/functions/-webkit-gradient.ts +69 -0
  347. package/src/css/types/functions/__tests__/radial-gradient.ts +69 -0
  348. package/src/css/types/functions/counter.ts +511 -0
  349. package/src/css/types/functions/gradient.ts +206 -0
  350. package/src/css/types/functions/linear-gradient.ts +28 -0
  351. package/src/css/types/functions/radial-gradient.ts +101 -0
  352. package/src/css/types/image.ts +120 -0
  353. package/src/css/types/index.ts +1 -0
  354. package/src/css/types/length-percentage.ts +137 -0
  355. package/src/css/types/length.ts +7 -0
  356. package/src/css/types/time.ts +20 -0
  357. package/src/dom/__mocks__/document-cloner.ts +22 -0
  358. package/{dist/lib/dom/__tests__/dom-normalizer.test.js → src/dom/__tests__/dom-normalizer.test.ts} +64 -44
  359. package/src/dom/__tests__/element-container.test.ts +129 -0
  360. package/src/dom/document-cloner.ts +929 -0
  361. package/src/dom/dom-normalizer.ts +133 -0
  362. package/src/dom/element-container.ts +75 -0
  363. package/src/dom/elements/li-element-container.ts +10 -0
  364. package/src/dom/elements/ol-element-container.ts +12 -0
  365. package/src/dom/elements/select-element-container.ts +10 -0
  366. package/src/dom/elements/textarea-element-container.ts +9 -0
  367. package/src/dom/node-parser.ts +177 -0
  368. package/src/dom/node-type-guards.ts +70 -0
  369. package/src/dom/replaced-elements/canvas-element-container.ts +15 -0
  370. package/src/dom/replaced-elements/iframe-element-container.ts +55 -0
  371. package/src/dom/replaced-elements/image-element-container.ts +16 -0
  372. package/src/dom/replaced-elements/index.ts +5 -0
  373. package/src/dom/replaced-elements/input-element-container.ts +105 -0
  374. package/src/dom/replaced-elements/pseudo-elements.ts +0 -0
  375. package/src/dom/replaced-elements/svg-element-container.ts +23 -0
  376. package/src/dom/text-container.ts +42 -0
  377. package/src/global.d.ts +19 -0
  378. package/src/index.ts +82 -0
  379. package/src/invariant.ts +5 -0
  380. package/src/options.ts +55 -0
  381. package/src/render/__tests__/object-fit.test.ts +85 -0
  382. package/src/render/background.ts +298 -0
  383. package/src/render/bezier-curve.ts +47 -0
  384. package/src/render/border.ts +165 -0
  385. package/src/render/bound-curves.ts +388 -0
  386. package/src/render/box-sizing.ts +31 -0
  387. package/{dist/lib/render/canvas/__tests__/background-renderer.test.js → src/render/canvas/__tests__/background-renderer.test.ts} +32 -25
  388. package/src/render/canvas/__tests__/border-renderer.test.ts +24 -0
  389. package/src/render/canvas/__tests__/effects-renderer.test.ts +32 -0
  390. package/src/render/canvas/__tests__/text-renderer.test.ts +471 -0
  391. package/src/render/canvas/background-renderer.ts +271 -0
  392. package/src/render/canvas/border-renderer.ts +224 -0
  393. package/src/render/canvas/canvas-path.ts +31 -0
  394. package/src/render/canvas/canvas-renderer.ts +641 -0
  395. package/src/render/canvas/effects-renderer.ts +130 -0
  396. package/src/render/canvas/foreignobject-renderer.ts +53 -0
  397. package/src/render/canvas/text-renderer.ts +700 -0
  398. package/src/render/effects.ts +75 -0
  399. package/src/render/font-metrics.ts +72 -0
  400. package/src/render/object-fit.ts +100 -0
  401. package/src/render/path.ts +37 -0
  402. package/src/render/renderer-interface.ts +28 -0
  403. package/src/render/stacking-context.ts +386 -0
  404. package/src/render/vector.ts +19 -0
  405. package/demo/image-smoothing-demo.html +0 -256
  406. package/demo/refactoring-test.html +0 -602
  407. package/dist/lib/__tests__/index.js +0 -85
  408. package/dist/lib/__tests__/index.js.map +0 -1
  409. package/dist/lib/config.js.map +0 -1
  410. package/dist/lib/core/__mocks__/cache-storage.js +0 -7
  411. package/dist/lib/core/__mocks__/cache-storage.js.map +0 -1
  412. package/dist/lib/core/__mocks__/context.js +0 -19
  413. package/dist/lib/core/__mocks__/context.js.map +0 -1
  414. package/dist/lib/core/__mocks__/features.js.map +0 -1
  415. package/dist/lib/core/__mocks__/logger.js +0 -16
  416. package/dist/lib/core/__mocks__/logger.js.map +0 -1
  417. package/dist/lib/core/__tests__/cache-storage.js.map +0 -1
  418. package/dist/lib/core/__tests__/cache-storage.test.js.map +0 -1
  419. package/dist/lib/core/__tests__/logger.js.map +0 -1
  420. package/dist/lib/core/__tests__/validator.js.map +0 -1
  421. package/dist/lib/core/bitwise.js.map +0 -1
  422. package/dist/lib/core/cache-storage.js.map +0 -1
  423. package/dist/lib/core/context.js.map +0 -1
  424. package/dist/lib/core/debugger.js.map +0 -1
  425. package/dist/lib/core/features.js.map +0 -1
  426. package/dist/lib/core/logger.js.map +0 -1
  427. package/dist/lib/core/origin-checker.js.map +0 -1
  428. package/dist/lib/core/performance-monitor.js.map +0 -1
  429. package/dist/lib/core/util.js.map +0 -1
  430. package/dist/lib/core/validator.js.map +0 -1
  431. package/dist/lib/css/IPropertyDescriptor.js.map +0 -1
  432. package/dist/lib/css/ITypeDescriptor.js.map +0 -1
  433. package/dist/lib/css/index.js.map +0 -1
  434. package/dist/lib/css/layout/__mocks__/bounds.js +0 -9
  435. package/dist/lib/css/layout/__mocks__/bounds.js.map +0 -1
  436. package/dist/lib/css/layout/bounds.js.map +0 -1
  437. package/dist/lib/css/layout/text.js.map +0 -1
  438. package/dist/lib/css/property-descriptors/__tests__/background-tests.js +0 -49
  439. package/dist/lib/css/property-descriptors/__tests__/background-tests.js.map +0 -1
  440. package/dist/lib/css/property-descriptors/__tests__/clip-path.test.js +0 -273
  441. package/dist/lib/css/property-descriptors/__tests__/clip-path.test.js.map +0 -1
  442. package/dist/lib/css/property-descriptors/__tests__/font-family.js +0 -19
  443. package/dist/lib/css/property-descriptors/__tests__/font-family.js.map +0 -1
  444. package/dist/lib/css/property-descriptors/__tests__/image-rendering-integration.test.js +0 -143
  445. package/dist/lib/css/property-descriptors/__tests__/image-rendering-integration.test.js.map +0 -1
  446. package/dist/lib/css/property-descriptors/__tests__/image-rendering-performance.test.js.map +0 -1
  447. package/dist/lib/css/property-descriptors/__tests__/image-rendering.test.js +0 -61
  448. package/dist/lib/css/property-descriptors/__tests__/image-rendering.test.js.map +0 -1
  449. package/dist/lib/css/property-descriptors/__tests__/paint-order.js +0 -66
  450. package/dist/lib/css/property-descriptors/__tests__/paint-order.js.map +0 -1
  451. package/dist/lib/css/property-descriptors/__tests__/text-shadow.js +0 -82
  452. package/dist/lib/css/property-descriptors/__tests__/text-shadow.js.map +0 -1
  453. package/dist/lib/css/property-descriptors/__tests__/transform-tests.js +0 -14
  454. package/dist/lib/css/property-descriptors/__tests__/transform-tests.js.map +0 -1
  455. package/dist/lib/css/property-descriptors/background-clip.js.map +0 -1
  456. package/dist/lib/css/property-descriptors/background-color.js.map +0 -1
  457. package/dist/lib/css/property-descriptors/background-image.js.map +0 -1
  458. package/dist/lib/css/property-descriptors/background-origin.js.map +0 -1
  459. package/dist/lib/css/property-descriptors/background-position.js.map +0 -1
  460. package/dist/lib/css/property-descriptors/background-repeat.js.map +0 -1
  461. package/dist/lib/css/property-descriptors/background-size.js.map +0 -1
  462. package/dist/lib/css/property-descriptors/border-color.js.map +0 -1
  463. package/dist/lib/css/property-descriptors/border-radius.js.map +0 -1
  464. package/dist/lib/css/property-descriptors/border-style.js.map +0 -1
  465. package/dist/lib/css/property-descriptors/border-width.js.map +0 -1
  466. package/dist/lib/css/property-descriptors/box-shadow.js.map +0 -1
  467. package/dist/lib/css/property-descriptors/clip-path.js.map +0 -1
  468. package/dist/lib/css/property-descriptors/color.js.map +0 -1
  469. package/dist/lib/css/property-descriptors/content.js.map +0 -1
  470. package/dist/lib/css/property-descriptors/counter-increment.js.map +0 -1
  471. package/dist/lib/css/property-descriptors/counter-reset.js.map +0 -1
  472. package/dist/lib/css/property-descriptors/direction.js.map +0 -1
  473. package/dist/lib/css/property-descriptors/display.js.map +0 -1
  474. package/dist/lib/css/property-descriptors/duration.js.map +0 -1
  475. package/dist/lib/css/property-descriptors/float.js.map +0 -1
  476. package/dist/lib/css/property-descriptors/font-family.js.map +0 -1
  477. package/dist/lib/css/property-descriptors/font-size.js.map +0 -1
  478. package/dist/lib/css/property-descriptors/font-style.js.map +0 -1
  479. package/dist/lib/css/property-descriptors/font-variant.js.map +0 -1
  480. package/dist/lib/css/property-descriptors/font-weight.js.map +0 -1
  481. package/dist/lib/css/property-descriptors/image-rendering.js.map +0 -1
  482. package/dist/lib/css/property-descriptors/letter-spacing.js.map +0 -1
  483. package/dist/lib/css/property-descriptors/line-break.js.map +0 -1
  484. package/dist/lib/css/property-descriptors/line-height.js.map +0 -1
  485. package/dist/lib/css/property-descriptors/list-style-image.js.map +0 -1
  486. package/dist/lib/css/property-descriptors/list-style-position.js.map +0 -1
  487. package/dist/lib/css/property-descriptors/list-style-type.js.map +0 -1
  488. package/dist/lib/css/property-descriptors/margin.js.map +0 -1
  489. package/dist/lib/css/property-descriptors/object-fit.js.map +0 -1
  490. package/dist/lib/css/property-descriptors/opacity.js.map +0 -1
  491. package/dist/lib/css/property-descriptors/overflow-wrap.js.map +0 -1
  492. package/dist/lib/css/property-descriptors/overflow.js.map +0 -1
  493. package/dist/lib/css/property-descriptors/padding.js.map +0 -1
  494. package/dist/lib/css/property-descriptors/paint-order.js.map +0 -1
  495. package/dist/lib/css/property-descriptors/position.js.map +0 -1
  496. package/dist/lib/css/property-descriptors/quotes.js.map +0 -1
  497. package/dist/lib/css/property-descriptors/rotate.js.map +0 -1
  498. package/dist/lib/css/property-descriptors/text-align.js.map +0 -1
  499. package/dist/lib/css/property-descriptors/text-decoration-color.js.map +0 -1
  500. package/dist/lib/css/property-descriptors/text-decoration-line.js.map +0 -1
  501. package/dist/lib/css/property-descriptors/text-decoration-style.js.map +0 -1
  502. package/dist/lib/css/property-descriptors/text-decoration-thickness.js.map +0 -1
  503. package/dist/lib/css/property-descriptors/text-overflow.js.map +0 -1
  504. package/dist/lib/css/property-descriptors/text-shadow.js.map +0 -1
  505. package/dist/lib/css/property-descriptors/text-transform.js.map +0 -1
  506. package/dist/lib/css/property-descriptors/text-underline-offset.js.map +0 -1
  507. package/dist/lib/css/property-descriptors/transform-origin.js.map +0 -1
  508. package/dist/lib/css/property-descriptors/transform.js.map +0 -1
  509. package/dist/lib/css/property-descriptors/visibility.js.map +0 -1
  510. package/dist/lib/css/property-descriptors/webkit-line-clamp.js.map +0 -1
  511. package/dist/lib/css/property-descriptors/webkit-text-stroke-color.js.map +0 -1
  512. package/dist/lib/css/property-descriptors/webkit-text-stroke-width.js.map +0 -1
  513. package/dist/lib/css/property-descriptors/word-break.js.map +0 -1
  514. package/dist/lib/css/property-descriptors/writing-mode.js.map +0 -1
  515. package/dist/lib/css/property-descriptors/z-index.js.map +0 -1
  516. package/dist/lib/css/syntax/__tests__/tokernizer-tests.js +0 -26
  517. package/dist/lib/css/syntax/__tests__/tokernizer-tests.js.map +0 -1
  518. package/dist/lib/css/syntax/parser.js.map +0 -1
  519. package/dist/lib/css/syntax/tokenizer.js.map +0 -1
  520. package/dist/lib/css/types/__tests__/color-tests.js +0 -111
  521. package/dist/lib/css/types/__tests__/color-tests.js.map +0 -1
  522. package/dist/lib/css/types/__tests__/image-tests.js +0 -215
  523. package/dist/lib/css/types/__tests__/image-tests.js.map +0 -1
  524. package/dist/lib/css/types/angle.js.map +0 -1
  525. package/dist/lib/css/types/color-math.js.map +0 -1
  526. package/dist/lib/css/types/color-spaces/a98.js.map +0 -1
  527. package/dist/lib/css/types/color-spaces/p3.js.map +0 -1
  528. package/dist/lib/css/types/color-spaces/pro-photo.js.map +0 -1
  529. package/dist/lib/css/types/color-spaces/rec2020.js.map +0 -1
  530. package/dist/lib/css/types/color-spaces/srgb.js.map +0 -1
  531. package/dist/lib/css/types/color-utilities.js.map +0 -1
  532. package/dist/lib/css/types/color.js.map +0 -1
  533. package/dist/lib/css/types/functions/-prefix-linear-gradient.js.map +0 -1
  534. package/dist/lib/css/types/functions/-prefix-radial-gradient.js.map +0 -1
  535. package/dist/lib/css/types/functions/-webkit-gradient.js.map +0 -1
  536. package/dist/lib/css/types/functions/__tests__/radial-gradient.js +0 -63
  537. package/dist/lib/css/types/functions/__tests__/radial-gradient.js.map +0 -1
  538. package/dist/lib/css/types/functions/counter.js.map +0 -1
  539. package/dist/lib/css/types/functions/gradient.js.map +0 -1
  540. package/dist/lib/css/types/functions/linear-gradient.js.map +0 -1
  541. package/dist/lib/css/types/functions/radial-gradient.js.map +0 -1
  542. package/dist/lib/css/types/image.js.map +0 -1
  543. package/dist/lib/css/types/index.js.map +0 -1
  544. package/dist/lib/css/types/length-percentage.js.map +0 -1
  545. package/dist/lib/css/types/length.js.map +0 -1
  546. package/dist/lib/css/types/time.js.map +0 -1
  547. package/dist/lib/dom/__mocks__/document-cloner.js +0 -23
  548. package/dist/lib/dom/__mocks__/document-cloner.js.map +0 -1
  549. package/dist/lib/dom/__tests__/dom-normalizer.test.js.map +0 -1
  550. package/dist/lib/dom/__tests__/element-container.test.js +0 -109
  551. package/dist/lib/dom/__tests__/element-container.test.js.map +0 -1
  552. package/dist/lib/dom/document-cloner.js.map +0 -1
  553. package/dist/lib/dom/dom-normalizer.js.map +0 -1
  554. package/dist/lib/dom/element-container.js.map +0 -1
  555. package/dist/lib/dom/elements/li-element-container.js.map +0 -1
  556. package/dist/lib/dom/elements/ol-element-container.js.map +0 -1
  557. package/dist/lib/dom/elements/select-element-container.js.map +0 -1
  558. package/dist/lib/dom/elements/textarea-element-container.js.map +0 -1
  559. package/dist/lib/dom/node-parser.js.map +0 -1
  560. package/dist/lib/dom/node-type-guards.js.map +0 -1
  561. package/dist/lib/dom/replaced-elements/canvas-element-container.js.map +0 -1
  562. package/dist/lib/dom/replaced-elements/iframe-element-container.js.map +0 -1
  563. package/dist/lib/dom/replaced-elements/image-element-container.js.map +0 -1
  564. package/dist/lib/dom/replaced-elements/index.js.map +0 -1
  565. package/dist/lib/dom/replaced-elements/input-element-container.js.map +0 -1
  566. package/dist/lib/dom/replaced-elements/pseudo-elements.js.map +0 -1
  567. package/dist/lib/dom/replaced-elements/svg-element-container.js.map +0 -1
  568. package/dist/lib/dom/text-container.js.map +0 -1
  569. package/dist/lib/index.js.map +0 -1
  570. package/dist/lib/invariant.js.map +0 -1
  571. package/dist/lib/render/background.js.map +0 -1
  572. package/dist/lib/render/bezier-curve.js.map +0 -1
  573. package/dist/lib/render/border.js.map +0 -1
  574. package/dist/lib/render/bound-curves.js.map +0 -1
  575. package/dist/lib/render/box-sizing.js.map +0 -1
  576. package/dist/lib/render/canvas/__tests__/background-renderer.test.js.map +0 -1
  577. package/dist/lib/render/canvas/__tests__/border-renderer.test.js +0 -23
  578. package/dist/lib/render/canvas/__tests__/border-renderer.test.js.map +0 -1
  579. package/dist/lib/render/canvas/__tests__/effects-renderer.test.js +0 -30
  580. package/dist/lib/render/canvas/__tests__/effects-renderer.test.js.map +0 -1
  581. package/dist/lib/render/canvas/__tests__/text-renderer.test.js +0 -402
  582. package/dist/lib/render/canvas/__tests__/text-renderer.test.js.map +0 -1
  583. package/dist/lib/render/canvas/background-renderer.js.map +0 -1
  584. package/dist/lib/render/canvas/border-renderer.js.map +0 -1
  585. package/dist/lib/render/canvas/canvas-renderer.js.map +0 -1
  586. package/dist/lib/render/canvas/effects-renderer.js.map +0 -1
  587. package/dist/lib/render/canvas/foreignobject-renderer.js.map +0 -1
  588. package/dist/lib/render/canvas/text-renderer.js.map +0 -1
  589. package/dist/lib/render/effects.js.map +0 -1
  590. package/dist/lib/render/font-metrics.js.map +0 -1
  591. package/dist/lib/render/path.js.map +0 -1
  592. package/dist/lib/render/renderer-interface.js.map +0 -1
  593. package/dist/lib/render/renderer.js +0 -11
  594. package/dist/lib/render/renderer.js.map +0 -1
  595. package/dist/lib/render/stacking-context.js.map +0 -1
  596. package/dist/lib/render/vector.js.map +0 -1
  597. package/dist/types/__tests__/index.d.ts +0 -1
  598. package/dist/types/core/__mocks__/cache-storage.d.ts +0 -2
  599. package/dist/types/core/__mocks__/context.d.ts +0 -9
  600. package/dist/types/core/__mocks__/features.d.ts +0 -8
  601. package/dist/types/core/__mocks__/logger.d.ts +0 -9
  602. package/dist/types/core/__tests__/cache-storage.d.ts +0 -1
  603. package/dist/types/core/__tests__/cache-storage.test.d.ts +0 -1
  604. package/dist/types/core/__tests__/logger.d.ts +0 -1
  605. package/dist/types/core/__tests__/validator.d.ts +0 -1
  606. package/dist/types/css/layout/__mocks__/bounds.d.ts +0 -2
  607. package/dist/types/css/property-descriptors/__tests__/background-tests.d.ts +0 -1
  608. package/dist/types/css/property-descriptors/__tests__/clip-path.test.d.ts +0 -1
  609. package/dist/types/css/property-descriptors/__tests__/font-family.d.ts +0 -1
  610. package/dist/types/css/property-descriptors/__tests__/image-rendering-integration.test.d.ts +0 -1
  611. package/dist/types/css/property-descriptors/__tests__/image-rendering-performance.test.d.ts +0 -1
  612. package/dist/types/css/property-descriptors/__tests__/image-rendering.test.d.ts +0 -1
  613. package/dist/types/css/property-descriptors/__tests__/paint-order.d.ts +0 -1
  614. package/dist/types/css/property-descriptors/__tests__/text-shadow.d.ts +0 -1
  615. package/dist/types/css/property-descriptors/__tests__/transform-tests.d.ts +0 -1
  616. package/dist/types/css/syntax/__tests__/tokernizer-tests.d.ts +0 -1
  617. package/dist/types/css/types/__tests__/color-tests.d.ts +0 -1
  618. package/dist/types/css/types/__tests__/image-tests.d.ts +0 -1
  619. package/dist/types/css/types/functions/__tests__/radial-gradient.d.ts +0 -1
  620. package/dist/types/dom/__mocks__/document-cloner.d.ts +0 -6
  621. package/dist/types/dom/__tests__/dom-normalizer.test.d.ts +0 -1
  622. package/dist/types/dom/__tests__/element-container.test.d.ts +0 -1
  623. package/dist/types/render/canvas/__tests__/background-renderer.test.d.ts +0 -1
  624. package/dist/types/render/canvas/__tests__/border-renderer.test.d.ts +0 -1
  625. package/dist/types/render/canvas/__tests__/effects-renderer.test.d.ts +0 -1
  626. package/dist/types/render/canvas/__tests__/text-renderer.test.d.ts +0 -1
  627. package/dist/types/render/renderer.d.ts +0 -7
  628. package/eslint.config.js +0 -35
  629. package/jest.config.cjs +0 -5
  630. package/karma.conf.cjs +0 -300
  631. /package/dist/types/css/{IPropertyDescriptor.d.ts → property-descriptor.d.ts} +0 -0
  632. /package/dist/types/css/{ITypeDescriptor.d.ts → type-descriptor.d.ts} +0 -0
@@ -0,0 +1,133 @@
1
+ /**
2
+ * DOM Normalizer
3
+ * Handles DOM side effects that need to happen before rendering
4
+ * Extracted from ElementContainer to follow SRP
5
+ */
6
+
7
+ import { CSSParsedDeclaration } from '../css';
8
+ import { isHTMLElementNode } from './node-type-guards';
9
+
10
+ /**
11
+ * Stored original styles for restoration
12
+ */
13
+ export interface OriginalStyles {
14
+ animationDuration?: string;
15
+ transform?: string;
16
+ rotate?: string;
17
+ }
18
+
19
+ /**
20
+ * Normalize element styles for accurate rendering
21
+ * This includes disabling animations and neutralizing transforms.
22
+ */
23
+ export class DOMNormalizer {
24
+ /**
25
+ * Normalize a single element and return original styles.
26
+ *
27
+ * ## Why we replace transforms with an identity value instead of "none"
28
+ *
29
+ * `getBoundingClientRect()` returns visual (post-transform) coordinates, so we
30
+ * must neutralize any active transform before measuring element bounds.
31
+ *
32
+ * The naive approach of setting `transform: none` (or `rotate: none`) has a
33
+ * critical side-effect: per **CSS Transforms Level 2**, an element whose
34
+ * `transform` is non-none automatically becomes the **containing block** for
35
+ * all of its `position: absolute` *and* `position: fixed` descendants.
36
+ * Setting it to `none` destroys that role, causing children to resolve their
37
+ * percentage dimensions and offsets against an unintended ancestor — which
38
+ * produces completely wrong bounds.
39
+ *
40
+ * Solution: instead of removing the transform, we replace it with a visually
41
+ * inert identity value:
42
+ *
43
+ * - `transform: scale(0.5)` → `transform: translate(0, 0)`
44
+ * - `translate(0, 0)` is an identity transform (no visual change, no layout shift).
45
+ * - `getBoundingClientRect()` returns the same layout-space coordinates as
46
+ * if there were no transform at all.
47
+ * - Because the value is still non-none, the element **remains a containing
48
+ * block** for both `position: absolute` and `position: fixed` descendants.
49
+ *
50
+ * - `rotate: 45deg` → `rotate: 0deg`
51
+ * - `0deg` is the identity rotation; `0deg ≠ none`, so the same containing-
52
+ * block guarantee holds.
53
+ *
54
+ * @param element - Element to normalize
55
+ * @param styles - Parsed CSS styles
56
+ * @returns Original styles map for restoration
57
+ */
58
+ static normalizeElement(element: Element, styles: CSSParsedDeclaration): OriginalStyles {
59
+ const originalStyles: OriginalStyles = {};
60
+
61
+ if (!isHTMLElementNode(element)) {
62
+ return originalStyles;
63
+ }
64
+
65
+ // Disable animations to capture static state
66
+ if (styles.animationDuration.some((duration) => duration > 0)) {
67
+ originalStyles.animationDuration = element.style.animationDuration;
68
+ element.style.animationDuration = '0s';
69
+ }
70
+
71
+ // Replace the actual transform with an identity translate so that:
72
+ // 1. getBoundingClientRect() returns layout-space (unscaled/unrotated) coords.
73
+ // 2. The element still satisfies "transform != none" and therefore keeps
74
+ // its role as a containing block for position:absolute / position:fixed
75
+ // descendants (CSS Transforms Level 2 §2.3).
76
+ if (styles.transform !== null) {
77
+ originalStyles.transform = element.style.transform;
78
+ element.style.transform = 'translate(0, 0)';
79
+ }
80
+
81
+ // Same rationale for the standalone `rotate` property.
82
+ // `rotate: 0deg` is an identity rotation with no visual effect.
83
+ //
84
+ // However, individual transform properties (`rotate`, `translate`, `scale`)
85
+ // are part of CSS Transforms Level 2 and their containing-block guarantee
86
+ // is not uniformly implemented across all browsers. To be safe, if `rotate`
87
+ // is the only transform-like property active on this element, we also set
88
+ // `transform: translate(0, 0)` so that the containing-block role is reliably
89
+ // preserved via the well-supported `transform` property.
90
+ if (styles.rotate !== null) {
91
+ originalStyles.rotate = element.style.rotate;
92
+ element.style.rotate = '0deg';
93
+
94
+ // Individual transform properties (`rotate`, `translate`, `scale`) are
95
+ // CSS Transforms Level 2 and their containing-block guarantee is not
96
+ // uniformly implemented in all browsers. If `transform` was not already
97
+ // set to translate(0,0) in the block above (i.e. this element has
98
+ // `rotate` but no `transform`), we set it now so the containing-block
99
+ // role is reliably established via the widely-supported `transform`
100
+ // property – independently of browser support for individual props.
101
+ if (originalStyles.transform === undefined) {
102
+ originalStyles.transform = element.style.transform;
103
+ element.style.transform = 'translate(0, 0)';
104
+ }
105
+ }
106
+
107
+ return originalStyles;
108
+ }
109
+
110
+ /**
111
+ * Restore element styles after rendering.
112
+ *
113
+ * @param element - Element to restore
114
+ * @param originalStyles - Original styles to restore
115
+ */
116
+ static restoreElement(element: Element, originalStyles: OriginalStyles): void {
117
+ if (!isHTMLElementNode(element)) {
118
+ return;
119
+ }
120
+
121
+ if (originalStyles.animationDuration !== undefined) {
122
+ element.style.animationDuration = originalStyles.animationDuration;
123
+ }
124
+
125
+ if (originalStyles.transform !== undefined) {
126
+ element.style.transform = originalStyles.transform;
127
+ }
128
+
129
+ if (originalStyles.rotate !== undefined) {
130
+ element.style.rotate = originalStyles.rotate;
131
+ }
132
+ }
133
+ }
@@ -0,0 +1,75 @@
1
+ import { CSSParsedDeclaration } from '../css/index';
2
+ import { TextContainer } from './text-container';
3
+ import { Bounds, parseBounds } from '../css/layout/bounds';
4
+ import { isHTMLElementNode } from './node-type-guards';
5
+ import { Context } from '../core/context';
6
+ import { DebuggerType, isDebugging } from '../core/debugger';
7
+ import { DOMNormalizer, OriginalStyles } from './dom-normalizer';
8
+
9
+ export interface ElementContainerOptions {
10
+ normalizeDom?: boolean;
11
+ }
12
+
13
+ export class ElementContainer {
14
+ readonly styles: CSSParsedDeclaration;
15
+ readonly textNodes: TextContainer[] = [];
16
+ readonly elements: ElementContainer[] = [];
17
+ bounds: Bounds;
18
+
19
+ createsStackingContext = false;
20
+ createsRealStackingContext = false;
21
+ isListOwner = false;
22
+ debugRender = false;
23
+
24
+ private originalStyles?: OriginalStyles;
25
+ private originalElement?: Element;
26
+
27
+ constructor(
28
+ protected readonly context: Context,
29
+ element: Element,
30
+ options: ElementContainerOptions = {}
31
+ ) {
32
+ if (isDebugging(element, DebuggerType.PARSE)) {
33
+ debugger;
34
+ }
35
+
36
+ this.styles = new CSSParsedDeclaration(context, context.config.window.getComputedStyle(element, null));
37
+
38
+ const shouldNormalize = options.normalizeDom !== false;
39
+ if (shouldNormalize && isHTMLElementNode(element)) {
40
+ this.originalStyles = DOMNormalizer.normalizeElement(element, this.styles);
41
+ this.originalElement = element;
42
+ }
43
+
44
+ this.bounds = parseBounds(this.context, element);
45
+
46
+ if (isDebugging(element, DebuggerType.RENDER)) {
47
+ this.debugRender = true;
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Restore original element styles (if normalized)
53
+ * Call this after rendering is complete to clean up DOM state
54
+ */
55
+ restore(): void {
56
+ if (this.originalStyles && this.originalElement) {
57
+ DOMNormalizer.restoreElement(this.originalElement, this.originalStyles);
58
+ // Clear references to prevent memory leaks
59
+ this.originalStyles = undefined;
60
+ this.originalElement = undefined;
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Recursively restore all elements in the tree
66
+ * Call this on the root container after rendering is complete
67
+ */
68
+ restoreTree(): void {
69
+ this.restore();
70
+ // Recursively restore all child elements
71
+ for (const child of this.elements) {
72
+ child.restoreTree();
73
+ }
74
+ }
75
+ }
@@ -0,0 +1,10 @@
1
+ import { ElementContainer } from '../element-container';
2
+ import { Context } from '../../core/context';
3
+ export class LIElementContainer extends ElementContainer {
4
+ readonly value: number;
5
+
6
+ constructor(context: Context, element: HTMLLIElement) {
7
+ super(context, element);
8
+ this.value = element.value;
9
+ }
10
+ }
@@ -0,0 +1,12 @@
1
+ import { ElementContainer } from '../element-container';
2
+ import { Context } from '../../core/context';
3
+ export class OLElementContainer extends ElementContainer {
4
+ readonly start: number;
5
+ readonly reversed: boolean;
6
+
7
+ constructor(context: Context, element: HTMLOListElement) {
8
+ super(context, element);
9
+ this.start = element.start;
10
+ this.reversed = typeof element.reversed === 'boolean' && element.reversed === true;
11
+ }
12
+ }
@@ -0,0 +1,10 @@
1
+ import { ElementContainer } from '../element-container';
2
+ import { Context } from '../../core/context';
3
+ export class SelectElementContainer extends ElementContainer {
4
+ readonly value: string;
5
+ constructor(context: Context, element: HTMLSelectElement) {
6
+ super(context, element);
7
+ const option = element.options[element.selectedIndex || 0];
8
+ this.value = option ? option.text || '' : '';
9
+ }
10
+ }
@@ -0,0 +1,9 @@
1
+ import { ElementContainer } from '../element-container';
2
+ import { Context } from '../../core/context';
3
+ export class TextareaElementContainer extends ElementContainer {
4
+ readonly value: string;
5
+ constructor(context: Context, element: HTMLTextAreaElement) {
6
+ super(context, element);
7
+ this.value = element.value;
8
+ }
9
+ }
@@ -0,0 +1,177 @@
1
+ import { CSSParsedDeclaration } from '../css';
2
+ import { ElementContainer } from './element-container';
3
+ import { TextContainer } from './text-container';
4
+ import { ImageElementContainer } from './replaced-elements/image-element-container';
5
+ import { CanvasElementContainer } from './replaced-elements/canvas-element-container';
6
+ import { SVGElementContainer } from './replaced-elements/svg-element-container';
7
+ import { LIElementContainer } from './elements/li-element-container';
8
+ import { OLElementContainer } from './elements/ol-element-container';
9
+ import { InputElementContainer } from './replaced-elements/input-element-container';
10
+ import { SelectElementContainer } from './elements/select-element-container';
11
+ import { TextareaElementContainer } from './elements/textarea-element-container';
12
+ import { IFrameElementContainer } from './replaced-elements/iframe-element-container';
13
+ import { Context } from '../core/context';
14
+ import {
15
+ isBodyElement,
16
+ isCanvasElement,
17
+ isCustomElement,
18
+ isElementNode,
19
+ isHTMLElement,
20
+ isHTMLElementNode,
21
+ isIFrameElement,
22
+ isImageElement,
23
+ isInputElement,
24
+ isLIElement,
25
+ isOLElement,
26
+ isScriptElement,
27
+ isSelectElement,
28
+ isSlotElement,
29
+ isStyleElement,
30
+ isSVGElement,
31
+ isSVGElementNode,
32
+ isTextareaElement,
33
+ isTextNode,
34
+ isVideoElement
35
+ } from './node-type-guards';
36
+
37
+ // Re-export all type guards for backward compatibility
38
+ export {
39
+ isBodyElement,
40
+ isCanvasElement,
41
+ isCustomElement,
42
+ isElementNode,
43
+ isHTMLElement,
44
+ isHTMLElementNode,
45
+ isIFrameElement,
46
+ isImageElement,
47
+ isInputElement,
48
+ isLIElement,
49
+ isOLElement,
50
+ isScriptElement,
51
+ isSelectElement,
52
+ isSlotElement,
53
+ isStyleElement,
54
+ isSVGElement,
55
+ isSVGElementNode,
56
+ isTextareaElement,
57
+ isTextNode,
58
+ isVideoElement
59
+ };
60
+ import { contains } from '../core/bitwise';
61
+ import { DISPLAY } from '../css/property-descriptors/display';
62
+
63
+ const LIST_OWNERS = ['OL', 'UL', 'MENU'];
64
+
65
+ const parseNodeTree = (context: Context, node: Node, parent: ElementContainer, root: ElementContainer) => {
66
+ for (let childNode = node.firstChild, nextNode; childNode; childNode = nextNode) {
67
+ nextNode = childNode.nextSibling;
68
+
69
+ // Fixes #2238 #1624 - Fix the issue of TextNode content being overlooked in rendering due to being perceived as blank by trim().
70
+ if (isTextNode(childNode) && childNode.data.length > 0) {
71
+ parent.textNodes.push(new TextContainer(context, childNode, parent.styles));
72
+ } else if (isElementNode(childNode)) {
73
+ if (isSlotElement(childNode) && childNode.assignedNodes) {
74
+ childNode
75
+ .assignedNodes()
76
+ .forEach((assignedNode: Node) => parseNodeTree(context, assignedNode, parent, root));
77
+ } else {
78
+ const container = createContainer(context, childNode);
79
+ if (container.styles.isVisible()) {
80
+ if (createsRealStackingContext(childNode, container, root)) {
81
+ container.createsRealStackingContext = true;
82
+ } else if (createsStackingContext(container.styles)) {
83
+ container.createsStackingContext = true;
84
+ }
85
+
86
+ if (LIST_OWNERS.indexOf(childNode.tagName) !== -1) {
87
+ container.isListOwner = true;
88
+ }
89
+
90
+ parent.elements.push(container);
91
+ if (childNode.shadowRoot) {
92
+ parseNodeTree(context, childNode.shadowRoot, container, root);
93
+ } else if (
94
+ !isTextareaElement(childNode) &&
95
+ !isSVGElement(childNode) &&
96
+ !isSelectElement(childNode)
97
+ ) {
98
+ parseNodeTree(context, childNode, container, root);
99
+ }
100
+ }
101
+ }
102
+ }
103
+ }
104
+ };
105
+
106
+ const createContainer = (context: Context, element: Element): ElementContainer => {
107
+ if (isImageElement(element)) {
108
+ return new ImageElementContainer(context, element);
109
+ }
110
+
111
+ if (isCanvasElement(element)) {
112
+ return new CanvasElementContainer(context, element);
113
+ }
114
+
115
+ if (isSVGElement(element)) {
116
+ return new SVGElementContainer(context, element);
117
+ }
118
+
119
+ if (isLIElement(element)) {
120
+ return new LIElementContainer(context, element);
121
+ }
122
+
123
+ if (isOLElement(element)) {
124
+ return new OLElementContainer(context, element);
125
+ }
126
+
127
+ if (isInputElement(element)) {
128
+ return new InputElementContainer(context, element);
129
+ }
130
+
131
+ if (isSelectElement(element)) {
132
+ return new SelectElementContainer(context, element);
133
+ }
134
+
135
+ if (isTextareaElement(element)) {
136
+ return new TextareaElementContainer(context, element);
137
+ }
138
+
139
+ if (isIFrameElement(element)) {
140
+ return new IFrameElementContainer(context, element, parseTree);
141
+ }
142
+
143
+ return new ElementContainer(context, element);
144
+ };
145
+
146
+ export const parseTree = (context: Context, element: HTMLElement): ElementContainer => {
147
+ const container = createContainer(context, element);
148
+ container.createsRealStackingContext = true;
149
+ parseNodeTree(context, element, container, container);
150
+ return container;
151
+ };
152
+
153
+ const createsRealStackingContext = (node: Element, container: ElementContainer, root: ElementContainer): boolean => {
154
+ return (
155
+ container.styles.isPositionedWithZIndex() ||
156
+ container.styles.opacity < 1 ||
157
+ container.styles.isTransformed() ||
158
+ (isBodyElement(node) && root.styles.isTransparent())
159
+ );
160
+ };
161
+
162
+ const createsStackingContext = (styles: CSSParsedDeclaration): boolean => {
163
+ // Positioned and floating elements create stacking contexts
164
+ if (styles.isPositioned() || styles.isFloating()) {
165
+ return true;
166
+ }
167
+
168
+ // Fix for Issue #137: Inline-level containers (inline-flex, inline-block, etc.)
169
+ // should create stacking contexts to prevent their children from being added
170
+ // to the parent's stacking context, which causes rendering order issues
171
+ return (
172
+ contains(styles.display, DISPLAY.INLINE_FLEX) ||
173
+ contains(styles.display, DISPLAY.INLINE_BLOCK) ||
174
+ contains(styles.display, DISPLAY.INLINE_GRID) ||
175
+ contains(styles.display, DISPLAY.INLINE_TABLE)
176
+ );
177
+ };
@@ -0,0 +1,70 @@
1
+ /**
2
+ * DOM Node Type Guards
3
+ *
4
+ * All DOM node type guards consolidated here to eliminate duplication
5
+ * and provide a single source of truth for node type checking.
6
+ */
7
+
8
+ // --- Generic node type guards ---
9
+
10
+ export const isElementNode = (node: Node): node is Element => node.nodeType === Node.ELEMENT_NODE;
11
+ export const isTextNode = (node: Node): node is Text => node.nodeType === Node.TEXT_NODE;
12
+
13
+ export const isSVGElementNode = (element: Element): element is SVGElement =>
14
+ typeof (element as SVGElement).className === 'object';
15
+
16
+ export const isHTMLElementNode = (node: Node): node is HTMLElement =>
17
+ isElementNode(node) && typeof (node as HTMLElement).style !== 'undefined' && !isSVGElementNode(node);
18
+
19
+ // --- Tag name based type guards ---
20
+
21
+ export const isInputElement = (node: Element): node is HTMLInputElement => node.tagName === 'INPUT';
22
+ export const isHTMLElement = (node: Element): node is HTMLHtmlElement => node.tagName === 'HTML';
23
+ export const isSVGElement = (node: Element): node is SVGSVGElement => node.tagName === 'svg';
24
+ export const isBodyElement = (node: Element): node is HTMLBodyElement => node.tagName === 'BODY';
25
+ export const isCanvasElement = (node: Element): node is HTMLCanvasElement => node.tagName === 'CANVAS';
26
+ export const isVideoElement = (node: Element): node is HTMLVideoElement => node.tagName === 'VIDEO';
27
+ export const isImageElement = (node: Element): node is HTMLImageElement => node.tagName === 'IMG';
28
+ export const isIFrameElement = (node: Element): node is HTMLIFrameElement => node.tagName === 'IFRAME';
29
+ export const isStyleElement = (node: Element): node is HTMLStyleElement => node.tagName === 'STYLE';
30
+ export const isScriptElement = (node: Element): node is HTMLScriptElement => node.tagName === 'SCRIPT';
31
+ export const isTextareaElement = (node: Element): node is HTMLTextAreaElement => node.tagName === 'TEXTAREA';
32
+ export const isSelectElement = (node: Element): node is HTMLSelectElement => node.tagName === 'SELECT';
33
+ export const isSlotElement = (node: Element): node is HTMLSlotElement => node.tagName === 'SLOT';
34
+ export const isLIElement = (node: Element): node is HTMLLIElement => node.tagName === 'LI';
35
+ export const isOLElement = (node: Element): node is HTMLOListElement => node.tagName === 'OL';
36
+
37
+ export const isCustomElement = (element: Element): element is HTMLElement =>
38
+ !isSVGElementNode(element) && element.tagName.indexOf('-') > 0;
39
+
40
+ const VOID_OR_REPLACED_TAGS = new Set([
41
+ 'IMG',
42
+ 'VIDEO',
43
+ 'AUDIO',
44
+ 'CANVAS',
45
+ 'IFRAME',
46
+ 'INPUT',
47
+ 'TEXTAREA',
48
+ 'SELECT',
49
+ 'BR',
50
+ 'HR',
51
+ 'META',
52
+ 'LINK',
53
+ 'BASE',
54
+ 'COL',
55
+ 'SOURCE',
56
+ 'TRACK',
57
+ 'WBR',
58
+ 'AREA',
59
+ 'PARAM',
60
+ 'EMBED',
61
+ 'OBJECT'
62
+ ]);
63
+
64
+ /**
65
+ * Check if an element can have ::before / ::after pseudo-elements.
66
+ * Per the CSS spec, replaced elements and void elements cannot have pseudo-elements.
67
+ * SVG elements also do not support pseudo-elements.
68
+ */
69
+ export const canHavePseudoElements = (element: Element): boolean =>
70
+ !isSVGElementNode(element) && !VOID_OR_REPLACED_TAGS.has(element.tagName);
@@ -0,0 +1,15 @@
1
+ import { ElementContainer } from '../element-container';
2
+ import { Context } from '../../core/context';
3
+
4
+ export class CanvasElementContainer extends ElementContainer {
5
+ canvas: HTMLCanvasElement;
6
+ intrinsicWidth: number;
7
+ intrinsicHeight: number;
8
+
9
+ constructor(context: Context, canvas: HTMLCanvasElement) {
10
+ super(context, canvas);
11
+ this.canvas = canvas;
12
+ this.intrinsicWidth = canvas.width;
13
+ this.intrinsicHeight = canvas.height;
14
+ }
15
+ }
@@ -0,0 +1,55 @@
1
+ import { ElementContainer } from '../element-container';
2
+ import { Color, parseColor, COLORS } from '../../css/types/color';
3
+ import { isTransparent } from '../../css/types/color-utilities';
4
+ import { Context } from '../../core/context';
5
+
6
+ // Parser function type to break circular dependency
7
+ type ParseTreeFunction = (context: Context, node: Node) => ElementContainer;
8
+
9
+ export class IFrameElementContainer extends ElementContainer {
10
+ src: string;
11
+ width: number;
12
+ height: number;
13
+ tree?: ElementContainer;
14
+ backgroundColor: Color;
15
+ private parseTreeFn?: ParseTreeFunction;
16
+
17
+ constructor(context: Context, iframe: HTMLIFrameElement, parseTreeFn?: ParseTreeFunction) {
18
+ super(context, iframe);
19
+ this.src = iframe.src;
20
+ this.width = parseInt(iframe.width, 10) || 0;
21
+ this.height = parseInt(iframe.height, 10) || 0;
22
+ this.backgroundColor = this.styles.backgroundColor;
23
+ this.parseTreeFn = parseTreeFn;
24
+ try {
25
+ if (
26
+ iframe.contentWindow &&
27
+ iframe.contentWindow.document &&
28
+ iframe.contentWindow.document.documentElement &&
29
+ this.parseTreeFn
30
+ ) {
31
+ this.tree = this.parseTreeFn(context, iframe.contentWindow.document.documentElement);
32
+
33
+ // http://www.w3.org/TR/css3-background/#special-backgrounds
34
+ const documentBackgroundColor = iframe.contentWindow.document.documentElement
35
+ ? parseColor(
36
+ context,
37
+ getComputedStyle(iframe.contentWindow.document.documentElement).backgroundColor as string
38
+ )
39
+ : COLORS.TRANSPARENT;
40
+ const bodyBackgroundColor = iframe.contentWindow.document.body
41
+ ? parseColor(
42
+ context,
43
+ getComputedStyle(iframe.contentWindow.document.body).backgroundColor as string
44
+ )
45
+ : COLORS.TRANSPARENT;
46
+
47
+ this.backgroundColor = isTransparent(documentBackgroundColor)
48
+ ? isTransparent(bodyBackgroundColor)
49
+ ? this.styles.backgroundColor
50
+ : bodyBackgroundColor
51
+ : documentBackgroundColor;
52
+ }
53
+ } catch (e) {}
54
+ }
55
+ }
@@ -0,0 +1,16 @@
1
+ import { ElementContainer } from '../element-container';
2
+ import { Context } from '../../core/context';
3
+
4
+ export class ImageElementContainer extends ElementContainer {
5
+ src: string;
6
+ intrinsicWidth: number;
7
+ intrinsicHeight: number;
8
+
9
+ constructor(context: Context, img: HTMLImageElement) {
10
+ super(context, img);
11
+ this.src = img.currentSrc || img.src;
12
+ this.intrinsicWidth = img.naturalWidth;
13
+ this.intrinsicHeight = img.naturalHeight;
14
+ this.context.cache.addImage(this.src);
15
+ }
16
+ }
@@ -0,0 +1,5 @@
1
+ import { CanvasElementContainer } from './canvas-element-container';
2
+ import { ImageElementContainer } from './image-element-container';
3
+ import { SVGElementContainer } from './svg-element-container';
4
+
5
+ export type ReplacedElementContainer = CanvasElementContainer | ImageElementContainer | SVGElementContainer;