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,733 @@
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
+ //! Keyframes: https://drafts.csswg.org/css-animations/#keyframes
6
+
7
+ use crate::derives::*;
8
+ use crate::error_reporting::ContextualParseError;
9
+ use crate::parser::{Parse, ParserContext};
10
+ #[cfg(feature = "servo")]
11
+ use crate::properties::PropertyDeclarationIdSet;
12
+ use crate::properties::{
13
+ longhands::{
14
+ animation_composition::single_value::SpecifiedValue as SpecifiedComposition,
15
+ transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction,
16
+ },
17
+ parse_property_declaration_list, LonghandId, PropertyDeclaration, PropertyDeclarationBlock,
18
+ PropertyDeclarationId,
19
+ };
20
+ use crate::shared_lock::{DeepCloneWithLock, SharedRwLock, SharedRwLockReadGuard};
21
+ use crate::shared_lock::{Locked, ToCssWithGuard};
22
+ use crate::stylesheets::rule_parser::VendorPrefix;
23
+ use crate::stylesheets::{CssRuleType, StylesheetContents};
24
+ use crate::values::specified::animation::TimelineRangeName;
25
+ use crate::values::specified::{Number, Percentage};
26
+ use crate::values::{serialize_percentage, KeyframesName};
27
+ use cssparser::{
28
+ parse_one_rule, AtRuleParser, DeclarationParser, Parser, ParserState, QualifiedRuleParser,
29
+ RuleBodyItemParser, RuleBodyParser, SourceLocation, Token,
30
+ };
31
+ use servo_arc::Arc;
32
+ use std::borrow::Cow;
33
+ use std::fmt::{self, Write};
34
+ use style_traits::{
35
+ CssStringWriter, CssWriter, ParseError, ParsingMode, StyleParseErrorKind, ToCss,
36
+ };
37
+
38
+ /// A [`@keyframes`][keyframes] rule.
39
+ ///
40
+ /// [keyframes]: https://drafts.csswg.org/css-animations/#keyframes
41
+ #[derive(Debug, ToShmem)]
42
+ pub struct KeyframesRule {
43
+ /// The name of the current animation.
44
+ pub name: KeyframesName,
45
+ /// The keyframes specified for this CSS rule.
46
+ pub keyframes: Vec<Arc<Locked<Keyframe>>>,
47
+ /// Vendor prefix type the @keyframes has.
48
+ pub vendor_prefix: Option<VendorPrefix>,
49
+ /// The line and column of the rule's source code.
50
+ pub source_location: SourceLocation,
51
+ }
52
+
53
+ impl ToCssWithGuard for KeyframesRule {
54
+ // Serialization of KeyframesRule is not specced.
55
+ fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result {
56
+ dest.write_str("@keyframes ")?;
57
+ self.name.to_css(&mut CssWriter::new(dest))?;
58
+ dest.write_str(" {")?;
59
+ let iter = self.keyframes.iter();
60
+ for lock in iter {
61
+ dest.write_str("\n")?;
62
+ let keyframe = lock.read_with(guard);
63
+ keyframe.to_css(guard, dest)?;
64
+ }
65
+ dest.write_str("\n}")
66
+ }
67
+ }
68
+
69
+ impl KeyframesRule {
70
+ /// Returns the index of the last keyframe that matches the given selector.
71
+ /// If the selector is not valid, or no keyframe is found, returns None.
72
+ ///
73
+ /// Related spec:
74
+ /// <https://drafts.csswg.org/css-animations-1/#interface-csskeyframesrule-findrule>
75
+ pub fn find_rule(&self, guard: &SharedRwLockReadGuard, selector: &str) -> Option<usize> {
76
+ if let Ok(selector) = Parser::new(selector).parse_entirely(KeyframeSelectors::parse) {
77
+ for (i, keyframe) in self.keyframes.iter().enumerate().rev() {
78
+ if keyframe.read_with(guard).selector == selector {
79
+ return Some(i);
80
+ }
81
+ }
82
+ }
83
+ None
84
+ }
85
+ }
86
+
87
+ impl DeepCloneWithLock for KeyframesRule {
88
+ fn deep_clone_with_lock(&self, lock: &SharedRwLock, guard: &SharedRwLockReadGuard) -> Self {
89
+ KeyframesRule {
90
+ name: self.name.clone(),
91
+ keyframes: self
92
+ .keyframes
93
+ .iter()
94
+ .map(|x| Arc::new(lock.wrap(x.read_with(guard).deep_clone_with_lock(lock, guard))))
95
+ .collect(),
96
+ vendor_prefix: self.vendor_prefix.clone(),
97
+ source_location: self.source_location,
98
+ }
99
+ }
100
+ }
101
+
102
+ /// A number from 0 to 1, indicating the percentage of the animation when this
103
+ /// keyframe should run.
104
+ #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToShmem)]
105
+ pub struct KeyframePercentage(pub f32);
106
+
107
+ impl ::std::cmp::Ord for KeyframePercentage {
108
+ #[inline]
109
+ fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
110
+ // We know we have a number from 0 to 1, so unwrap() here is safe.
111
+ self.0.partial_cmp(&other.0).unwrap()
112
+ }
113
+ }
114
+
115
+ impl ::std::cmp::Eq for KeyframePercentage {}
116
+
117
+ impl ToCss for KeyframePercentage {
118
+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
119
+ where
120
+ W: Write,
121
+ {
122
+ serialize_percentage(self.0, dest)
123
+ }
124
+ }
125
+
126
+ impl KeyframePercentage {
127
+ /// Trivially constructs a new `KeyframePercentage`.
128
+ #[inline]
129
+ pub fn new(value: f32) -> KeyframePercentage {
130
+ KeyframePercentage(value)
131
+ }
132
+
133
+ fn parse(input: &mut Parser) -> Result<KeyframePercentage, ParseError> {
134
+ let token = input.next()?.clone();
135
+ match token {
136
+ Token::Ident(ref identifier) if identifier.as_ref().eq_ignore_ascii_case("from") => {
137
+ Ok(KeyframePercentage::new(0.))
138
+ },
139
+ Token::Ident(ref identifier) if identifier.as_ref().eq_ignore_ascii_case("to") => {
140
+ Ok(KeyframePercentage::new(1.))
141
+ },
142
+ Token::Percentage {
143
+ unit_value: percentage,
144
+ ..
145
+ } if (0. ..=1.).contains(&percentage) => Ok(KeyframePercentage::new(percentage)),
146
+ _ => Err(ParseError::unexpected_token()),
147
+ }
148
+ }
149
+ }
150
+
151
+ /// A single `<keyframe-selector>`:
152
+ /// `<keyframe-selector> = from | to | <percentage [0,100]> | <timeline-range-name> <percentage>`
153
+ /// It could be a percentage, from/to, or a timeline range name together with a percentage.
154
+ /// https://drafts.csswg.org/scroll-animations-1/#named-range-keyframes
155
+ #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss, ToShmem)]
156
+ pub struct KeyframeSelector {
157
+ /// The named timeline range name component of the selector. If it is omitted, we use
158
+ /// `TimelineRangeName::None`. Note that `TimelineRangeName::Normal` is not used for the
159
+ /// selector.
160
+ pub range_name: TimelineRangeName,
161
+ /// The percentage component of the selector. It is a percentage or a from/to symbol, which is
162
+ /// converted at parse time to percentage.
163
+ pub percentage: KeyframePercentage,
164
+ }
165
+
166
+ impl KeyframeSelector {
167
+ /// Returns Self as a percentage.
168
+ fn from_percentage(percentage: KeyframePercentage) -> Self {
169
+ debug_assert!(percentage.0 >= 0. && percentage.0 <= 1.);
170
+ KeyframeSelector {
171
+ range_name: TimelineRangeName::None,
172
+ percentage,
173
+ }
174
+ }
175
+
176
+ /// Parse a keyframe selector from CSS input.
177
+ pub fn parse_internal(input: &mut Parser) -> Result<Self, ParseError> {
178
+ // `from | to | <percentage [0,100]>`
179
+ if let Ok(percentage) = input.try_parse(KeyframePercentage::parse) {
180
+ return Ok(Self::from_percentage(percentage));
181
+ }
182
+
183
+ // We parse the the extension of keyframe selector for scroll-driven animation.
184
+ if !crate::pref!("layout.css.scroll-driven-animations.enabled") {
185
+ return Err(ParseError::custom(StyleParseErrorKind::UnspecifiedError));
186
+ }
187
+
188
+ // `<timeline-range-name> <percentage>`
189
+ // Note that <percentage> could be out of [0,100].
190
+ Ok(Self {
191
+ range_name: TimelineRangeName::parse(input)?,
192
+ percentage: KeyframePercentage::new(input.expect_percentage()?),
193
+ })
194
+ }
195
+ }
196
+
197
+ impl Parse for KeyframeSelector {
198
+ fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ParseError> {
199
+ KeyframeSelector::parse_internal(input)
200
+ }
201
+ }
202
+
203
+ /// A list of `<keyframe-selector>`s.
204
+ #[derive(Clone, Debug, Eq, PartialEq, ToCss, ToShmem)]
205
+ #[css(comma)]
206
+ pub struct KeyframeSelectors(#[css(iterable)] Vec<KeyframeSelector>);
207
+
208
+ impl KeyframeSelectors {
209
+ /// A dummy public function so we can write a unit test for this.
210
+ pub fn new_for_unit_testing(percentages: Vec<KeyframePercentage>) -> KeyframeSelectors {
211
+ KeyframeSelectors(
212
+ percentages
213
+ .into_iter()
214
+ .map(KeyframeSelector::from_percentage)
215
+ .collect(),
216
+ )
217
+ }
218
+
219
+ /// Parse the keyframe selectors from CSS input.
220
+ pub fn parse(input: &mut Parser) -> Result<Self, ParseError> {
221
+ input
222
+ .parse_comma_separated(KeyframeSelector::parse_internal)
223
+ .map(KeyframeSelectors)
224
+ }
225
+ }
226
+
227
+ /// A keyframe.
228
+ #[derive(Debug, ToShmem)]
229
+ pub struct Keyframe {
230
+ /// The selector this keyframe was specified from.
231
+ pub selector: KeyframeSelectors,
232
+
233
+ /// The declaration block that was declared inside this keyframe.
234
+ ///
235
+ /// Note that `!important` rules in keyframes don't apply, but we keep this
236
+ /// `Arc` just for convenience.
237
+ pub block: Arc<Locked<PropertyDeclarationBlock>>,
238
+
239
+ /// The line and column of the rule's source code.
240
+ pub source_location: SourceLocation,
241
+ }
242
+
243
+ impl ToCssWithGuard for Keyframe {
244
+ fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result {
245
+ self.selector.to_css(&mut CssWriter::new(dest))?;
246
+ dest.write_str(" { ")?;
247
+ self.block.read_with(guard).to_css(dest)?;
248
+ dest.write_str(" }")?;
249
+ Ok(())
250
+ }
251
+ }
252
+
253
+ impl Keyframe {
254
+ /// Parse a CSS keyframe.
255
+ pub fn parse(
256
+ css: &str,
257
+ parent_stylesheet_contents: &StylesheetContents,
258
+ lock: &SharedRwLock,
259
+ ) -> Result<Arc<Locked<Self>>, ParseError> {
260
+ let url_data = &parent_stylesheet_contents.url_data;
261
+ let namespaces = &parent_stylesheet_contents.namespaces;
262
+ let mut context = ParserContext::new(
263
+ parent_stylesheet_contents.origin,
264
+ url_data,
265
+ Some(CssRuleType::Keyframe),
266
+ ParsingMode::DEFAULT,
267
+ parent_stylesheet_contents.quirks_mode,
268
+ Cow::Borrowed(namespaces),
269
+ None,
270
+ None,
271
+ /* attr_taint */ Default::default(),
272
+ );
273
+ let mut input = Parser::new(css);
274
+
275
+ let mut rule_parser = KeyframeListParser {
276
+ context: &mut context,
277
+ shared_lock: lock,
278
+ };
279
+ parse_one_rule(&mut input, &mut rule_parser)
280
+ }
281
+ }
282
+
283
+ impl DeepCloneWithLock for Keyframe {
284
+ /// Deep clones this Keyframe.
285
+ fn deep_clone_with_lock(&self, lock: &SharedRwLock, guard: &SharedRwLockReadGuard) -> Keyframe {
286
+ Keyframe {
287
+ selector: self.selector.clone(),
288
+ block: Arc::new(lock.wrap(self.block.read_with(guard).clone())),
289
+ source_location: self.source_location,
290
+ }
291
+ }
292
+ }
293
+
294
+ /// A keyframes step value. This can be a synthetised keyframes animation, that
295
+ /// is, one autogenerated from the current computed values, or a list of
296
+ /// declarations to apply.
297
+ ///
298
+ /// TODO: Find a better name for this?
299
+ #[derive(Clone, Debug, MallocSizeOf)]
300
+ pub enum KeyframesStepValue {
301
+ /// A step formed by a declaration block specified by the CSS.
302
+ Declarations {
303
+ /// The declaration block per se.
304
+ #[cfg_attr(
305
+ feature = "gecko",
306
+ ignore_malloc_size_of = "XXX: Primary ref, measure if DMD says it's worthwhile"
307
+ )]
308
+ #[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")]
309
+ block: Arc<Locked<PropertyDeclarationBlock>>,
310
+ },
311
+ /// A synthetic step computed from the current computed values at the time
312
+ /// of the animation.
313
+ ComputedValues,
314
+ }
315
+
316
+ /// A single step from a keyframe animation.
317
+ #[derive(Clone, Debug, MallocSizeOf)]
318
+ pub struct KeyframesStep {
319
+ /// The offset of the animation duration when this step starts.
320
+ pub start_offset: KeyframeSelector,
321
+ /// Declarations that will determine the final style during the step, or
322
+ /// `ComputedValues` if this is an autogenerated step.
323
+ pub value: KeyframesStepValue,
324
+ /// Whether an animation-timing-function declaration exists in the list of
325
+ /// declarations.
326
+ ///
327
+ /// This is used to know when to override the keyframe animation style.
328
+ pub declared_timing_function: bool,
329
+ /// Whether an animation-composition declaration exists in the list of
330
+ /// declarations.
331
+ ///
332
+ /// This is used to know when to override the keyframe animation style.
333
+ pub declared_composition: bool,
334
+ }
335
+
336
+ impl KeyframesStep {
337
+ #[inline]
338
+ fn new(
339
+ start_offset: KeyframeSelector,
340
+ value: KeyframesStepValue,
341
+ guard: &SharedRwLockReadGuard,
342
+ ) -> Self {
343
+ let mut declared_timing_function = false;
344
+ let mut declared_composition = false;
345
+ if let KeyframesStepValue::Declarations { ref block } = value {
346
+ for prop_decl in block.read_with(guard).declarations().iter() {
347
+ match *prop_decl {
348
+ PropertyDeclaration::AnimationTimingFunction(..) => {
349
+ declared_timing_function = true;
350
+ },
351
+ PropertyDeclaration::AnimationComposition(..) => {
352
+ declared_composition = true;
353
+ },
354
+ _ => continue,
355
+ }
356
+ // Don't need to continue the loop if both are found.
357
+ if declared_timing_function && declared_composition {
358
+ break;
359
+ }
360
+ }
361
+ }
362
+
363
+ KeyframesStep {
364
+ start_offset,
365
+ value,
366
+ declared_timing_function,
367
+ declared_composition,
368
+ }
369
+ }
370
+
371
+ /// Return specified PropertyDeclaration.
372
+ #[inline]
373
+ fn get_declared_property<'a>(
374
+ &'a self,
375
+ guard: &'a SharedRwLockReadGuard,
376
+ property: LonghandId,
377
+ ) -> Option<&'a PropertyDeclaration> {
378
+ match self.value {
379
+ KeyframesStepValue::Declarations { ref block } => {
380
+ let guard = block.read_with(guard);
381
+ let (declaration, _) = guard
382
+ .get(PropertyDeclarationId::Longhand(property))
383
+ .unwrap();
384
+ match *declaration {
385
+ PropertyDeclaration::CSSWideKeyword(..) => None,
386
+ // FIXME: Bug 1710735: Support css variable in @keyframes rule.
387
+ PropertyDeclaration::WithVariables(..) => None,
388
+ _ => Some(declaration),
389
+ }
390
+ },
391
+ KeyframesStepValue::ComputedValues => {
392
+ panic!("Shouldn't happen to set this property in missing keyframes")
393
+ },
394
+ }
395
+ }
396
+
397
+ /// Return specified TransitionTimingFunction if this KeyframesSteps has
398
+ /// 'animation-timing-function'.
399
+ pub fn get_animation_timing_function(
400
+ &self,
401
+ guard: &SharedRwLockReadGuard,
402
+ ) -> Option<SpecifiedTimingFunction> {
403
+ if !self.declared_timing_function {
404
+ return None;
405
+ }
406
+
407
+ self.get_declared_property(guard, LonghandId::AnimationTimingFunction)
408
+ .map(|decl| {
409
+ match *decl {
410
+ PropertyDeclaration::AnimationTimingFunction(ref value) => {
411
+ // Use the first value
412
+ value.0[0].clone()
413
+ },
414
+ _ => unreachable!("Unexpected PropertyDeclaration"),
415
+ }
416
+ })
417
+ }
418
+
419
+ /// Return CompositeOperation if this KeyframesSteps has 'animation-composition'.
420
+ pub fn get_animation_composition(
421
+ &self,
422
+ guard: &SharedRwLockReadGuard,
423
+ ) -> Option<SpecifiedComposition> {
424
+ if !self.declared_composition {
425
+ return None;
426
+ }
427
+
428
+ self.get_declared_property(guard, LonghandId::AnimationComposition)
429
+ .map(|decl| {
430
+ match *decl {
431
+ PropertyDeclaration::AnimationComposition(ref value) => {
432
+ // Use the first value
433
+ value.0[0]
434
+ },
435
+ _ => unreachable!("Unexpected PropertyDeclaration"),
436
+ }
437
+ })
438
+ }
439
+ }
440
+
441
+ /// This structure represents a list of animation steps computed from the list
442
+ /// of keyframes, in order.
443
+ ///
444
+ /// It only takes into account animable properties.
445
+ #[derive(Clone, Debug, MallocSizeOf)]
446
+ pub struct KeyframesAnimation {
447
+ /// The different steps of the animation.
448
+ pub steps: Vec<KeyframesStep>,
449
+ /// The different steps of the animation. Those steps are only for keyframe selectors with
450
+ /// timeline range names. We intentionally use a different vector because it is unsorted and we
451
+ /// would like to maintain its specified order when grouping them. Also, per spec, the computed
452
+ /// order requires us to pull percentage-only keyframes to the front and sort them, so using a
453
+ /// separate vector makes it easier to group them to maintain the computed order.
454
+ /// https://drafts.csswg.org/css-animations-2/#keyframe-processing
455
+ /// https://github.com/w3c/csswg-drafts/issues/8507
456
+ pub steps_with_range_name: Vec<KeyframesStep>,
457
+ /// The properties that change in this animation.
458
+ #[cfg(feature = "servo")]
459
+ pub properties_changed: PropertyDeclarationIdSet,
460
+ /// Vendor prefix type the @keyframes has.
461
+ pub vendor_prefix: Option<VendorPrefix>,
462
+ }
463
+
464
+ #[cfg(feature = "servo")]
465
+ type AnimatedPropertiesInner = PropertyDeclarationIdSet;
466
+ #[cfg(feature = "gecko")]
467
+ type AnimatedPropertiesInner = bool;
468
+
469
+ #[derive(Default)]
470
+ struct AnimatedProperties(AnimatedPropertiesInner);
471
+
472
+ #[cfg(feature = "servo")]
473
+ impl AnimatedProperties {
474
+ const CAN_STOP_AFTER_FINDING_PROPERTY: bool = false;
475
+
476
+ #[inline]
477
+ fn insert_animated_property(&mut self, declaration_id: PropertyDeclarationId) {
478
+ self.0.insert(declaration_id);
479
+ }
480
+
481
+ #[inline]
482
+ fn is_empty(&self) -> bool {
483
+ self.0.is_empty()
484
+ }
485
+ }
486
+
487
+ #[cfg(feature = "gecko")]
488
+ impl AnimatedProperties {
489
+ const CAN_STOP_AFTER_FINDING_PROPERTY: bool = true;
490
+
491
+ #[inline]
492
+ fn insert_animated_property(&mut self, _: PropertyDeclarationId) {
493
+ self.0 = true;
494
+ }
495
+
496
+ #[inline]
497
+ fn is_empty(&self) -> bool {
498
+ !self.0
499
+ }
500
+ }
501
+
502
+ /// Returns an `AnimatedProperties` for the animated properties in a keyframes animation.
503
+ /// In Gecko that only has a bool tracking if there is any such property, while Servo
504
+ /// tracks the set of all these properties.
505
+ fn get_animated_properties(
506
+ keyframes: &[Arc<Locked<Keyframe>>],
507
+ guard: &SharedRwLockReadGuard,
508
+ ) -> AnimatedProperties {
509
+ let mut animated_properties = AnimatedProperties::default();
510
+
511
+ // NB: declarations are already deduplicated, so we don't have to check for
512
+ // it here.
513
+ for keyframe in keyframes {
514
+ let keyframe = keyframe.read_with(guard);
515
+ let block = keyframe.block.read_with(guard);
516
+ // CSS Animations spec clearly defines that properties with !important
517
+ // in keyframe rules are invalid and ignored, but it's still ambiguous
518
+ // whether we should drop the !important properties or retain the
519
+ // properties when they are set via CSSOM. So we assume there might
520
+ // be properties with !important in keyframe rules here.
521
+ // See the spec issue https://github.com/w3c/csswg-drafts/issues/1824
522
+ for declaration in block.normal_declaration_iter() {
523
+ let declaration_id = declaration.id();
524
+
525
+ if declaration_id == PropertyDeclarationId::Longhand(LonghandId::Display)
526
+ && !crate::pref!("layout.css.display-animations.enabled")
527
+ {
528
+ continue;
529
+ }
530
+
531
+ if !declaration_id.is_animatable() {
532
+ continue;
533
+ }
534
+
535
+ animated_properties.insert_animated_property(declaration_id);
536
+ if AnimatedProperties::CAN_STOP_AFTER_FINDING_PROPERTY {
537
+ return animated_properties;
538
+ }
539
+ }
540
+ }
541
+
542
+ animated_properties
543
+ }
544
+
545
+ impl KeyframesAnimation {
546
+ /// Create a keyframes animation from a given list of keyframes.
547
+ ///
548
+ /// This will return a keyframe animation with empty steps if the list of
549
+ /// keyframes is empty, or there are no animated properties obtained from
550
+ /// the keyframes.
551
+ ///
552
+ /// Otherwise, this will compute and sort the steps used for the animation,
553
+ /// and return the animation object.
554
+ pub fn from_keyframes(
555
+ keyframes: &[Arc<Locked<Keyframe>>],
556
+ vendor_prefix: Option<VendorPrefix>,
557
+ guard: &SharedRwLockReadGuard,
558
+ ) -> Self {
559
+ let mut result = KeyframesAnimation {
560
+ steps: vec![],
561
+ steps_with_range_name: vec![],
562
+ #[cfg(feature = "servo")]
563
+ properties_changed: PropertyDeclarationIdSet::default(),
564
+ vendor_prefix,
565
+ };
566
+
567
+ if keyframes.is_empty() {
568
+ return result;
569
+ }
570
+
571
+ let animated_properties = get_animated_properties(keyframes, guard);
572
+ if animated_properties.is_empty() {
573
+ return result;
574
+ }
575
+ #[cfg(feature = "servo")] {
576
+ result.properties_changed = animated_properties.0;
577
+ }
578
+
579
+ // The steps with percentage only.
580
+ let mut steps = vec![];
581
+
582
+ for keyframe in keyframes {
583
+ let keyframe = keyframe.read_with(guard);
584
+ for selector in keyframe.selector.0.iter() {
585
+ let step = KeyframesStep::new(
586
+ *selector,
587
+ KeyframesStepValue::Declarations {
588
+ block: keyframe.block.clone(),
589
+ },
590
+ guard,
591
+ );
592
+
593
+ if !selector.range_name.is_none() {
594
+ result.steps_with_range_name.push(step);
595
+ } else {
596
+ steps.push(step);
597
+ }
598
+ }
599
+ }
600
+
601
+ // Sort by the percentage, so we can easily find a frame. Note that we only sort the
602
+ // keyframes with percentage since we have to maintain the order of keyframes with
603
+ // TimelineRange as specified.
604
+ steps.sort_by_key(|step| step.start_offset.percentage);
605
+
606
+ // Prepend autogenerated keyframes if appropriate.
607
+ #[cfg(feature = "servo")] {
608
+ if steps.is_empty() || steps[0].start_offset.percentage.0 != 0. {
609
+ steps.insert(
610
+ 0,
611
+ KeyframesStep::new(
612
+ KeyframeSelector::from_percentage(KeyframePercentage::new(0.)),
613
+ KeyframesStepValue::ComputedValues,
614
+ guard,
615
+ ),
616
+ );
617
+ }
618
+ if steps.last().unwrap().start_offset.percentage.0 != 1. {
619
+ steps.push(KeyframesStep::new(
620
+ KeyframeSelector::from_percentage(KeyframePercentage::new(1.)),
621
+ KeyframesStepValue::ComputedValues,
622
+ guard,
623
+ ));
624
+ }
625
+ }
626
+
627
+ result.steps = steps;
628
+ result
629
+ }
630
+ }
631
+
632
+ /// Parses a keyframes list, like:
633
+ /// 0%, 50% {
634
+ /// width: 50%;
635
+ /// }
636
+ ///
637
+ /// 40%, 60%, 100% {
638
+ /// width: 100%;
639
+ /// }
640
+ struct KeyframeListParser<'a, 'b> {
641
+ context: &'a mut ParserContext<'b>,
642
+ shared_lock: &'a SharedRwLock,
643
+ }
644
+
645
+ /// Parses a keyframe list from CSS input.
646
+ pub fn parse_keyframe_list<'a>(
647
+ context: &mut ParserContext<'a>,
648
+ input: &mut Parser,
649
+ shared_lock: &SharedRwLock,
650
+ ) -> Vec<Arc<Locked<Keyframe>>> {
651
+ let mut parser = KeyframeListParser {
652
+ context,
653
+ shared_lock,
654
+ };
655
+ RuleBodyParser::new(input, &mut parser)
656
+ .filter_map(Result::ok)
657
+ .collect()
658
+ }
659
+
660
+ impl<'a, 'b, 'i> AtRuleParser<'i> for KeyframeListParser<'a, 'b> {
661
+ type Prelude = ();
662
+ type AtRule = Arc<Locked<Keyframe>>;
663
+ type Error = StyleParseErrorKind;
664
+ }
665
+
666
+ impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeListParser<'a, 'b> {
667
+ type Declaration = Arc<Locked<Keyframe>>;
668
+ type Error = StyleParseErrorKind;
669
+ }
670
+
671
+ impl<'a, 'b, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a, 'b> {
672
+ type Prelude = KeyframeSelectors;
673
+ type QualifiedRule = Arc<Locked<Keyframe>>;
674
+ type Error = StyleParseErrorKind;
675
+
676
+ fn parse_prelude(&mut self, input: &mut Parser<'i>) -> Result<Self::Prelude, ParseError> {
677
+ let start_position = input.position();
678
+ let start_location = input.current_source_location();
679
+ KeyframeSelectors::parse(input).inspect_err(|e| {
680
+ let error = ContextualParseError::InvalidKeyframeRule(
681
+ input.slice_from(start_position),
682
+ e.clone(),
683
+ );
684
+ self.context.log_css_error(start_location, error);
685
+ })
686
+ }
687
+
688
+ fn parse_block(
689
+ &mut self,
690
+ selector: Self::Prelude,
691
+ start: &ParserState,
692
+ input: &mut Parser<'i>,
693
+ ) -> Result<Self::QualifiedRule, ParseError> {
694
+ let block = self.context.nest_for_rule(CssRuleType::Keyframe, |p| {
695
+ parse_property_declaration_list(p, input, &[])
696
+ });
697
+ Ok(Arc::new(self.shared_lock.wrap(Keyframe {
698
+ selector,
699
+ block: Arc::new(self.shared_lock.wrap(block)),
700
+ source_location: start.source_location(),
701
+ })))
702
+ }
703
+ }
704
+
705
+ impl<'a, 'b, 'i> RuleBodyItemParser<'i, Arc<Locked<Keyframe>>, StyleParseErrorKind>
706
+ for KeyframeListParser<'a, 'b>
707
+ {
708
+ fn parse_qualified(&self) -> bool {
709
+ true
710
+ }
711
+ fn parse_declarations(&self) -> bool {
712
+ false
713
+ }
714
+ }
715
+
716
+ /// The Keyframe offset for Web Animations. Since we support double value from JS, so we need to
717
+ /// include a number for it as well.
718
+ // Note: we don't do the range check at parse time for Web animations.
719
+ // Per spec (step 7 in [1]), we check the range of the offset in a separate step and throw a
720
+ // TypeError if needed. That's why we would like to handle Percentage separately and we don't check
721
+ // the range of Number and Percentage.
722
+ //
723
+ // [1] https://drafts.csswg.org/web-animations-1/#process-a-keyframes-argument
724
+ #[derive(Debug, Parse)]
725
+ pub enum KeyframeOffset {
726
+ /// The double value, e.g. 0.5.
727
+ Number(Number),
728
+ /// The percentage (including calc() percentage), e.g. 10%, calc(50%).
729
+ // FIXME: Bug 2007780. Support length and percentage.
730
+ Percentage(Percentage),
731
+ /// The pair of TimelineRangeName and percentage.
732
+ KeyframeSelector(KeyframeSelector),
733
+ }