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,1086 @@
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 struct to encapsulate all the style fixups and flags propagations
6
+ //! a computed style needs in order for it to adhere to the CSS spec.
7
+
8
+ use crate::computed_value_flags::ComputedValueFlags;
9
+ use crate::dom::TElement;
10
+ use crate::logical_geometry::PhysicalSide;
11
+ use crate::properties::longhands::display::computed_value::T as Display;
12
+ use crate::properties::longhands::float::computed_value::T as Float;
13
+ use crate::properties::longhands::position::computed_value::T as Position;
14
+ #[cfg(feature = "gecko")]
15
+ use crate::properties::longhands::{
16
+ contain::computed_value::T as Contain, container_type::computed_value::T as ContainerType,
17
+ content_visibility::computed_value::T as ContentVisibility,
18
+ };
19
+ #[cfg(feature = "gecko")]
20
+ use crate::properties::LonghandId;
21
+ use crate::properties::{ComputedValues, LonghandIdSet, StyleBuilder};
22
+ use crate::values::computed::position::{
23
+ PositionTryFallbacksTryTactic, PositionTryFallbacksTryTacticKeyword, TryTacticAdjustment,
24
+ };
25
+ use crate::values::specified::align::AlignFlags;
26
+
27
+ /// A struct that implements all the adjustment methods.
28
+ ///
29
+ /// NOTE(emilio): If new adjustments are introduced that depend on reset
30
+ /// properties of the parent, you may need tweaking the
31
+ /// `ChildCascadeRequirement` code in `matching.rs`.
32
+ ///
33
+ /// NOTE(emilio): Also, if new adjustments are introduced that break the
34
+ /// following invariant:
35
+ ///
36
+ /// Given same tag name, namespace, rules and parent style, two elements would
37
+ /// end up with exactly the same style.
38
+ ///
39
+ /// Then you need to adjust the lookup_by_rules conditions in the sharing cache.
40
+ pub struct StyleAdjuster<'a, 'b: 'a> {
41
+ style: &'a mut StyleBuilder<'b>,
42
+ }
43
+
44
+ #[cfg(feature = "gecko")]
45
+ fn is_topmost_svg_svg_element<E>(e: E) -> bool
46
+ where
47
+ E: TElement,
48
+ {
49
+ debug_assert!(e.is_svg_element());
50
+ if e.local_name() != &*atom!("svg") {
51
+ return false;
52
+ }
53
+
54
+ let parent = match e.traversal_parent() {
55
+ Some(n) => n,
56
+ None => return true,
57
+ };
58
+
59
+ if !parent.is_svg_element() {
60
+ return true;
61
+ }
62
+
63
+ parent.local_name() == &*atom!("foreignObject")
64
+ }
65
+
66
+ // https://drafts.csswg.org/css-display/#unbox
67
+ #[cfg(feature = "gecko")]
68
+ fn is_effective_display_none_for_display_contents<E>(element: E) -> bool
69
+ where
70
+ E: TElement,
71
+ {
72
+ use crate::Atom;
73
+
74
+ const SPECIAL_HTML_ELEMENTS: [Atom; 16] = [
75
+ atom!("br"),
76
+ atom!("wbr"),
77
+ atom!("meter"),
78
+ atom!("progress"),
79
+ atom!("canvas"),
80
+ atom!("embed"),
81
+ atom!("object"),
82
+ atom!("audio"),
83
+ atom!("iframe"),
84
+ atom!("img"),
85
+ atom!("video"),
86
+ atom!("frame"),
87
+ atom!("frameset"),
88
+ atom!("input"),
89
+ atom!("textarea"),
90
+ atom!("select"),
91
+ ];
92
+
93
+ // https://drafts.csswg.org/css-display/#unbox-svg
94
+ //
95
+ // There's a note about "Unknown elements", but there's not a good way to
96
+ // know what that means, or to get that information from here, and no other
97
+ // UA implements this either.
98
+ const SPECIAL_SVG_ELEMENTS: [Atom; 6] = [
99
+ atom!("svg"),
100
+ atom!("a"),
101
+ atom!("g"),
102
+ atom!("use"),
103
+ atom!("tspan"),
104
+ atom!("textPath"),
105
+ ];
106
+
107
+ // https://drafts.csswg.org/css-display/#unbox-html
108
+ if element.is_html_element() {
109
+ let local_name = element.local_name();
110
+ return SPECIAL_HTML_ELEMENTS
111
+ .iter()
112
+ .any(|name| &**name == local_name);
113
+ }
114
+
115
+ // https://drafts.csswg.org/css-display/#unbox-svg
116
+ if element.is_svg_element() {
117
+ if is_topmost_svg_svg_element(element) {
118
+ return true;
119
+ }
120
+ let local_name = element.local_name();
121
+ return !SPECIAL_SVG_ELEMENTS
122
+ .iter()
123
+ .any(|name| &**name == local_name);
124
+ }
125
+
126
+ // https://drafts.csswg.org/css-display/#unbox-mathml
127
+ if element.is_mathml_element() {
128
+ return true;
129
+ }
130
+
131
+ false
132
+ }
133
+
134
+ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
135
+ /// Trivially constructs a new StyleAdjuster.
136
+ #[inline]
137
+ pub fn new(style: &'a mut StyleBuilder<'b>) -> Self {
138
+ StyleAdjuster { style }
139
+ }
140
+
141
+ /// <https://fullscreen.spec.whatwg.org/#new-stacking-layer>
142
+ ///
143
+ /// Any position value other than 'absolute' and 'fixed' are
144
+ /// computed to 'absolute' if the element is in a top layer.
145
+ ///
146
+ fn adjust_for_top_layer(&mut self) {
147
+ if !self.style.in_top_layer() {
148
+ return;
149
+ }
150
+ if !self.style.is_absolutely_positioned() {
151
+ self.style.mutate_box().set_position(Position::Absolute);
152
+ }
153
+ if self.style.get_box().clone_display().is_contents() {
154
+ self.style.mutate_box().set_display(Display::Block);
155
+ }
156
+ }
157
+
158
+ /// -webkit-box with line-clamp and vertical orientation gets turned into
159
+ /// flow-root at computed-value time.
160
+ ///
161
+ /// This makes the element not be a flex container, with all that it
162
+ /// implies, but it should be safe. It matches blink, see
163
+ /// https://bugzilla.mozilla.org/show_bug.cgi?id=1786147#c10
164
+ #[cfg(feature = "gecko")]
165
+ fn adjust_for_webkit_line_clamp(&mut self) {
166
+ use crate::properties::longhands::_moz_box_orient::computed_value::T as BoxOrient;
167
+ use crate::values::specified::box_::{DisplayInside, DisplayOutside};
168
+ let box_style = self.style.get_box();
169
+ let line_clamp = box_style.clone_line_clamp();
170
+ if line_clamp.is_none() {
171
+ return;
172
+ }
173
+
174
+ let disp = box_style.clone_display();
175
+ if disp.inside() != DisplayInside::WebkitBox
176
+ || self.style.get_xul().clone__moz_box_orient() != BoxOrient::Vertical
177
+ {
178
+ return;
179
+ }
180
+ let new_display = if disp.outside() == DisplayOutside::Block {
181
+ Display::FlowRoot
182
+ } else {
183
+ debug_assert_eq!(disp.outside(), DisplayOutside::Inline);
184
+ Display::InlineBlock
185
+ };
186
+ self.style
187
+ .mutate_box()
188
+ .set_adjusted_display(new_display, false);
189
+ }
190
+
191
+ /// CSS 2.1 section 9.7:
192
+ ///
193
+ /// If 'position' has the value 'absolute' or 'fixed', [...] the computed
194
+ /// value of 'float' is 'none'.
195
+ ///
196
+ fn adjust_for_position(&mut self) {
197
+ if self.style.is_absolutely_positioned() && self.style.is_floating() {
198
+ self.style.mutate_box().set_float(Float::None);
199
+ }
200
+ }
201
+
202
+ /// Whether we should skip any item-based display property blockification on
203
+ /// this element.
204
+ fn skip_item_display_fixup<E>(&self, element: Option<E>) -> bool
205
+ where
206
+ E: TElement,
207
+ {
208
+ if let Some(pseudo) = self.style.pseudo {
209
+ return pseudo.skip_item_display_fixup();
210
+ }
211
+
212
+ element.is_some_and(|e| e.skip_item_display_fixup())
213
+ }
214
+
215
+ /// Apply the blockification rules based on the table in CSS 2.2 section 9.7.
216
+ /// <https://drafts.csswg.org/css2/visuren.html#dis-pos-flo>
217
+ /// A ::marker pseudo-element with 'list-style-position:outside' needs to
218
+ /// have its 'display' blockified, unless the ::marker is for an inline
219
+ /// list-item (for which 'list-style-position:outside' behaves as 'inside').
220
+ /// https://drafts.csswg.org/css-lists-3/#list-style-position-property
221
+ fn blockify_if_necessary<E>(&mut self, layout_parent_style: &ComputedValues, element: Option<E>)
222
+ where
223
+ E: TElement,
224
+ {
225
+ let mut blockify = false;
226
+ macro_rules! blockify_if {
227
+ ($if_what:expr) => {
228
+ if !blockify {
229
+ blockify = $if_what;
230
+ }
231
+ };
232
+ }
233
+
234
+ blockify_if!(self.style.is_root_element);
235
+ if !self.skip_item_display_fixup(element) {
236
+ let parent_display = layout_parent_style.get_box().clone_display();
237
+ blockify_if!(parent_display.is_item_container());
238
+ }
239
+
240
+ let is_item_or_root = blockify;
241
+
242
+ blockify_if!(self.style.is_floating());
243
+ blockify_if!(self.style.is_absolutely_positioned());
244
+
245
+ if !blockify {
246
+ return;
247
+ }
248
+
249
+ let display = self.style.get_box().clone_display();
250
+ let blockified_display = display.equivalent_block_display(self.style.is_root_element);
251
+ if display != blockified_display {
252
+ self.style
253
+ .mutate_box()
254
+ .set_adjusted_display(blockified_display, is_item_or_root);
255
+ }
256
+ }
257
+
258
+ /// Compute a few common flags for both text and element's style.
259
+ fn set_bits(&mut self) {
260
+ let box_style = self.style.get_box();
261
+ let display = box_style.clone_display();
262
+
263
+ if !display.is_contents() {
264
+ if !self
265
+ .style
266
+ .get_text()
267
+ .clone_text_decoration_line()
268
+ .is_empty()
269
+ {
270
+ self.style
271
+ .add_flags(ComputedValueFlags::HAS_TEXT_DECORATION_LINES);
272
+ }
273
+
274
+ if self.style.get_effects().clone_opacity() == 0. {
275
+ self.style
276
+ .add_flags(ComputedValueFlags::IS_IN_OPACITY_ZERO_SUBTREE);
277
+ }
278
+ } else if self
279
+ .style
280
+ .get_parent_box()
281
+ .clone_display()
282
+ .is_item_container()
283
+ || self
284
+ .style
285
+ .get_parent_flags()
286
+ .contains(ComputedValueFlags::DISPLAY_CONTENTS_IN_ITEM_CONTAINER)
287
+ {
288
+ self.style
289
+ .add_flags(ComputedValueFlags::DISPLAY_CONTENTS_IN_ITEM_CONTAINER);
290
+ }
291
+
292
+ if self.style.pseudo.is_some_and(|p| p.is_first_line()) {
293
+ self.style
294
+ .add_flags(ComputedValueFlags::IS_IN_FIRST_LINE_SUBTREE);
295
+ }
296
+
297
+ if self.style.is_root_element {
298
+ self.style
299
+ .add_flags(ComputedValueFlags::IS_ROOT_ELEMENT_STYLE);
300
+ }
301
+
302
+ #[cfg(feature = "gecko")]
303
+ if box_style
304
+ .clone_effective_containment()
305
+ .contains(Contain::STYLE)
306
+ {
307
+ self.style
308
+ .add_flags(ComputedValueFlags::SELF_OR_ANCESTOR_HAS_CONTAIN_STYLE);
309
+ }
310
+
311
+ if box_style.clone_container_type().is_size_container_type() {
312
+ self.style
313
+ .add_flags(ComputedValueFlags::SELF_OR_ANCESTOR_HAS_SIZE_CONTAINER_TYPE);
314
+ }
315
+ }
316
+
317
+ /// Adjust the style for text style.
318
+ ///
319
+ /// The adjustments here are a subset of the adjustments generally, because
320
+ /// text only inherits properties.
321
+ ///
322
+ /// Note that this, for Gecko, comes through Servo_ComputedValues_Inherit.
323
+ #[cfg(feature = "gecko")]
324
+ pub fn adjust_for_text(&mut self) {
325
+ debug_assert!(!self.style.is_root_element);
326
+ self.adjust_for_text_combine_upright();
327
+ self.adjust_for_text_in_ruby();
328
+ self.set_bits();
329
+ }
330
+
331
+ /// Change writing mode of the text frame for text-combine-upright.
332
+ ///
333
+ /// It is safe to look at our own style because we are looking at inherited
334
+ /// properties, and text is just plain inheritance.
335
+ ///
336
+ /// TODO(emilio): we should (Gecko too) revise these adjustments in presence
337
+ /// of display: contents.
338
+ ///
339
+ /// FIXME(emilio): How does this play with logical properties? Doesn't
340
+ /// mutating writing-mode change the potential physical sides chosen?
341
+ #[cfg(feature = "gecko")]
342
+ fn adjust_for_text_combine_upright(&mut self) {
343
+ use crate::computed_values::text_combine_upright::T as TextCombineUpright;
344
+ use crate::computed_values::writing_mode::T as WritingMode;
345
+ use crate::logical_geometry;
346
+
347
+ let writing_mode = self.style.get_inherited_box().clone_writing_mode();
348
+ let text_combine_upright = self.style.get_inherited_text().clone_text_combine_upright();
349
+
350
+ if matches!(
351
+ writing_mode,
352
+ WritingMode::VerticalRl | WritingMode::VerticalLr
353
+ ) && text_combine_upright == TextCombineUpright::All
354
+ {
355
+ self.style.add_flags(ComputedValueFlags::IS_TEXT_COMBINED);
356
+ self.style
357
+ .mutate_inherited_box()
358
+ .set_writing_mode(WritingMode::HorizontalTb);
359
+ self.style.writing_mode =
360
+ logical_geometry::WritingMode::new(self.style.get_inherited_box());
361
+ }
362
+ }
363
+
364
+ /// Unconditionally propagates the line break suppression flag to text, and
365
+ /// additionally it applies it if it is in any ruby box.
366
+ ///
367
+ /// This is necessary because its parent may not itself have the flag set
368
+ /// (e.g. ruby or ruby containers), thus we may not inherit the flag from
369
+ /// them.
370
+ #[cfg(feature = "gecko")]
371
+ fn adjust_for_text_in_ruby(&mut self) {
372
+ let parent_display = self.style.get_parent_box().clone_display();
373
+ if parent_display.is_ruby_type()
374
+ || self
375
+ .style
376
+ .get_parent_flags()
377
+ .contains(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK)
378
+ {
379
+ self.style
380
+ .add_flags(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK);
381
+ }
382
+ }
383
+
384
+ /// <https://drafts.csswg.org/css-writing-modes-3/#block-flow:>
385
+ ///
386
+ /// If a box has a different writing-mode value than its containing
387
+ /// block:
388
+ ///
389
+ /// - If the box has a specified display of inline, its display
390
+ /// computes to inline-block. [CSS21]
391
+ ///
392
+ /// This matches the adjustment that Gecko does, not exactly following
393
+ /// the spec. See also:
394
+ ///
395
+ /// <https://lists.w3.org/Archives/Public/www-style/2017Mar/0045.html>
396
+ /// <https://github.com/servo/servo/issues/15754>
397
+ fn adjust_for_writing_mode(&mut self, layout_parent_style: &ComputedValues) {
398
+ let our_writing_mode = self.style.get_inherited_box().clone_writing_mode();
399
+ let parent_writing_mode = layout_parent_style.get_inherited_box().clone_writing_mode();
400
+
401
+ if our_writing_mode != parent_writing_mode
402
+ && self.style.get_box().clone_display() == Display::Inline
403
+ {
404
+ // TODO(emilio): Figure out if we can just set the adjusted display
405
+ // on Gecko too and unify this code path.
406
+ if cfg!(feature = "servo") {
407
+ self.style
408
+ .mutate_box()
409
+ .set_adjusted_display(Display::InlineBlock, false);
410
+ } else {
411
+ self.style.mutate_box().set_display(Display::InlineBlock);
412
+ }
413
+ }
414
+ }
415
+
416
+ /// CSS overflow-x and overflow-y require some fixup as well in some cases.
417
+ /// https://drafts.csswg.org/css-overflow-3/#overflow-properties
418
+ /// "Computed value: as specified, except with `visible`/`clip` computing to
419
+ /// `auto`/`hidden` (respectively) if one of `overflow-x` or `overflow-y` is
420
+ /// neither `visible` nor `clip`."
421
+ fn adjust_for_overflow(&mut self) {
422
+ let overflow_x = self.style.get_box().clone_overflow_x();
423
+ let overflow_y = self.style.get_box().clone_overflow_y();
424
+ if overflow_x == overflow_y {
425
+ return; // optimization for the common case
426
+ }
427
+
428
+ if overflow_x.is_scrollable() != overflow_y.is_scrollable() {
429
+ let box_style = self.style.mutate_box();
430
+ box_style.set_overflow_x(overflow_x.to_scrollable());
431
+ box_style.set_overflow_y(overflow_y.to_scrollable());
432
+ }
433
+ }
434
+
435
+ #[cfg(feature = "gecko")]
436
+ fn adjust_for_contain(&mut self) {
437
+ let box_style = self.style.get_box();
438
+ let container_type = box_style.clone_container_type();
439
+ let content_visibility = box_style.clone_content_visibility();
440
+ if !container_type.is_size_container_type()
441
+ && content_visibility == ContentVisibility::Visible
442
+ {
443
+ debug_assert_eq!(
444
+ box_style.clone_contain(),
445
+ box_style.clone_effective_containment()
446
+ );
447
+ return;
448
+ }
449
+ let old_contain = box_style.clone_contain();
450
+ let mut new_contain = old_contain;
451
+ match content_visibility {
452
+ ContentVisibility::Visible => {},
453
+ // `content-visibility:auto` also applies size containment when content
454
+ // is not relevant (and therefore skipped). This is checked in
455
+ // nsIFrame::GetContainSizeAxes.
456
+ ContentVisibility::Auto => {
457
+ new_contain.insert(Contain::LAYOUT | Contain::PAINT | Contain::STYLE)
458
+ },
459
+ ContentVisibility::Hidden => new_contain
460
+ .insert(Contain::LAYOUT | Contain::PAINT | Contain::SIZE | Contain::STYLE),
461
+ }
462
+ if container_type.intersects(ContainerType::INLINE_SIZE) {
463
+ // https://drafts.csswg.org/css-contain-3/#valdef-container-type-inline-size:
464
+ // Applies layout containment, style containment, and inline-size
465
+ // containment to the principal box.
466
+ new_contain.insert(Contain::STYLE | Contain::INLINE_SIZE);
467
+ } else if container_type.intersects(ContainerType::SIZE) {
468
+ // https://drafts.csswg.org/css-contain-3/#valdef-container-type-size:
469
+ // Applies layout containment, style containment, and size
470
+ // containment to the principal box.
471
+ new_contain.insert(Contain::STYLE | Contain::SIZE);
472
+ }
473
+ if new_contain == old_contain {
474
+ debug_assert_eq!(
475
+ box_style.clone_contain(),
476
+ box_style.clone_effective_containment()
477
+ );
478
+ return;
479
+ }
480
+ self.style
481
+ .mutate_box()
482
+ .set_effective_containment(new_contain);
483
+ }
484
+
485
+ /// content-visibility: auto should force contain-intrinsic-size to gain
486
+ /// an auto value
487
+ ///
488
+ /// <https://github.com/w3c/csswg-drafts/issues/8407>
489
+ #[cfg(feature = "gecko")]
490
+ fn adjust_for_contain_intrinsic_size(&mut self) {
491
+ let content_visibility = self.style.get_box().clone_content_visibility();
492
+ if content_visibility != ContentVisibility::Auto {
493
+ return;
494
+ }
495
+
496
+ let pos = self.style.get_position();
497
+ let new_width = pos.clone_contain_intrinsic_width().add_auto_if_needed();
498
+ let new_height = pos.clone_contain_intrinsic_height().add_auto_if_needed();
499
+ if new_width.is_none() && new_height.is_none() {
500
+ return;
501
+ }
502
+
503
+ let pos = self.style.mutate_position();
504
+ if let Some(width) = new_width {
505
+ pos.set_contain_intrinsic_width(width);
506
+ }
507
+ if let Some(height) = new_height {
508
+ pos.set_contain_intrinsic_height(height);
509
+ }
510
+ }
511
+
512
+ /// Handles the relevant sections in:
513
+ ///
514
+ /// https://drafts.csswg.org/css-display/#unbox-html
515
+ ///
516
+ /// And forbidding display: contents in pseudo-elements, at least for now.
517
+ #[cfg(feature = "gecko")]
518
+ fn adjust_for_prohibited_display_contents<E>(&mut self, element: Option<E>)
519
+ where
520
+ E: TElement,
521
+ {
522
+ if self.style.get_box().clone_display() != Display::Contents {
523
+ return;
524
+ }
525
+
526
+ // FIXME(emilio): ::before and ::after should support display: contents, see bug 1418138.
527
+ if self.style.pseudo.is_some_and(|p| !p.is_element_backed()) {
528
+ self.style.mutate_box().set_display(Display::Inline);
529
+ return;
530
+ }
531
+
532
+ let element = match element {
533
+ Some(e) => e,
534
+ None => return,
535
+ };
536
+
537
+ if is_effective_display_none_for_display_contents(element) {
538
+ self.style.mutate_box().set_display(Display::None);
539
+ }
540
+ }
541
+
542
+ /// <textarea>'s editor root needs to inherit the overflow value from its
543
+ /// parent, but we need to make sure it's still scrollable.
544
+ #[cfg(feature = "gecko")]
545
+ fn adjust_for_text_control_editing_root(&mut self) {
546
+ use crate::properties::longhands::white_space_collapse::computed_value::T as WhiteSpaceCollapse;
547
+ use crate::selector_parser::PseudoElement;
548
+
549
+ if self.style.pseudo != Some(&PseudoElement::MozTextControlEditingRoot) {
550
+ return;
551
+ }
552
+
553
+ let old_collapse = self.style.get_inherited_text().clone_white_space_collapse();
554
+ let new_collapse = match old_collapse {
555
+ WhiteSpaceCollapse::Preserve | WhiteSpaceCollapse::BreakSpaces => old_collapse,
556
+ WhiteSpaceCollapse::Collapse
557
+ | WhiteSpaceCollapse::PreserveSpaces
558
+ | WhiteSpaceCollapse::PreserveBreaks => WhiteSpaceCollapse::Preserve,
559
+ };
560
+ if new_collapse != old_collapse {
561
+ self.style
562
+ .mutate_inherited_text()
563
+ .set_white_space_collapse(new_collapse);
564
+ }
565
+ }
566
+
567
+ /// If a <fieldset> has grid/flex display type, we need to inherit
568
+ /// this type into its ::-moz-fieldset-content anonymous box.
569
+ #[cfg(feature = "gecko")]
570
+ fn adjust_for_fieldset_content(&mut self) {
571
+ use crate::selector_parser::PseudoElement;
572
+ if self.style.pseudo != Some(&PseudoElement::MozFieldsetContent) {
573
+ return;
574
+ }
575
+ let parent_display = self.style.get_parent_box().clone_display();
576
+ debug_assert!(
577
+ !parent_display.is_contents(),
578
+ "How did we create a fieldset-content box with display: contents?"
579
+ );
580
+ let new_display = match parent_display {
581
+ Display::Flex | Display::InlineFlex => Some(Display::Flex),
582
+ Display::Grid | Display::InlineGrid => Some(Display::Grid),
583
+ _ => None,
584
+ };
585
+ if let Some(new_display) = new_display {
586
+ self.style.mutate_box().set_display(new_display);
587
+ }
588
+ }
589
+
590
+ /// -moz-center, -moz-left and -moz-right are used for HTML's alignment.
591
+ ///
592
+ /// This is covering the <div align="right"><table>...</table></div> case.
593
+ ///
594
+ /// In this case, we don't want to inherit the text alignment into the
595
+ /// table.
596
+ fn adjust_for_table_text_align(&mut self) {
597
+ use crate::properties::longhands::text_align::computed_value::T as TextAlign;
598
+ if self.style.get_box().clone_display() != Display::Table {
599
+ return;
600
+ }
601
+
602
+ match self.style.get_inherited_text().clone_text_align() {
603
+ TextAlign::MozLeft | TextAlign::MozCenter | TextAlign::MozRight => {},
604
+ _ => return,
605
+ }
606
+
607
+ self.style
608
+ .mutate_inherited_text()
609
+ .set_text_align(TextAlign::Start)
610
+ }
611
+
612
+ #[cfg(feature = "gecko")]
613
+ fn should_suppress_linebreak<E>(&self, element: Option<E>) -> bool
614
+ where
615
+ E: TElement,
616
+ {
617
+ // Line break suppression should only be propagated to in-flow children.
618
+ if self.style.is_floating() || self.style.is_absolutely_positioned() {
619
+ return false;
620
+ }
621
+ let parent_display = self.style.get_parent_box().clone_display();
622
+ if self
623
+ .style
624
+ .get_parent_flags()
625
+ .contains(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK)
626
+ {
627
+ // Line break suppression is propagated to any children of
628
+ // line participants, and across display: contents boundaries.
629
+ if parent_display.is_line_participant() || parent_display.is_contents() {
630
+ return true;
631
+ }
632
+ }
633
+ match self.style.get_box().clone_display() {
634
+ // Ruby base and text are always non-breakable.
635
+ Display::RubyBase | Display::RubyText => true,
636
+ // Ruby base container and text container are breakable.
637
+ // Non-HTML elements may not form ruby base / text container because
638
+ // they may not respect ruby-internal display values, so we can't
639
+ // make them escaped from line break suppression.
640
+ // Note that, when certain HTML tags, e.g. form controls, have ruby
641
+ // level container display type, they could also escape from the
642
+ // line break suppression flag while they shouldn't. However, it is
643
+ // generally fine as far as they can't break the line inside them.
644
+ Display::RubyBaseContainer | Display::RubyTextContainer
645
+ if element.is_none_or(|e| e.is_html_element()) =>
646
+ {
647
+ false
648
+ },
649
+ // Anything else is non-breakable if and only if its layout parent
650
+ // has a ruby display type, because any of the ruby boxes can be
651
+ // anonymous.
652
+ _ => parent_display.is_ruby_type(),
653
+ }
654
+ }
655
+
656
+ /// Do ruby-related style adjustments, which include:
657
+ /// * propagate the line break suppression flag,
658
+ /// * inlinify block descendants,
659
+ /// * suppress border and padding for ruby level containers,
660
+ /// * correct unicode-bidi.
661
+ #[cfg(feature = "gecko")]
662
+ fn adjust_for_ruby<E>(&mut self, element: Option<E>)
663
+ where
664
+ E: TElement,
665
+ {
666
+ use crate::properties::longhands::unicode_bidi::computed_value::T as UnicodeBidi;
667
+
668
+ let self_display = self.style.get_box().clone_display();
669
+ // Check whether line break should be suppressed for this element.
670
+ if self.should_suppress_linebreak(element) {
671
+ self.style
672
+ .add_flags(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK);
673
+ // Inlinify the display type if allowed.
674
+ if !self.skip_item_display_fixup(element) {
675
+ let inline_display = self_display.inlinify();
676
+ if self_display != inline_display {
677
+ self.style
678
+ .mutate_box()
679
+ .set_adjusted_display(inline_display, false);
680
+ }
681
+ }
682
+ }
683
+ // Suppress border and padding for ruby level containers.
684
+ // This is actually not part of the spec. It is currently unspecified
685
+ // how border and padding should be handled for ruby level container,
686
+ // and suppressing them here make it easier for layout to handle.
687
+ if self_display.is_ruby_level_container() {
688
+ self.style.reset_border_struct();
689
+ self.style.reset_padding_struct();
690
+ }
691
+
692
+ // Force bidi isolation on all internal ruby boxes and ruby container
693
+ // per spec https://drafts.csswg.org/css-ruby-1/#bidi
694
+ if self_display.is_ruby_type() {
695
+ let new_value = match self.style.get_text().clone_unicode_bidi() {
696
+ UnicodeBidi::Normal | UnicodeBidi::Embed => Some(UnicodeBidi::Isolate),
697
+ UnicodeBidi::BidiOverride => Some(UnicodeBidi::IsolateOverride),
698
+ _ => None,
699
+ };
700
+ if let Some(new_value) = new_value {
701
+ self.style.mutate_text().set_unicode_bidi(new_value);
702
+ }
703
+ }
704
+ }
705
+
706
+ /// Computes the RELEVANT_LINK_VISITED flag based on the parent style and on
707
+ /// whether we're a relevant link.
708
+ ///
709
+ /// NOTE(emilio): We don't do this for text styles, which is... dubious, but
710
+ /// Gecko doesn't seem to do it either. It's extremely easy to do if needed
711
+ /// though.
712
+ ///
713
+ /// FIXME(emilio): This isn't technically a style adjustment thingie, could
714
+ /// it move somewhere else?
715
+ fn adjust_for_visited<E>(&mut self, element: Option<E>)
716
+ where
717
+ E: TElement,
718
+ {
719
+ if !self.style.has_visited_style() {
720
+ return;
721
+ }
722
+
723
+ let is_link_element = self.style.pseudo.is_none() && element.is_some_and(|e| e.is_link());
724
+
725
+ if !is_link_element {
726
+ return;
727
+ }
728
+
729
+ if element.unwrap().is_visited_link() {
730
+ self.style
731
+ .add_flags(ComputedValueFlags::IS_RELEVANT_LINK_VISITED);
732
+ } else {
733
+ // Need to remove to handle unvisited link inside visited.
734
+ self.style
735
+ .remove_flags(ComputedValueFlags::IS_RELEVANT_LINK_VISITED);
736
+ }
737
+ }
738
+
739
+ /// Resolves "justify-items: legacy" based on the inherited style if needed
740
+ /// to comply with:
741
+ ///
742
+ /// <https://drafts.csswg.org/css-align/#valdef-justify-items-legacy>
743
+ #[cfg(feature = "gecko")]
744
+ fn adjust_for_justify_items(&mut self) {
745
+ use crate::values::specified::align;
746
+ let justify_items = self.style.get_position().clone_justify_items();
747
+ if justify_items.specified != align::JustifyItems::legacy() {
748
+ return;
749
+ }
750
+
751
+ let parent_justify_items = self.style.get_parent_position().clone_justify_items();
752
+
753
+ if !parent_justify_items.computed.contains(AlignFlags::LEGACY) {
754
+ return;
755
+ }
756
+
757
+ if parent_justify_items.computed == justify_items.computed {
758
+ return;
759
+ }
760
+
761
+ self.style
762
+ .mutate_position()
763
+ .set_computed_justify_items(parent_justify_items.computed);
764
+ }
765
+
766
+ /// If '-webkit-appearance' is 'menulist' on a <select> element then
767
+ /// the computed value of 'line-height' is 'normal'.
768
+ ///
769
+ /// https://github.com/w3c/csswg-drafts/issues/3257
770
+ fn adjust_for_appearance<E>(&mut self, element: Option<E>)
771
+ where
772
+ E: TElement,
773
+ {
774
+ use crate::properties::longhands::appearance::computed_value::T as Appearance;
775
+ use crate::properties::longhands::line_height::computed_value::T as LineHeight;
776
+
777
+ let box_ = self.style.get_box();
778
+ let appearance = match box_.clone_appearance() {
779
+ Appearance::Auto => box_.clone__moz_default_appearance(),
780
+ a => a,
781
+ };
782
+
783
+ if appearance == Appearance::Menulist {
784
+ if self.style.get_font().clone_line_height() == LineHeight::normal() {
785
+ return;
786
+ }
787
+ if self.style.pseudo.is_some() {
788
+ return;
789
+ }
790
+ let is_html_select_element =
791
+ element.is_some_and(|e| e.is_html_element() && e.local_name() == &*atom!("select"));
792
+ if !is_html_select_element {
793
+ return;
794
+ }
795
+ self.style
796
+ .mutate_font()
797
+ .set_line_height(LineHeight::normal());
798
+ }
799
+ }
800
+
801
+ /// A legacy ::marker (i.e. no 'content') without an author-specified 'font-family'
802
+ /// and 'list-style-type:disc|circle|square|disclosure-closed|disclosure-open'
803
+ /// is assigned 'font-family:-moz-bullet-font'. (This is for <ul><li> etc.)
804
+ /// We don't want synthesized italic/bold for this font, so turn that off too.
805
+ /// Likewise for 'letter/word-spacing' -- unless the author specified it then reset
806
+ /// them to their initial value because traditionally we never added such spacing
807
+ /// between a legacy bullet and the list item's content, so we keep that behavior
808
+ /// for web-compat reasons.
809
+ /// We intentionally don't check 'list-style-image' below since we want it to use
810
+ /// the same font as its fallback ('list-style-type') in case it fails to load.
811
+ #[cfg(feature = "gecko")]
812
+ fn adjust_for_marker_pseudo(&mut self, author_specified_properties: &LonghandIdSet) {
813
+ use crate::values::computed::counters::Content;
814
+ use crate::values::computed::font::{FontFamily, FontSynthesis, FontSynthesisStyle};
815
+ use crate::values::computed::text::{LetterSpacing, WordSpacing};
816
+
817
+ let is_legacy_marker = self.style.pseudo.is_some_and(|p| p.is_marker())
818
+ && self.style.get_list().clone_list_style_type().is_bullet()
819
+ && self.style.get_counters().clone_content() == Content::Normal;
820
+ if !is_legacy_marker {
821
+ return;
822
+ }
823
+ if !author_specified_properties.contains(LonghandId::FontFamily) {
824
+ self.style
825
+ .mutate_font()
826
+ .set_font_family(FontFamily::moz_bullet().clone());
827
+
828
+ // FIXME(mats): We can remove this if support for font-synthesis is added to @font-face rules.
829
+ // Then we can add it to the @font-face rule in html.css instead.
830
+ // https://github.com/w3c/csswg-drafts/issues/6081
831
+ if !author_specified_properties.contains(LonghandId::FontSynthesisWeight) {
832
+ self.style
833
+ .mutate_font()
834
+ .set_font_synthesis_weight(FontSynthesis::None);
835
+ }
836
+ if !author_specified_properties.contains(LonghandId::FontSynthesisStyle) {
837
+ self.style
838
+ .mutate_font()
839
+ .set_font_synthesis_style(FontSynthesisStyle::None);
840
+ }
841
+ }
842
+ if !author_specified_properties.contains(LonghandId::LetterSpacing) {
843
+ self.style
844
+ .mutate_inherited_text()
845
+ .set_letter_spacing(LetterSpacing::normal());
846
+ }
847
+ if !author_specified_properties.contains(LonghandId::WordSpacing) {
848
+ self.style
849
+ .mutate_inherited_text()
850
+ .set_word_spacing(WordSpacing::normal());
851
+ }
852
+ }
853
+
854
+ /// Performs adjustments for position-try-fallbacks. The properties that need adjustments here
855
+ /// are luckily not affected by previous adjustments nor by other computed-value-time effects,
856
+ /// so we can just perform them here.
857
+ ///
858
+ /// NOTE(emilio): If we ever perform the interleaving dance, this could / should probably move
859
+ /// around to the specific properties' to_computed_value implementations, but that seems
860
+ /// overkill for now.
861
+ fn adjust_for_try_tactic(&mut self, tactic: &PositionTryFallbacksTryTactic) {
862
+ debug_assert!(!tactic.is_empty());
863
+ // TODO: This is supposed to use the containing block's WM (bug 1995256).
864
+ let wm = self.style.writing_mode;
865
+ // TODO: Flip inset / margin / sizes percentages and anchor lookup sides as necessary.
866
+ for tactic in tactic.iter() {
867
+ use PositionTryFallbacksTryTacticKeyword::*;
868
+ match tactic {
869
+ FlipBlock => {
870
+ self.flip_self_alignment(/* block = */ true);
871
+ self.flip_insets_and_margins(/* horizontal = */ wm.is_vertical());
872
+ },
873
+ FlipInline => {
874
+ self.flip_self_alignment(/* block = */ false);
875
+ self.flip_insets_and_margins(/* horizontal = */ wm.is_horizontal());
876
+ },
877
+ FlipX => {
878
+ self.flip_self_alignment(/* block = */ wm.is_vertical());
879
+ self.flip_insets_and_margins(/* horizontal = */ true);
880
+ },
881
+ FlipY => {
882
+ self.flip_self_alignment(/* block = */ wm.is_horizontal());
883
+ self.flip_insets_and_margins(/* horizontal = */ false);
884
+ },
885
+ FlipStart => {
886
+ self.flip_start();
887
+ },
888
+ }
889
+ self.apply_position_area_tactic(*tactic);
890
+ }
891
+ }
892
+
893
+ fn apply_position_area_tactic(&mut self, tactic: PositionTryFallbacksTryTacticKeyword) {
894
+ let pos = self.style.get_position();
895
+ let old = pos.clone_position_area();
896
+ let wm = self.style.writing_mode;
897
+ let new = old.with_tactic(wm, tactic);
898
+ if new == old {
899
+ return;
900
+ }
901
+ let pos = self.style.mutate_position();
902
+ pos.set_position_area(new);
903
+ }
904
+
905
+ // TODO: Could avoid some clones here and below.
906
+ fn swap_insets(&mut self, a_side: PhysicalSide, b_side: PhysicalSide) {
907
+ debug_assert_ne!(a_side, b_side);
908
+ let pos = self.style.mutate_position();
909
+ let mut a = pos.get_inset(a_side).clone();
910
+ a.try_tactic_adjustment(a_side, b_side);
911
+ let mut b = pos.get_inset(b_side).clone();
912
+ b.try_tactic_adjustment(b_side, a_side);
913
+ pos.set_inset(a_side, b);
914
+ pos.set_inset(b_side, a);
915
+ }
916
+
917
+ fn swap_margins(&mut self, a_side: PhysicalSide, b_side: PhysicalSide) {
918
+ debug_assert_ne!(a_side, b_side);
919
+ let margin = self.style.get_margin();
920
+ let mut a = margin.get_margin(a_side).clone();
921
+ a.try_tactic_adjustment(a_side, b_side);
922
+ let mut b = margin.get_margin(b_side).clone();
923
+ b.try_tactic_adjustment(b_side, a_side);
924
+ let margin = self.style.mutate_margin();
925
+ margin.set_margin(a_side, b);
926
+ margin.set_margin(b_side, a);
927
+ }
928
+
929
+ fn swap_sizes(&mut self, block_start: PhysicalSide, inline_start: PhysicalSide) {
930
+ let pos = self.style.mutate_position();
931
+ let mut min_width = pos.clone_min_width();
932
+ min_width.try_tactic_adjustment(inline_start, block_start);
933
+ let mut max_width = pos.clone_max_width();
934
+ max_width.try_tactic_adjustment(inline_start, block_start);
935
+ let mut width = pos.clone_width();
936
+ width.try_tactic_adjustment(inline_start, block_start);
937
+
938
+ let mut min_height = pos.clone_min_height();
939
+ min_height.try_tactic_adjustment(block_start, inline_start);
940
+ let mut max_height = pos.clone_max_height();
941
+ max_height.try_tactic_adjustment(block_start, inline_start);
942
+ let mut height = pos.clone_height();
943
+ height.try_tactic_adjustment(block_start, inline_start);
944
+
945
+ let pos = self.style.mutate_position();
946
+ pos.set_width(height);
947
+ pos.set_height(width);
948
+ pos.set_max_width(max_height);
949
+ pos.set_max_height(max_width);
950
+ pos.set_min_width(min_height);
951
+ pos.set_min_height(min_width);
952
+ }
953
+
954
+ fn flip_start(&mut self) {
955
+ let wm = self.style.writing_mode;
956
+ let bs = wm.block_start_physical_side();
957
+ let is = wm.inline_start_physical_side();
958
+ let be = wm.block_end_physical_side();
959
+ let ie = wm.inline_end_physical_side();
960
+ self.swap_sizes(bs, is);
961
+ self.swap_insets(bs, is);
962
+ self.swap_insets(ie, be);
963
+ self.swap_margins(bs, is);
964
+ self.swap_margins(ie, be);
965
+ self.flip_alignment_start();
966
+ }
967
+
968
+ fn flip_insets_and_margins(&mut self, horizontal: bool) {
969
+ if horizontal {
970
+ self.swap_insets(PhysicalSide::Left, PhysicalSide::Right);
971
+ self.swap_margins(PhysicalSide::Left, PhysicalSide::Right);
972
+ } else {
973
+ self.swap_insets(PhysicalSide::Top, PhysicalSide::Bottom);
974
+ self.swap_margins(PhysicalSide::Top, PhysicalSide::Bottom);
975
+ }
976
+ }
977
+
978
+ fn flip_alignment_start(&mut self) {
979
+ let pos = self.style.get_position();
980
+ let align = pos.clone_align_self();
981
+ let mut justify = pos.clone_justify_self();
982
+ if align == justify {
983
+ return;
984
+ }
985
+
986
+ // Fix-up potential justify-self: {left, right} values which might end up as alignment
987
+ // values.
988
+ if matches!(justify.value(), AlignFlags::LEFT | AlignFlags::RIGHT) {
989
+ let left = justify.value() == AlignFlags::LEFT;
990
+ let ltr = self.style.writing_mode.is_bidi_ltr();
991
+ justify = justify.with_value(if left == ltr {
992
+ AlignFlags::SELF_START
993
+ } else {
994
+ AlignFlags::SELF_END
995
+ });
996
+ }
997
+
998
+ let pos = self.style.mutate_position();
999
+ pos.set_align_self(justify);
1000
+ pos.set_justify_self(align);
1001
+ }
1002
+
1003
+ fn flip_self_alignment(&mut self, block: bool) {
1004
+ let pos = self.style.get_position();
1005
+ let cur = if block {
1006
+ pos.clone_align_self()
1007
+ } else {
1008
+ pos.clone_justify_self()
1009
+ };
1010
+ let flipped = cur.flip_position();
1011
+ if flipped == cur {
1012
+ return;
1013
+ }
1014
+ let pos = self.style.mutate_position();
1015
+ if block {
1016
+ pos.set_align_self(flipped);
1017
+ } else {
1018
+ pos.set_justify_self(flipped);
1019
+ }
1020
+ }
1021
+
1022
+ /// Adjusts the style to account for various fixups that don't fit naturally into the cascade.
1023
+ #[allow(unused_variables)]
1024
+ pub fn adjust<E>(
1025
+ &mut self,
1026
+ layout_parent_style: &ComputedValues,
1027
+ element: Option<E>,
1028
+ try_tactic: &PositionTryFallbacksTryTactic,
1029
+ author_specified_properties: &LonghandIdSet,
1030
+ ) where
1031
+ E: TElement,
1032
+ {
1033
+ if cfg!(debug_assertions) {
1034
+ if let Some(e) = element {
1035
+ if let Some(p) = e.implemented_pseudo_element() {
1036
+ // It'd be nice to assert `self.style.pseudo == Some(&pseudo)`,
1037
+ // but we do resolve ::-moz-list pseudos on ::before / ::after
1038
+ // content, sigh.
1039
+ debug_assert!(
1040
+ self.style.pseudo.is_some(),
1041
+ "Someone really messed up (no pseudo style for {e:?}, {p:?})"
1042
+ );
1043
+ }
1044
+ }
1045
+ }
1046
+ // FIXME(emilio): The apply_declarations callsite in Servo's
1047
+ // animation, and the font stuff for Gecko
1048
+ // (Stylist::compute_for_declarations) should pass an element to
1049
+ // cascade(), then we can make this assertion hold everywhere.
1050
+ // debug_assert!(
1051
+ // element.is_some() || self.style.pseudo.is_some(),
1052
+ // "Should always have an element around for non-pseudo styles"
1053
+ // );
1054
+
1055
+ self.adjust_for_visited(element);
1056
+ #[cfg(feature = "gecko")]
1057
+ {
1058
+ self.adjust_for_prohibited_display_contents(element);
1059
+ self.adjust_for_fieldset_content();
1060
+ self.adjust_for_text_control_editing_root();
1061
+ }
1062
+ self.adjust_for_top_layer();
1063
+ self.blockify_if_necessary(layout_parent_style, element);
1064
+ #[cfg(feature = "gecko")]
1065
+ self.adjust_for_webkit_line_clamp();
1066
+ self.adjust_for_position();
1067
+ self.adjust_for_overflow();
1068
+ #[cfg(feature = "gecko")]
1069
+ {
1070
+ self.adjust_for_contain();
1071
+ self.adjust_for_contain_intrinsic_size();
1072
+ self.adjust_for_justify_items();
1073
+ }
1074
+ self.adjust_for_table_text_align();
1075
+ self.adjust_for_writing_mode(layout_parent_style);
1076
+ #[cfg(feature = "gecko")]
1077
+ self.adjust_for_ruby(element);
1078
+ self.adjust_for_appearance(element);
1079
+ #[cfg(feature = "gecko")]
1080
+ self.adjust_for_marker_pseudo(author_specified_properties);
1081
+ if !try_tactic.is_empty() {
1082
+ self.adjust_for_try_tactic(try_tactic);
1083
+ }
1084
+ self.set_bits();
1085
+ }
1086
+ }