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.
- package/LICENSE +21 -0
- package/README.md +355 -2
- package/THIRD_PARTY_NOTICES.md +25 -0
- package/assets/icon.svg +4 -0
- package/dist/api.d.ts +7 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +46 -0
- package/dist/api.js.map +1 -0
- package/dist/assets.d.ts +7 -0
- package/dist/assets.d.ts.map +1 -0
- package/dist/assets.js +52 -0
- package/dist/assets.js.map +1 -0
- package/dist/browser.d.ts +3 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +3 -0
- package/dist/browser.js.map +1 -0
- package/dist/node.d.ts +3 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +10 -0
- package/dist/node.js.map +1 -0
- package/dist/options.d.ts +24 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +135 -0
- package/dist/options.js.map +1 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/examples/bun.ts +8 -0
- package/examples/german-invoice/README.md +70 -0
- package/examples/german-invoice/data.mjs +83 -0
- package/examples/german-invoice/invoice.css +59 -0
- package/examples/german-invoice/template.mjs +49 -0
- package/examples/german-invoice.mjs +20 -0
- package/examples/invoice.html +29 -0
- package/examples/node.mjs +8 -0
- package/examples/pagination.html +40 -0
- package/examples/pagination.mjs +8 -0
- package/licenses/DejaVu.txt +187 -0
- package/licenses/RUST_DEPENDENCIES.txt +11577 -0
- package/package.json +89 -4
- package/src/api.ts +44 -0
- package/src/assets.ts +43 -0
- package/src/browser.ts +6 -0
- package/src/node.ts +12 -0
- package/src/options.ts +101 -0
- package/src/types.ts +49 -0
- package/vendor/README.md +17 -0
- package/vendor/stylo/.cargo-ok +1 -0
- package/vendor/stylo/.cargo_vcs_info.json +6 -0
- package/vendor/stylo/Cargo.lock +1485 -0
- package/vendor/stylo/Cargo.toml +274 -0
- package/vendor/stylo/LICENSE +373 -0
- package/vendor/stylo/README.md +6 -0
- package/vendor/stylo/applicable_declarations.rs +328 -0
- package/vendor/stylo/author_styles.rs +79 -0
- package/vendor/stylo/bezier.rs +176 -0
- package/vendor/stylo/bloom.rs +414 -0
- package/vendor/stylo/build.rs +91 -0
- package/vendor/stylo/build_gecko.rs +393 -0
- package/vendor/stylo/color/color_function.rs +601 -0
- package/vendor/stylo/color/component.rs +207 -0
- package/vendor/stylo/color/convert.rs +935 -0
- package/vendor/stylo/color/gamut/raytrace.rs +265 -0
- package/vendor/stylo/color/gamut.rs +227 -0
- package/vendor/stylo/color/mix.rs +645 -0
- package/vendor/stylo/color/mod.rs +750 -0
- package/vendor/stylo/color/parsing.rs +770 -0
- package/vendor/stylo/color/to_css.rs +297 -0
- package/vendor/stylo/context.rs +716 -0
- package/vendor/stylo/counter_style/mod.rs +754 -0
- package/vendor/stylo/counter_style/predefined.rs +61 -0
- package/vendor/stylo/counter_style/update_predefined.py +35 -0
- package/vendor/stylo/custom_properties.rs +2023 -0
- package/vendor/stylo/custom_properties_map.rs +220 -0
- package/vendor/stylo/data.rs +693 -0
- package/vendor/stylo/device/gecko.rs +486 -0
- package/vendor/stylo/device/mod.rs +304 -0
- package/vendor/stylo/device/servo.rs +507 -0
- package/vendor/stylo/dom.rs +1164 -0
- package/vendor/stylo/dom_apis.rs +937 -0
- package/vendor/stylo/driver.rs +172 -0
- package/vendor/stylo/error_reporting.rs +484 -0
- package/vendor/stylo/font_face.rs +558 -0
- package/vendor/stylo/font_metrics.rs +124 -0
- package/vendor/stylo/gecko/anon_boxes.toml +113 -0
- package/vendor/stylo/gecko/arc_types.rs +211 -0
- package/vendor/stylo/gecko/conversions.rs +59 -0
- package/vendor/stylo/gecko/data.rs +222 -0
- package/vendor/stylo/gecko/media_features.rs +971 -0
- package/vendor/stylo/gecko/mod.rs +20 -0
- package/vendor/stylo/gecko/non_ts_pseudo_class_list.rs +119 -0
- package/vendor/stylo/gecko/pseudo_element.rs +640 -0
- package/vendor/stylo/gecko/pseudo_element_definition.mako.rs +298 -0
- package/vendor/stylo/gecko/pseudo_elements.py +137 -0
- package/vendor/stylo/gecko/pseudo_elements.toml +197 -0
- package/vendor/stylo/gecko/regen_pseudo_elements.py +33 -0
- package/vendor/stylo/gecko/restyle_damage.rs +127 -0
- package/vendor/stylo/gecko/selector_parser.rs +627 -0
- package/vendor/stylo/gecko/snapshot.rs +202 -0
- package/vendor/stylo/gecko/snapshot_helpers.rs +334 -0
- package/vendor/stylo/gecko/traversal.rs +52 -0
- package/vendor/stylo/gecko/wrapper.rs +2258 -0
- package/vendor/stylo/gecko_bindings/mod.rs +34 -0
- package/vendor/stylo/gecko_bindings/sugar/mod.rs +12 -0
- package/vendor/stylo/gecko_bindings/sugar/ns_com_ptr.rs +15 -0
- package/vendor/stylo/gecko_bindings/sugar/ns_compatibility.rs +19 -0
- package/vendor/stylo/gecko_bindings/sugar/ns_style_auto_array.rs +111 -0
- package/vendor/stylo/gecko_bindings/sugar/origin_flags.rs +31 -0
- package/vendor/stylo/gecko_bindings/sugar/ownership.rs +70 -0
- package/vendor/stylo/gecko_bindings/sugar/refptr.rs +299 -0
- package/vendor/stylo/gecko_string_cache/mod.rs +543 -0
- package/vendor/stylo/gecko_string_cache/namespace.rs +106 -0
- package/vendor/stylo/global_style_data.rs +224 -0
- package/vendor/stylo/invalidation/element/document_state.rs +156 -0
- package/vendor/stylo/invalidation/element/element_wrapper.rs +432 -0
- package/vendor/stylo/invalidation/element/invalidation_map.rs +1631 -0
- package/vendor/stylo/invalidation/element/invalidator.rs +1470 -0
- package/vendor/stylo/invalidation/element/mod.rs +13 -0
- package/vendor/stylo/invalidation/element/relative_selector.rs +1399 -0
- package/vendor/stylo/invalidation/element/restyle_hints.rs +226 -0
- package/vendor/stylo/invalidation/element/state_and_attributes.rs +756 -0
- package/vendor/stylo/invalidation/media_queries.rs +144 -0
- package/vendor/stylo/invalidation/mod.rs +10 -0
- package/vendor/stylo/invalidation/stylesheets.rs +745 -0
- package/vendor/stylo/invalidation/viewport_units.rs +71 -0
- package/vendor/stylo/lib.rs +336 -0
- package/vendor/stylo/logical_geometry.rs +1684 -0
- package/vendor/stylo/macros.rs +70 -0
- package/vendor/stylo/matching.rs +1226 -0
- package/vendor/stylo/media_queries/media_list.rs +168 -0
- package/vendor/stylo/media_queries/media_query.rs +190 -0
- package/vendor/stylo/media_queries/mod.rs +13 -0
- package/vendor/stylo/parallel.rs +205 -0
- package/vendor/stylo/parser.rs +276 -0
- package/vendor/stylo/piecewise_linear.rs +282 -0
- package/vendor/stylo/prefs.rs +33 -0
- package/vendor/stylo/properties/build.py +119 -0
- package/vendor/stylo/properties/cascade.rs +2704 -0
- package/vendor/stylo/properties/computed_value_flags.rs +206 -0
- package/vendor/stylo/properties/counted_unknown_properties.py +104 -0
- package/vendor/stylo/properties/counter_style_descriptors.toml +45 -0
- package/vendor/stylo/properties/data.py +1375 -0
- package/vendor/stylo/properties/declaration_block.rs +1788 -0
- package/vendor/stylo/properties/font_face_descriptors.toml +50 -0
- package/vendor/stylo/properties/gecko.mako.rs +1555 -0
- package/vendor/stylo/properties/helpers/animated_properties.mako.rs +800 -0
- package/vendor/stylo/properties/helpers.mako.rs +812 -0
- package/vendor/stylo/properties/longhands.toml +4305 -0
- package/vendor/stylo/properties/mod.rs +1857 -0
- package/vendor/stylo/properties/properties.html.mako +31 -0
- package/vendor/stylo/properties/properties.mako.rs +3103 -0
- package/vendor/stylo/properties/property_descriptors.toml +18 -0
- package/vendor/stylo/properties/shorthands.rs +4241 -0
- package/vendor/stylo/properties/shorthands.toml +575 -0
- package/vendor/stylo/properties/vendored_python/mako-1.3.10-py3-none-any.whl +0 -0
- package/vendor/stylo/properties/vendored_python/markupsafe/LICENSE.txt +28 -0
- package/vendor/stylo/properties/vendored_python/markupsafe/__init__.py +384 -0
- package/vendor/stylo/properties/vendored_python/toml-0.10.2-py2.py3-none-any.whl +0 -0
- package/vendor/stylo/properties/view_transition_descriptors.toml +11 -0
- package/vendor/stylo/properties_and_values/mod.rs +12 -0
- package/vendor/stylo/properties_and_values/registry.rs +65 -0
- package/vendor/stylo/properties_and_values/rule.rs +331 -0
- package/vendor/stylo/properties_and_values/syntax/ascii.rs +60 -0
- package/vendor/stylo/properties_and_values/syntax/data_type.rs +146 -0
- package/vendor/stylo/properties_and_values/syntax/mod.rs +437 -0
- package/vendor/stylo/properties_and_values/value.rs +758 -0
- package/vendor/stylo/queries/condition.rs +996 -0
- package/vendor/stylo/queries/feature.rs +199 -0
- package/vendor/stylo/queries/feature_expression.rs +1170 -0
- package/vendor/stylo/queries/mod.rs +19 -0
- package/vendor/stylo/queries/values.rs +46 -0
- package/vendor/stylo/rule_cache.rs +267 -0
- package/vendor/stylo/rule_collector.rs +554 -0
- package/vendor/stylo/rule_tree/core.rs +787 -0
- package/vendor/stylo/rule_tree/level.rs +396 -0
- package/vendor/stylo/rule_tree/map.rs +201 -0
- package/vendor/stylo/rule_tree/mod.rs +427 -0
- package/vendor/stylo/rule_tree/source.rs +80 -0
- package/vendor/stylo/rule_tree/unsafe_box.rs +78 -0
- package/vendor/stylo/scoped_tls.rs +80 -0
- package/vendor/stylo/selector_map.rs +1050 -0
- package/vendor/stylo/selector_parser.rs +305 -0
- package/vendor/stylo/servo/animation.rs +1922 -0
- package/vendor/stylo/servo/attr.rs +714 -0
- package/vendor/stylo/servo/encoding_support.rs +81 -0
- package/vendor/stylo/servo/media_features.rs +254 -0
- package/vendor/stylo/servo/mod.rs +16 -0
- package/vendor/stylo/servo/restyle_damage.rs +215 -0
- package/vendor/stylo/servo/selector_parser.rs +1036 -0
- package/vendor/stylo/servo/shadow_parts.rs +207 -0
- package/vendor/stylo/shared_lock.rs +271 -0
- package/vendor/stylo/sharing/checks.rs +281 -0
- package/vendor/stylo/sharing/mod.rs +1000 -0
- package/vendor/stylo/simple_buckets_map.rs +52 -0
- package/vendor/stylo/str.rs +168 -0
- package/vendor/stylo/style_adjuster.rs +1086 -0
- package/vendor/stylo/style_resolver.rs +658 -0
- package/vendor/stylo/stylesheet_set.rs +658 -0
- package/vendor/stylo/stylesheets/appearance_base_rule.rs +51 -0
- package/vendor/stylo/stylesheets/container_rule.rs +769 -0
- package/vendor/stylo/stylesheets/counter_style_rule.rs +7 -0
- package/vendor/stylo/stylesheets/document_rule.rs +272 -0
- package/vendor/stylo/stylesheets/font_face_rule.rs +7 -0
- package/vendor/stylo/stylesheets/font_feature_values_rule.rs +481 -0
- package/vendor/stylo/stylesheets/font_palette_values_rule.rs +304 -0
- package/vendor/stylo/stylesheets/import_rule.rs +259 -0
- package/vendor/stylo/stylesheets/keyframes_rule.rs +733 -0
- package/vendor/stylo/stylesheets/layer_rule.rs +221 -0
- package/vendor/stylo/stylesheets/loader.rs +29 -0
- package/vendor/stylo/stylesheets/margin_rule.rs +190 -0
- package/vendor/stylo/stylesheets/media_rule.rs +191 -0
- package/vendor/stylo/stylesheets/mod.rs +918 -0
- package/vendor/stylo/stylesheets/namespace_rule.rs +43 -0
- package/vendor/stylo/stylesheets/nested_declarations_rule.rs +51 -0
- package/vendor/stylo/stylesheets/origin.rs +249 -0
- package/vendor/stylo/stylesheets/page_rule.rs +354 -0
- package/vendor/stylo/stylesheets/position_try_rule.rs +68 -0
- package/vendor/stylo/stylesheets/property_rule.rs +5 -0
- package/vendor/stylo/stylesheets/rule_list.rs +167 -0
- package/vendor/stylo/stylesheets/rule_parser.rs +1189 -0
- package/vendor/stylo/stylesheets/rules_iterator.rs +397 -0
- package/vendor/stylo/stylesheets/scope_rule.rs +511 -0
- package/vendor/stylo/stylesheets/starting_style_rule.rs +54 -0
- package/vendor/stylo/stylesheets/style_rule.rs +80 -0
- package/vendor/stylo/stylesheets/stylesheet.rs +570 -0
- package/vendor/stylo/stylesheets/supports_rule.rs +486 -0
- package/vendor/stylo/stylesheets/view_transition_rule.rs +81 -0
- package/vendor/stylo/stylist.rs +5076 -0
- package/vendor/stylo/thread_state.rs +87 -0
- package/vendor/stylo/traversal.rs +765 -0
- package/vendor/stylo/traversal_flags.rs +68 -0
- package/vendor/stylo/typed_om/mod.rs +981 -0
- package/vendor/stylo/typed_om/numeric.rs +128 -0
- package/vendor/stylo/typed_om/numeric_declaration.rs +93 -0
- package/vendor/stylo/typed_om/numeric_type.rs +640 -0
- package/vendor/stylo/typed_om/sum_value.rs +426 -0
- package/vendor/stylo/url/gecko.rs +367 -0
- package/vendor/stylo/url/mod.rs +71 -0
- package/vendor/stylo/url/servo.rs +239 -0
- package/vendor/stylo/use_counters/mod.rs +137 -0
- package/vendor/stylo/values/animated/color.rs +103 -0
- package/vendor/stylo/values/animated/effects.rs +26 -0
- package/vendor/stylo/values/animated/font.rs +37 -0
- package/vendor/stylo/values/animated/grid.rs +161 -0
- package/vendor/stylo/values/animated/lists.rs +141 -0
- package/vendor/stylo/values/animated/mod.rs +550 -0
- package/vendor/stylo/values/animated/svg.rs +46 -0
- package/vendor/stylo/values/animated/text.rs +58 -0
- package/vendor/stylo/values/animated/transform.rs +1592 -0
- package/vendor/stylo/values/computed/align.rs +90 -0
- package/vendor/stylo/values/computed/angle.rs +130 -0
- package/vendor/stylo/values/computed/animation.rs +124 -0
- package/vendor/stylo/values/computed/background.rs +13 -0
- package/vendor/stylo/values/computed/basic_shape.rs +267 -0
- package/vendor/stylo/values/computed/border.rs +163 -0
- package/vendor/stylo/values/computed/box.rs +267 -0
- package/vendor/stylo/values/computed/calc.rs +334 -0
- package/vendor/stylo/values/computed/color.rs +161 -0
- package/vendor/stylo/values/computed/column.rs +11 -0
- package/vendor/stylo/values/computed/corner_shape.rs +155 -0
- package/vendor/stylo/values/computed/counters.rs +26 -0
- package/vendor/stylo/values/computed/easing.rs +109 -0
- package/vendor/stylo/values/computed/effects.rs +30 -0
- package/vendor/stylo/values/computed/flex.rs +19 -0
- package/vendor/stylo/values/computed/font.rs +1517 -0
- package/vendor/stylo/values/computed/image.rs +273 -0
- package/vendor/stylo/values/computed/length.rs +576 -0
- package/vendor/stylo/values/computed/length_percentage.rs +1055 -0
- package/vendor/stylo/values/computed/list.rs +16 -0
- package/vendor/stylo/values/computed/mod.rs +1141 -0
- package/vendor/stylo/values/computed/motion.rs +73 -0
- package/vendor/stylo/values/computed/outline.rs +7 -0
- package/vendor/stylo/values/computed/page.rs +77 -0
- package/vendor/stylo/values/computed/param.rs +9 -0
- package/vendor/stylo/values/computed/percentage.rs +143 -0
- package/vendor/stylo/values/computed/position.rs +273 -0
- package/vendor/stylo/values/computed/ratio.rs +88 -0
- package/vendor/stylo/values/computed/rect.rs +19 -0
- package/vendor/stylo/values/computed/resolution.rs +76 -0
- package/vendor/stylo/values/computed/svg.rs +66 -0
- package/vendor/stylo/values/computed/table.rs +7 -0
- package/vendor/stylo/values/computed/text.rs +199 -0
- package/vendor/stylo/values/computed/time.rs +83 -0
- package/vendor/stylo/values/computed/transform.rs +559 -0
- package/vendor/stylo/values/computed/tree_counting.rs +30 -0
- package/vendor/stylo/values/computed/ui.rs +23 -0
- package/vendor/stylo/values/computed/url.rs +12 -0
- package/vendor/stylo/values/distance.rs +139 -0
- package/vendor/stylo/values/generics/animation.rs +363 -0
- package/vendor/stylo/values/generics/background.rs +65 -0
- package/vendor/stylo/values/generics/basic_shape.rs +1389 -0
- package/vendor/stylo/values/generics/border.rs +303 -0
- package/vendor/stylo/values/generics/box.rs +552 -0
- package/vendor/stylo/values/generics/calc.rs +2986 -0
- package/vendor/stylo/values/generics/color.rs +318 -0
- package/vendor/stylo/values/generics/column.rs +44 -0
- package/vendor/stylo/values/generics/counters.rs +320 -0
- package/vendor/stylo/values/generics/easing.rs +132 -0
- package/vendor/stylo/values/generics/effects.rs +131 -0
- package/vendor/stylo/values/generics/flex.rs +34 -0
- package/vendor/stylo/values/generics/font.rs +376 -0
- package/vendor/stylo/values/generics/grid.rs +962 -0
- package/vendor/stylo/values/generics/image.rs +653 -0
- package/vendor/stylo/values/generics/length.rs +656 -0
- package/vendor/stylo/values/generics/mod.rs +303 -0
- package/vendor/stylo/values/generics/motion.rs +274 -0
- package/vendor/stylo/values/generics/page.rs +167 -0
- package/vendor/stylo/values/generics/position.rs +669 -0
- package/vendor/stylo/values/generics/ratio.rs +88 -0
- package/vendor/stylo/values/generics/rect.rs +147 -0
- package/vendor/stylo/values/generics/size.rs +102 -0
- package/vendor/stylo/values/generics/svg.rs +226 -0
- package/vendor/stylo/values/generics/text.rs +268 -0
- package/vendor/stylo/values/generics/transform.rs +1157 -0
- package/vendor/stylo/values/generics/ui.rs +147 -0
- package/vendor/stylo/values/generics/url.rs +51 -0
- package/vendor/stylo/values/mod.rs +820 -0
- package/vendor/stylo/values/resolved/animation.rs +33 -0
- package/vendor/stylo/values/resolved/color.rs +53 -0
- package/vendor/stylo/values/resolved/counters.rs +45 -0
- package/vendor/stylo/values/resolved/mod.rs +316 -0
- package/vendor/stylo/values/specified/align.rs +711 -0
- package/vendor/stylo/values/specified/angle.rs +407 -0
- package/vendor/stylo/values/specified/animation.rs +921 -0
- package/vendor/stylo/values/specified/background.rs +270 -0
- package/vendor/stylo/values/specified/basic_shape.rs +986 -0
- package/vendor/stylo/values/specified/border.rs +430 -0
- package/vendor/stylo/values/specified/box.rs +2231 -0
- package/vendor/stylo/values/specified/calc.rs +1657 -0
- package/vendor/stylo/values/specified/color.rs +1210 -0
- package/vendor/stylo/values/specified/column.rs +11 -0
- package/vendor/stylo/values/specified/corner_shape.rs +152 -0
- package/vendor/stylo/values/specified/counters.rs +242 -0
- package/vendor/stylo/values/specified/easing.rs +225 -0
- package/vendor/stylo/values/specified/effects.rs +421 -0
- package/vendor/stylo/values/specified/flex.rs +42 -0
- package/vendor/stylo/values/specified/font.rs +2103 -0
- package/vendor/stylo/values/specified/frequency.rs +39 -0
- package/vendor/stylo/values/specified/grid.rs +407 -0
- package/vendor/stylo/values/specified/image.rs +1385 -0
- package/vendor/stylo/values/specified/intersection_observer.rs +80 -0
- package/vendor/stylo/values/specified/length.rs +2024 -0
- package/vendor/stylo/values/specified/list.rs +190 -0
- package/vendor/stylo/values/specified/mod.rs +531 -0
- package/vendor/stylo/values/specified/motion.rs +316 -0
- package/vendor/stylo/values/specified/number.rs +603 -0
- package/vendor/stylo/values/specified/outline.rs +69 -0
- package/vendor/stylo/values/specified/page.rs +94 -0
- package/vendor/stylo/values/specified/param.rs +121 -0
- package/vendor/stylo/values/specified/percentage.rs +364 -0
- package/vendor/stylo/values/specified/position.rs +2247 -0
- package/vendor/stylo/values/specified/ratio.rs +29 -0
- package/vendor/stylo/values/specified/rect.rs +28 -0
- package/vendor/stylo/values/specified/resolution.rs +237 -0
- package/vendor/stylo/values/specified/source_size_list.rs +135 -0
- package/vendor/stylo/values/specified/svg.rs +427 -0
- package/vendor/stylo/values/specified/svg_path.rs +1115 -0
- package/vendor/stylo/values/specified/table.rs +38 -0
- package/vendor/stylo/values/specified/text.rs +1561 -0
- package/vendor/stylo/values/specified/time.rs +313 -0
- package/vendor/stylo/values/specified/transform.rs +599 -0
- package/vendor/stylo/values/specified/tree_counting.rs +32 -0
- package/vendor/stylo/values/specified/ui.rs +344 -0
- package/vendor/stylo/values/specified/url.rs +12 -0
- package/vendor/stylo/values/tagged_numeric.rs +253 -0
- package/wasm/blitz_pdf.d.ts +67 -0
- package/wasm/blitz_pdf.js +699 -0
- package/wasm/blitz_pdf_bg.wasm +0 -0
- package/wasm/blitz_pdf_bg.wasm.d.ts +20 -0
|
@@ -0,0 +1,168 @@
|
|
|
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 media query list:
|
|
6
|
+
//!
|
|
7
|
+
//! https://drafts.csswg.org/mediaqueries/#typedef-media-query-list
|
|
8
|
+
|
|
9
|
+
use super::{MediaQuery, Qualifier};
|
|
10
|
+
use crate::context::QuirksMode;
|
|
11
|
+
use crate::derives::*;
|
|
12
|
+
use crate::device::Device;
|
|
13
|
+
use crate::dom::AttributeTracker;
|
|
14
|
+
use crate::error_reporting::ContextualParseError;
|
|
15
|
+
use crate::parser::ParserContext;
|
|
16
|
+
use crate::stylesheets::CustomMediaEvaluator;
|
|
17
|
+
use crate::values::computed;
|
|
18
|
+
use cssparser::Token;
|
|
19
|
+
use cssparser::{Delimiter, Parser};
|
|
20
|
+
use selectors::kleene_value::KleeneValue;
|
|
21
|
+
use style_traits::ParsingMode;
|
|
22
|
+
|
|
23
|
+
/// A type that encapsulates a media query list.
|
|
24
|
+
#[derive(Clone, MallocSizeOf, ToCss, ToShmem)]
|
|
25
|
+
#[css(comma, derive_debug)]
|
|
26
|
+
pub struct MediaList {
|
|
27
|
+
/// The list of media queries.
|
|
28
|
+
#[css(iterable)]
|
|
29
|
+
pub media_queries: Vec<MediaQuery>,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
impl MediaList {
|
|
33
|
+
/// Parse a media query list from CSS.
|
|
34
|
+
///
|
|
35
|
+
/// Always returns a media query list. If any invalid media query is
|
|
36
|
+
/// found, the media query list is only filled with the equivalent of
|
|
37
|
+
/// "not all", see:
|
|
38
|
+
///
|
|
39
|
+
/// <https://drafts.csswg.org/mediaqueries/#error-handling>
|
|
40
|
+
pub fn parse(context: &mut ParserContext, input: &mut Parser) -> Self {
|
|
41
|
+
context.with_parsing_mode(ParsingMode::MEDIA_QUERY_CONDITION, |context| {
|
|
42
|
+
if input.is_exhausted() {
|
|
43
|
+
return Self::empty();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let mut media_queries = vec![];
|
|
47
|
+
loop {
|
|
48
|
+
let start_position = input.position();
|
|
49
|
+
let start_location = input.current_source_location();
|
|
50
|
+
match input.parse_until_before(Delimiter::Comma, |i| MediaQuery::parse(context, i))
|
|
51
|
+
{
|
|
52
|
+
Ok(mq) => {
|
|
53
|
+
media_queries.push(mq);
|
|
54
|
+
},
|
|
55
|
+
Err(err) => {
|
|
56
|
+
media_queries.push(MediaQuery::never_matching());
|
|
57
|
+
let error = ContextualParseError::InvalidMediaRule(
|
|
58
|
+
input.slice_from(start_position),
|
|
59
|
+
err,
|
|
60
|
+
);
|
|
61
|
+
context.log_css_error(start_location, error);
|
|
62
|
+
},
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
match input.next() {
|
|
66
|
+
Ok(&Token::Comma) => {},
|
|
67
|
+
Ok(_) => unreachable!(),
|
|
68
|
+
Err(_) => break,
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
MediaList { media_queries }
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// Create an empty MediaList.
|
|
77
|
+
pub fn empty() -> Self {
|
|
78
|
+
MediaList {
|
|
79
|
+
media_queries: vec![],
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/// Evaluate a whole `MediaList` against `Device`.
|
|
84
|
+
pub fn evaluate(
|
|
85
|
+
&self,
|
|
86
|
+
device: &Device,
|
|
87
|
+
quirks_mode: QuirksMode,
|
|
88
|
+
custom: &mut CustomMediaEvaluator,
|
|
89
|
+
) -> bool {
|
|
90
|
+
computed::Context::for_media_query_evaluation(device, quirks_mode, |context| {
|
|
91
|
+
self.matches(context, custom).to_bool(/* unknown = */ false)
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/// Evaluate the current `MediaList` with a pre-existing context and custom-media evaluator.
|
|
96
|
+
pub fn matches(
|
|
97
|
+
&self,
|
|
98
|
+
context: &computed::Context,
|
|
99
|
+
custom: &mut CustomMediaEvaluator,
|
|
100
|
+
) -> KleeneValue {
|
|
101
|
+
// Check if it is an empty media query list or any queries match.
|
|
102
|
+
// https://drafts.csswg.org/mediaqueries-4/#mq-list
|
|
103
|
+
if self.media_queries.is_empty() {
|
|
104
|
+
return KleeneValue::True;
|
|
105
|
+
}
|
|
106
|
+
KleeneValue::any(self.media_queries.iter(), |mq| {
|
|
107
|
+
let mut query_match = if mq.media_type.matches(context.device().media_type()) {
|
|
108
|
+
mq.condition.as_ref().map_or(KleeneValue::True, |c| {
|
|
109
|
+
c.matches(context, custom, &mut AttributeTracker::new_dummy())
|
|
110
|
+
})
|
|
111
|
+
} else {
|
|
112
|
+
KleeneValue::False
|
|
113
|
+
};
|
|
114
|
+
// Apply the logical NOT qualifier to the result
|
|
115
|
+
if matches!(mq.qualifier, Some(Qualifier::Not)) {
|
|
116
|
+
query_match = !query_match;
|
|
117
|
+
}
|
|
118
|
+
query_match
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/// Whether this `MediaList` contains no media queries.
|
|
123
|
+
pub fn is_empty(&self) -> bool {
|
|
124
|
+
self.media_queries.is_empty()
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/// Whether this `MediaList` depends on the viewport size.
|
|
128
|
+
pub fn is_viewport_dependent(&self) -> bool {
|
|
129
|
+
self.media_queries.iter().any(|q| q.is_viewport_dependent())
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/// Append a new media query item to the media list.
|
|
133
|
+
/// <https://drafts.csswg.org/cssom/#dom-medialist-appendmedium>
|
|
134
|
+
///
|
|
135
|
+
/// Returns true if added, false if fail to parse the medium string.
|
|
136
|
+
pub fn append_medium(&mut self, context: &ParserContext, new_medium: &str) -> bool {
|
|
137
|
+
let mut parser = Parser::new(new_medium);
|
|
138
|
+
let new_query = match MediaQuery::parse(context, &mut parser) {
|
|
139
|
+
Ok(query) => query,
|
|
140
|
+
Err(_) => {
|
|
141
|
+
return false;
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
// This algorithm doesn't actually matches the current spec,
|
|
145
|
+
// but it matches the behavior of Gecko and Edge.
|
|
146
|
+
// See https://github.com/w3c/csswg-drafts/issues/697
|
|
147
|
+
self.media_queries.retain(|query| query != &new_query);
|
|
148
|
+
self.media_queries.push(new_query);
|
|
149
|
+
true
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/// Delete a media query from the media list.
|
|
153
|
+
/// <https://drafts.csswg.org/cssom/#dom-medialist-deletemedium>
|
|
154
|
+
///
|
|
155
|
+
/// Returns true if found and deleted, false otherwise.
|
|
156
|
+
pub fn delete_medium(&mut self, context: &ParserContext, old_medium: &str) -> bool {
|
|
157
|
+
let mut parser = Parser::new(old_medium);
|
|
158
|
+
let old_query = match MediaQuery::parse(context, &mut parser) {
|
|
159
|
+
Ok(query) => query,
|
|
160
|
+
Err(_) => {
|
|
161
|
+
return false;
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
let old_len = self.media_queries.len();
|
|
165
|
+
self.media_queries.retain(|query| query != &old_query);
|
|
166
|
+
old_len != self.media_queries.len()
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
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 media query:
|
|
6
|
+
//!
|
|
7
|
+
//! https://drafts.csswg.org/mediaqueries/#typedef-media-query
|
|
8
|
+
|
|
9
|
+
use crate::derives::*;
|
|
10
|
+
use crate::parser::ParserContext;
|
|
11
|
+
use crate::queries::{FeatureFlags, FeatureType, QueryCondition};
|
|
12
|
+
use crate::str::string_as_ascii_lowercase;
|
|
13
|
+
use crate::values::CustomIdent;
|
|
14
|
+
use crate::Atom;
|
|
15
|
+
use cssparser::{match_ignore_ascii_case, Parser};
|
|
16
|
+
use std::fmt::{self, Write};
|
|
17
|
+
use style_traits::{CssWriter, ParseError, ToCss};
|
|
18
|
+
|
|
19
|
+
/// <https://drafts.csswg.org/mediaqueries/#mq-prefix>
|
|
20
|
+
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToCss, ToShmem)]
|
|
21
|
+
pub enum Qualifier {
|
|
22
|
+
/// Hide a media query from legacy UAs:
|
|
23
|
+
/// <https://drafts.csswg.org/mediaqueries/#mq-only>
|
|
24
|
+
Only,
|
|
25
|
+
/// Negate a media query:
|
|
26
|
+
/// <https://drafts.csswg.org/mediaqueries/#mq-not>
|
|
27
|
+
Not,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/// <https://drafts.csswg.org/mediaqueries/#media-types>
|
|
31
|
+
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToShmem)]
|
|
32
|
+
pub struct MediaType(pub CustomIdent);
|
|
33
|
+
|
|
34
|
+
impl MediaType {
|
|
35
|
+
/// The `screen` media type.
|
|
36
|
+
pub fn screen() -> Self {
|
|
37
|
+
MediaType(CustomIdent(atom!("screen")))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/// The `print` media type.
|
|
41
|
+
pub fn print() -> Self {
|
|
42
|
+
MediaType(CustomIdent(atom!("print")))
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fn parse(name: &str) -> Result<Self, ()> {
|
|
46
|
+
// From https://drafts.csswg.org/mediaqueries/#mq-syntax:
|
|
47
|
+
//
|
|
48
|
+
// The <media-type> production does not include the keywords only, not, and, or, and layer.
|
|
49
|
+
//
|
|
50
|
+
// Here we also perform the to-ascii-lowercase part of the serialization
|
|
51
|
+
// algorithm: https://drafts.csswg.org/cssom/#serializing-media-queries
|
|
52
|
+
match_ignore_ascii_case! { name,
|
|
53
|
+
"not" | "or" | "and" | "only" | "layer" => Err(()),
|
|
54
|
+
_ => Ok(MediaType(CustomIdent(Atom::from(string_as_ascii_lowercase(name))))),
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/// A [media query][mq].
|
|
60
|
+
///
|
|
61
|
+
/// [mq]: https://drafts.csswg.org/mediaqueries/
|
|
62
|
+
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
|
|
63
|
+
pub struct MediaQuery {
|
|
64
|
+
/// The qualifier for this query.
|
|
65
|
+
pub qualifier: Option<Qualifier>,
|
|
66
|
+
/// The media type for this query, that can be known, unknown, or "all".
|
|
67
|
+
pub media_type: MediaQueryType,
|
|
68
|
+
/// The condition that this media query contains. This cannot have `or`
|
|
69
|
+
/// in the first level.
|
|
70
|
+
pub condition: Option<QueryCondition>,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
impl ToCss for MediaQuery {
|
|
74
|
+
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
|
75
|
+
where
|
|
76
|
+
W: Write,
|
|
77
|
+
{
|
|
78
|
+
if let Some(qual) = self.qualifier {
|
|
79
|
+
qual.to_css(dest)?;
|
|
80
|
+
dest.write_char(' ')?;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
match self.media_type {
|
|
84
|
+
MediaQueryType::All => {
|
|
85
|
+
// We need to print "all" if there's a qualifier, or there's
|
|
86
|
+
// just an empty list of expressions.
|
|
87
|
+
//
|
|
88
|
+
// Otherwise, we'd serialize media queries like "(min-width:
|
|
89
|
+
// 40px)" in "all (min-width: 40px)", which is unexpected.
|
|
90
|
+
if self.qualifier.is_some() || self.condition.is_none() {
|
|
91
|
+
dest.write_str("all")?;
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
MediaQueryType::Concrete(MediaType(ref desc)) => desc.to_css(dest)?,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
let condition = match self.condition {
|
|
98
|
+
Some(ref c) => c,
|
|
99
|
+
None => return Ok(()),
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
if self.media_type != MediaQueryType::All || self.qualifier.is_some() {
|
|
103
|
+
dest.write_str(" and ")?;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
condition.to_css(dest)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
impl MediaQuery {
|
|
111
|
+
/// Return a media query that never matches, used for when we fail to parse
|
|
112
|
+
/// a given media query.
|
|
113
|
+
pub fn never_matching() -> Self {
|
|
114
|
+
Self {
|
|
115
|
+
qualifier: Some(Qualifier::Not),
|
|
116
|
+
media_type: MediaQueryType::All,
|
|
117
|
+
condition: None,
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/// Returns whether this media query depends on the viewport.
|
|
122
|
+
pub fn is_viewport_dependent(&self) -> bool {
|
|
123
|
+
self.condition.as_ref().is_some_and(|c| {
|
|
124
|
+
c.cumulative_flags()
|
|
125
|
+
.contains(FeatureFlags::VIEWPORT_DEPENDENT)
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/// Parse a media query given css input.
|
|
130
|
+
///
|
|
131
|
+
/// Returns an error if any of the expressions is unknown.
|
|
132
|
+
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ParseError> {
|
|
133
|
+
let (qualifier, explicit_media_type) = input
|
|
134
|
+
.try_parse(|input| -> Result<_, ()> {
|
|
135
|
+
let qualifier = input.try_parse(Qualifier::parse).ok();
|
|
136
|
+
let ident = input.expect_ident().map_err(|_| ())?;
|
|
137
|
+
let media_type = MediaQueryType::parse(ident)?;
|
|
138
|
+
Ok((qualifier, Some(media_type)))
|
|
139
|
+
})
|
|
140
|
+
.unwrap_or_default();
|
|
141
|
+
|
|
142
|
+
let condition = if explicit_media_type.is_none() {
|
|
143
|
+
Some(QueryCondition::parse(context, input, FeatureType::Media)?)
|
|
144
|
+
} else if input.try_parse(|i| i.expect_ident_matching("and")).is_ok() {
|
|
145
|
+
Some(QueryCondition::parse_disallow_or(
|
|
146
|
+
context,
|
|
147
|
+
input,
|
|
148
|
+
FeatureType::Media,
|
|
149
|
+
)?)
|
|
150
|
+
} else {
|
|
151
|
+
None
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
let media_type = explicit_media_type.unwrap_or(MediaQueryType::All);
|
|
155
|
+
Ok(Self {
|
|
156
|
+
qualifier,
|
|
157
|
+
media_type,
|
|
158
|
+
condition,
|
|
159
|
+
})
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/// <http://dev.w3.org/csswg/mediaqueries-3/#media0>
|
|
164
|
+
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToShmem)]
|
|
165
|
+
pub enum MediaQueryType {
|
|
166
|
+
/// A media type that matches every device.
|
|
167
|
+
All,
|
|
168
|
+
/// A specific media type.
|
|
169
|
+
Concrete(MediaType),
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
impl MediaQueryType {
|
|
173
|
+
fn parse(ident: &str) -> Result<Self, ()> {
|
|
174
|
+
match_ignore_ascii_case! { ident,
|
|
175
|
+
"all" => return Ok(MediaQueryType::All),
|
|
176
|
+
_ => (),
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// If parseable, accept this type as a concrete type.
|
|
180
|
+
MediaType::parse(ident).map(MediaQueryType::Concrete)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/// Returns whether this media query type matches a MediaType.
|
|
184
|
+
pub fn matches(&self, other: MediaType) -> bool {
|
|
185
|
+
match *self {
|
|
186
|
+
MediaQueryType::All => true,
|
|
187
|
+
MediaQueryType::Concrete(ref known_type) => *known_type == other,
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
//! [Media queries][mq].
|
|
6
|
+
//!
|
|
7
|
+
//! [mq]: https://drafts.csswg.org/mediaqueries/
|
|
8
|
+
|
|
9
|
+
mod media_list;
|
|
10
|
+
mod media_query;
|
|
11
|
+
|
|
12
|
+
pub use self::media_list::MediaList;
|
|
13
|
+
pub use self::media_query::{MediaQuery, MediaQueryType, MediaType, Qualifier};
|
|
@@ -0,0 +1,205 @@
|
|
|
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
|
+
//! Implements parallel traversal over the DOM tree.
|
|
6
|
+
//!
|
|
7
|
+
//! This traversal is based on Rayon, and therefore its safety is largely
|
|
8
|
+
//! verified by the type system.
|
|
9
|
+
//!
|
|
10
|
+
//! The primary trickiness and fine print for the above relates to the
|
|
11
|
+
//! thread safety of the DOM nodes themselves. Accessing a DOM element
|
|
12
|
+
//! concurrently on multiple threads is actually mostly "safe", since all
|
|
13
|
+
//! the mutable state is protected by an AtomicRefCell, and so we'll
|
|
14
|
+
//! generally panic if something goes wrong. Still, we try to to enforce our
|
|
15
|
+
//! thread invariants at compile time whenever possible. As such, TNode and
|
|
16
|
+
//! TElement are not Send, so ordinary style system code cannot accidentally
|
|
17
|
+
//! share them with other threads. In the parallel traversal, we explicitly
|
|
18
|
+
//! invoke |unsafe { SendNode::new(n) }| to put nodes in containers that may
|
|
19
|
+
//! be sent to other threads. This occurs in only a handful of places and is
|
|
20
|
+
//! easy to grep for. At the time of this writing, there is no other unsafe
|
|
21
|
+
//! code in the parallel traversal.
|
|
22
|
+
|
|
23
|
+
#![deny(missing_docs)]
|
|
24
|
+
|
|
25
|
+
use crate::context::{StyleContext, ThreadLocalStyleContext};
|
|
26
|
+
use crate::dom::{OpaqueNode, SendNode, TElement};
|
|
27
|
+
use crate::scoped_tls::ScopedTLS;
|
|
28
|
+
use crate::traversal::DomTraversal;
|
|
29
|
+
use std::collections::VecDeque;
|
|
30
|
+
|
|
31
|
+
/// The minimum stack size for a thread in the styling pool, in kilobytes.
|
|
32
|
+
#[cfg(feature = "gecko")]
|
|
33
|
+
pub const STYLE_THREAD_STACK_SIZE_KB: usize = 256;
|
|
34
|
+
|
|
35
|
+
/// The minimum stack size for a thread in the styling pool, in kilobytes.
|
|
36
|
+
/// Servo requires a bigger stack in debug builds.
|
|
37
|
+
/// We allow configuring the size, since running with ASAN requires an even larger
|
|
38
|
+
/// stack size.
|
|
39
|
+
#[cfg(feature = "servo")]
|
|
40
|
+
pub const STYLE_THREAD_STACK_SIZE_KB: usize = const {
|
|
41
|
+
let default_stack_size = 512;
|
|
42
|
+
if let Some(user_def_size) = option_env!("SERVO_STYLE_THREAD_STACK_SIZE_KB") {
|
|
43
|
+
if let Ok(user_def_size) = usize::from_str_radix(user_def_size, 10) {
|
|
44
|
+
user_def_size
|
|
45
|
+
} else {
|
|
46
|
+
panic!("SERVO_STYLE_THREAD_STACK_SIZE_KB must be a valid integer")
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
default_stack_size
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/// The stack margin. If we get this deep in the stack, we will skip recursive
|
|
54
|
+
/// optimizations to ensure that there is sufficient room for non-recursive work.
|
|
55
|
+
///
|
|
56
|
+
/// We allocate large safety margins because certain OS calls can use very large
|
|
57
|
+
/// amounts of stack space [1]. Reserving a larger-than-necessary stack costs us
|
|
58
|
+
/// address space, but if we keep our safety margin big, we will generally avoid
|
|
59
|
+
/// committing those extra pages, and only use them in edge cases that would
|
|
60
|
+
/// otherwise cause crashes.
|
|
61
|
+
///
|
|
62
|
+
/// When measured with 128KB stacks and 40KB margin, we could support 53
|
|
63
|
+
/// levels of recursion before the limiter kicks in, on x86_64-Linux [2]. When
|
|
64
|
+
/// we doubled the stack size, we added it all to the safety margin, so we should
|
|
65
|
+
/// be able to get the same amount of recursion.
|
|
66
|
+
///
|
|
67
|
+
/// [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1395708#c15
|
|
68
|
+
/// [2] See Gecko bug 1376883 for more discussion on the measurements.
|
|
69
|
+
pub const STACK_SAFETY_MARGIN_KB: usize = 168;
|
|
70
|
+
|
|
71
|
+
/// A callback to create our thread local context. This needs to be
|
|
72
|
+
/// out of line so we don't allocate stack space for the entire struct
|
|
73
|
+
/// in the caller.
|
|
74
|
+
#[inline(never)]
|
|
75
|
+
pub(crate) fn create_thread_local_context<'scope, E>(slot: &mut Option<ThreadLocalStyleContext<E>>)
|
|
76
|
+
where
|
|
77
|
+
E: TElement + 'scope,
|
|
78
|
+
{
|
|
79
|
+
*slot = Some(ThreadLocalStyleContext::new());
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Sends one chunk of work to the thread-pool.
|
|
83
|
+
fn distribute_one_chunk<'a, 'scope, E, D>(
|
|
84
|
+
items: VecDeque<SendNode<E::ConcreteNode>>,
|
|
85
|
+
traversal_root: OpaqueNode,
|
|
86
|
+
work_unit_max: usize,
|
|
87
|
+
dom_depth: usize,
|
|
88
|
+
scope: &'a rayon::ScopeFifo<'scope>,
|
|
89
|
+
traversal: &'scope D,
|
|
90
|
+
tls: &'scope ScopedTLS<'scope, ThreadLocalStyleContext<E>>,
|
|
91
|
+
) where
|
|
92
|
+
E: TElement + 'scope,
|
|
93
|
+
D: DomTraversal<E>,
|
|
94
|
+
{
|
|
95
|
+
scope.spawn_fifo(move |scope| {
|
|
96
|
+
#[cfg(feature = "gecko")]
|
|
97
|
+
gecko_profiler_label!(Layout, StyleComputation);
|
|
98
|
+
let mut tlc = tls.ensure(create_thread_local_context);
|
|
99
|
+
tlc.current_dom_depth = dom_depth;
|
|
100
|
+
let mut context = StyleContext {
|
|
101
|
+
shared: traversal.shared_context(),
|
|
102
|
+
thread_local: &mut *tlc,
|
|
103
|
+
};
|
|
104
|
+
style_trees(
|
|
105
|
+
&mut context,
|
|
106
|
+
items,
|
|
107
|
+
traversal_root,
|
|
108
|
+
work_unit_max,
|
|
109
|
+
Some(scope),
|
|
110
|
+
traversal,
|
|
111
|
+
tls,
|
|
112
|
+
);
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/// Distributes all items into the thread pool, in `work_unit_max` chunks.
|
|
117
|
+
fn distribute_work<'a, 'scope, E, D>(
|
|
118
|
+
mut items: impl Iterator<Item = SendNode<E::ConcreteNode>>,
|
|
119
|
+
traversal_root: OpaqueNode,
|
|
120
|
+
work_unit_max: usize,
|
|
121
|
+
dom_depth: usize,
|
|
122
|
+
scope: &'a rayon::ScopeFifo<'scope>,
|
|
123
|
+
traversal: &'scope D,
|
|
124
|
+
tls: &'scope ScopedTLS<'scope, ThreadLocalStyleContext<E>>,
|
|
125
|
+
) where
|
|
126
|
+
E: TElement + 'scope,
|
|
127
|
+
D: DomTraversal<E>,
|
|
128
|
+
{
|
|
129
|
+
use std::iter::FromIterator;
|
|
130
|
+
loop {
|
|
131
|
+
let chunk = VecDeque::from_iter(items.by_ref().take(work_unit_max));
|
|
132
|
+
if chunk.is_empty() {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
distribute_one_chunk(
|
|
136
|
+
chunk,
|
|
137
|
+
traversal_root,
|
|
138
|
+
work_unit_max,
|
|
139
|
+
dom_depth,
|
|
140
|
+
scope,
|
|
141
|
+
traversal,
|
|
142
|
+
tls,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/// Processes `discovered` items, possibly spawning work in other threads as needed.
|
|
148
|
+
#[inline]
|
|
149
|
+
pub fn style_trees<'a, 'scope, E, D>(
|
|
150
|
+
context: &mut StyleContext<E>,
|
|
151
|
+
mut discovered: VecDeque<SendNode<E::ConcreteNode>>,
|
|
152
|
+
traversal_root: OpaqueNode,
|
|
153
|
+
work_unit_max: usize,
|
|
154
|
+
scope: Option<&'a rayon::ScopeFifo<'scope>>,
|
|
155
|
+
traversal: &'scope D,
|
|
156
|
+
tls: &'scope ScopedTLS<'scope, ThreadLocalStyleContext<E>>,
|
|
157
|
+
) where
|
|
158
|
+
E: TElement + 'scope,
|
|
159
|
+
D: DomTraversal<E>,
|
|
160
|
+
{
|
|
161
|
+
let local_queue_size = if tls.current_thread_index() == 0 {
|
|
162
|
+
crate::pref!("layout.css.stylo-local-work-queue.in-main-thread")
|
|
163
|
+
} else {
|
|
164
|
+
crate::pref!("layout.css.stylo-local-work-queue.in-worker")
|
|
165
|
+
} as usize;
|
|
166
|
+
|
|
167
|
+
let mut nodes_remaining_at_current_depth = discovered.len();
|
|
168
|
+
while let Some(node) = discovered.pop_front() {
|
|
169
|
+
let mut children_to_process = 0isize;
|
|
170
|
+
traversal.process_preorder(context, *node, |n| {
|
|
171
|
+
children_to_process += 1;
|
|
172
|
+
discovered.push_back(unsafe { SendNode::new(n) });
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
traversal.handle_postorder_traversal(context, traversal_root, *node, children_to_process);
|
|
176
|
+
|
|
177
|
+
nodes_remaining_at_current_depth -= 1;
|
|
178
|
+
|
|
179
|
+
// If we have enough children at the next depth in the DOM, spawn them to a different job
|
|
180
|
+
// relatively soon, while keeping always at least `local_queue_size` worth of work for
|
|
181
|
+
// ourselves.
|
|
182
|
+
let discovered_children = discovered.len() - nodes_remaining_at_current_depth;
|
|
183
|
+
if discovered_children >= work_unit_max
|
|
184
|
+
&& discovered.len() >= local_queue_size + work_unit_max
|
|
185
|
+
&& scope.is_some()
|
|
186
|
+
{
|
|
187
|
+
let kept_work = std::cmp::max(nodes_remaining_at_current_depth, local_queue_size);
|
|
188
|
+
distribute_work(
|
|
189
|
+
discovered.range(kept_work..).cloned(),
|
|
190
|
+
traversal_root,
|
|
191
|
+
work_unit_max,
|
|
192
|
+
context.thread_local.current_dom_depth + 1,
|
|
193
|
+
scope.unwrap(),
|
|
194
|
+
traversal,
|
|
195
|
+
tls,
|
|
196
|
+
);
|
|
197
|
+
discovered.truncate(kept_work);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if nodes_remaining_at_current_depth == 0 {
|
|
201
|
+
context.thread_local.current_dom_depth += 1;
|
|
202
|
+
nodes_remaining_at_current_depth = discovered.len();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|