blitz-pdf 0.0.0-stage → 0.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 (370) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +355 -2
  3. package/THIRD_PARTY_NOTICES.md +25 -0
  4. package/assets/icon.svg +4 -0
  5. package/dist/api.d.ts +7 -0
  6. package/dist/api.d.ts.map +1 -0
  7. package/dist/api.js +46 -0
  8. package/dist/api.js.map +1 -0
  9. package/dist/assets.d.ts +7 -0
  10. package/dist/assets.d.ts.map +1 -0
  11. package/dist/assets.js +52 -0
  12. package/dist/assets.js.map +1 -0
  13. package/dist/browser.d.ts +3 -0
  14. package/dist/browser.d.ts.map +1 -0
  15. package/dist/browser.js +3 -0
  16. package/dist/browser.js.map +1 -0
  17. package/dist/node.d.ts +3 -0
  18. package/dist/node.d.ts.map +1 -0
  19. package/dist/node.js +10 -0
  20. package/dist/node.js.map +1 -0
  21. package/dist/options.d.ts +24 -0
  22. package/dist/options.d.ts.map +1 -0
  23. package/dist/options.js +135 -0
  24. package/dist/options.js.map +1 -0
  25. package/dist/types.d.ts +51 -0
  26. package/dist/types.d.ts.map +1 -0
  27. package/dist/types.js +2 -0
  28. package/dist/types.js.map +1 -0
  29. package/examples/bun.ts +8 -0
  30. package/examples/german-invoice/README.md +70 -0
  31. package/examples/german-invoice/data.mjs +83 -0
  32. package/examples/german-invoice/invoice.css +59 -0
  33. package/examples/german-invoice/template.mjs +49 -0
  34. package/examples/german-invoice.mjs +20 -0
  35. package/examples/invoice.html +29 -0
  36. package/examples/node.mjs +8 -0
  37. package/examples/pagination.html +40 -0
  38. package/examples/pagination.mjs +8 -0
  39. package/licenses/DejaVu.txt +187 -0
  40. package/licenses/RUST_DEPENDENCIES.txt +11577 -0
  41. package/package.json +89 -4
  42. package/src/api.ts +44 -0
  43. package/src/assets.ts +43 -0
  44. package/src/browser.ts +6 -0
  45. package/src/node.ts +12 -0
  46. package/src/options.ts +101 -0
  47. package/src/types.ts +49 -0
  48. package/vendor/README.md +17 -0
  49. package/vendor/stylo/.cargo-ok +1 -0
  50. package/vendor/stylo/.cargo_vcs_info.json +6 -0
  51. package/vendor/stylo/Cargo.lock +1485 -0
  52. package/vendor/stylo/Cargo.toml +274 -0
  53. package/vendor/stylo/LICENSE +373 -0
  54. package/vendor/stylo/README.md +6 -0
  55. package/vendor/stylo/applicable_declarations.rs +328 -0
  56. package/vendor/stylo/author_styles.rs +79 -0
  57. package/vendor/stylo/bezier.rs +176 -0
  58. package/vendor/stylo/bloom.rs +414 -0
  59. package/vendor/stylo/build.rs +91 -0
  60. package/vendor/stylo/build_gecko.rs +393 -0
  61. package/vendor/stylo/color/color_function.rs +601 -0
  62. package/vendor/stylo/color/component.rs +207 -0
  63. package/vendor/stylo/color/convert.rs +935 -0
  64. package/vendor/stylo/color/gamut/raytrace.rs +265 -0
  65. package/vendor/stylo/color/gamut.rs +227 -0
  66. package/vendor/stylo/color/mix.rs +645 -0
  67. package/vendor/stylo/color/mod.rs +750 -0
  68. package/vendor/stylo/color/parsing.rs +770 -0
  69. package/vendor/stylo/color/to_css.rs +297 -0
  70. package/vendor/stylo/context.rs +716 -0
  71. package/vendor/stylo/counter_style/mod.rs +754 -0
  72. package/vendor/stylo/counter_style/predefined.rs +61 -0
  73. package/vendor/stylo/counter_style/update_predefined.py +35 -0
  74. package/vendor/stylo/custom_properties.rs +2023 -0
  75. package/vendor/stylo/custom_properties_map.rs +220 -0
  76. package/vendor/stylo/data.rs +693 -0
  77. package/vendor/stylo/device/gecko.rs +486 -0
  78. package/vendor/stylo/device/mod.rs +304 -0
  79. package/vendor/stylo/device/servo.rs +507 -0
  80. package/vendor/stylo/dom.rs +1164 -0
  81. package/vendor/stylo/dom_apis.rs +937 -0
  82. package/vendor/stylo/driver.rs +172 -0
  83. package/vendor/stylo/error_reporting.rs +484 -0
  84. package/vendor/stylo/font_face.rs +558 -0
  85. package/vendor/stylo/font_metrics.rs +124 -0
  86. package/vendor/stylo/gecko/anon_boxes.toml +113 -0
  87. package/vendor/stylo/gecko/arc_types.rs +211 -0
  88. package/vendor/stylo/gecko/conversions.rs +59 -0
  89. package/vendor/stylo/gecko/data.rs +222 -0
  90. package/vendor/stylo/gecko/media_features.rs +971 -0
  91. package/vendor/stylo/gecko/mod.rs +20 -0
  92. package/vendor/stylo/gecko/non_ts_pseudo_class_list.rs +119 -0
  93. package/vendor/stylo/gecko/pseudo_element.rs +640 -0
  94. package/vendor/stylo/gecko/pseudo_element_definition.mako.rs +298 -0
  95. package/vendor/stylo/gecko/pseudo_elements.py +137 -0
  96. package/vendor/stylo/gecko/pseudo_elements.toml +197 -0
  97. package/vendor/stylo/gecko/regen_pseudo_elements.py +33 -0
  98. package/vendor/stylo/gecko/restyle_damage.rs +127 -0
  99. package/vendor/stylo/gecko/selector_parser.rs +627 -0
  100. package/vendor/stylo/gecko/snapshot.rs +202 -0
  101. package/vendor/stylo/gecko/snapshot_helpers.rs +334 -0
  102. package/vendor/stylo/gecko/traversal.rs +52 -0
  103. package/vendor/stylo/gecko/wrapper.rs +2258 -0
  104. package/vendor/stylo/gecko_bindings/mod.rs +34 -0
  105. package/vendor/stylo/gecko_bindings/sugar/mod.rs +12 -0
  106. package/vendor/stylo/gecko_bindings/sugar/ns_com_ptr.rs +15 -0
  107. package/vendor/stylo/gecko_bindings/sugar/ns_compatibility.rs +19 -0
  108. package/vendor/stylo/gecko_bindings/sugar/ns_style_auto_array.rs +111 -0
  109. package/vendor/stylo/gecko_bindings/sugar/origin_flags.rs +31 -0
  110. package/vendor/stylo/gecko_bindings/sugar/ownership.rs +70 -0
  111. package/vendor/stylo/gecko_bindings/sugar/refptr.rs +299 -0
  112. package/vendor/stylo/gecko_string_cache/mod.rs +543 -0
  113. package/vendor/stylo/gecko_string_cache/namespace.rs +106 -0
  114. package/vendor/stylo/global_style_data.rs +224 -0
  115. package/vendor/stylo/invalidation/element/document_state.rs +156 -0
  116. package/vendor/stylo/invalidation/element/element_wrapper.rs +432 -0
  117. package/vendor/stylo/invalidation/element/invalidation_map.rs +1631 -0
  118. package/vendor/stylo/invalidation/element/invalidator.rs +1470 -0
  119. package/vendor/stylo/invalidation/element/mod.rs +13 -0
  120. package/vendor/stylo/invalidation/element/relative_selector.rs +1399 -0
  121. package/vendor/stylo/invalidation/element/restyle_hints.rs +226 -0
  122. package/vendor/stylo/invalidation/element/state_and_attributes.rs +756 -0
  123. package/vendor/stylo/invalidation/media_queries.rs +144 -0
  124. package/vendor/stylo/invalidation/mod.rs +10 -0
  125. package/vendor/stylo/invalidation/stylesheets.rs +745 -0
  126. package/vendor/stylo/invalidation/viewport_units.rs +71 -0
  127. package/vendor/stylo/lib.rs +336 -0
  128. package/vendor/stylo/logical_geometry.rs +1684 -0
  129. package/vendor/stylo/macros.rs +70 -0
  130. package/vendor/stylo/matching.rs +1226 -0
  131. package/vendor/stylo/media_queries/media_list.rs +168 -0
  132. package/vendor/stylo/media_queries/media_query.rs +190 -0
  133. package/vendor/stylo/media_queries/mod.rs +13 -0
  134. package/vendor/stylo/parallel.rs +205 -0
  135. package/vendor/stylo/parser.rs +276 -0
  136. package/vendor/stylo/piecewise_linear.rs +282 -0
  137. package/vendor/stylo/prefs.rs +33 -0
  138. package/vendor/stylo/properties/build.py +119 -0
  139. package/vendor/stylo/properties/cascade.rs +2704 -0
  140. package/vendor/stylo/properties/computed_value_flags.rs +206 -0
  141. package/vendor/stylo/properties/counted_unknown_properties.py +104 -0
  142. package/vendor/stylo/properties/counter_style_descriptors.toml +45 -0
  143. package/vendor/stylo/properties/data.py +1375 -0
  144. package/vendor/stylo/properties/declaration_block.rs +1788 -0
  145. package/vendor/stylo/properties/font_face_descriptors.toml +50 -0
  146. package/vendor/stylo/properties/gecko.mako.rs +1555 -0
  147. package/vendor/stylo/properties/helpers/animated_properties.mako.rs +800 -0
  148. package/vendor/stylo/properties/helpers.mako.rs +812 -0
  149. package/vendor/stylo/properties/longhands.toml +4305 -0
  150. package/vendor/stylo/properties/mod.rs +1857 -0
  151. package/vendor/stylo/properties/properties.html.mako +31 -0
  152. package/vendor/stylo/properties/properties.mako.rs +3103 -0
  153. package/vendor/stylo/properties/property_descriptors.toml +18 -0
  154. package/vendor/stylo/properties/shorthands.rs +4241 -0
  155. package/vendor/stylo/properties/shorthands.toml +575 -0
  156. package/vendor/stylo/properties/vendored_python/mako-1.3.10-py3-none-any.whl +0 -0
  157. package/vendor/stylo/properties/vendored_python/markupsafe/LICENSE.txt +28 -0
  158. package/vendor/stylo/properties/vendored_python/markupsafe/__init__.py +384 -0
  159. package/vendor/stylo/properties/vendored_python/toml-0.10.2-py2.py3-none-any.whl +0 -0
  160. package/vendor/stylo/properties/view_transition_descriptors.toml +11 -0
  161. package/vendor/stylo/properties_and_values/mod.rs +12 -0
  162. package/vendor/stylo/properties_and_values/registry.rs +65 -0
  163. package/vendor/stylo/properties_and_values/rule.rs +331 -0
  164. package/vendor/stylo/properties_and_values/syntax/ascii.rs +60 -0
  165. package/vendor/stylo/properties_and_values/syntax/data_type.rs +146 -0
  166. package/vendor/stylo/properties_and_values/syntax/mod.rs +437 -0
  167. package/vendor/stylo/properties_and_values/value.rs +758 -0
  168. package/vendor/stylo/queries/condition.rs +996 -0
  169. package/vendor/stylo/queries/feature.rs +199 -0
  170. package/vendor/stylo/queries/feature_expression.rs +1170 -0
  171. package/vendor/stylo/queries/mod.rs +19 -0
  172. package/vendor/stylo/queries/values.rs +46 -0
  173. package/vendor/stylo/rule_cache.rs +267 -0
  174. package/vendor/stylo/rule_collector.rs +554 -0
  175. package/vendor/stylo/rule_tree/core.rs +787 -0
  176. package/vendor/stylo/rule_tree/level.rs +396 -0
  177. package/vendor/stylo/rule_tree/map.rs +201 -0
  178. package/vendor/stylo/rule_tree/mod.rs +427 -0
  179. package/vendor/stylo/rule_tree/source.rs +80 -0
  180. package/vendor/stylo/rule_tree/unsafe_box.rs +78 -0
  181. package/vendor/stylo/scoped_tls.rs +80 -0
  182. package/vendor/stylo/selector_map.rs +1050 -0
  183. package/vendor/stylo/selector_parser.rs +305 -0
  184. package/vendor/stylo/servo/animation.rs +1922 -0
  185. package/vendor/stylo/servo/attr.rs +714 -0
  186. package/vendor/stylo/servo/encoding_support.rs +81 -0
  187. package/vendor/stylo/servo/media_features.rs +254 -0
  188. package/vendor/stylo/servo/mod.rs +16 -0
  189. package/vendor/stylo/servo/restyle_damage.rs +215 -0
  190. package/vendor/stylo/servo/selector_parser.rs +1036 -0
  191. package/vendor/stylo/servo/shadow_parts.rs +207 -0
  192. package/vendor/stylo/shared_lock.rs +271 -0
  193. package/vendor/stylo/sharing/checks.rs +281 -0
  194. package/vendor/stylo/sharing/mod.rs +1000 -0
  195. package/vendor/stylo/simple_buckets_map.rs +52 -0
  196. package/vendor/stylo/str.rs +168 -0
  197. package/vendor/stylo/style_adjuster.rs +1086 -0
  198. package/vendor/stylo/style_resolver.rs +658 -0
  199. package/vendor/stylo/stylesheet_set.rs +658 -0
  200. package/vendor/stylo/stylesheets/appearance_base_rule.rs +51 -0
  201. package/vendor/stylo/stylesheets/container_rule.rs +769 -0
  202. package/vendor/stylo/stylesheets/counter_style_rule.rs +7 -0
  203. package/vendor/stylo/stylesheets/document_rule.rs +272 -0
  204. package/vendor/stylo/stylesheets/font_face_rule.rs +7 -0
  205. package/vendor/stylo/stylesheets/font_feature_values_rule.rs +481 -0
  206. package/vendor/stylo/stylesheets/font_palette_values_rule.rs +304 -0
  207. package/vendor/stylo/stylesheets/import_rule.rs +259 -0
  208. package/vendor/stylo/stylesheets/keyframes_rule.rs +733 -0
  209. package/vendor/stylo/stylesheets/layer_rule.rs +221 -0
  210. package/vendor/stylo/stylesheets/loader.rs +29 -0
  211. package/vendor/stylo/stylesheets/margin_rule.rs +190 -0
  212. package/vendor/stylo/stylesheets/media_rule.rs +191 -0
  213. package/vendor/stylo/stylesheets/mod.rs +918 -0
  214. package/vendor/stylo/stylesheets/namespace_rule.rs +43 -0
  215. package/vendor/stylo/stylesheets/nested_declarations_rule.rs +51 -0
  216. package/vendor/stylo/stylesheets/origin.rs +249 -0
  217. package/vendor/stylo/stylesheets/page_rule.rs +354 -0
  218. package/vendor/stylo/stylesheets/position_try_rule.rs +68 -0
  219. package/vendor/stylo/stylesheets/property_rule.rs +5 -0
  220. package/vendor/stylo/stylesheets/rule_list.rs +167 -0
  221. package/vendor/stylo/stylesheets/rule_parser.rs +1189 -0
  222. package/vendor/stylo/stylesheets/rules_iterator.rs +397 -0
  223. package/vendor/stylo/stylesheets/scope_rule.rs +511 -0
  224. package/vendor/stylo/stylesheets/starting_style_rule.rs +54 -0
  225. package/vendor/stylo/stylesheets/style_rule.rs +80 -0
  226. package/vendor/stylo/stylesheets/stylesheet.rs +570 -0
  227. package/vendor/stylo/stylesheets/supports_rule.rs +486 -0
  228. package/vendor/stylo/stylesheets/view_transition_rule.rs +81 -0
  229. package/vendor/stylo/stylist.rs +5076 -0
  230. package/vendor/stylo/thread_state.rs +87 -0
  231. package/vendor/stylo/traversal.rs +765 -0
  232. package/vendor/stylo/traversal_flags.rs +68 -0
  233. package/vendor/stylo/typed_om/mod.rs +981 -0
  234. package/vendor/stylo/typed_om/numeric.rs +128 -0
  235. package/vendor/stylo/typed_om/numeric_declaration.rs +93 -0
  236. package/vendor/stylo/typed_om/numeric_type.rs +640 -0
  237. package/vendor/stylo/typed_om/sum_value.rs +426 -0
  238. package/vendor/stylo/url/gecko.rs +367 -0
  239. package/vendor/stylo/url/mod.rs +71 -0
  240. package/vendor/stylo/url/servo.rs +239 -0
  241. package/vendor/stylo/use_counters/mod.rs +137 -0
  242. package/vendor/stylo/values/animated/color.rs +103 -0
  243. package/vendor/stylo/values/animated/effects.rs +26 -0
  244. package/vendor/stylo/values/animated/font.rs +37 -0
  245. package/vendor/stylo/values/animated/grid.rs +161 -0
  246. package/vendor/stylo/values/animated/lists.rs +141 -0
  247. package/vendor/stylo/values/animated/mod.rs +550 -0
  248. package/vendor/stylo/values/animated/svg.rs +46 -0
  249. package/vendor/stylo/values/animated/text.rs +58 -0
  250. package/vendor/stylo/values/animated/transform.rs +1592 -0
  251. package/vendor/stylo/values/computed/align.rs +90 -0
  252. package/vendor/stylo/values/computed/angle.rs +130 -0
  253. package/vendor/stylo/values/computed/animation.rs +124 -0
  254. package/vendor/stylo/values/computed/background.rs +13 -0
  255. package/vendor/stylo/values/computed/basic_shape.rs +267 -0
  256. package/vendor/stylo/values/computed/border.rs +163 -0
  257. package/vendor/stylo/values/computed/box.rs +267 -0
  258. package/vendor/stylo/values/computed/calc.rs +334 -0
  259. package/vendor/stylo/values/computed/color.rs +161 -0
  260. package/vendor/stylo/values/computed/column.rs +11 -0
  261. package/vendor/stylo/values/computed/corner_shape.rs +155 -0
  262. package/vendor/stylo/values/computed/counters.rs +26 -0
  263. package/vendor/stylo/values/computed/easing.rs +109 -0
  264. package/vendor/stylo/values/computed/effects.rs +30 -0
  265. package/vendor/stylo/values/computed/flex.rs +19 -0
  266. package/vendor/stylo/values/computed/font.rs +1517 -0
  267. package/vendor/stylo/values/computed/image.rs +273 -0
  268. package/vendor/stylo/values/computed/length.rs +576 -0
  269. package/vendor/stylo/values/computed/length_percentage.rs +1055 -0
  270. package/vendor/stylo/values/computed/list.rs +16 -0
  271. package/vendor/stylo/values/computed/mod.rs +1141 -0
  272. package/vendor/stylo/values/computed/motion.rs +73 -0
  273. package/vendor/stylo/values/computed/outline.rs +7 -0
  274. package/vendor/stylo/values/computed/page.rs +77 -0
  275. package/vendor/stylo/values/computed/param.rs +9 -0
  276. package/vendor/stylo/values/computed/percentage.rs +143 -0
  277. package/vendor/stylo/values/computed/position.rs +273 -0
  278. package/vendor/stylo/values/computed/ratio.rs +88 -0
  279. package/vendor/stylo/values/computed/rect.rs +19 -0
  280. package/vendor/stylo/values/computed/resolution.rs +76 -0
  281. package/vendor/stylo/values/computed/svg.rs +66 -0
  282. package/vendor/stylo/values/computed/table.rs +7 -0
  283. package/vendor/stylo/values/computed/text.rs +199 -0
  284. package/vendor/stylo/values/computed/time.rs +83 -0
  285. package/vendor/stylo/values/computed/transform.rs +559 -0
  286. package/vendor/stylo/values/computed/tree_counting.rs +30 -0
  287. package/vendor/stylo/values/computed/ui.rs +23 -0
  288. package/vendor/stylo/values/computed/url.rs +12 -0
  289. package/vendor/stylo/values/distance.rs +139 -0
  290. package/vendor/stylo/values/generics/animation.rs +363 -0
  291. package/vendor/stylo/values/generics/background.rs +65 -0
  292. package/vendor/stylo/values/generics/basic_shape.rs +1389 -0
  293. package/vendor/stylo/values/generics/border.rs +303 -0
  294. package/vendor/stylo/values/generics/box.rs +552 -0
  295. package/vendor/stylo/values/generics/calc.rs +2986 -0
  296. package/vendor/stylo/values/generics/color.rs +318 -0
  297. package/vendor/stylo/values/generics/column.rs +44 -0
  298. package/vendor/stylo/values/generics/counters.rs +320 -0
  299. package/vendor/stylo/values/generics/easing.rs +132 -0
  300. package/vendor/stylo/values/generics/effects.rs +131 -0
  301. package/vendor/stylo/values/generics/flex.rs +34 -0
  302. package/vendor/stylo/values/generics/font.rs +376 -0
  303. package/vendor/stylo/values/generics/grid.rs +962 -0
  304. package/vendor/stylo/values/generics/image.rs +653 -0
  305. package/vendor/stylo/values/generics/length.rs +656 -0
  306. package/vendor/stylo/values/generics/mod.rs +303 -0
  307. package/vendor/stylo/values/generics/motion.rs +274 -0
  308. package/vendor/stylo/values/generics/page.rs +167 -0
  309. package/vendor/stylo/values/generics/position.rs +669 -0
  310. package/vendor/stylo/values/generics/ratio.rs +88 -0
  311. package/vendor/stylo/values/generics/rect.rs +147 -0
  312. package/vendor/stylo/values/generics/size.rs +102 -0
  313. package/vendor/stylo/values/generics/svg.rs +226 -0
  314. package/vendor/stylo/values/generics/text.rs +268 -0
  315. package/vendor/stylo/values/generics/transform.rs +1157 -0
  316. package/vendor/stylo/values/generics/ui.rs +147 -0
  317. package/vendor/stylo/values/generics/url.rs +51 -0
  318. package/vendor/stylo/values/mod.rs +820 -0
  319. package/vendor/stylo/values/resolved/animation.rs +33 -0
  320. package/vendor/stylo/values/resolved/color.rs +53 -0
  321. package/vendor/stylo/values/resolved/counters.rs +45 -0
  322. package/vendor/stylo/values/resolved/mod.rs +316 -0
  323. package/vendor/stylo/values/specified/align.rs +711 -0
  324. package/vendor/stylo/values/specified/angle.rs +407 -0
  325. package/vendor/stylo/values/specified/animation.rs +921 -0
  326. package/vendor/stylo/values/specified/background.rs +270 -0
  327. package/vendor/stylo/values/specified/basic_shape.rs +986 -0
  328. package/vendor/stylo/values/specified/border.rs +430 -0
  329. package/vendor/stylo/values/specified/box.rs +2231 -0
  330. package/vendor/stylo/values/specified/calc.rs +1657 -0
  331. package/vendor/stylo/values/specified/color.rs +1210 -0
  332. package/vendor/stylo/values/specified/column.rs +11 -0
  333. package/vendor/stylo/values/specified/corner_shape.rs +152 -0
  334. package/vendor/stylo/values/specified/counters.rs +242 -0
  335. package/vendor/stylo/values/specified/easing.rs +225 -0
  336. package/vendor/stylo/values/specified/effects.rs +421 -0
  337. package/vendor/stylo/values/specified/flex.rs +42 -0
  338. package/vendor/stylo/values/specified/font.rs +2103 -0
  339. package/vendor/stylo/values/specified/frequency.rs +39 -0
  340. package/vendor/stylo/values/specified/grid.rs +407 -0
  341. package/vendor/stylo/values/specified/image.rs +1385 -0
  342. package/vendor/stylo/values/specified/intersection_observer.rs +80 -0
  343. package/vendor/stylo/values/specified/length.rs +2024 -0
  344. package/vendor/stylo/values/specified/list.rs +190 -0
  345. package/vendor/stylo/values/specified/mod.rs +531 -0
  346. package/vendor/stylo/values/specified/motion.rs +316 -0
  347. package/vendor/stylo/values/specified/number.rs +603 -0
  348. package/vendor/stylo/values/specified/outline.rs +69 -0
  349. package/vendor/stylo/values/specified/page.rs +94 -0
  350. package/vendor/stylo/values/specified/param.rs +121 -0
  351. package/vendor/stylo/values/specified/percentage.rs +364 -0
  352. package/vendor/stylo/values/specified/position.rs +2247 -0
  353. package/vendor/stylo/values/specified/ratio.rs +29 -0
  354. package/vendor/stylo/values/specified/rect.rs +28 -0
  355. package/vendor/stylo/values/specified/resolution.rs +237 -0
  356. package/vendor/stylo/values/specified/source_size_list.rs +135 -0
  357. package/vendor/stylo/values/specified/svg.rs +427 -0
  358. package/vendor/stylo/values/specified/svg_path.rs +1115 -0
  359. package/vendor/stylo/values/specified/table.rs +38 -0
  360. package/vendor/stylo/values/specified/text.rs +1561 -0
  361. package/vendor/stylo/values/specified/time.rs +313 -0
  362. package/vendor/stylo/values/specified/transform.rs +599 -0
  363. package/vendor/stylo/values/specified/tree_counting.rs +32 -0
  364. package/vendor/stylo/values/specified/ui.rs +344 -0
  365. package/vendor/stylo/values/specified/url.rs +12 -0
  366. package/vendor/stylo/values/tagged_numeric.rs +253 -0
  367. package/wasm/blitz_pdf.d.ts +67 -0
  368. package/wasm/blitz_pdf.js +699 -0
  369. package/wasm/blitz_pdf_bg.wasm +0 -0
  370. package/wasm/blitz_pdf_bg.wasm.d.ts +20 -0
