blitz-pdf 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (370) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +391 -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,996 @@
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
+ //! A query condition:
6
+ //!
7
+ //! https://drafts.csswg.org/mediaqueries-4/#typedef-media-condition
8
+ //! https://drafts.csswg.org/css-contain-3/#typedef-container-condition
9
+
10
+ use super::{FeatureFlags, FeatureType, QueryFeatureExpression, QueryStyleRange};
11
+ use crate::computed_value_flags::ComputedValueFlags;
12
+ use crate::context::QuirksMode;
13
+ use crate::custom_properties;
14
+ use crate::derives::*;
15
+ use crate::dom::AttributeTracker;
16
+ use crate::properties::CSSWideKeyword;
17
+ use crate::properties_and_values::rule::Descriptors as PropertyDescriptors;
18
+ use crate::properties_and_values::value::{
19
+ AllowComputationallyDependent, ComputedValue as ComputedRegisteredValue,
20
+ SpecifiedValue as SpecifiedRegisteredValue,
21
+ };
22
+ use crate::stylesheets::container_rule::AttrReferenceSet;
23
+ use crate::stylesheets::{CssRuleType, CustomMediaEvaluator, Origin, UrlExtraData};
24
+ use crate::stylist::Stylist;
25
+ use crate::values::{computed, AtomString, DashedIdent};
26
+ use crate::{error_reporting::ContextualParseError, parser::Parse, parser::ParserContext};
27
+ use cssparser::{
28
+ match_ignore_ascii_case, parse_important, Parser, SourceLocation, SourcePosition, Token,
29
+ };
30
+ use selectors::kleene_value::KleeneValue;
31
+ use servo_arc::Arc;
32
+ use std::fmt::{self, Write};
33
+ use style_traits::{CssWriter, ParseError, ParsingMode, StyleParseErrorKind, ToCss};
34
+
35
+ /// A binary `and` or `or` operator.
36
+ #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToCss, ToShmem)]
37
+ #[allow(missing_docs)]
38
+ pub enum Operator {
39
+ And,
40
+ Or,
41
+ }
42
+
43
+ /// Whether to allow an `or` condition or not during parsing.
44
+ #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss)]
45
+ enum AllowOr {
46
+ Yes,
47
+ No,
48
+ }
49
+
50
+ #[derive(Clone, Debug, PartialEq, ToShmem)]
51
+ enum StyleFeatureValue {
52
+ Value(Option<Arc<custom_properties::SpecifiedValue>>),
53
+ Keyword(CSSWideKeyword),
54
+ }
55
+
56
+ /// Trait for query elements that parse a series of conditions separated by
57
+ /// AND or OR operators, or prefixed with NOT.
58
+ ///
59
+ /// This is used by both QueryCondition and StyleQuery as they support similar
60
+ /// syntax for combining multiple conditions with a boolean operator.
61
+ trait OperationParser: Sized {
62
+ /// https://drafts.csswg.org/mediaqueries-5/#typedef-media-condition or
63
+ /// https://drafts.csswg.org/mediaqueries-5/#typedef-media-condition-without-or
64
+ /// (depending on `allow_or`).
65
+ fn parse_internal(
66
+ context: &ParserContext,
67
+ input: &mut Parser,
68
+ feature_type: FeatureType,
69
+ allow_or: AllowOr,
70
+ ) -> Result<Self, ParseError> {
71
+ if input.try_parse(|i| i.expect_ident_matching("not")).is_ok() {
72
+ let inner_condition = Self::parse_in_parens(context, input, feature_type)?;
73
+ return Ok(Self::new_not(Box::new(inner_condition)));
74
+ }
75
+
76
+ let first_condition = Self::parse_in_parens(context, input, feature_type)?;
77
+ let operator = match input.try_parse(Operator::parse) {
78
+ Ok(op) => op,
79
+ Err(..) => return Ok(first_condition),
80
+ };
81
+
82
+ if allow_or == AllowOr::No && operator == Operator::Or {
83
+ return Err(ParseError::custom(StyleParseErrorKind::UnspecifiedError));
84
+ }
85
+
86
+ let mut conditions = vec![];
87
+ conditions.push(first_condition);
88
+ conditions.push(Self::parse_in_parens(context, input, feature_type)?);
89
+
90
+ let delim = match operator {
91
+ Operator::And => "and",
92
+ Operator::Or => "or",
93
+ };
94
+
95
+ loop {
96
+ if input.try_parse(|i| i.expect_ident_matching(delim)).is_err() {
97
+ return Ok(Self::new_operation(conditions.into_boxed_slice(), operator));
98
+ }
99
+
100
+ conditions.push(Self::parse_in_parens(context, input, feature_type)?);
101
+ }
102
+ }
103
+
104
+ // Parse a condition in parentheses, or `<general-enclosed>`.
105
+ fn parse_in_parens(
106
+ context: &ParserContext,
107
+ input: &mut Parser,
108
+ feature_type: FeatureType,
109
+ ) -> Result<Self, ParseError>;
110
+
111
+ // Helpers to create the appropriate enum variant of the implementing type:
112
+ // Create a Not result that encapsulates the `inner` condition.
113
+ fn new_not(inner: Box<Self>) -> Self;
114
+
115
+ // Create an Operation result with the given list of `conditions` using `operator`.
116
+ fn new_operation(conditions: Box<[Self]>, operator: Operator) -> Self;
117
+ }
118
+
119
+ fn try_parse_block<'i, T, F>(
120
+ context: &ParserContext,
121
+ input: &mut Parser<'i>,
122
+ start: SourcePosition,
123
+ start_location: SourceLocation,
124
+ parse: F,
125
+ ) -> Option<T>
126
+ where
127
+ F: FnOnce(&mut Parser<'i>) -> Result<T, ParseError>,
128
+ {
129
+ input
130
+ .try_parse(|input| {
131
+ let result = input.parse_nested_block(parse);
132
+ if let Err(ref e) = result {
133
+ if context.error_reporting_enabled() {
134
+ // We're about to swallow the error in a `<general-enclosed>` condition, so report
135
+ // it while we can.
136
+ let error =
137
+ ContextualParseError::InvalidMediaRule(input.slice_from(start), e.clone());
138
+ context.log_css_error(start_location, error);
139
+ }
140
+ }
141
+ result
142
+ })
143
+ .ok()
144
+ }
145
+
146
+ /// https://drafts.csswg.org/css-conditional-5/#typedef-style-query
147
+ #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
148
+ pub enum StyleQuery {
149
+ /// A negation of a condition.
150
+ Not(Box<StyleQuery>),
151
+ /// A set of joint operations.
152
+ Operation(Box<[StyleQuery]>, Operator),
153
+ /// A condition wrapped in parenthesis.
154
+ InParens(Box<StyleQuery>),
155
+ /// A feature query (`--foo: bar` or just `--foo`).
156
+ Feature(StyleFeature),
157
+ /// An unknown "general-enclosed" term.
158
+ GeneralEnclosed(String),
159
+ }
160
+
161
+ impl ToCss for StyleQuery {
162
+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
163
+ where
164
+ W: fmt::Write,
165
+ {
166
+ match *self {
167
+ StyleQuery::Not(ref c) => {
168
+ dest.write_str("not ")?;
169
+ c.maybe_parenthesized(dest)
170
+ },
171
+ StyleQuery::Operation(ref list, op) => {
172
+ let mut iter = list.iter();
173
+ let item = iter.next().unwrap();
174
+ item.maybe_parenthesized(dest)?;
175
+ for item in iter {
176
+ dest.write_char(' ')?;
177
+ op.to_css(dest)?;
178
+ dest.write_char(' ')?;
179
+ item.maybe_parenthesized(dest)?;
180
+ }
181
+ Ok(())
182
+ },
183
+ StyleQuery::InParens(ref c) => match &**c {
184
+ StyleQuery::Feature(_) | StyleQuery::InParens(_) => {
185
+ dest.write_char('(')?;
186
+ c.to_css(dest)?;
187
+ dest.write_char(')')
188
+ },
189
+ _ => c.to_css(dest),
190
+ },
191
+ StyleQuery::Feature(ref f) => f.to_css(dest),
192
+ StyleQuery::GeneralEnclosed(ref s) => dest.write_str(s),
193
+ }
194
+ }
195
+ }
196
+
197
+ impl StyleQuery {
198
+ // Helper for to_css when handling values within boolean operators:
199
+ // GeneralEnclosed includes its parens in the string, so we don't need to
200
+ // wrap the value with an additional set here.
201
+ fn maybe_parenthesized<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
202
+ where
203
+ W: fmt::Write,
204
+ {
205
+ if let StyleQuery::GeneralEnclosed(s) = self {
206
+ dest.write_str(s)
207
+ } else {
208
+ dest.write_char('(')?;
209
+ self.to_css(dest)?;
210
+ dest.write_char(')')
211
+ }
212
+ }
213
+
214
+ fn parse(
215
+ context: &ParserContext,
216
+ input: &mut Parser,
217
+ feature_type: FeatureType,
218
+ ) -> Result<Self, ParseError> {
219
+ if !crate::pref!("layout.css.style-queries.enabled")
220
+ || feature_type != FeatureType::Container
221
+ {
222
+ return Err(ParseError::custom(StyleParseErrorKind::UnspecifiedError));
223
+ }
224
+
225
+ if let Ok(feature) = input.try_parse(|input| StyleFeature::parse(context, input)) {
226
+ return Ok(Self::Feature(feature));
227
+ }
228
+
229
+ let inner = Self::parse_internal(context, input, feature_type, AllowOr::Yes)?;
230
+ Ok(Self::InParens(Box::new(inner)))
231
+ }
232
+
233
+ fn parse_in_parenthesis_block(
234
+ context: &ParserContext,
235
+ input: &mut Parser,
236
+ ) -> Result<Self, ParseError> {
237
+ // Base case. Make sure to preserve this error as it's more generally
238
+ // relevant.
239
+ let feature_error = match input.try_parse(|input| StyleFeature::parse(context, input)) {
240
+ Ok(feature) => return Ok(Self::Feature(feature)),
241
+ Err(e) => e,
242
+ };
243
+
244
+ if let Ok(inner) = Self::parse(context, input, FeatureType::Container) {
245
+ return Ok(inner);
246
+ }
247
+
248
+ Err(feature_error)
249
+ }
250
+
251
+ fn matches(
252
+ &self,
253
+ ctx: &computed::Context,
254
+ attribute_tracker: &mut AttributeTracker,
255
+ ) -> KleeneValue {
256
+ ctx.builder
257
+ .add_flags(ComputedValueFlags::DEPENDS_ON_CONTAINER_STYLE_QUERY);
258
+ match *self {
259
+ StyleQuery::Feature(ref f) => f.matches(ctx, attribute_tracker),
260
+ StyleQuery::Not(ref c) => !c.matches(ctx, attribute_tracker),
261
+ StyleQuery::InParens(ref c) => c.matches(ctx, attribute_tracker),
262
+ StyleQuery::Operation(ref conditions, op) => {
263
+ debug_assert!(!conditions.is_empty(), "We never create an empty op");
264
+ match op {
265
+ Operator::And => KleeneValue::any_false(conditions.iter(), |c| {
266
+ c.matches(ctx, attribute_tracker)
267
+ }),
268
+ Operator::Or => {
269
+ KleeneValue::any(conditions.iter(), |c| c.matches(ctx, attribute_tracker))
270
+ },
271
+ }
272
+ },
273
+ StyleQuery::GeneralEnclosed(_) => KleeneValue::Unknown,
274
+ }
275
+ }
276
+
277
+ fn collect_attribute_references(&self, references: &mut AttrReferenceSet) {
278
+ match self {
279
+ Self::Feature(c) => c.collect_attribute_references(references),
280
+ Self::GeneralEnclosed(_) => {},
281
+ Self::InParens(c) => c.collect_attribute_references(references),
282
+ Self::Not(c) => c.collect_attribute_references(references),
283
+ Self::Operation(c, _) => c
284
+ .iter()
285
+ .for_each(|c| c.collect_attribute_references(references)),
286
+ }
287
+ }
288
+ }
289
+
290
+ impl OperationParser for StyleQuery {
291
+ fn parse_in_parens(
292
+ context: &ParserContext,
293
+ input: &mut Parser,
294
+ feature_type: FeatureType,
295
+ ) -> Result<Self, ParseError> {
296
+ assert!(feature_type == FeatureType::Container);
297
+ input.skip_whitespace();
298
+ let start = input.position();
299
+ let start_location = input.current_source_location();
300
+ match *input.next()? {
301
+ Token::ParenthesisBlock => {
302
+ if let Some(nested) = try_parse_block(context, input, start, start_location, |i| {
303
+ Self::parse_in_parenthesis_block(context, i)
304
+ }) {
305
+ return Ok(nested);
306
+ }
307
+ // Accept <ident>: <any-value> as a GeneralEnclosed (which evaluates
308
+ // to false, but does not invalidate the query as a whole).
309
+ input.parse_nested_block(|i| {
310
+ i.expect_ident()?;
311
+ i.expect_colon()?;
312
+ consume_any_value(i)
313
+ })?;
314
+ Ok(Self::GeneralEnclosed(input.slice_from(start).to_owned()))
315
+ },
316
+ _ => Err(ParseError::unexpected_token()),
317
+ }
318
+ }
319
+
320
+ fn new_not(inner: Box<Self>) -> Self {
321
+ Self::Not(inner)
322
+ }
323
+
324
+ fn new_operation(conditions: Box<[Self]>, operator: Operator) -> Self {
325
+ Self::Operation(conditions, operator)
326
+ }
327
+ }
328
+
329
+ /// A style query feature:
330
+ /// https://drafts.csswg.org/css-conditional-5/#typedef-style-feature
331
+ #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss, ToShmem)]
332
+ pub enum StyleFeature {
333
+ /// A property name and optional value to match.
334
+ Plain(StyleFeaturePlain),
335
+ /// A style query range expression.
336
+ Range(QueryStyleRange),
337
+ }
338
+
339
+ impl StyleFeature {
340
+ fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ParseError> {
341
+ if let Ok(range) = input.try_parse(|i| QueryStyleRange::parse(context, i)) {
342
+ return Ok(Self::Range(range));
343
+ }
344
+
345
+ Ok(Self::Plain(StyleFeaturePlain::parse(context, input)?))
346
+ }
347
+
348
+ fn matches(
349
+ &self,
350
+ ctx: &computed::Context,
351
+ attribute_tracker: &mut AttributeTracker,
352
+ ) -> KleeneValue {
353
+ match self {
354
+ Self::Plain(plain) => plain.matches(ctx, attribute_tracker),
355
+ Self::Range(range) => range.evaluate(ctx, attribute_tracker),
356
+ }
357
+ }
358
+
359
+ fn collect_attribute_references(&self, references: &mut AttrReferenceSet) {
360
+ match self {
361
+ Self::Plain(plain) => plain.collect_attribute_references(references),
362
+ Self::Range(range) => range.collect_attribute_references(references),
363
+ }
364
+ }
365
+ }
366
+
367
+ /// A style feature consisting of a custom property name and (optionally) value.
368
+ #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
369
+ pub struct StyleFeaturePlain {
370
+ name: custom_properties::Name,
371
+ #[ignore_malloc_size_of = "StyleFeatureValue has an Arc variant"]
372
+ value: StyleFeatureValue,
373
+ }
374
+
375
+ impl ToCss for StyleFeaturePlain {
376
+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
377
+ where
378
+ W: fmt::Write,
379
+ {
380
+ dest.write_str("--")?;
381
+ crate::values::serialize_atom_identifier(&self.name, dest)?;
382
+ match self.value {
383
+ StyleFeatureValue::Keyword(k) => {
384
+ dest.write_str(": ")?;
385
+ k.to_css(dest)?;
386
+ },
387
+ StyleFeatureValue::Value(Some(ref v)) => {
388
+ dest.write_str(": ")?;
389
+ v.to_css(dest)?;
390
+ },
391
+ StyleFeatureValue::Value(None) => (),
392
+ }
393
+ Ok(())
394
+ }
395
+ }
396
+
397
+ impl StyleFeaturePlain {
398
+ fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ParseError> {
399
+ let ident = input.expect_ident()?;
400
+ // TODO(emilio): Maybe support non-custom properties?
401
+ let name = match custom_properties::parse_name(ident.as_ref()) {
402
+ Ok(name) => custom_properties::Name::from(name),
403
+ Err(()) => return Err(ParseError::custom(StyleParseErrorKind::UnspecifiedError)),
404
+ };
405
+ let value = if input.try_parse(|i| i.expect_colon()).is_ok() {
406
+ input.skip_whitespace();
407
+ if let Ok(keyword) = input.try_parse(|i| CSSWideKeyword::parse(i)) {
408
+ StyleFeatureValue::Keyword(keyword)
409
+ } else {
410
+ let value = custom_properties::SpecifiedValue::parse(
411
+ input,
412
+ Some(&context.namespaces.prefixes),
413
+ context.url_data,
414
+ )?;
415
+ // `!important` is allowed (but ignored) after the value.
416
+ let _ = input.try_parse(parse_important);
417
+ StyleFeatureValue::Value(Some(Arc::new(value)))
418
+ }
419
+ } else {
420
+ StyleFeatureValue::Value(None)
421
+ };
422
+ Ok(Self { name, value })
423
+ }
424
+
425
+ // Substitute custom-property references in `value`, then re-parse and compute it,
426
+ // and compare against `current_value`.
427
+ fn substitute_and_compare(
428
+ value: &Arc<custom_properties::SpecifiedValue>,
429
+ registration: &PropertyDescriptors,
430
+ stylist: &Stylist,
431
+ ctx: &computed::Context,
432
+ attribute_tracker: &mut AttributeTracker,
433
+ current_value: Option<&ComputedRegisteredValue>,
434
+ ) -> bool {
435
+ let substitution_functions = custom_properties::ComputedSubstitutionFunctions::new(
436
+ Some(ctx.inherited_custom_properties().clone()),
437
+ None,
438
+ );
439
+ let custom_properties::SubstitutionResult { css, attr_taint } =
440
+ match custom_properties::substitute(
441
+ value,
442
+ &substitution_functions,
443
+ stylist,
444
+ ctx,
445
+ attribute_tracker,
446
+ ) {
447
+ Ok(sub) => sub,
448
+ Err(_) => return current_value.is_none(),
449
+ };
450
+ if registration.is_universal() {
451
+ return match current_value {
452
+ Some(v) => v.as_universal().is_some_and(|v| v.css == css),
453
+ None => css.is_empty(),
454
+ };
455
+ }
456
+ let mut parser = Parser::new(&css);
457
+ let computed = SpecifiedRegisteredValue::compute(
458
+ &mut parser,
459
+ registration,
460
+ None,
461
+ &value.url_data,
462
+ ctx,
463
+ AllowComputationallyDependent::Yes,
464
+ attr_taint,
465
+ )
466
+ .ok();
467
+ computed.as_ref() == current_value
468
+ }
469
+
470
+ fn matches(
471
+ &self,
472
+ ctx: &computed::Context,
473
+ attribute_tracker: &mut AttributeTracker,
474
+ ) -> KleeneValue {
475
+ // FIXME(emilio): Confirm this is the right style to query.
476
+ let stylist = ctx
477
+ .builder
478
+ .stylist
479
+ .expect("container queries should have a stylist around");
480
+ let registration = stylist.get_custom_property_registration(&self.name);
481
+ let current_value = ctx
482
+ .inherited_custom_properties()
483
+ .get(registration, &self.name);
484
+ KleeneValue::from(match self.value {
485
+ StyleFeatureValue::Value(Some(ref v)) => {
486
+ if ctx.container_info.is_none() {
487
+ // If no container, custom props are guaranteed-unknown.
488
+ false
489
+ } else if v.has_references() {
490
+ // If there are --var() references in the query value,
491
+ // try to substitute them before comparing to current.
492
+ Self::substitute_and_compare(
493
+ v,
494
+ registration,
495
+ stylist,
496
+ ctx,
497
+ attribute_tracker,
498
+ current_value,
499
+ )
500
+ } else {
501
+ custom_properties::compute_variable_value(v, registration, ctx).as_ref()
502
+ == current_value
503
+ }
504
+ },
505
+ StyleFeatureValue::Value(None) => current_value.is_some(),
506
+ StyleFeatureValue::Keyword(kw) => {
507
+ match kw {
508
+ CSSWideKeyword::Unset => current_value.is_none(),
509
+ CSSWideKeyword::Initial => {
510
+ if let Some(initial) = &registration.initial_value {
511
+ let v = custom_properties::compute_variable_value(
512
+ initial,
513
+ registration,
514
+ ctx,
515
+ );
516
+ v.as_ref() == current_value
517
+ } else {
518
+ current_value.is_none()
519
+ }
520
+ },
521
+ CSSWideKeyword::Inherit => {
522
+ if let Some(inherited) = ctx
523
+ .container_info
524
+ .as_ref()
525
+ .expect("queries should provide container info")
526
+ .inherited_style()
527
+ {
528
+ inherited.custom_properties().get(registration, &self.name)
529
+ == current_value
530
+ } else {
531
+ false
532
+ }
533
+ },
534
+ // Cascade-dependent keywords, such as revert and revert-layer,
535
+ // are invalid as values in a style feature, and cause the
536
+ // container style query to be false.
537
+ // https://drafts.csswg.org/css-conditional-5/#evaluate-a-style-range
538
+ CSSWideKeyword::Revert
539
+ | CSSWideKeyword::RevertLayer
540
+ | CSSWideKeyword::RevertRule => false,
541
+ }
542
+ },
543
+ })
544
+ }
545
+
546
+ fn collect_attribute_references(&self, references: &mut AttrReferenceSet) {
547
+ if let StyleFeatureValue::Value(Some(v)) = &self.value {
548
+ v.collect_attribute_references(references)
549
+ }
550
+ }
551
+ }
552
+
553
+ /// A boolean value for a pref query.
554
+ #[derive(
555
+ Clone,
556
+ Debug,
557
+ MallocSizeOf,
558
+ PartialEq,
559
+ Eq,
560
+ Parse,
561
+ SpecifiedValueInfo,
562
+ ToComputedValue,
563
+ ToCss,
564
+ ToShmem,
565
+ )]
566
+ #[repr(u8)]
567
+ #[allow(missing_docs)]
568
+ pub enum BoolValue {
569
+ False,
570
+ True,
571
+ }
572
+
573
+ /// Simple values we support for -moz-pref(). We don't want to deal with calc() and other
574
+ /// shenanigans for now.
575
+ #[derive(
576
+ Clone,
577
+ Debug,
578
+ Eq,
579
+ MallocSizeOf,
580
+ Parse,
581
+ PartialEq,
582
+ SpecifiedValueInfo,
583
+ ToComputedValue,
584
+ ToCss,
585
+ ToShmem,
586
+ )]
587
+ #[repr(u8)]
588
+ pub enum MozPrefFeatureValue<I> {
589
+ /// No pref value, implicitly bool, but also used to represent missing prefs.
590
+ #[css(skip)]
591
+ None,
592
+ /// A bool value.
593
+ Boolean(BoolValue),
594
+ /// An integer value, useful for int prefs.
595
+ Integer(I),
596
+ /// A string pref value.
597
+ String(crate::values::AtomString),
598
+ }
599
+
600
+ type SpecifiedMozPrefFeatureValue = MozPrefFeatureValue<crate::values::specified::Integer>;
601
+ /// The computed -moz-pref() value.
602
+ pub type ComputedMozPrefFeatureValue = MozPrefFeatureValue<crate::values::computed::Integer>;
603
+
604
+ /// A custom -moz-pref(<name>, <value>) query feature.
605
+ #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
606
+ pub struct MozPrefFeature {
607
+ name: crate::values::AtomString,
608
+ value: SpecifiedMozPrefFeatureValue,
609
+ }
610
+
611
+ impl MozPrefFeature {
612
+ fn parse(
613
+ context: &ParserContext,
614
+ input: &mut Parser,
615
+ feature_type: FeatureType,
616
+ ) -> Result<Self, ParseError> {
617
+ use crate::parser::Parse;
618
+ if !context.chrome_rules_enabled() || feature_type != FeatureType::Media {
619
+ return Err(ParseError::custom(StyleParseErrorKind::UnspecifiedError));
620
+ }
621
+ let name = AtomString::parse(context, input)?;
622
+ let value = if input.try_parse(|i| i.expect_comma()).is_ok() {
623
+ SpecifiedMozPrefFeatureValue::parse(context, input)?
624
+ } else {
625
+ SpecifiedMozPrefFeatureValue::None
626
+ };
627
+ Ok(Self { name, value })
628
+ }
629
+
630
+ #[cfg(feature = "gecko")]
631
+ fn matches(&self, ctx: &computed::Context) -> KleeneValue {
632
+ use crate::values::computed::ToComputedValue;
633
+ let value = self.value.to_computed_value(ctx);
634
+ KleeneValue::from(unsafe {
635
+ crate::gecko_bindings::bindings::Gecko_EvalMozPrefFeature(self.name.as_ptr(), &value)
636
+ })
637
+ }
638
+
639
+ #[cfg(feature = "servo")]
640
+ fn matches(&self, _: &computed::Context) -> KleeneValue {
641
+ KleeneValue::Unknown
642
+ }
643
+ }
644
+
645
+ impl ToCss for MozPrefFeature {
646
+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
647
+ where
648
+ W: fmt::Write,
649
+ {
650
+ self.name.to_css(dest)?;
651
+ if !matches!(self.value, MozPrefFeatureValue::None) {
652
+ dest.write_str(", ")?;
653
+ self.value.to_css(dest)?;
654
+ }
655
+ Ok(())
656
+ }
657
+ }
658
+
659
+ /// Represents a condition.
660
+ #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
661
+ pub enum QueryCondition {
662
+ /// A simple feature expression, implicitly parenthesized.
663
+ Feature(QueryFeatureExpression),
664
+ /// A custom media query reference in a boolean context, implicitly parenthesized.
665
+ Custom(DashedIdent),
666
+ /// A negation of a condition.
667
+ Not(Box<QueryCondition>),
668
+ /// A set of joint operations.
669
+ Operation(Box<[QueryCondition]>, Operator),
670
+ /// A condition wrapped in parenthesis.
671
+ InParens(Box<QueryCondition>),
672
+ /// A <style> query.
673
+ Style(StyleQuery),
674
+ /// A -moz-pref() query.
675
+ MozPref(MozPrefFeature),
676
+ /// [ <function-token> <any-value>? ) ] | [ ( <any-value>? ) ]
677
+ GeneralEnclosed(String, UrlExtraData),
678
+ }
679
+
680
+ impl ToCss for QueryCondition {
681
+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
682
+ where
683
+ W: fmt::Write,
684
+ {
685
+ match *self {
686
+ // NOTE(emilio): QueryFeatureExpression already includes the
687
+ // parenthesis.
688
+ QueryCondition::Feature(ref f) => f.to_css(dest),
689
+ QueryCondition::Custom(ref name) => {
690
+ dest.write_char('(')?;
691
+ name.to_css(dest)?;
692
+ dest.write_char(')')
693
+ },
694
+ QueryCondition::Not(ref c) => {
695
+ dest.write_str("not ")?;
696
+ c.to_css(dest)
697
+ },
698
+ QueryCondition::InParens(ref c) => {
699
+ dest.write_char('(')?;
700
+ c.to_css(dest)?;
701
+ dest.write_char(')')
702
+ },
703
+ QueryCondition::Style(ref c) => {
704
+ dest.write_str("style(")?;
705
+ c.to_css(dest)?;
706
+ dest.write_char(')')
707
+ },
708
+ QueryCondition::MozPref(ref c) => {
709
+ dest.write_str("-moz-pref(")?;
710
+ c.to_css(dest)?;
711
+ dest.write_char(')')
712
+ },
713
+ QueryCondition::Operation(ref list, op) => {
714
+ let mut iter = list.iter();
715
+ iter.next().unwrap().to_css(dest)?;
716
+ for item in iter {
717
+ dest.write_char(' ')?;
718
+ op.to_css(dest)?;
719
+ dest.write_char(' ')?;
720
+ item.to_css(dest)?;
721
+ }
722
+ Ok(())
723
+ },
724
+ QueryCondition::GeneralEnclosed(ref s, _) => dest.write_str(s),
725
+ }
726
+ }
727
+ }
728
+
729
+ /// <https://drafts.csswg.org/css-syntax-3/#typedef-any-value>
730
+ fn consume_any_value(input: &mut Parser) -> Result<(), ParseError> {
731
+ input.expect_no_error_token().map_err(Into::into)
732
+ }
733
+
734
+ impl QueryCondition {
735
+ /// Parse a single condition.
736
+ pub fn parse(
737
+ context: &ParserContext,
738
+ input: &mut Parser,
739
+ feature_type: FeatureType,
740
+ ) -> Result<Self, ParseError> {
741
+ Self::parse_internal(context, input, feature_type, AllowOr::Yes)
742
+ }
743
+
744
+ fn visit<F>(&self, visitor: &mut F)
745
+ where
746
+ F: FnMut(&Self),
747
+ {
748
+ visitor(self);
749
+ match *self {
750
+ Self::Custom(..)
751
+ | Self::Feature(..)
752
+ | Self::GeneralEnclosed(..)
753
+ | Self::Style(..)
754
+ | Self::MozPref(..) => {},
755
+ Self::Not(ref cond) => cond.visit(visitor),
756
+ Self::Operation(ref conds, _op) => {
757
+ for cond in conds.iter() {
758
+ cond.visit(visitor);
759
+ }
760
+ },
761
+ Self::InParens(ref cond) => cond.visit(visitor),
762
+ }
763
+ }
764
+
765
+ /// Returns the union of all flags in the expression. This is useful for
766
+ /// container queries.
767
+ pub fn cumulative_flags(&self) -> FeatureFlags {
768
+ let mut result = FeatureFlags::empty();
769
+ self.visit(&mut |condition| {
770
+ if let Self::Style(..) = condition {
771
+ result.insert(FeatureFlags::STYLE);
772
+ }
773
+ if let Self::Feature(f) = condition {
774
+ result.insert(f.feature_flags())
775
+ }
776
+ });
777
+ result
778
+ }
779
+
780
+ /// Parse a single condition, disallowing `or` expressions.
781
+ ///
782
+ /// To be used from the legacy query syntax.
783
+ pub fn parse_disallow_or(
784
+ context: &ParserContext,
785
+ input: &mut Parser,
786
+ feature_type: FeatureType,
787
+ ) -> Result<Self, ParseError> {
788
+ Self::parse_internal(context, input, feature_type, AllowOr::No)
789
+ }
790
+
791
+ fn parse_in_parenthesis_block(
792
+ context: &ParserContext,
793
+ input: &mut Parser,
794
+ feature_type: FeatureType,
795
+ ) -> Result<Self, ParseError> {
796
+ // Base case. Make sure to preserve this error as it's more generally
797
+ // relevant.
798
+ let feature_error = match input.try_parse(|input| {
799
+ QueryFeatureExpression::parse_in_parenthesis_block(context, input, feature_type)
800
+ }) {
801
+ Ok(expr) => return Ok(Self::Feature(expr)),
802
+ Err(e) => e,
803
+ };
804
+ if crate::pref!("layout.css.custom-media.enabled") {
805
+ if let Ok(custom) = input.try_parse(|input| DashedIdent::parse(context, input)) {
806
+ return Ok(Self::Custom(custom));
807
+ }
808
+ }
809
+ if let Ok(inner) = Self::parse(context, input, feature_type) {
810
+ return Ok(Self::InParens(Box::new(inner)));
811
+ }
812
+ Err(feature_error)
813
+ }
814
+
815
+ /// Whether this condition matches the device and quirks mode.
816
+ /// https://drafts.csswg.org/mediaqueries/#evaluating
817
+ /// https://drafts.csswg.org/mediaqueries/#typedef-general-enclosed
818
+ /// Kleene 3-valued logic is adopted here due to the introduction of
819
+ /// <general-enclosed>.
820
+ pub fn matches(
821
+ &self,
822
+ context: &computed::Context,
823
+ custom: &mut CustomMediaEvaluator,
824
+ attribute_tracker: &mut AttributeTracker,
825
+ ) -> KleeneValue {
826
+ match *self {
827
+ Self::Custom(ref f) => custom.matches(f, context),
828
+ Self::Feature(ref f) => f.matches(context),
829
+ Self::GeneralEnclosed(ref str, ref url_data) => {
830
+ self.matches_general(str, url_data, context, custom, attribute_tracker)
831
+ },
832
+ Self::InParens(ref c) => c.matches(context, custom, attribute_tracker),
833
+ Self::Not(ref c) => !c.matches(context, custom, attribute_tracker),
834
+ Self::Style(ref c) => c.matches(context, attribute_tracker),
835
+ Self::MozPref(ref c) => c.matches(context),
836
+ Self::Operation(ref conditions, op) => {
837
+ debug_assert!(!conditions.is_empty(), "We never create an empty op");
838
+ match op {
839
+ Operator::And => KleeneValue::any_false(conditions.iter(), |c| {
840
+ c.matches(context, custom, attribute_tracker)
841
+ }),
842
+ Operator::Or => KleeneValue::any(conditions.iter(), |c| {
843
+ c.matches(context, custom, attribute_tracker)
844
+ }),
845
+ }
846
+ },
847
+ }
848
+ }
849
+
850
+ /// For a condition that was parsed as GeneralEnclosed, try applying custom-property
851
+ /// substitution and re-parse the result.
852
+ fn matches_general(
853
+ &self,
854
+ css_text: &str,
855
+ url_data: &UrlExtraData,
856
+ context: &computed::Context,
857
+ custom: &mut CustomMediaEvaluator,
858
+ attribute_tracker: &mut AttributeTracker,
859
+ ) -> KleeneValue {
860
+ // This only applies (currently, at least) to container queries.
861
+ if !context.in_container_query {
862
+ return KleeneValue::Unknown;
863
+ }
864
+
865
+ let stylist = context
866
+ .builder
867
+ .stylist
868
+ .expect("container query should provide a Stylist");
869
+
870
+ // Parse the text as a custom-property value to identify references.
871
+ let value = match custom_properties::SpecifiedValue::parse(
872
+ &mut Parser::new(css_text),
873
+ None, // TODO: what Namespaces should we pass here?
874
+ url_data,
875
+ ) {
876
+ Ok(val) => val,
877
+ Err(_) => return KleeneValue::Unknown,
878
+ };
879
+
880
+ // If no references, we're not going to end up with a new result, just bail out.
881
+ if !value.has_references() {
882
+ return KleeneValue::Unknown;
883
+ }
884
+
885
+ // Substitute var() functions if possible.
886
+ let substitution_functions = custom_properties::ComputedSubstitutionFunctions::new(
887
+ Some(context.inherited_custom_properties().clone()),
888
+ None,
889
+ );
890
+ let custom_properties::SubstitutionResult { css, attr_taint } =
891
+ match custom_properties::substitute(
892
+ &value,
893
+ &substitution_functions,
894
+ stylist,
895
+ context,
896
+ attribute_tracker,
897
+ ) {
898
+ Ok(sub) => sub,
899
+ Err(_) => return KleeneValue::Unknown,
900
+ };
901
+
902
+ // Re-parse the result as a query-condition, and evaluate it.
903
+ let parser_context = ParserContext::new(
904
+ Origin::Author,
905
+ url_data,
906
+ Some(CssRuleType::Container),
907
+ ParsingMode::DEFAULT,
908
+ QuirksMode::NoQuirks,
909
+ /* namespaces = */ Default::default(),
910
+ /* error_reporter = */ None,
911
+ /* use_counters = */ None,
912
+ attr_taint,
913
+ );
914
+ let result = match Self::parse(
915
+ &parser_context,
916
+ &mut Parser::new(&css),
917
+ FeatureType::Container,
918
+ ) {
919
+ Ok(Self::GeneralEnclosed(..)) => {
920
+ // If the result is still GeneralEnclosed, the query is unknown.
921
+ KleeneValue::Unknown
922
+ },
923
+ Ok(query) => query.matches(context, custom, attribute_tracker),
924
+ Err(_) => KleeneValue::Unknown,
925
+ };
926
+
927
+ result
928
+ }
929
+
930
+ /// Collect the attribute references in this query condition, if any.
931
+ pub fn collect_attribute_references(&self, references: &mut AttrReferenceSet) {
932
+ if let QueryCondition::Style(c) = self {
933
+ c.collect_attribute_references(references)
934
+ }
935
+ }
936
+ }
937
+
938
+ impl OperationParser for QueryCondition {
939
+ /// Parse a condition in parentheses, or `<general-enclosed>`.
940
+ ///
941
+ /// https://drafts.csswg.org/mediaqueries/#typedef-media-in-parens
942
+ fn parse_in_parens(
943
+ context: &ParserContext,
944
+ input: &mut Parser,
945
+ feature_type: FeatureType,
946
+ ) -> Result<Self, ParseError> {
947
+ input.skip_whitespace();
948
+ let start = input.position();
949
+ let start_location = input.current_source_location();
950
+ match *input.next()? {
951
+ Token::ParenthesisBlock => {
952
+ let nested = try_parse_block(context, input, start, start_location, |input| {
953
+ Self::parse_in_parenthesis_block(context, input, feature_type)
954
+ });
955
+ if let Some(nested) = nested {
956
+ return Ok(nested);
957
+ }
958
+ },
959
+ Token::Function(ref name) => {
960
+ match_ignore_ascii_case! { name,
961
+ "style" => {
962
+ let query = try_parse_block(context, input, start, start_location, |input| {
963
+ StyleQuery::parse(context, input, feature_type)
964
+ });
965
+ if let Some(query) = query {
966
+ return Ok(Self::Style(query));
967
+ }
968
+ },
969
+ "-moz-pref" => {
970
+ let feature = try_parse_block(context, input, start, start_location, |input| {
971
+ MozPrefFeature::parse(context, input, feature_type)
972
+ });
973
+ if let Some(feature) = feature {
974
+ return Ok(Self::MozPref(feature));
975
+ }
976
+ },
977
+ _ => {},
978
+ }
979
+ },
980
+ _ => return Err(ParseError::unexpected_token()),
981
+ }
982
+ input.parse_nested_block(consume_any_value)?;
983
+ Ok(Self::GeneralEnclosed(
984
+ input.slice_from(start).to_owned(),
985
+ context.url_data.clone(),
986
+ ))
987
+ }
988
+
989
+ fn new_not(inner: Box<Self>) -> Self {
990
+ Self::Not(inner)
991
+ }
992
+
993
+ fn new_operation(conditions: Box<[Self]>, operator: Operator) -> Self {
994
+ Self::Operation(conditions, operator)
995
+ }
996
+ }