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,427 @@
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
+ #![deny(unsafe_code)]
6
+
7
+ //! The rule tree.
8
+
9
+ use crate::applicable_declarations::{ApplicableDeclarationList, CascadePriority};
10
+ use crate::properties::{LonghandIdSet, PropertyDeclarationBlock};
11
+ use crate::shared_lock::{Locked, StylesheetGuards};
12
+ use crate::stylesheets::layer_rule::LayerOrder;
13
+ use servo_arc::ArcBorrow;
14
+ use smallvec::SmallVec;
15
+ use std::io::{self, Write};
16
+
17
+ mod core;
18
+ pub mod level;
19
+ mod map;
20
+ mod source;
21
+ mod unsafe_box;
22
+
23
+ pub use self::core::{RuleTree, StrongRuleNode};
24
+ pub use self::level::{CascadeLevel, CascadeOrigin, ShadowCascadeOrder};
25
+ pub use self::source::StyleSource;
26
+
27
+ bitflags! {
28
+ /// Flags that are part of the cascade priority, and that we use to track
29
+ /// information about where the rule came from.
30
+ #[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
31
+ pub struct RuleCascadeFlags: u8 {
32
+ /// Whether the rule is inside a @starting-style block.
33
+ const STARTING_STYLE = 1 << 0;
34
+ /// Whether the rule is inside an @appearance-base block.
35
+ const APPEARANCE_BASE = 1 << 1;
36
+ }
37
+ }
38
+
39
+ malloc_size_of::malloc_size_of_is_0!(RuleCascadeFlags);
40
+
41
+ impl RuleTree {
42
+ fn dump<W: Write>(&self, guards: &StylesheetGuards, writer: &mut W) {
43
+ let _ = writeln!(writer, " + RuleTree");
44
+ self.root().dump(guards, writer, 0);
45
+ }
46
+
47
+ /// Dump the rule tree to stdout.
48
+ pub fn dump_stdout(&self, guards: &StylesheetGuards) {
49
+ let mut stdout = io::stdout();
50
+ self.dump(guards, &mut stdout);
51
+ }
52
+
53
+ /// Inserts the given rules, that must be in proper order by specifity, and
54
+ /// returns the corresponding rule node representing the last inserted one.
55
+ ///
56
+ /// !important rules are detected and inserted into the appropriate position
57
+ /// in the rule tree. This allows selector matching to ignore importance,
58
+ /// while still maintaining the appropriate cascade order in the rule tree.
59
+ pub fn insert_ordered_rules_with_important<'a, I>(
60
+ &self,
61
+ iter: I,
62
+ guards: &StylesheetGuards,
63
+ ) -> StrongRuleNode
64
+ where
65
+ I: Iterator<Item = (StyleSource, CascadePriority)>,
66
+ {
67
+ let mut current = self.root().clone();
68
+
69
+ let mut found_important = false;
70
+
71
+ let mut important_author = SmallVec::<[(StyleSource, CascadePriority); 4]>::new();
72
+ let mut important_user = SmallVec::<[(StyleSource, CascadePriority); 4]>::new();
73
+ let mut important_ua = SmallVec::<[(StyleSource, CascadePriority); 4]>::new();
74
+ let mut transition = None;
75
+
76
+ for (source, priority) in iter {
77
+ let level = priority.cascade_level();
78
+ debug_assert!(!level.is_important(), "Important levels handled internally");
79
+
80
+ let any_important = {
81
+ let pdb = source.read(level.guard(guards));
82
+ pdb.any_important()
83
+ };
84
+
85
+ if any_important {
86
+ found_important = true;
87
+ match level.origin() {
88
+ CascadeOrigin::Author => {
89
+ important_author.push((source.clone(), priority.important()))
90
+ },
91
+ CascadeOrigin::UA => important_ua.push((source.clone(), priority.important())),
92
+ CascadeOrigin::User => {
93
+ important_user.push((source.clone(), priority.important()))
94
+ },
95
+ _ => {},
96
+ };
97
+ }
98
+
99
+ // We don't optimize out empty rules, even though we could.
100
+ //
101
+ // Inspector relies on every rule being inserted in the normal level
102
+ // at least once, in order to return the rules with the correct
103
+ // specificity order.
104
+ //
105
+ // TODO(emilio): If we want to apply these optimizations without
106
+ // breaking inspector's expectations, we'd need to run
107
+ // selector-matching again at the inspector's request. That may or
108
+ // may not be a better trade-off.
109
+ if level.origin() == CascadeOrigin::Transitions && found_important {
110
+ // There can be at most one transition, and it will come at
111
+ // the end of the iterator. Stash it and apply it after
112
+ // !important rules.
113
+ debug_assert!(transition.is_none());
114
+ transition = Some(source);
115
+ } else {
116
+ current = current.ensure_child(self.root(), source, priority);
117
+ }
118
+ }
119
+
120
+ // Early-return in the common case of no !important declarations.
121
+ if !found_important {
122
+ return current;
123
+ }
124
+
125
+ // Insert important declarations, in order of increasing importance,
126
+ // followed by any transition rule.
127
+ //
128
+ // Important rules are sorted differently from unimportant ones by
129
+ // shadow order and cascade order.
130
+ if !important_author.is_empty()
131
+ && important_author.first().unwrap().1 != important_author.last().unwrap().1
132
+ {
133
+ // We only need to sort if the important rules come from
134
+ // different trees, but we need this sort to be stable.
135
+ //
136
+ // FIXME(emilio): This could maybe be smarter, probably by chunking
137
+ // the important rules while inserting, and iterating the outer
138
+ // chunks in reverse order.
139
+ //
140
+ // That is, if we have rules with levels like: -1 -1 -1 0 0 0 1 1 1,
141
+ // we're really only sorting the chunks, while keeping elements
142
+ // inside the same chunk already sorted. Seems like we could try to
143
+ // keep a SmallVec-of-SmallVecs with the chunks and just iterate the
144
+ // outer in reverse.
145
+ important_author.sort_by_key(|&(_, priority)| priority);
146
+ }
147
+
148
+ for (source, priority) in important_author.drain(..) {
149
+ current = current.ensure_child(self.root(), source, priority);
150
+ }
151
+
152
+ for (source, priority) in important_user.drain(..) {
153
+ current = current.ensure_child(self.root(), source, priority);
154
+ }
155
+
156
+ for (source, priority) in important_ua.drain(..) {
157
+ current = current.ensure_child(self.root(), source, priority);
158
+ }
159
+
160
+ if let Some(source) = transition {
161
+ current = current.ensure_child(
162
+ self.root(),
163
+ source,
164
+ CascadePriority::new(
165
+ CascadeLevel::new(CascadeOrigin::Transitions),
166
+ LayerOrder::root(),
167
+ RuleCascadeFlags::empty(),
168
+ ),
169
+ );
170
+ }
171
+
172
+ current
173
+ }
174
+
175
+ /// Given a list of applicable declarations, insert the rules and return the
176
+ /// corresponding rule node.
177
+ pub fn compute_rule_node(
178
+ &self,
179
+ applicable_declarations: &mut ApplicableDeclarationList,
180
+ guards: &StylesheetGuards,
181
+ ) -> StrongRuleNode {
182
+ self.insert_ordered_rules_with_important(
183
+ applicable_declarations.drain(..).map(|d| d.for_rule_tree()),
184
+ guards,
185
+ )
186
+ }
187
+
188
+ /// Insert the given rules, that must be in proper order by specifity, and
189
+ /// return the corresponding rule node representing the last inserted one.
190
+ pub fn insert_ordered_rules<'a, I>(&self, iter: I) -> StrongRuleNode
191
+ where
192
+ I: Iterator<Item = (StyleSource, CascadePriority)>,
193
+ {
194
+ self.insert_ordered_rules_from(self.root().clone(), iter)
195
+ }
196
+
197
+ fn insert_ordered_rules_from<'a, I>(&self, from: StrongRuleNode, iter: I) -> StrongRuleNode
198
+ where
199
+ I: Iterator<Item = (StyleSource, CascadePriority)>,
200
+ {
201
+ let mut current = from;
202
+ for (source, priority) in iter {
203
+ current = current.ensure_child(self.root(), source, priority);
204
+ }
205
+ current
206
+ }
207
+
208
+ /// Replaces a rule in a given level (if present) for another rule.
209
+ ///
210
+ /// Returns the resulting node that represents the new path, or None if
211
+ /// the old path is still valid.
212
+ pub fn update_rule_at_level(
213
+ &self,
214
+ level: CascadeLevel,
215
+ layer_order: LayerOrder,
216
+ pdb: Option<ArcBorrow<Locked<PropertyDeclarationBlock>>>,
217
+ path: &StrongRuleNode,
218
+ guards: &StylesheetGuards,
219
+ important_rules_changed: &mut bool,
220
+ ) -> Option<StrongRuleNode> {
221
+ // TODO(emilio): Being smarter with lifetimes we could avoid a bit of
222
+ // the refcount churn.
223
+ let mut current = path.clone();
224
+ *important_rules_changed = false;
225
+
226
+ // First walk up until the first less-or-equally specific rule.
227
+ let mut children = SmallVec::<[_; 10]>::new();
228
+ while current.cascade_priority().cascade_level() > level {
229
+ children.push((
230
+ current.style_source().unwrap().clone(),
231
+ current.cascade_priority(),
232
+ ));
233
+ current = current.parent().unwrap().clone();
234
+ }
235
+
236
+ let cascade_priority = CascadePriority::new(level, layer_order, RuleCascadeFlags::empty());
237
+
238
+ // Then remove the one at the level we want to replace, if any.
239
+ //
240
+ // NOTE: Here we assume that only one rule can be at the level + priority we're replacing,
241
+ // which holds because we only use this for HTML style attribute, animations and transition
242
+ // rules.
243
+ //
244
+ // This is certainly true for HTML style attribute rules, animations, transitions, and
245
+ // SMIL.
246
+ if current.cascade_priority() == cascade_priority {
247
+ *important_rules_changed |= level.is_important();
248
+
249
+ let current_decls = current.style_source().unwrap().get();
250
+
251
+ // If the only rule at the level we're replacing is exactly the
252
+ // same as `pdb`, we're done, and `path` is still valid.
253
+ if let Some(ref pdb) = pdb {
254
+ // If the only rule at the level we're replacing is exactly the
255
+ // same as `pdb`, we're done, and `path` is still valid.
256
+ //
257
+ // TODO(emilio): Another potential optimization is the one where
258
+ // we can just replace the rule at that level for `pdb`, and
259
+ // then we don't need to re-create the children, and `path` is
260
+ // also equally valid. This is less likely, and would require an
261
+ // in-place mutation of the source, which is, at best, fiddly,
262
+ // so let's skip it for now.
263
+ let is_here_already = ArcBorrow::ptr_eq(pdb, &current_decls.borrow_arc());
264
+ if is_here_already {
265
+ debug!("Picking the fast path in rule replacement");
266
+ return None;
267
+ }
268
+ }
269
+
270
+ current = current.parent().unwrap().clone();
271
+ }
272
+
273
+ // Insert the rule if it's relevant at this level in the cascade.
274
+ //
275
+ // These optimizations are likely to be important, because the levels where replacements
276
+ // apply (style and animations) tend to trigger pretty bad styling cases already.
277
+ if let Some(pdb) = pdb {
278
+ if level.is_important() {
279
+ if pdb.read_with(level.guard(guards)).any_important() {
280
+ current = current.ensure_child(
281
+ self.root(),
282
+ StyleSource::from_declarations(pdb.clone_arc()),
283
+ cascade_priority,
284
+ );
285
+ *important_rules_changed = true;
286
+ }
287
+ } else if pdb.read_with(level.guard(guards)).any_normal() {
288
+ current = current.ensure_child(
289
+ self.root(),
290
+ StyleSource::from_declarations(pdb.clone_arc()),
291
+ cascade_priority,
292
+ );
293
+ }
294
+ }
295
+
296
+ // Now the rule is in the relevant place, push the children as
297
+ // necessary.
298
+ let rule = self.insert_ordered_rules_from(current, children.drain(..).rev());
299
+ Some(rule)
300
+ }
301
+
302
+ /// Returns whether this rule node has any @starting-style rule.
303
+ pub fn has_starting_style(path: &StrongRuleNode) -> bool {
304
+ path.self_and_ancestors().any(|node| {
305
+ node.cascade_priority()
306
+ .flags()
307
+ .intersects(RuleCascadeFlags::STARTING_STYLE)
308
+ })
309
+ }
310
+
311
+ /// Returns new rule nodes without Transitions level rule.
312
+ pub fn remove_transition_rule_if_applicable(path: &StrongRuleNode) -> StrongRuleNode {
313
+ // Return a clone if there is no transition level.
314
+ if path.cascade_level().origin() != CascadeOrigin::Transitions {
315
+ return path.clone();
316
+ }
317
+
318
+ path.parent().unwrap().clone()
319
+ }
320
+
321
+ /// Returns new rule node without rules from declarative animations.
322
+ pub fn remove_animation_rules(&self, path: &StrongRuleNode) -> StrongRuleNode {
323
+ // Return a clone if there are no animation rules.
324
+ if !path.has_animation_or_transition_rules() {
325
+ return path.clone();
326
+ }
327
+
328
+ let iter = path.self_and_ancestors().take_while(|node| {
329
+ node.cascade_level() >= CascadeLevel::new(CascadeOrigin::SMILOverride)
330
+ });
331
+ let mut last = path;
332
+ let mut children = SmallVec::<[_; 10]>::new();
333
+ for node in iter {
334
+ if !node.cascade_level().is_animation() {
335
+ children.push((
336
+ node.style_source().unwrap().clone(),
337
+ node.cascade_priority(),
338
+ ));
339
+ }
340
+ last = node;
341
+ }
342
+
343
+ let rule = self
344
+ .insert_ordered_rules_from(last.parent().unwrap().clone(), children.drain(..).rev());
345
+ rule
346
+ }
347
+ }
348
+
349
+ impl StrongRuleNode {
350
+ /// Get an iterator for this rule node and its ancestors.
351
+ pub fn self_and_ancestors(&self) -> SelfAndAncestors<'_> {
352
+ SelfAndAncestors {
353
+ current: Some(self),
354
+ }
355
+ }
356
+
357
+ /// Returns true if there is either animation or transition level rule.
358
+ pub fn has_animation_or_transition_rules(&self) -> bool {
359
+ self.self_and_ancestors()
360
+ .take_while(|node| {
361
+ node.cascade_level() >= CascadeLevel::new(CascadeOrigin::SMILOverride)
362
+ })
363
+ .any(|node| node.cascade_level().is_animation())
364
+ }
365
+
366
+ /// Get a set of properties whose CascadeLevel are higher than Animations
367
+ /// but not equal to Transitions.
368
+ ///
369
+ /// If there are any custom properties, we set the boolean value of the
370
+ /// returned tuple to true.
371
+ pub fn get_properties_overriding_animations(
372
+ &self,
373
+ guards: &StylesheetGuards,
374
+ ) -> (LonghandIdSet, bool) {
375
+ use crate::properties::PropertyDeclarationId;
376
+
377
+ // We want to iterate over cascade levels that override the animations
378
+ // level, i.e. !important levels and the transitions level.
379
+ //
380
+ // However, we actually want to skip the transitions level because
381
+ // although it is higher in the cascade than animations, when both
382
+ // transitions and animations are present for a given element and
383
+ // property, transitions are suppressed so that they don't actually
384
+ // override animations.
385
+ let iter = self
386
+ .self_and_ancestors()
387
+ .skip_while(|node| node.cascade_level().origin() == CascadeOrigin::Transitions)
388
+ .take_while(|node| node.cascade_level() > CascadeLevel::new(CascadeOrigin::Animations));
389
+ let mut result = (LonghandIdSet::new(), false);
390
+ for node in iter {
391
+ let style = node.style_source().unwrap();
392
+ for (decl, important) in style
393
+ .read(node.cascade_level().guard(guards))
394
+ .declaration_importance_iter()
395
+ {
396
+ // Although we are only iterating over cascade levels that
397
+ // override animations, in a given property declaration block we
398
+ // can have a mixture of !important and non-!important
399
+ // declarations but only the !important declarations actually
400
+ // override animations.
401
+ if important.important() {
402
+ match decl.id() {
403
+ PropertyDeclarationId::Longhand(id) => result.0.insert(id),
404
+ PropertyDeclarationId::Custom(_) => result.1 = true,
405
+ }
406
+ }
407
+ }
408
+ }
409
+ result
410
+ }
411
+ }
412
+
413
+ /// An iterator over a rule node and its ancestors.
414
+ #[derive(Clone)]
415
+ pub struct SelfAndAncestors<'a> {
416
+ current: Option<&'a StrongRuleNode>,
417
+ }
418
+
419
+ impl<'a> Iterator for SelfAndAncestors<'a> {
420
+ type Item = &'a StrongRuleNode;
421
+
422
+ fn next(&mut self) -> Option<Self::Item> {
423
+ self.current.inspect(|node| {
424
+ self.current = node.parent();
425
+ })
426
+ }
427
+ }
@@ -0,0 +1,80 @@
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
+ #![deny(unsafe_code)]
6
+
7
+ use crate::properties::PropertyDeclarationBlock;
8
+ use crate::shared_lock::{Locked, SharedRwLockReadGuard};
9
+ use servo_arc::Arc;
10
+ use std::io::Write;
11
+ use std::ptr;
12
+
13
+ /// A style source for the rule node. It is a declaration block that may come from either a style
14
+ /// rule or a standalone block like animations / transitions / smil / preshints / style attr...
15
+ ///
16
+ /// Keeping the style rule around would provide more debugability, but also causes more
17
+ /// pointer-chasing in the common code-path, which is undesired. If needed, we could keep it around
18
+ /// in debug builds or something along those lines.
19
+ #[derive(Clone, Debug)]
20
+ pub struct StyleSource(Arc<Locked<PropertyDeclarationBlock>>);
21
+
22
+ impl PartialEq for StyleSource {
23
+ fn eq(&self, other: &Self) -> bool {
24
+ Arc::ptr_eq(&self.0, &other.0)
25
+ }
26
+ }
27
+
28
+ impl StyleSource {
29
+ #[inline]
30
+ pub(super) fn key(&self) -> ptr::NonNull<()> {
31
+ self.0.raw_ptr()
32
+ }
33
+
34
+ /// Creates a StyleSource from a PropertyDeclarationBlock.
35
+ #[inline]
36
+ pub fn from_declarations(decls: Arc<Locked<PropertyDeclarationBlock>>) -> Self {
37
+ Self(decls)
38
+ }
39
+
40
+ pub(super) fn dump<W: Write>(&self, guard: &SharedRwLockReadGuard, writer: &mut W) {
41
+ let _ = write!(writer, " -> {:?}", self.read(guard).declarations());
42
+ }
43
+
44
+ /// Read the style source guard, and obtain thus read access to the
45
+ /// underlying property declaration block.
46
+ #[inline]
47
+ pub fn read<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> &'a PropertyDeclarationBlock {
48
+ self.0.read_with(guard)
49
+ }
50
+
51
+ /// Returns the declaration block if applicable, otherwise None.
52
+ #[inline]
53
+ pub fn get(&self) -> &Arc<Locked<PropertyDeclarationBlock>> {
54
+ &self.0
55
+ }
56
+
57
+ /// Marks this block as part of the rule tree.
58
+ #[inline]
59
+ pub fn mark_in_rule_tree(&self) {
60
+ use std::sync::atomic::Ordering;
61
+ if self.0.is_static() {
62
+ // For static pointers, it doesn't matter whether we might be in the rule tree or not,
63
+ // because those are not mutable.
64
+ return;
65
+ }
66
+ // SAFETY: We're only accessing a relaxed atomic inside the locked object, which we know
67
+ // is alive. In theory, we could/should track that boolean outside of the
68
+ // Locked<PropertyDeclarationBlock>, but that is kind of a PITA.
69
+ #[allow(unsafe_code)]
70
+ unsafe {
71
+ // Load before storing: the flag is never cleared, so after the first mark every
72
+ // store is redundant, and an unconditional store would still take the cache line
73
+ // exclusive and invalidate it for every other thread reading this block.
74
+ let immutable = &self.0.read_unchecked().immutable;
75
+ if !immutable.load(Ordering::Relaxed) {
76
+ immutable.store(true, Ordering::Relaxed);
77
+ }
78
+ }
79
+ }
80
+ }
@@ -0,0 +1,78 @@
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
+ #![allow(unsafe_code)]
6
+
7
+ use std::mem::ManuallyDrop;
8
+ use std::ops::Deref;
9
+ use std::ptr;
10
+
11
+ /// An unsafe box, derefs to `T`.
12
+ pub(super) struct UnsafeBox<T> {
13
+ inner: ManuallyDrop<Box<T>>,
14
+ }
15
+
16
+ impl<T> UnsafeBox<T> {
17
+ /// Creates a new unsafe box.
18
+ pub(super) fn from_box(value: Box<T>) -> Self {
19
+ Self {
20
+ inner: ManuallyDrop::new(value),
21
+ }
22
+ }
23
+
24
+ /// Creates a new box from a pointer.
25
+ ///
26
+ /// # Safety
27
+ ///
28
+ /// The input should point to a valid `T`.
29
+ pub(super) unsafe fn from_raw(ptr: *mut T) -> Self {
30
+ unsafe {
31
+ Self {
32
+ inner: ManuallyDrop::new(Box::from_raw(ptr)),
33
+ }
34
+ }
35
+ }
36
+
37
+ /// Creates a new unsafe box from an existing one.
38
+ ///
39
+ /// # Safety
40
+ ///
41
+ /// There is no refcounting or whatever else in an unsafe box, so this
42
+ /// operation can lead to double frees.
43
+ pub(super) unsafe fn clone(this: &Self) -> Self {
44
+ unsafe {
45
+ Self {
46
+ inner: ptr::read(&this.inner),
47
+ }
48
+ }
49
+ }
50
+
51
+ /// Returns a mutable reference to the inner value of this unsafe box.
52
+ ///
53
+ /// # Safety
54
+ ///
55
+ /// Given `Self::clone`, nothing prevents anyone from creating
56
+ /// multiple mutable references to the inner value, which is completely UB.
57
+ pub(crate) unsafe fn deref_mut(this: &mut Self) -> &mut T {
58
+ &mut this.inner
59
+ }
60
+
61
+ /// Drops the inner value of this unsafe box.
62
+ ///
63
+ /// # Safety
64
+ ///
65
+ /// Given this doesn't consume the unsafe box itself, this has the same
66
+ /// safety caveats as `ManuallyDrop::drop`.
67
+ pub(super) unsafe fn drop(this: &mut Self) {
68
+ unsafe { ManuallyDrop::drop(&mut this.inner) }
69
+ }
70
+ }
71
+
72
+ impl<T> Deref for UnsafeBox<T> {
73
+ type Target = T;
74
+
75
+ fn deref(&self) -> &Self::Target {
76
+ &self.inner
77
+ }
78
+ }
@@ -0,0 +1,80 @@
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
+ //! Stack-scoped thread-local storage for rayon thread pools.
6
+
7
+ #![allow(unsafe_code)]
8
+ #![deny(missing_docs)]
9
+
10
+ use crate::global_style_data::STYLO_MAX_THREADS;
11
+ use std::cell::{Ref, RefCell, RefMut};
12
+ use std::ops::DerefMut;
13
+
14
+ /// A scoped TLS set, that is alive during the `'scope` lifetime.
15
+ ///
16
+ /// We use this on Servo to construct thread-local contexts, but clear them once
17
+ /// we're done with restyling.
18
+ ///
19
+ /// Note that the cleanup is done on the thread that owns the scoped TLS, thus
20
+ /// the Send bound.
21
+ pub struct ScopedTLS<'scope, T: Send> {
22
+ pool: Option<&'scope rayon::ThreadPool>,
23
+ slots: [RefCell<Option<T>>; STYLO_MAX_THREADS],
24
+ }
25
+
26
+ /// The scoped TLS is `Sync` because no more than one worker thread can access a
27
+ /// given slot.
28
+ unsafe impl<'scope, T: Send> Sync for ScopedTLS<'scope, T> {}
29
+
30
+ impl<'scope, T: Send> ScopedTLS<'scope, T> {
31
+ /// Create a new scoped TLS that will last as long as this rayon threadpool
32
+ /// reference.
33
+ pub fn new(pool: Option<&'scope rayon::ThreadPool>) -> Self {
34
+ debug_assert!(pool.is_none_or(|p| p.current_num_threads() <= STYLO_MAX_THREADS));
35
+ ScopedTLS {
36
+ pool,
37
+ slots: Default::default(),
38
+ }
39
+ }
40
+
41
+ /// Returns the index corresponding to the calling thread in the thread pool.
42
+ #[inline]
43
+ pub fn current_thread_index(&self) -> usize {
44
+ self.pool.map_or(0, |p| p.current_thread_index().unwrap())
45
+ }
46
+
47
+ /// Return an immutable reference to the `Option<T>` that this thread owns.
48
+ pub fn borrow(&self) -> Ref<'_, Option<T>> {
49
+ let idx = self.current_thread_index();
50
+ self.slots[idx].borrow()
51
+ }
52
+
53
+ /// Return a mutable reference to the `Option<T>` that this thread owns.
54
+ pub fn borrow_mut(&self) -> RefMut<'_, Option<T>> {
55
+ let idx = self.current_thread_index();
56
+ self.slots[idx].borrow_mut()
57
+ }
58
+
59
+ /// Ensure that the current data this thread owns is initialized, or
60
+ /// initialize it using `f`. We want ensure() to be fast and inline, and we
61
+ /// want to inline the memmove that initializes the Option<T>. But we don't
62
+ /// want to inline space for the entire large T struct in our stack frame.
63
+ /// That's why we hand `f` a mutable borrow to write to instead of just
64
+ /// having it return a T.
65
+ #[inline(always)]
66
+ pub fn ensure<F: FnOnce(&mut Option<T>)>(&self, f: F) -> RefMut<'_, T> {
67
+ let mut opt = self.borrow_mut();
68
+ if opt.is_none() {
69
+ f(opt.deref_mut());
70
+ }
71
+
72
+ RefMut::map(opt, |x| x.as_mut().unwrap())
73
+ }
74
+
75
+ /// Returns the slots. Safe because if we have a mut reference the tls can't be referenced by
76
+ /// any other thread.
77
+ pub fn slots(&mut self) -> &mut [RefCell<Option<T>>] {
78
+ &mut self.slots
79
+ }
80
+ }