@@ -0,0 +1,1226 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+
5
+ //! High-level interface to CSS selector matching.
6
+
7
+ #![allow(unsafe_code)]
8
+ #![deny(missing_docs)]
9
+
10
+ use crate::computed_value_flags::ComputedValueFlags;
11
+ #[cfg(feature = "servo")]
12
+ use crate::context::CascadeInputs;
13
+ use crate::context::{ElementCascadeInputs, QuirksMode};
14
+ use crate::context::{SharedStyleContext, StyleContext};
15
+ use crate::data::{ElementData, ElementStyles};
16
+ use crate::dom::TElement;
17
+ #[cfg(feature = "servo")]
18
+ use crate::dom::TNode;
19
+ use crate::invalidation::element::restyle_hints::RestyleHint;
20
+ use crate::properties::longhands::display::computed_value::T as Display;
21
+ use crate::properties::ComputedValues;
22
+ use crate::properties::PropertyDeclarationBlock;
23
+ #[cfg(feature = "servo")]
24
+ use crate::rule_tree::RuleCascadeFlags;
25
+ use crate::rule_tree::{CascadeLevel, CascadeOrigin, StrongRuleNode};
26
+ use crate::selector_parser::{PseudoElement, RestyleDamage};
27
+ use crate::shared_lock::Locked;
28
+ use crate::style_resolver::StyleResolverForElement;
29
+ use crate::style_resolver::{PseudoElementResolution, ResolvedElementStyles};
30
+ use crate::stylesheets::layer_rule::LayerOrder;
31
+ use crate::stylist::RuleInclusion;
32
+ use crate::traversal_flags::TraversalFlags;
33
+ use crate::values::generics::animation::GenericAnimationTimeline;
34
+ use crate::values::specified::animation::Scroller;
35
+ use servo_arc::{Arc, ArcBorrow};
36
+
37
+ /// Represents the result of comparing an element's old and new style.
38
+ #[derive(Debug)]
39
+ pub struct StyleDifference {
40
+ /// The resulting damage.
41
+ pub damage: RestyleDamage,
42
+ /// Whether any styles changed.
43
+ pub change: StyleChange,
44
+ }
45
+
46
+ /// Represents whether or not the style of an element has changed.
47
+ #[derive(Clone, Copy, Debug)]
48
+ pub enum StyleChange {
49
+ /// The style hasn't changed.
50
+ Unchanged,
51
+ /// The style has changed.
52
+ Changed {
53
+ /// Whether only reset properties have changed.
54
+ reset_only: bool,
55
+ /// Whether custom properties have changed.
56
+ custom_properties_changed: bool,
57
+ },
58
+ }
59
+
60
+ /// Determines which styles are being cascaded currently.
61
+ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
62
+ enum CascadeVisitedMode {
63
+ /// Cascade the regular, unvisited styles.
64
+ Unvisited,
65
+ /// Cascade the styles used when an element's relevant link is visited. A
66
+ /// "relevant link" is the element being matched if it is a link or the
67
+ /// nearest ancestor link.
68
+ Visited,
69
+ }
70
+
71
+ trait PrivateMatchMethods: TElement {
72
+ fn replace_single_rule_node(
73
+ context: &SharedStyleContext,
74
+ level: CascadeLevel,
75
+ layer_order: LayerOrder,
76
+ pdb: Option<ArcBorrow<Locked<PropertyDeclarationBlock>>>,
77
+ path: &mut StrongRuleNode,
78
+ ) -> bool {
79
+ let stylist = &context.stylist;
80
+ let guards = &context.guards;
81
+
82
+ let mut important_rules_changed = false;
83
+ let new_node = stylist.rule_tree().update_rule_at_level(
84
+ level,
85
+ layer_order,
86
+ pdb,
87
+ path,
88
+ guards,
89
+ &mut important_rules_changed,
90
+ );
91
+ if let Some(n) = new_node {
92
+ *path = n;
93
+ }
94
+ important_rules_changed
95
+ }
96
+
97
+ /// Updates the rule nodes without re-running selector matching, using just
98
+ /// the rule tree, for a specific visited mode.
99
+ ///
100
+ /// Returns true if an !important rule was replaced.
101
+ fn replace_rules_internal(
102
+ &self,
103
+ replacements: RestyleHint,
104
+ context: &mut StyleContext<Self>,
105
+ cascade_visited: CascadeVisitedMode,
106
+ cascade_inputs: &mut ElementCascadeInputs,
107
+ ) -> bool {
108
+ debug_assert!(
109
+ replacements.intersects(RestyleHint::replacements())
110
+ && (replacements & !RestyleHint::replacements()).is_empty()
111
+ );
112
+
113
+ let primary_rules = match cascade_visited {
114
+ CascadeVisitedMode::Unvisited => cascade_inputs.primary.rules.as_mut(),
115
+ CascadeVisitedMode::Visited => cascade_inputs.primary.visited_rules.as_mut(),
116
+ };
117
+
118
+ let primary_rules = match primary_rules {
119
+ Some(r) => r,
120
+ None => return false,
121
+ };
122
+
123
+ if !context.shared.traversal_flags.for_animation_only() {
124
+ let mut result = false;
125
+ if replacements.contains(RestyleHint::RESTYLE_STYLE_ATTRIBUTE) {
126
+ let style_attribute = self.style_attribute();
127
+ result |= Self::replace_single_rule_node(
128
+ context.shared,
129
+ CascadeLevel::same_tree_author_normal(),
130
+ LayerOrder::style_attribute(),
131
+ style_attribute,
132
+ primary_rules,
133
+ );
134
+ result |= Self::replace_single_rule_node(
135
+ context.shared,
136
+ CascadeLevel::same_tree_author_important(),
137
+ LayerOrder::style_attribute(),
138
+ style_attribute,
139
+ primary_rules,
140
+ );
141
+ }
142
+ return result;
143
+ }
144
+
145
+ // Animation restyle hints are processed prior to other restyle
146
+ // hints in the animation-only traversal.
147
+ //
148
+ // Non-animation restyle hints will be processed in a subsequent
149
+ // normal traversal.
150
+ if replacements.intersects(RestyleHint::for_animations()) {
151
+ debug_assert!(context.shared.traversal_flags.for_animation_only());
152
+
153
+ if replacements.contains(RestyleHint::RESTYLE_SMIL) {
154
+ Self::replace_single_rule_node(
155
+ context.shared,
156
+ CascadeLevel::new(CascadeOrigin::SMILOverride),
157
+ LayerOrder::root(),
158
+ self.smil_override(),
159
+ primary_rules,
160
+ );
161
+ }
162
+
163
+ if replacements.contains(RestyleHint::RESTYLE_CSS_TRANSITIONS) {
164
+ Self::replace_single_rule_node(
165
+ context.shared,
166
+ CascadeLevel::new(CascadeOrigin::Transitions),
167
+ LayerOrder::root(),
168
+ self.transition_rule(context.shared)
169
+ .as_ref()
170
+ .map(|a| a.borrow_arc()),
171
+ primary_rules,
172
+ );
173
+ }
174
+
175
+ if replacements.contains(RestyleHint::RESTYLE_CSS_ANIMATIONS) {
176
+ Self::replace_single_rule_node(
177
+ context.shared,
178
+ CascadeLevel::new(CascadeOrigin::Animations),
179
+ LayerOrder::root(),
180
+ self.animation_rule(context.shared)
181
+ .as_ref()
182
+ .map(|a| a.borrow_arc()),
183
+ primary_rules,
184
+ );
185
+ }
186
+ }
187
+
188
+ false
189
+ }
190
+
191
+ #[inline]
192
+ fn requires_animation_update_for_scroll_self(
193
+ old: &ComputedValues,
194
+ new: &ComputedValues,
195
+ ) -> bool {
196
+ // Need to specifically take care of `animation-timeline: scroll(self)` - unlike other values, it can become inactive.
197
+ // When we switch in and out of being scrollable, we should make sure to perform the animation update.
198
+ // Specifying scroll in any axis makes the other axis scrollable [1], so we need to update on either axis changing.
199
+ // This does not apply to `scroll(root)`, since the viewport scroller is always available, or `scroll(nearest)`,
200
+ // which will go up to root.
201
+ // [1]: https://drafts.csswg.org/css-overflow/#propdef-overflow
202
+ let scrollable_changed = old.clone_overflow_x().is_scrollable()
203
+ != new.clone_overflow_x().is_scrollable()
204
+ || old.clone_overflow_y().is_scrollable() != new.clone_overflow_y().is_scrollable();
205
+ if !scrollable_changed {
206
+ return false;
207
+ }
208
+ new.get_ui().animation_timeline_iter().any(|timeline| {
209
+ let scroll_function = match timeline {
210
+ GenericAnimationTimeline::Scroll(ref sf) => sf,
211
+ _ => return false,
212
+ };
213
+ if scroll_function.scroller != Scroller::SelfElement {
214
+ return false;
215
+ }
216
+ true
217
+ })
218
+ }
219
+
220
+ /// If there is no transition rule in the ComputedValues, it returns None.
221
+ fn after_change_style(
222
+ &self,
223
+ context: &mut StyleContext<Self>,
224
+ primary_style: &Arc<ComputedValues>,
225
+ ) -> Option<Arc<ComputedValues>> {
226
+ // Actually `PseudoElementResolution` doesn't really matter.
227
+ StyleResolverForElement::new(
228
+ *self,
229
+ context,
230
+ RuleInclusion::All,
231
+ PseudoElementResolution::IfApplicable,
232
+ )
233
+ .after_change_style(primary_style)
234
+ }
235
+
236
+ fn needs_animations_update(
237
+ &self,
238
+ context: &mut StyleContext<Self>,
239
+ old_style: Option<&ComputedValues>,
240
+ new_style: &ComputedValues,
241
+ pseudo_element: Option<PseudoElement>,
242
+ ) -> bool {
243
+ let new_ui_style = new_style.get_ui();
244
+ let new_style_specifies_animations = new_ui_style.specifies_animations();
245
+
246
+ let has_animations = self.has_css_animations(context.shared, pseudo_element);
247
+ if !new_style_specifies_animations && !has_animations {
248
+ return false;
249
+ }
250
+
251
+ let old_style = match old_style {
252
+ Some(old) => old,
253
+ // If we have no old style but have animations, we may be a
254
+ // pseudo-element which was re-created without style changes.
255
+ //
256
+ // This can happen when we reframe the pseudo-element without
257
+ // restyling it (due to content insertion on a flex container or
258
+ // such, for example). See bug 1564366.
259
+ //
260
+ // FIXME(emilio): The really right fix for this is keeping the
261
+ // pseudo-element itself around on reframes, but that's a bit
262
+ // harder. If we do that we can probably remove quite a lot of the
263
+ // EffectSet complexity though, since right now it's stored on the
264
+ // parent element for pseudo-elements given we need to keep it
265
+ // around...
266
+ None => {
267
+ return new_style_specifies_animations || new_style.is_pseudo_style();
268
+ },
269
+ };
270
+
271
+ let old_ui_style = old_style.get_ui();
272
+
273
+ let keyframes_could_have_changed = context
274
+ .shared
275
+ .traversal_flags
276
+ .contains(TraversalFlags::ForCSSRuleChanges);
277
+
278
+ // If the traversal is triggered due to changes in CSS rules changes, we
279
+ // need to try to update all CSS animations on the element if the
280
+ // element has or will have CSS animation style regardless of whether
281
+ // the animation is running or not.
282
+ //
283
+ // TODO: We should check which @keyframes were added/changed/deleted and
284
+ // update only animations corresponding to those @keyframes.
285
+ if keyframes_could_have_changed {
286
+ return true;
287
+ }
288
+
289
+ // If the animations changed, well...
290
+ if !old_ui_style.animations_equals(new_ui_style) {
291
+ return true;
292
+ }
293
+
294
+ let old_display = old_style.clone_display();
295
+ let new_display = new_style.clone_display();
296
+
297
+ // If we were display: none, we may need to trigger animations.
298
+ if old_display == Display::None && new_display != Display::None {
299
+ return new_style_specifies_animations;
300
+ }
301
+
302
+ // If we are becoming display: none, we may need to stop animations.
303
+ if old_display != Display::None && new_display == Display::None {
304
+ return has_animations;
305
+ }
306
+
307
+ // We might need to update animations if writing-mode or direction
308
+ // changed, and any of the animations contained logical properties.
309
+ //
310
+ // We may want to be more granular, but it's probably not worth it.
311
+ if new_style.writing_mode != old_style.writing_mode {
312
+ return has_animations;
313
+ }
314
+
315
+ if Self::requires_animation_update_for_scroll_self(old_style, new_style) {
316
+ return has_animations;
317
+ }
318
+
319
+ false
320
+ }
321
+
322
+ fn might_need_transitions_update(
323
+ &self,
324
+ context: &StyleContext<Self>,
325
+ old_style: Option<&ComputedValues>,
326
+ new_style: &ComputedValues,
327
+ pseudo_element: Option<PseudoElement>,
328
+ ) -> bool {
329
+ let old_style = match old_style {
330
+ Some(v) => v,
331
+ None => return false,
332
+ };
333
+
334
+ if !self.has_css_transitions(context.shared, pseudo_element)
335
+ && !new_style.get_ui().specifies_transitions()
336
+ {
337
+ return false;
338
+ }
339
+
340
+ if old_style.clone_display().is_none() {
341
+ return false;
342
+ }
343
+
344
+ true
345
+ }
346
+
347
+ #[cfg(feature = "gecko")]
348
+ fn maybe_resolve_starting_style(
349
+ &self,
350
+ context: &mut StyleContext<Self>,
351
+ old_values: Option<&Arc<ComputedValues>>,
352
+ new_styles: &ResolvedElementStyles,
353
+ ) -> Option<Arc<ComputedValues>> {
354
+ // For both cases:
355
+ // If there is no transitions specified we don't have to resolve starting style.
356
+ let new_primary = new_styles.primary_style();
357
+ if !new_primary.get_ui().specifies_transitions() {
358
+ return None;
359
+ }
360
+
361
+ // We resolve starting style only if we don't have before-change-style, or we change from
362
+ // display:none.
363
+ if old_values.is_some()
364
+ && !new_primary.is_display_property_changed_from_none(old_values.map(|s| &**s))
365
+ {
366
+ return None;
367
+ }
368
+
369
+ let mut resolver = StyleResolverForElement::new(
370
+ *self,
371
+ context,
372
+ RuleInclusion::All,
373
+ PseudoElementResolution::IfApplicable,
374
+ );
375
+
376
+ let starting_style = resolver.resolve_starting_style(new_primary)?;
377
+ if starting_style.style().clone_display().is_none() {
378
+ return None;
379
+ }
380
+
381
+ Some(starting_style.0)
382
+ }
383
+
384
+ /// Handle CSS Transitions. Returns None if we don't need to update transitions. And it returns
385
+ /// the before-change style per CSS Transitions spec.
386
+ ///
387
+ /// Note: The before-change style could be the computed values of all properties on the element
388
+ /// as of the previous style change event, or the starting style if we don't have the valid
389
+ /// before-change style there.
390
+ #[cfg(feature = "gecko")]
391
+ fn process_transitions(
392
+ &self,
393
+ context: &mut StyleContext<Self>,
394
+ old_values: Option<&Arc<ComputedValues>>,
395
+ new_styles: &mut ResolvedElementStyles,
396
+ ) -> Option<Arc<ComputedValues>> {
397
+ let starting_values = self.maybe_resolve_starting_style(context, old_values, new_styles);
398
+ let before_change_or_starting = starting_values.as_ref().or(old_values);
399
+ let new_values = new_styles.primary_style_mut();
400
+
401
+ if !self.might_need_transitions_update(
402
+ context,
403
+ before_change_or_starting.map(|s| &**s),
404
+ new_values,
405
+ /* pseudo_element = */ None,
406
+ ) {
407
+ return None;
408
+ }
409
+
410
+ let after_change_style =
411
+ if self.has_css_transitions(context.shared, /* pseudo_element = */ None) {
412
+ self.after_change_style(context, new_values)
413
+ } else {
414
+ None
415
+ };
416
+
417
+ // In order to avoid creating a SequentialTask for transitions which
418
+ // may not be updated, we check it per property to make sure Gecko
419
+ // side will really update transition.
420
+ if !self.needs_transitions_update(
421
+ before_change_or_starting.unwrap(),
422
+ after_change_style.as_ref().unwrap_or(new_values),
423
+ ) {
424
+ return None;
425
+ }
426
+
427
+ if let Some(values_without_transitions) = after_change_style {
428
+ *new_values = values_without_transitions;
429
+ }
430
+
431
+ // Move the new-created starting style, or clone the old values.
432
+ if starting_values.is_some() {
433
+ starting_values
434
+ } else {
435
+ old_values.cloned()
436
+ }
437
+ }
438
+
439
+ #[cfg(feature = "gecko")]
440
+ fn process_animations(
441
+ &self,
442
+ context: &mut StyleContext<Self>,
443
+ old_styles: &mut ElementStyles,
444
+ new_styles: &mut ResolvedElementStyles,
445
+ important_rules_changed: bool,
446
+ ) {
447
+ use crate::context::UpdateAnimationsTasks;
448
+
449
+ let old_values = &old_styles.primary;
450
+ if context.shared.traversal_flags.for_animation_only() && old_values.is_some() {
451
+ return;
452
+ }
453
+
454
+ // Bug 868975: These steps should examine and update the visited styles
455
+ // in addition to the unvisited styles.
456
+
457
+ let mut tasks = UpdateAnimationsTasks::empty();
458
+
459
+ if old_values.as_deref().map_or_else(
460
+ || {
461
+ new_styles
462
+ .primary_style()
463
+ .get_ui()
464
+ .specifies_timeline_scope()
465
+ },
466
+ |old| {
467
+ !old.get_ui()
468
+ .timeline_scope_equals(new_styles.primary_style().get_ui())
469
+ },
470
+ ) {
471
+ tasks.insert(UpdateAnimationsTasks::TIMELINE_SCOPES);
472
+ }
473
+
474
+ if old_values.as_deref().map_or_else(
475
+ || {
476
+ new_styles
477
+ .primary_style()
478
+ .get_ui()
479
+ .specifies_scroll_timelines()
480
+ },
481
+ |old| {
482
+ !old.get_ui()
483
+ .scroll_timelines_equals(new_styles.primary_style().get_ui())
484
+ },
485
+ ) {
486
+ tasks.insert(UpdateAnimationsTasks::SCROLL_TIMELINES);
487
+ }
488
+
489
+ if old_values.as_deref().map_or_else(
490
+ || {
491
+ new_styles
492
+ .primary_style()
493
+ .get_ui()
494
+ .specifies_view_timelines()
495
+ },
496
+ |old| {
497
+ !old.get_ui()
498
+ .view_timelines_equals(new_styles.primary_style().get_ui())
499
+ },
500
+ ) {
501
+ tasks.insert(UpdateAnimationsTasks::VIEW_TIMELINES);
502
+ }
503
+
504
+ if self.needs_animations_update(
505
+ context,
506
+ old_values.as_deref(),
507
+ new_styles.primary_style(),
508
+ /* pseudo_element = */ None,
509
+ ) {
510
+ tasks.insert(UpdateAnimationsTasks::CSS_ANIMATIONS);
511
+ }
512
+
513
+ let before_change_style =
514
+ self.process_transitions(context, old_values.as_ref(), new_styles);
515
+ if before_change_style.is_some() {
516
+ tasks.insert(UpdateAnimationsTasks::CSS_TRANSITIONS);
517
+ }
518
+
519
+ if self.has_animations(context.shared) {
520
+ tasks.insert(UpdateAnimationsTasks::EFFECT_PROPERTIES);
521
+ if important_rules_changed {
522
+ tasks.insert(UpdateAnimationsTasks::CASCADE_RESULTS);
523
+ }
524
+ if new_styles
525
+ .primary_style()
526
+ .is_display_property_changed_from_none(old_values.as_deref())
527
+ {
528
+ tasks.insert(UpdateAnimationsTasks::DISPLAY_CHANGED_FROM_NONE);
529
+ }
530
+ }
531
+
532
+ if !tasks.is_empty() {
533
+ let task = crate::context::SequentialTask::update_animations(
534
+ *self,
535
+ before_change_style,
536
+ tasks,
537
+ );
538
+ context.thread_local.tasks.push(task);
539
+ }
540
+ }
541
+
542
+ #[cfg(feature = "servo")]
543
+ fn process_animations(
544
+ &self,
545
+ context: &mut StyleContext<Self>,
546
+ old_styles: &mut ElementStyles,
547
+ new_resolved_styles: &mut ResolvedElementStyles,
548
+ _important_rules_changed: bool,
549
+ ) {
550
+ use crate::animation::AnimationSetKey;
551
+ use crate::dom::TDocument;
552
+
553
+ let style_changed = self.process_animations_for_style(
554
+ context,
555
+ &mut old_styles.primary,
556
+ new_resolved_styles.primary_style_mut(),
557
+ /* pseudo_element = */ None,
558
+ );
559
+
560
+ // If we have modified animation or transitions, we recascade style for this node.
561
+ if style_changed {
562
+ let primary_style = new_resolved_styles.primary_style();
563
+ let mut rule_node = primary_style.rules().clone();
564
+ let declarations = context.shared.animations.get_all_declarations(
565
+ &AnimationSetKey::new_for_non_pseudo(self.as_node().opaque()),
566
+ context.shared.current_time_for_animations,
567
+ self.as_node().owner_doc().shared_lock(),
568
+ );
569
+ Self::replace_single_rule_node(
570
+ &context.shared,
571
+ CascadeLevel::new(CascadeOrigin::Transitions),
572
+ LayerOrder::root(),
573
+ declarations.transitions.as_ref().map(|a| a.borrow_arc()),
574
+ &mut rule_node,
575
+ );
576
+ Self::replace_single_rule_node(
577
+ &context.shared,
578
+ CascadeLevel::new(CascadeOrigin::Animations),
579
+ LayerOrder::root(),
580
+ declarations.animations.as_ref().map(|a| a.borrow_arc()),
581
+ &mut rule_node,
582
+ );
583
+
584
+ if rule_node != *primary_style.rules() {
585
+ let inputs = CascadeInputs {
586
+ rules: Some(rule_node),
587
+ visited_rules: primary_style.visited_rules().cloned(),
588
+ flags: primary_style.flags.for_cascade_inputs(),
589
+ included_cascade_flags: RuleCascadeFlags::empty(),
590
+ };
591
+
592
+ new_resolved_styles.primary.style = StyleResolverForElement::new(
593
+ *self,
594
+ context,
595
+ RuleInclusion::All,
596
+ PseudoElementResolution::IfApplicable,
597
+ )
598
+ .cascade_style_and_visited_with_default_parents(inputs);
599
+ }
600
+ }
601
+
602
+ self.process_animations_for_pseudo(
603
+ context,
604
+ old_styles,
605
+ new_resolved_styles,
606
+ PseudoElement::Before,
607
+ );
608
+ self.process_animations_for_pseudo(
609
+ context,
610
+ old_styles,
611
+ new_resolved_styles,
612
+ PseudoElement::After,
613
+ );
614
+ }
615
+
616
+ #[cfg(feature = "servo")]
617
+ fn process_animations_for_pseudo(
618
+ &self,
619
+ context: &mut StyleContext<Self>,
620
+ old_styles: &ElementStyles,
621
+ new_resolved_styles: &mut ResolvedElementStyles,
622
+ pseudo_element: PseudoElement,
623
+ ) {
624
+ use crate::animation::AnimationSetKey;
625
+ use crate::dom::TDocument;
626
+
627
+ let key = AnimationSetKey::new_for_pseudo(self.as_node().opaque(), pseudo_element.clone());
628
+ let style = match new_resolved_styles.pseudos.get(&pseudo_element) {
629
+ Some(style) => Arc::clone(style),
630
+ None => {
631
+ context
632
+ .shared
633
+ .animations
634
+ .cancel_all_animations_for_key(&key);
635
+ return;
636
+ },
637
+ };
638
+
639
+ let old_style = old_styles.pseudos.get(&pseudo_element).cloned();
640
+ self.process_animations_for_style(
641
+ context,
642
+ &old_style,
643
+ &style,
644
+ Some(pseudo_element.clone()),
645
+ );
646
+
647
+ let declarations = context.shared.animations.get_all_declarations(
648
+ &key,
649
+ context.shared.current_time_for_animations,
650
+ self.as_node().owner_doc().shared_lock(),
651
+ );
652
+ if declarations.is_empty() {
653
+ return;
654
+ }
655
+
656
+ let mut rule_node = style.rules().clone();
657
+ Self::replace_single_rule_node(
658
+ &context.shared,
659
+ CascadeLevel::new(CascadeOrigin::Transitions),
660
+ LayerOrder::root(),
661
+ declarations.transitions.as_ref().map(|a| a.borrow_arc()),
662
+ &mut rule_node,
663
+ );
664
+ Self::replace_single_rule_node(
665
+ &context.shared,
666
+ CascadeLevel::new(CascadeOrigin::Animations),
667
+ LayerOrder::root(),
668
+ declarations.animations.as_ref().map(|a| a.borrow_arc()),
669
+ &mut rule_node,
670
+ );
671
+ if rule_node == *style.rules() {
672
+ return;
673
+ }
674
+
675
+ let inputs = CascadeInputs {
676
+ rules: Some(rule_node),
677
+ visited_rules: style.visited_rules().cloned(),
678
+ flags: style.flags.for_cascade_inputs(),
679
+ included_cascade_flags: RuleCascadeFlags::empty(),
680
+ };
681
+
682
+ let new_style = StyleResolverForElement::new(
683
+ *self,
684
+ context,
685
+ RuleInclusion::All,
686
+ PseudoElementResolution::IfApplicable,
687
+ )
688
+ .cascade_style_and_visited_for_pseudo_with_default_parents(
689
+ inputs,
690
+ &pseudo_element,
691
+ &new_resolved_styles.primary,
692
+ );
693
+
694
+ new_resolved_styles
695
+ .pseudos
696
+ .set(&pseudo_element, new_style.0);
697
+ }
698
+
699
+ #[cfg(feature = "servo")]
700
+ fn process_animations_for_style(
701
+ &self,
702
+ context: &mut StyleContext<Self>,
703
+ old_values: &Option<Arc<ComputedValues>>,
704
+ new_values: &Arc<ComputedValues>,
705
+ pseudo_element: Option<PseudoElement>,
706
+ ) -> bool {
707
+ use crate::animation::{AnimationSetKey, AnimationState};
708
+
709
+ // We need to call this before accessing the `ElementAnimationSet` from the
710
+ // map because this call will do a RwLock::read().
711
+ let needs_animations_update = self.needs_animations_update(
712
+ context,
713
+ old_values.as_deref(),
714
+ new_values,
715
+ pseudo_element,
716
+ );
717
+
718
+ let might_need_transitions_update = self.might_need_transitions_update(
719
+ context,
720
+ old_values.as_deref(),
721
+ new_values,
722
+ pseudo_element,
723
+ );
724
+
725
+ let mut after_change_style = None;
726
+ if might_need_transitions_update {
727
+ after_change_style = self.after_change_style(context, new_values);
728
+ }
729
+
730
+ let key = AnimationSetKey::new(self.as_node().opaque(), pseudo_element);
731
+ let shared_context = context.shared;
732
+ let mut animation_set = shared_context
733
+ .animations
734
+ .sets
735
+ .write()
736
+ .remove(&key)
737
+ .unwrap_or_default();
738
+
739
+ // Starting animations is expensive, because we have to recalculate the style
740
+ // for all the keyframes. We only want to do this if we think that there's a
741
+ // chance that the animations really changed.
742
+ if needs_animations_update {
743
+ let mut resolver = StyleResolverForElement::new(
744
+ *self,
745
+ context,
746
+ RuleInclusion::All,
747
+ PseudoElementResolution::IfApplicable,
748
+ );
749
+
750
+ animation_set.update_animations_for_new_style::<Self>(
751
+ *self,
752
+ &shared_context,
753
+ &new_values,
754
+ &mut resolver,
755
+ );
756
+ }
757
+
758
+ animation_set.update_transitions_for_new_style(
759
+ might_need_transitions_update,
760
+ &shared_context,
761
+ old_values.as_ref(),
762
+ after_change_style.as_ref().unwrap_or(new_values),
763
+ );
764
+
765
+ // This should change the computed values in the style, so we don't need
766
+ // to mark this set as dirty.
767
+ animation_set
768
+ .transitions
769
+ .retain(|transition| transition.state != AnimationState::Finished);
770
+
771
+ animation_set
772
+ .animations
773
+ .retain(|animation| animation.state != AnimationState::Finished);
774
+
775
+ // If the ElementAnimationSet is empty, and don't store it in order to
776
+ // save memory and to avoid extra processing later.
777
+ let changed_animations = animation_set.dirty;
778
+ if !animation_set.is_empty() {
779
+ animation_set.dirty = false;
780
+ shared_context
781
+ .animations
782
+ .sets
783
+ .write()
784
+ .insert(key, animation_set);
785
+ }
786
+
787
+ changed_animations
788
+ }
789
+
790
+ /// Computes and applies non-redundant damage.
791
+ fn accumulate_damage_for(
792
+ &self,
793
+ shared_context: &SharedStyleContext,
794
+ damage: &mut RestyleDamage,
795
+ old_values: &ComputedValues,
796
+ new_values: &ComputedValues,
797
+ pseudo: Option<&PseudoElement>,
798
+ ) -> RestyleHint {
799
+ debug!("accumulate_damage_for: {:?}", self);
800
+ debug_assert!(!shared_context
801
+ .traversal_flags
802
+ .contains(TraversalFlags::FinalAnimationTraversal));
803
+
804
+ let difference = self.compute_style_difference(old_values, new_values, pseudo);
805
+
806
+ *damage |= difference.damage;
807
+
808
+ debug!(" > style difference: {:?}", difference);
809
+
810
+ let mut children_hint = RestyleHint::empty();
811
+ if old_values.flags.maybe_inherited() != new_values.flags.maybe_inherited() {
812
+ // Even if the styles are otherwise equal, we need to cascade the children in order to
813
+ // ensure the correct propagation of inherited computed value flags.
814
+ debug!(
815
+ " > flags changed: {:?} != {:?}",
816
+ old_values.flags, new_values.flags
817
+ );
818
+ children_hint |= RestyleHint::RECASCADE_SELF;
819
+ } else if old_values.effective_zoom != new_values.effective_zoom {
820
+ // Similarly, even if styles are equal, we need to propagate zoom changes.
821
+ debug!(
822
+ " > zoom changed: {:?} != {:?}",
823
+ old_values.effective_zoom, new_values.effective_zoom
824
+ );
825
+ children_hint |= RestyleHint::RECASCADE_SELF;
826
+ }
827
+
828
+ let StyleChange::Changed {
829
+ reset_only,
830
+ custom_properties_changed,
831
+ } = difference.change
832
+ else {
833
+ return children_hint;
834
+ };
835
+
836
+ let new_container_name = new_values.clone_container_name();
837
+ if new_container_name != old_values.clone_container_name() {
838
+ // If we're becoming or stopped to become a named container, we need to potentially
839
+ // restyle children.
840
+ children_hint |= RestyleHint::RESTYLE_IF_AFFECTED_BY_NAMED_STYLE_CONTAINER;
841
+ } else if custom_properties_changed {
842
+ // Custom property changes affect style queries. How specifically depends on whether
843
+ // we're a named container (more expensive, need to check the subtree) or not.
844
+ children_hint |= if !new_container_name.is_none() {
845
+ RestyleHint::RESTYLE_IF_AFFECTED_BY_NAMED_STYLE_CONTAINER
846
+ } else {
847
+ RestyleHint::RESTYLE_IF_AFFECTED_BY_STYLE_QUERIES
848
+ };
849
+ }
850
+
851
+ if reset_only {
852
+ // If only reset properties changed, we _might_ need to unconditionally restyle, but
853
+ // most likely we can get away with stopping the cascade at the next level, if our
854
+ // children don't inherit reset properties.
855
+ children_hint |=
856
+ if need_to_unconditionally_recascade_for_reset_change(old_values, new_values) {
857
+ RestyleHint::RECASCADE_SELF
858
+ } else {
859
+ RestyleHint::RECASCADE_SELF_IF_INHERIT_RESET_STYLE
860
+ };
861
+ } else {
862
+ // If inherited properties changed, we need to cascade our children.
863
+ children_hint |= RestyleHint::RECASCADE_SELF;
864
+ }
865
+
866
+ children_hint
867
+ }
868
+ }
869
+
870
+ /// Whether we need to recascade children for a change in non-inherited properties.
871
+ fn need_to_unconditionally_recascade_for_reset_change(
872
+ old_values: &ComputedValues,
873
+ new_values: &ComputedValues,
874
+ ) -> bool {
875
+ let old_display = old_values.clone_display();
876
+ let new_display = new_values.clone_display();
877
+
878
+ if old_display != new_display {
879
+ // If we used to be a display: none element, and no longer are, our
880
+ // children need to be restyled because they're unstyled.
881
+ if old_display == Display::None {
882
+ return true;
883
+ }
884
+ // Blockification of children may depend on our display value, so we need to actually do the
885
+ // recascade. We could potentially do better, but it doesn't seem worth it.
886
+ if old_display.is_item_container() != new_display.is_item_container() {
887
+ return true;
888
+ }
889
+ // We may also need to blockify and un-blockify descendants if our display goes from / to
890
+ // display: contents, since the "layout parent style" changes.
891
+ if old_display.is_contents() || new_display.is_contents() {
892
+ return true;
893
+ }
894
+ // Line break suppression may also be affected if the display
895
+ // type changes from ruby to non-ruby.
896
+ #[cfg(feature = "gecko")]
897
+ if old_display.is_ruby_type() != new_display.is_ruby_type() {
898
+ return true;
899
+ }
900
+ }
901
+
902
+ // Children with justify-items: auto may depend on our
903
+ // justify-items property value.
904
+ //
905
+ // Similarly, we could potentially do better, but this really
906
+ // seems not common enough to care about.
907
+ #[cfg(feature = "gecko")]
908
+ {
909
+ use crate::values::specified::align::AlignFlags;
910
+
911
+ let old_justify_items = old_values.get_position().clone_justify_items();
912
+ let new_justify_items = new_values.get_position().clone_justify_items();
913
+
914
+ let was_legacy_justify_items = old_justify_items.computed.contains(AlignFlags::LEGACY);
915
+
916
+ let is_legacy_justify_items = new_justify_items.computed.contains(AlignFlags::LEGACY);
917
+
918
+ if is_legacy_justify_items != was_legacy_justify_items {
919
+ return true;
920
+ }
921
+
922
+ if was_legacy_justify_items && old_justify_items.computed != new_justify_items.computed {
923
+ return true;
924
+ }
925
+ }
926
+
927
+ false
928
+ }
929
+
930
+ impl<E: TElement> PrivateMatchMethods for E {}
931
+
932
+ /// The public API that elements expose for selector matching.
933
+ pub trait MatchMethods: TElement {
934
+ /// Returns the closest parent element that doesn't have a display: contents
935
+ /// style (and thus generates a box).
936
+ ///
937
+ /// This is needed to correctly handle blockification of flex and grid
938
+ /// items.
939
+ ///
940
+ /// Returns itself if the element has no parent. In practice this doesn't
941
+ /// happen because the root element is blockified per spec, but it could
942
+ /// happen if we decide to not blockify for roots of disconnected subtrees,
943
+ /// which is a kind of dubious behavior.
944
+ fn layout_parent(&self) -> Self {
945
+ let mut current = *self;
946
+ loop {
947
+ current = match current.traversal_parent() {
948
+ Some(el) => el,
949
+ None => return current,
950
+ };
951
+
952
+ let is_display_contents = current
953
+ .borrow_data()
954
+ .unwrap()
955
+ .styles
956
+ .primary()
957
+ .is_display_contents();
958
+
959
+ if !is_display_contents {
960
+ return current;
961
+ }
962
+ }
963
+ }
964
+
965
+ /// Rather than comparing the resolved line-height, which can be expensive to compute
966
+ /// as it involves locking and font metrics access, we consider that line-height may have
967
+ /// changed if the font-size or line-height property itself has changed, or if the value
968
+ /// is 'normal' and one of the properties that affects font selection (family, style,
969
+ /// weight, width) has changed.
970
+ fn line_height_likely_changed(
971
+ old_style: Option<&Arc<ComputedValues>>,
972
+ new_style: &Arc<ComputedValues>,
973
+ ) -> bool {
974
+ let old_line_height = old_style.map(|s| s.get_font().clone_line_height());
975
+ let new_line_height = new_style.get_font().clone_line_height();
976
+ // Return true if the old value was missing, or if the computed values are different.
977
+ if old_line_height.is_none_or(|lh| lh != new_line_height) {
978
+ return true;
979
+ }
980
+ // If the value isn't `normal`, it doesn't depend on font metrics: return false.
981
+ if !new_line_height.is_normal() {
982
+ return false;
983
+ }
984
+ // Check the font-selection properties, which could affect metrics used to resolve
985
+ // `normal` line-height.
986
+ macro_rules! font_property_changed {
987
+ ($getter: ident) => {
988
+ old_style
989
+ .map(|s| s.get_font().$getter())
990
+ .is_none_or(|v| v != new_style.get_font().$getter())
991
+ };
992
+ }
993
+ font_property_changed!(clone_font_family)
994
+ || font_property_changed!(clone_font_style)
995
+ || font_property_changed!(clone_font_weight)
996
+ || font_property_changed!(clone_font_width)
997
+ }
998
+
999
+ /// Updates the styles with the new ones, diffs them, and stores the restyle
1000
+ /// damage.
1001
+ fn finish_restyle(
1002
+ &self,
1003
+ context: &mut StyleContext<Self>,
1004
+ data: &mut ElementData,
1005
+ mut new_styles: ResolvedElementStyles,
1006
+ important_rules_changed: bool,
1007
+ ) -> RestyleHint {
1008
+ self.process_animations(
1009
+ context,
1010
+ &mut data.styles,
1011
+ &mut new_styles,
1012
+ important_rules_changed,
1013
+ );
1014
+
1015
+ // First of all, update the styles.
1016
+ let old_styles = data.set_styles(new_styles);
1017
+
1018
+ let new_primary_style = data.styles.primary.as_ref().unwrap();
1019
+
1020
+ let mut child_restyle_hint = RestyleHint::empty();
1021
+ let is_root = new_primary_style
1022
+ .flags
1023
+ .contains(ComputedValueFlags::IS_ROOT_ELEMENT_STYLE);
1024
+
1025
+ let device = context.shared.stylist.device();
1026
+ let new_font_size = new_primary_style.get_font().clone_font_size();
1027
+ let new_container_type = new_primary_style.clone_container_type();
1028
+
1029
+ let old_style = old_styles.primary.as_ref();
1030
+ let old_font_size = old_style.map(|s| s.get_font().clone_font_size());
1031
+ let font_size_changed = old_font_size.is_none_or(|fs| fs != new_font_size);
1032
+
1033
+ let line_height_likely_changed =
1034
+ font_size_changed || Self::line_height_likely_changed(old_style, new_primary_style);
1035
+
1036
+ // Update root font-relative units. If any of these unit values changed
1037
+ // since last time, ensure that we recascade the entire tree.
1038
+ if is_root {
1039
+ debug_assert!(self.owner_doc_matches_for_testing(device));
1040
+ device.set_root_style(new_primary_style);
1041
+
1042
+ // Update root font size for rem units
1043
+ if font_size_changed {
1044
+ let size = new_font_size.computed_size();
1045
+ device.set_root_font_size(new_primary_style.effective_zoom.unzoom(size.px()));
1046
+ }
1047
+
1048
+ // Update root line height for rlh units
1049
+ if line_height_likely_changed {
1050
+ let new_line_height = device
1051
+ .calc_line_height(
1052
+ new_primary_style.get_font(),
1053
+ new_primary_style.writing_mode,
1054
+ None,
1055
+ )
1056
+ .0;
1057
+ device.set_root_line_height(
1058
+ new_primary_style
1059
+ .effective_zoom
1060
+ .unzoom(new_line_height.px()),
1061
+ );
1062
+ }
1063
+
1064
+ // Update root font metrics for rcap, rch, rex, ric units. Since querying
1065
+ // font metrics can be an expensive call, they are only updated if these
1066
+ // units are used in the document.
1067
+ if device.used_root_font_metrics() && device.update_root_font_metrics() {
1068
+ child_restyle_hint |= RestyleHint::RESTYLE_IF_AFFECTED_BY_WM_OR_ANCESTOR_FONT;
1069
+ }
1070
+ }
1071
+
1072
+ if font_size_changed || line_height_likely_changed {
1073
+ child_restyle_hint |= RestyleHint::RESTYLE_IF_AFFECTED_BY_WM_OR_ANCESTOR_FONT;
1074
+ }
1075
+
1076
+ if context.shared.stylist.quirks_mode() == QuirksMode::Quirks
1077
+ && self.is_html_document_body_element()
1078
+ {
1079
+ // NOTE(emilio): We _could_ handle dynamic changes to it if it
1080
+ // changes and before we reach our children the cascade stops,
1081
+ // but we don't track right now whether we use the document body
1082
+ // color, and nobody else handles that properly anyway.
1083
+ let device = context.shared.stylist.device();
1084
+
1085
+ // Needed for the "inherit from body" quirk.
1086
+ let text_color = new_primary_style.get_inherited_text().clone_color();
1087
+ device.set_body_text_color(text_color);
1088
+ }
1089
+
1090
+ // Don't accumulate damage if we're in the final animation traversal.
1091
+ if context
1092
+ .shared
1093
+ .traversal_flags
1094
+ .contains(TraversalFlags::FinalAnimationTraversal)
1095
+ {
1096
+ return RestyleHint::RECASCADE_SELF;
1097
+ }
1098
+
1099
+ // Also, don't do anything if there was no style.
1100
+ let old_primary_style = match old_styles.primary {
1101
+ Some(s) => s,
1102
+ None => return RestyleHint::RECASCADE_SELF,
1103
+ };
1104
+
1105
+ // Check for changes in writing mode here because we don't care
1106
+ // if the old style didn't exist because that should be resolved
1107
+ // when computing the style from scratch.
1108
+ if !old_primary_style.writing_mode_equals(new_primary_style) {
1109
+ child_restyle_hint |= RestyleHint::RESTYLE_IF_AFFECTED_BY_WM_OR_ANCESTOR_FONT;
1110
+ }
1111
+
1112
+ let old_container_type = old_primary_style.clone_container_type();
1113
+ if old_container_type != new_container_type && !new_container_type.is_size_container_type()
1114
+ {
1115
+ // Stopped being a size container. Re-evaluate container queries and units on all our descendants.
1116
+ // Changes into and between different size containment is handled in `UpdateContainerQueryStyles`.
1117
+ child_restyle_hint |= RestyleHint::restyle_subtree();
1118
+ } else if old_container_type.is_size_container_type()
1119
+ && !old_primary_style.is_display_contents()
1120
+ && new_primary_style.is_display_contents()
1121
+ {
1122
+ // Also re-evaluate when a container gets 'display: contents', since size queries will now evaluate to unknown.
1123
+ // Other displays like 'inline' will keep generating a box, so they are handled in `UpdateContainerQueryStyles`.
1124
+ child_restyle_hint |= RestyleHint::restyle_subtree();
1125
+ }
1126
+
1127
+ child_restyle_hint |= self.accumulate_damage_for(
1128
+ context.shared,
1129
+ &mut data.damage,
1130
+ &old_primary_style,
1131
+ new_primary_style,
1132
+ None,
1133
+ );
1134
+
1135
+ if data.styles.pseudos.is_empty() && old_styles.pseudos.is_empty() {
1136
+ // This is the common case; no need to examine pseudos here.
1137
+ return child_restyle_hint;
1138
+ }
1139
+
1140
+ let pseudo_styles = old_styles
1141
+ .pseudos
1142
+ .as_array()
1143
+ .iter()
1144
+ .zip(data.styles.pseudos.as_array().iter());
1145
+
1146
+ for (i, (old, new)) in pseudo_styles.enumerate() {
1147
+ match (old, new) {
1148
+ (Some(old), Some(new)) => {
1149
+ self.accumulate_damage_for(
1150
+ context.shared,
1151
+ &mut data.damage,
1152
+ old,
1153
+ new,
1154
+ Some(&PseudoElement::from_eager_index(i)),
1155
+ );
1156
+ },
1157
+ (&None, &None) => {},
1158
+ _ => {
1159
+ // It's possible that we're switching from not having
1160
+ // ::before/::after at all to having styles for them but not
1161
+ // actually having a useful pseudo-element. Check for that
1162
+ // case.
1163
+ let pseudo = PseudoElement::from_eager_index(i);
1164
+ let new_pseudo_should_exist =
1165
+ new.as_ref().is_some_and(|s| pseudo.should_exist(s));
1166
+ let old_pseudo_should_exist =
1167
+ old.as_ref().is_some_and(|s| pseudo.should_exist(s));
1168
+ if new_pseudo_should_exist != old_pseudo_should_exist {
1169
+ data.damage |= RestyleDamage::reconstruct();
1170
+ return child_restyle_hint;
1171
+ }
1172
+ },
1173
+ }
1174
+ }
1175
+
1176
+ child_restyle_hint
1177
+ }
1178
+
1179
+ /// Updates the rule nodes without re-running selector matching, using just
1180
+ /// the rule tree.
1181
+ ///
1182
+ /// Returns true if an !important rule was replaced.
1183
+ fn replace_rules(
1184
+ &self,
1185
+ replacements: RestyleHint,
1186
+ context: &mut StyleContext<Self>,
1187
+ cascade_inputs: &mut ElementCascadeInputs,
1188
+ ) -> bool {
1189
+ let mut result = false;
1190
+ result |= self.replace_rules_internal(
1191
+ replacements,
1192
+ context,
1193
+ CascadeVisitedMode::Unvisited,
1194
+ cascade_inputs,
1195
+ );
1196
+ result |= self.replace_rules_internal(
1197
+ replacements,
1198
+ context,
1199
+ CascadeVisitedMode::Visited,
1200
+ cascade_inputs,
1201
+ );
1202
+ result
1203
+ }
1204
+
1205
+ /// Given the old and new style of this element, and whether it's a
1206
+ /// pseudo-element, compute the restyle damage used to determine which
1207
+ /// kind of layout or painting operations we'll need.
1208
+ fn compute_style_difference(
1209
+ &self,
1210
+ old_values: &ComputedValues,
1211
+ new_values: &ComputedValues,
1212
+ pseudo: Option<&PseudoElement>,
1213
+ ) -> StyleDifference {
1214
+ debug_assert!(pseudo.is_none_or(|p| p.is_eager()));
1215
+ #[cfg(feature = "gecko")]
1216
+ {
1217
+ RestyleDamage::compute_style_difference(old_values, new_values)
1218
+ }
1219
+ #[cfg(feature = "servo")]
1220
+ {
1221
+ RestyleDamage::compute_style_difference::<Self>(old_values, new_values)
1222
+ }
1223
+ }
1224
+ }
1225
+
1226
+ impl<E: TElement> MatchMethods for E {}