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,1375 @@
|
|
|
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
|
+
import re
|
|
6
|
+
import toml
|
|
7
|
+
import os
|
|
8
|
+
from itertools import groupby
|
|
9
|
+
from counted_unknown_properties import COUNTED_UNKNOWN_PROPERTIES
|
|
10
|
+
|
|
11
|
+
# It is important that the order of these physical / logical variants matches
|
|
12
|
+
# the order of the enum variants in logical_geometry.rs
|
|
13
|
+
PHYSICAL_SIDES = ["top", "right", "bottom", "left"]
|
|
14
|
+
PHYSICAL_CORNERS = ["top-left", "top-right", "bottom-right", "bottom-left"]
|
|
15
|
+
PHYSICAL_AXES = ["y", "x"]
|
|
16
|
+
PHYSICAL_SIZES = ["height", "width"]
|
|
17
|
+
LOGICAL_SIDES = ["block-start", "block-end", "inline-start", "inline-end"]
|
|
18
|
+
LOGICAL_CORNERS = ["start-start", "start-end", "end-start", "end-end"]
|
|
19
|
+
LOGICAL_SIZES = ["block-size", "inline-size"]
|
|
20
|
+
LOGICAL_AXES = ["block", "inline"]
|
|
21
|
+
|
|
22
|
+
SYSTEM_FONT_LONGHANDS = """font_family font_size font_style
|
|
23
|
+
font_width font_weight""".split()
|
|
24
|
+
|
|
25
|
+
PRIORITARY_PROPERTIES = set(
|
|
26
|
+
[
|
|
27
|
+
# The writing-mode group has the most priority of all property groups, as
|
|
28
|
+
# sizes like font-size can depend on it.
|
|
29
|
+
"writing-mode",
|
|
30
|
+
"direction",
|
|
31
|
+
"text-orientation",
|
|
32
|
+
# The fonts and colors group has the second priority, as all other lengths
|
|
33
|
+
# and colors depend on them.
|
|
34
|
+
#
|
|
35
|
+
# There are some interdependencies between these, but we fix them up in
|
|
36
|
+
# Cascade::fixup_font_stuff.
|
|
37
|
+
# Needed to properly compute the zoomed font-size.
|
|
38
|
+
"-x-text-scale",
|
|
39
|
+
# Needed to do font-size computation in a language-dependent way.
|
|
40
|
+
"-x-lang",
|
|
41
|
+
# Needed for ruby to respect language-dependent min-font-size
|
|
42
|
+
# preferences properly, see bug 1165538.
|
|
43
|
+
"-moz-min-font-size-ratio",
|
|
44
|
+
# font-size depends on math-depth's computed value.
|
|
45
|
+
"math-depth",
|
|
46
|
+
# Needed to compute the first available font and its used size,
|
|
47
|
+
# in order to compute font-relative units correctly.
|
|
48
|
+
"font-size",
|
|
49
|
+
"font-size-adjust",
|
|
50
|
+
"font-weight",
|
|
51
|
+
"font-width",
|
|
52
|
+
"font-style",
|
|
53
|
+
"font-family",
|
|
54
|
+
# color-scheme affects how system colors and light-dark() resolve.
|
|
55
|
+
"color-scheme",
|
|
56
|
+
# forced-color-adjust affects whether colors are adjusted.
|
|
57
|
+
"forced-color-adjust",
|
|
58
|
+
# Zoom affects all absolute lengths.
|
|
59
|
+
"zoom",
|
|
60
|
+
# Line height lengths depend on this.
|
|
61
|
+
"line-height",
|
|
62
|
+
# appearance and -moz-default-appearance control whether
|
|
63
|
+
# @appearance-base rules apply.
|
|
64
|
+
"-moz-default-appearance",
|
|
65
|
+
"appearance",
|
|
66
|
+
]
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# Set of prioritary properties and dependencies between them.
|
|
70
|
+
#
|
|
71
|
+
# Some properties must depend on appearance because of the @appearance-base rule.
|
|
72
|
+
# If a property doesn't depend on `appearance` (either directly or transitively), then
|
|
73
|
+
# declarations inside the @appearance-base rule might not apply consistently.
|
|
74
|
+
#
|
|
75
|
+
# We don't want to necessarily make all properties work in @appearance-base, however.
|
|
76
|
+
# For example we don't want to mess with writing-modes etc there, so we can skip the
|
|
77
|
+
# dependency.
|
|
78
|
+
PRIORITARY_PROPERTY_DEPENDENCIES = {
|
|
79
|
+
# Needed for @appearance-base
|
|
80
|
+
"-moz-default-appearance": [],
|
|
81
|
+
"appearance": ["-moz-default-appearance"],
|
|
82
|
+
# Language affects font-family and thus other prioritary font properties.
|
|
83
|
+
"-x-lang": [],
|
|
84
|
+
# font-family potentially changes keyword font sizes, we want to apply text
|
|
85
|
+
# un-scaling after it.
|
|
86
|
+
"-x-text-scale": ["font-family"],
|
|
87
|
+
# Affects all colors due to forced-colors mode.
|
|
88
|
+
"forced-color-adjust": [],
|
|
89
|
+
# color-scheme potentially affects all colors via light-dark() / system colors.
|
|
90
|
+
# It depends on forced-color-adjust because it's one of the
|
|
91
|
+
# "ignored_when_colors_disabled" properties.
|
|
92
|
+
"color-scheme": ["forced-color-adjust"],
|
|
93
|
+
# Affects all lengths.
|
|
94
|
+
"zoom": [],
|
|
95
|
+
# Affects the `math` keyword font-size.
|
|
96
|
+
"math-depth": [],
|
|
97
|
+
# Affects min font-size.
|
|
98
|
+
"-moz-min-font-size-ratio": [],
|
|
99
|
+
# Default font-family depends on language.
|
|
100
|
+
"font-family": ["-x-lang", "appearance"],
|
|
101
|
+
# font-size depends on zoom because it's a length, and other properties because of
|
|
102
|
+
# their respective size implications, see their comments.
|
|
103
|
+
"font-size": [
|
|
104
|
+
"zoom",
|
|
105
|
+
"math-depth",
|
|
106
|
+
"-x-text-scale",
|
|
107
|
+
"-moz-min-font-size-ratio",
|
|
108
|
+
],
|
|
109
|
+
# Various font properties affect primary font selection, which affect all other
|
|
110
|
+
# lengths (other than font-size) via font-relative units.
|
|
111
|
+
"font-size-adjust": ["appearance"],
|
|
112
|
+
"font-weight": ["appearance"],
|
|
113
|
+
"font-width": ["appearance"],
|
|
114
|
+
"font-style": ["appearance"],
|
|
115
|
+
# Writing-mode properties affect logical -> physical property conversions, but also
|
|
116
|
+
# font metrics.
|
|
117
|
+
"direction": [],
|
|
118
|
+
"writing-mode": [],
|
|
119
|
+
"text-orientation": [],
|
|
120
|
+
# Line-height depends on the primary font and writing-mode because it can be a
|
|
121
|
+
# length.
|
|
122
|
+
"line-height": [
|
|
123
|
+
"direction",
|
|
124
|
+
"writing-mode",
|
|
125
|
+
"text-orientation",
|
|
126
|
+
"font-size",
|
|
127
|
+
"font-weight",
|
|
128
|
+
"font-width",
|
|
129
|
+
"font-style",
|
|
130
|
+
"font-size-adjust",
|
|
131
|
+
],
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
PRIORITARY_PROPERTIES = set(PRIORITARY_PROPERTY_DEPENDENCIES.keys())
|
|
135
|
+
|
|
136
|
+
VISITED_DEPENDENT_PROPERTIES = set(
|
|
137
|
+
[
|
|
138
|
+
"column-rule-color",
|
|
139
|
+
"text-emphasis-color",
|
|
140
|
+
"-webkit-text-fill-color",
|
|
141
|
+
"-webkit-text-stroke-color",
|
|
142
|
+
"text-decoration-color",
|
|
143
|
+
"fill",
|
|
144
|
+
"stroke",
|
|
145
|
+
"caret-color",
|
|
146
|
+
"background-color",
|
|
147
|
+
"border-top-color",
|
|
148
|
+
"border-right-color",
|
|
149
|
+
"border-bottom-color",
|
|
150
|
+
"border-left-color",
|
|
151
|
+
"border-block-start-color",
|
|
152
|
+
"border-inline-end-color",
|
|
153
|
+
"border-block-end-color",
|
|
154
|
+
"border-inline-start-color",
|
|
155
|
+
"outline-color",
|
|
156
|
+
"color",
|
|
157
|
+
]
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Bitfield values for all rule types which can have property declarations.
|
|
161
|
+
STYLE_RULE = 1 << 0
|
|
162
|
+
PAGE_RULE = 1 << 1
|
|
163
|
+
KEYFRAME_RULE = 1 << 2
|
|
164
|
+
POSITION_TRY_RULE = 1 << 3
|
|
165
|
+
SCOPE_RULE = 1 << 4
|
|
166
|
+
|
|
167
|
+
ALL_RULES = STYLE_RULE | PAGE_RULE | KEYFRAME_RULE | SCOPE_RULE
|
|
168
|
+
DEFAULT_RULES = STYLE_RULE | KEYFRAME_RULE | SCOPE_RULE
|
|
169
|
+
DEFAULT_RULES_AND_PAGE = DEFAULT_RULES | PAGE_RULE
|
|
170
|
+
DEFAULT_RULES_EXCEPT_KEYFRAME = STYLE_RULE | SCOPE_RULE
|
|
171
|
+
DEFAULT_RULES_AND_POSITION_TRY = DEFAULT_RULES | POSITION_TRY_RULE
|
|
172
|
+
|
|
173
|
+
# Rule name to value dict
|
|
174
|
+
RULE_VALUES = {
|
|
175
|
+
"style": STYLE_RULE,
|
|
176
|
+
"page": PAGE_RULE,
|
|
177
|
+
"keyframe": KEYFRAME_RULE,
|
|
178
|
+
"position-try": POSITION_TRY_RULE,
|
|
179
|
+
"scope": SCOPE_RULE,
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def rule_values_from_arg(rule_types):
|
|
184
|
+
if not rule_types:
|
|
185
|
+
return DEFAULT_RULES
|
|
186
|
+
mask = 0
|
|
187
|
+
for rule in rule_types:
|
|
188
|
+
mask |= RULE_VALUES[rule]
|
|
189
|
+
return mask
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def to_rust_ident(name):
|
|
193
|
+
name = name.replace("-", "_")
|
|
194
|
+
if name in ["static", "super", "box", "move"]: # Rust keywords
|
|
195
|
+
name += "_"
|
|
196
|
+
return name
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def idl_method(name, camel_case):
|
|
200
|
+
if name == "float":
|
|
201
|
+
return "CssFloat"
|
|
202
|
+
if name.startswith("-x-"):
|
|
203
|
+
return camel_case[1:]
|
|
204
|
+
return camel_case
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def to_snake_case(ident):
|
|
208
|
+
return re.sub("([A-Z]+)", lambda m: "_" + m.group(1).lower(), ident).strip("_")
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def to_camel_case(ident):
|
|
212
|
+
return re.sub(
|
|
213
|
+
"(^|_|-)([a-z0-9])", lambda m: m.group(2).upper(), ident.strip("_").strip("-")
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def to_camel_case_lower(ident):
|
|
218
|
+
camel = to_camel_case(ident)
|
|
219
|
+
return camel[0].lower() + camel[1:]
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
# https://drafts.csswg.org/cssom/#css-property-to-idl-attribute
|
|
223
|
+
def to_idl_name(name):
|
|
224
|
+
return re.sub("-([a-z])", lambda m: m.group(1).upper(), name)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def parse_aliases(value):
|
|
228
|
+
aliases = {}
|
|
229
|
+
for pair in value:
|
|
230
|
+
[a, v] = pair.split("=")
|
|
231
|
+
aliases[a] = v
|
|
232
|
+
return aliases
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
class Vector(object):
|
|
236
|
+
def __init__(
|
|
237
|
+
self,
|
|
238
|
+
need_index=False,
|
|
239
|
+
none_value=None,
|
|
240
|
+
separator='Comma',
|
|
241
|
+
animation_type=None,
|
|
242
|
+
simple_bindings=False,
|
|
243
|
+
):
|
|
244
|
+
self.need_index = need_index
|
|
245
|
+
self.none_value = none_value
|
|
246
|
+
self.separator = separator
|
|
247
|
+
self.animation_type = animation_type
|
|
248
|
+
self.simple_bindings = simple_bindings
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class Keyword(object):
|
|
252
|
+
def __init__(
|
|
253
|
+
self,
|
|
254
|
+
name,
|
|
255
|
+
values,
|
|
256
|
+
gecko_constant_prefix=None,
|
|
257
|
+
gecko_enum_prefix=None,
|
|
258
|
+
extra_gecko_values=None,
|
|
259
|
+
extra_servo_values=None,
|
|
260
|
+
gecko_aliases=None,
|
|
261
|
+
servo_aliases=None,
|
|
262
|
+
gecko_inexhaustive=None,
|
|
263
|
+
):
|
|
264
|
+
self.name = name
|
|
265
|
+
self.values = values;
|
|
266
|
+
assert isinstance(values, list), name
|
|
267
|
+
if gecko_constant_prefix and gecko_enum_prefix:
|
|
268
|
+
raise TypeError(
|
|
269
|
+
"Only one of gecko_constant_prefix and gecko_enum_prefix "
|
|
270
|
+
"can be specified"
|
|
271
|
+
)
|
|
272
|
+
self.gecko_constant_prefix = gecko_constant_prefix
|
|
273
|
+
self.gecko_enum_prefix = gecko_enum_prefix
|
|
274
|
+
if not gecko_constant_prefix and not gecko_enum_prefix:
|
|
275
|
+
self.gecko_enum_prefix = "Style" + to_camel_case(name.replace("-moz-", "").replace("-webkit-", ""))
|
|
276
|
+
self.extra_gecko_values = extra_gecko_values or []
|
|
277
|
+
self.extra_servo_values = extra_servo_values or []
|
|
278
|
+
self.gecko_aliases = parse_aliases(gecko_aliases or [])
|
|
279
|
+
self.servo_aliases = parse_aliases(servo_aliases or [])
|
|
280
|
+
self.gecko_inexhaustive = gecko_inexhaustive or self.gecko_constant_prefix is not None
|
|
281
|
+
|
|
282
|
+
def values_for(self, engine):
|
|
283
|
+
if engine == "gecko":
|
|
284
|
+
return self.values + self.extra_gecko_values
|
|
285
|
+
elif engine == "servo":
|
|
286
|
+
return self.values + self.extra_servo_values
|
|
287
|
+
else:
|
|
288
|
+
raise Exception("Bad engine: " + engine)
|
|
289
|
+
|
|
290
|
+
def aliases_for(self, engine):
|
|
291
|
+
if engine == "gecko":
|
|
292
|
+
return self.gecko_aliases
|
|
293
|
+
elif engine == "servo":
|
|
294
|
+
return self.servo_aliases
|
|
295
|
+
else:
|
|
296
|
+
raise Exception("Bad engine: " + engine)
|
|
297
|
+
|
|
298
|
+
def gecko_constant(self, value):
|
|
299
|
+
moz_stripped = value.replace("-moz-", "")
|
|
300
|
+
if self.gecko_enum_prefix:
|
|
301
|
+
parts = moz_stripped.replace("-", "_").split("_")
|
|
302
|
+
parts = [p.title() for p in parts]
|
|
303
|
+
return self.gecko_enum_prefix + "::" + "".join(parts)
|
|
304
|
+
else:
|
|
305
|
+
suffix = moz_stripped.replace("-", "_")
|
|
306
|
+
return self.gecko_constant_prefix + "_" + suffix.upper()
|
|
307
|
+
|
|
308
|
+
def needs_cast(self):
|
|
309
|
+
return self.gecko_enum_prefix is None
|
|
310
|
+
|
|
311
|
+
def maybe_cast(self, type_str):
|
|
312
|
+
return "as " + type_str if self.needs_cast() else ""
|
|
313
|
+
|
|
314
|
+
def casted_constant_name(self, value, cast_type):
|
|
315
|
+
if cast_type is None:
|
|
316
|
+
raise TypeError("We should specify the cast_type.")
|
|
317
|
+
|
|
318
|
+
if self.gecko_enum_prefix is None:
|
|
319
|
+
return cast_type.upper() + "_" + self.gecko_constant(value)
|
|
320
|
+
else:
|
|
321
|
+
return (
|
|
322
|
+
cast_type.upper()
|
|
323
|
+
+ "_"
|
|
324
|
+
+ self.gecko_constant(value).upper().replace("::", "_")
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def parse_property_aliases(alias_list):
|
|
329
|
+
result = []
|
|
330
|
+
if alias_list:
|
|
331
|
+
for alias in alias_list:
|
|
332
|
+
(name, _, pref) = alias.partition(":")
|
|
333
|
+
result.append((name, pref))
|
|
334
|
+
return result
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def to_phys(name, logical, physical):
|
|
338
|
+
return name.replace(logical, physical).replace("inset-", "")
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
class Property(object):
|
|
342
|
+
def __init__(
|
|
343
|
+
self,
|
|
344
|
+
name,
|
|
345
|
+
spec,
|
|
346
|
+
servo_pref,
|
|
347
|
+
gecko_pref,
|
|
348
|
+
enabled_in,
|
|
349
|
+
rule_types_allowed,
|
|
350
|
+
aliases,
|
|
351
|
+
extra_prefixes,
|
|
352
|
+
flags,
|
|
353
|
+
):
|
|
354
|
+
self.name = name
|
|
355
|
+
if not spec:
|
|
356
|
+
raise TypeError("Spec should be specified for " + name)
|
|
357
|
+
self.spec = spec
|
|
358
|
+
self.ident = to_rust_ident(name)
|
|
359
|
+
self.camel_case = to_camel_case(self.ident)
|
|
360
|
+
self.servo_pref = servo_pref
|
|
361
|
+
self.gecko_pref = gecko_pref
|
|
362
|
+
self.idl_method = idl_method(name, self.camel_case)
|
|
363
|
+
self.rule_types_allowed = rule_values_from_arg(rule_types_allowed)
|
|
364
|
+
# For enabled_in, the setup is as follows:
|
|
365
|
+
# It needs to be one of the four values: ["", "ua", "chrome", "content"]
|
|
366
|
+
# * "chrome" implies "ua", and implies that they're explicitly
|
|
367
|
+
# enabled.
|
|
368
|
+
# * "" implies the property will never be parsed.
|
|
369
|
+
# * "content" implies the property is accessible unconditionally,
|
|
370
|
+
# modulo a pref, set via servo_pref / gecko_pref.
|
|
371
|
+
assert enabled_in in ("", "ua", "chrome", "content")
|
|
372
|
+
self.enabled_in = enabled_in
|
|
373
|
+
self.aliases = parse_property_aliases(aliases)
|
|
374
|
+
self.extra_prefixes = parse_property_aliases(extra_prefixes)
|
|
375
|
+
self.flags = flags.split() if flags else []
|
|
376
|
+
|
|
377
|
+
def rule_types_allowed_names(self):
|
|
378
|
+
for name in RULE_VALUES:
|
|
379
|
+
if self.rule_types_allowed & RULE_VALUES[name] != 0:
|
|
380
|
+
yield name
|
|
381
|
+
|
|
382
|
+
def experimental(self, engine):
|
|
383
|
+
if engine == "gecko":
|
|
384
|
+
return bool(self.gecko_pref)
|
|
385
|
+
elif engine == "servo":
|
|
386
|
+
return bool(self.servo_pref)
|
|
387
|
+
else:
|
|
388
|
+
raise Exception("Bad engine: " + engine)
|
|
389
|
+
|
|
390
|
+
def explicitly_enabled_in_ua_sheets(self):
|
|
391
|
+
return self.enabled_in in ("ua", "chrome")
|
|
392
|
+
|
|
393
|
+
def explicitly_enabled_in_chrome(self):
|
|
394
|
+
return self.enabled_in == "chrome"
|
|
395
|
+
|
|
396
|
+
def enabled_in_content(self):
|
|
397
|
+
return self.enabled_in == "content"
|
|
398
|
+
|
|
399
|
+
def is_visited_dependent(self):
|
|
400
|
+
return self.name in VISITED_DEPENDENT_PROPERTIES
|
|
401
|
+
|
|
402
|
+
def is_prioritary(self):
|
|
403
|
+
return self.name in PRIORITARY_PROPERTIES
|
|
404
|
+
|
|
405
|
+
def noncustomcsspropertyid(self):
|
|
406
|
+
return "NonCustomCSSPropertyId::eCSSProperty_" + self.ident
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
class Longhand(Property):
|
|
410
|
+
def __init__(
|
|
411
|
+
self,
|
|
412
|
+
style_struct,
|
|
413
|
+
name,
|
|
414
|
+
initial_value=None,
|
|
415
|
+
initial_specified_value=None,
|
|
416
|
+
parse_method='parse',
|
|
417
|
+
spec=None,
|
|
418
|
+
animation_type="normal",
|
|
419
|
+
keyword=None,
|
|
420
|
+
predefined_type=None,
|
|
421
|
+
servo_pref=None,
|
|
422
|
+
gecko_pref=None,
|
|
423
|
+
enabled_in="content",
|
|
424
|
+
gecko_ffi_name=None,
|
|
425
|
+
has_effect_on_gecko_scrollbars=None,
|
|
426
|
+
rule_types_allowed=None,
|
|
427
|
+
cast_type="u8",
|
|
428
|
+
logical=False,
|
|
429
|
+
logical_group=None,
|
|
430
|
+
aliases=None,
|
|
431
|
+
extra_prefixes=None,
|
|
432
|
+
boxed=False,
|
|
433
|
+
flags=None,
|
|
434
|
+
allow_quirks=False,
|
|
435
|
+
ignored_when_colors_disabled=False,
|
|
436
|
+
vector=None,
|
|
437
|
+
servo_restyle_damage="rebuild_box",
|
|
438
|
+
affects=None,
|
|
439
|
+
):
|
|
440
|
+
Property.__init__(
|
|
441
|
+
self,
|
|
442
|
+
name=name,
|
|
443
|
+
spec=spec,
|
|
444
|
+
servo_pref=servo_pref,
|
|
445
|
+
gecko_pref=gecko_pref,
|
|
446
|
+
enabled_in=enabled_in,
|
|
447
|
+
rule_types_allowed=rule_types_allowed,
|
|
448
|
+
aliases=aliases,
|
|
449
|
+
extra_prefixes=extra_prefixes,
|
|
450
|
+
flags=flags,
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
self.affects = affects
|
|
454
|
+
self.flags += self.affects_flags()
|
|
455
|
+
|
|
456
|
+
self.parse_method = parse_method
|
|
457
|
+
self.initial_value = initial_value
|
|
458
|
+
self.initial_specified_value = initial_specified_value
|
|
459
|
+
self.keyword = keyword
|
|
460
|
+
self.predefined_type = predefined_type
|
|
461
|
+
self.style_struct = style_struct
|
|
462
|
+
self.has_effect_on_gecko_scrollbars = has_effect_on_gecko_scrollbars
|
|
463
|
+
assert (
|
|
464
|
+
has_effect_on_gecko_scrollbars in [None, False, True]
|
|
465
|
+
and not style_struct.inherited
|
|
466
|
+
or (gecko_pref is None and enabled_in != "")
|
|
467
|
+
== (has_effect_on_gecko_scrollbars is None)
|
|
468
|
+
), (
|
|
469
|
+
"Property "
|
|
470
|
+
+ name
|
|
471
|
+
+ ": has_effect_on_gecko_scrollbars must be "
|
|
472
|
+
+ "specified, and must have a value of True or False, iff a "
|
|
473
|
+
+ "property is inherited and is behind a Gecko pref or internal"
|
|
474
|
+
)
|
|
475
|
+
self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case
|
|
476
|
+
self.cast_type = cast_type
|
|
477
|
+
self.logical = logical
|
|
478
|
+
self.logical_group = logical_group
|
|
479
|
+
if self.logical:
|
|
480
|
+
assert logical_group, f"Property {name} must have a logical group"
|
|
481
|
+
|
|
482
|
+
self.boxed = boxed
|
|
483
|
+
self.allow_quirks = allow_quirks
|
|
484
|
+
self.ignored_when_colors_disabled = ignored_when_colors_disabled
|
|
485
|
+
self.vector = Vector(**vector) if vector is not None else None
|
|
486
|
+
|
|
487
|
+
assert animation_type in ["none", "normal", "discrete"]
|
|
488
|
+
self.animation_type = animation_type
|
|
489
|
+
self.animatable = animation_type != "none"
|
|
490
|
+
|
|
491
|
+
# See compute_damage for the various values this can take
|
|
492
|
+
self.servo_restyle_damage = servo_restyle_damage
|
|
493
|
+
|
|
494
|
+
def affects_flags(self):
|
|
495
|
+
# Layout is the stronger hint. This property animation affects layout
|
|
496
|
+
# or frame construction. `display` or `width` are examples that should
|
|
497
|
+
# use this.
|
|
498
|
+
if self.affects == "layout":
|
|
499
|
+
return ["AFFECTS_LAYOUT"]
|
|
500
|
+
# This property doesn't affect layout, but affects overflow.
|
|
501
|
+
# `transform` and co. are examples of this.
|
|
502
|
+
if self.affects == "overflow":
|
|
503
|
+
return ["AFFECTS_OVERFLOW"]
|
|
504
|
+
# This property affects the rendered output but doesn't affect layout.
|
|
505
|
+
# `opacity`, `color`, or `z-index` are examples of this.
|
|
506
|
+
if self.affects == "paint":
|
|
507
|
+
return ["AFFECTS_PAINT"]
|
|
508
|
+
# This property doesn't affect rendering in any way.
|
|
509
|
+
# `user-select` is an example of this.
|
|
510
|
+
assert self.affects == "", (
|
|
511
|
+
"Property "
|
|
512
|
+
+ self.name
|
|
513
|
+
+ ': affects must be specified and be one of ["layout", "overflow", "paint", ""], see Longhand.affects_flags for documentation'
|
|
514
|
+
)
|
|
515
|
+
return []
|
|
516
|
+
|
|
517
|
+
@staticmethod
|
|
518
|
+
def type():
|
|
519
|
+
return "longhand"
|
|
520
|
+
|
|
521
|
+
# For a given logical property, return the kind of mapping we need to
|
|
522
|
+
# perform, and which logical value we represent, in a tuple.
|
|
523
|
+
def logical_mapping_data(self, data):
|
|
524
|
+
if not self.logical:
|
|
525
|
+
return []
|
|
526
|
+
# Sizes and axes are basically the same for mapping, we just need
|
|
527
|
+
# slightly different replacements (block-size -> height, etc rather
|
|
528
|
+
# than -x/-y) below.
|
|
529
|
+
for [ty, logical_items, physical_items] in [
|
|
530
|
+
["Side", LOGICAL_SIDES, PHYSICAL_SIDES],
|
|
531
|
+
["Corner", LOGICAL_CORNERS, PHYSICAL_CORNERS],
|
|
532
|
+
["Axis", LOGICAL_SIZES, PHYSICAL_SIZES],
|
|
533
|
+
["Axis", LOGICAL_AXES, PHYSICAL_AXES],
|
|
534
|
+
]:
|
|
535
|
+
candidate = [s for s in logical_items if s in self.name]
|
|
536
|
+
if candidate:
|
|
537
|
+
assert len(candidate) == 1
|
|
538
|
+
return [ty, candidate[0], logical_items, physical_items]
|
|
539
|
+
assert False, "Don't know how to deal with " + self.name
|
|
540
|
+
|
|
541
|
+
def logical_mapping_kind(self, data):
|
|
542
|
+
assert self.logical
|
|
543
|
+
[kind, item, _, _] = self.logical_mapping_data(data)
|
|
544
|
+
return "LogicalMappingKind::{}(Logical{}::{})".format(
|
|
545
|
+
kind, kind, to_camel_case(item.replace("-size", ""))
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
# For a given logical property return all the physical property names
|
|
549
|
+
# corresponding to it.
|
|
550
|
+
def all_physical_mapped_properties(self, data):
|
|
551
|
+
if not self.logical:
|
|
552
|
+
return []
|
|
553
|
+
[_, logical_side, _, physical_items] = self.logical_mapping_data(data)
|
|
554
|
+
return [
|
|
555
|
+
data.longhands_by_name[to_phys(self.name, logical_side, physical_side)]
|
|
556
|
+
for physical_side in physical_items
|
|
557
|
+
]
|
|
558
|
+
|
|
559
|
+
def may_be_disabled_in(self, shorthand, engine):
|
|
560
|
+
if "ALLOWS_DISABLED_SUBPROPERTIES" in shorthand.flags:
|
|
561
|
+
assert "IS_LEGACY_SHORTHAND" in shorthand.flags
|
|
562
|
+
assert len(shorthand.sub_properties) == 1
|
|
563
|
+
return False
|
|
564
|
+
|
|
565
|
+
if engine == "gecko":
|
|
566
|
+
return self.gecko_pref and self.gecko_pref != shorthand.gecko_pref
|
|
567
|
+
elif engine == "servo":
|
|
568
|
+
return self.servo_pref and self.servo_pref != shorthand.servo_pref
|
|
569
|
+
else:
|
|
570
|
+
raise Exception("Bad engine: " + engine)
|
|
571
|
+
|
|
572
|
+
def base_type(self):
|
|
573
|
+
if self.predefined_type and not self.vector:
|
|
574
|
+
return "crate::values::specified::{}".format(self.predefined_type)
|
|
575
|
+
return "longhands::{}::SpecifiedValue".format(self.ident)
|
|
576
|
+
|
|
577
|
+
def specified_type(self):
|
|
578
|
+
if self.predefined_type and not self.vector:
|
|
579
|
+
ty = "crate::values::specified::{}".format(self.predefined_type)
|
|
580
|
+
else:
|
|
581
|
+
ty = "longhands::{}::SpecifiedValue".format(self.ident)
|
|
582
|
+
if self.boxed:
|
|
583
|
+
ty = "Box<{}>".format(ty)
|
|
584
|
+
return ty
|
|
585
|
+
|
|
586
|
+
def is_zoom_dependent(self):
|
|
587
|
+
if not self.predefined_type:
|
|
588
|
+
return False
|
|
589
|
+
# TODO: Get this from SpecifiedValueInfo or so instead; see bug 1887627.
|
|
590
|
+
return self.predefined_type in {
|
|
591
|
+
"BorderSideWidth",
|
|
592
|
+
"BorderSpacing",
|
|
593
|
+
"BoxShadow",
|
|
594
|
+
"Filter",
|
|
595
|
+
"FontSize",
|
|
596
|
+
"Inset",
|
|
597
|
+
"Length",
|
|
598
|
+
"LengthPercentage",
|
|
599
|
+
"LengthPercentageOrAuto",
|
|
600
|
+
"LetterSpacing",
|
|
601
|
+
"LineHeight",
|
|
602
|
+
"LineWidth",
|
|
603
|
+
"MaxSize",
|
|
604
|
+
"Margin",
|
|
605
|
+
"NonNegativeLength",
|
|
606
|
+
"NonNegativeLengthOrAuto",
|
|
607
|
+
"NonNegativeLengthOrNumber",
|
|
608
|
+
"NonNegativeLengthOrNumberRect",
|
|
609
|
+
"NonNegativeLengthPercentage",
|
|
610
|
+
"NonNegativeLengthPercentageOrAuto",
|
|
611
|
+
"NonNegativeLengthPercentageOrNormal",
|
|
612
|
+
"Position",
|
|
613
|
+
"PositionOrAuto",
|
|
614
|
+
"SimpleShadow",
|
|
615
|
+
"Size",
|
|
616
|
+
"SVGLength",
|
|
617
|
+
"SVGStrokeDashArray",
|
|
618
|
+
"SVGWidth",
|
|
619
|
+
"TextDecorationLength",
|
|
620
|
+
"TextDecorationInset",
|
|
621
|
+
"TextIndent",
|
|
622
|
+
"WordSpacing",
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
def is_inherited_zoom_dependent_property(self):
|
|
626
|
+
if self.logical:
|
|
627
|
+
return False
|
|
628
|
+
if not self.style_struct.inherited:
|
|
629
|
+
return False
|
|
630
|
+
return self.is_zoom_dependent()
|
|
631
|
+
|
|
632
|
+
def specified_is_copy(self):
|
|
633
|
+
if self.vector or self.boxed:
|
|
634
|
+
return False
|
|
635
|
+
if self.predefined_type:
|
|
636
|
+
return self.predefined_type in {
|
|
637
|
+
"AlignmentBaseline",
|
|
638
|
+
"Appearance",
|
|
639
|
+
"AnimationComposition",
|
|
640
|
+
"AnimationDirection",
|
|
641
|
+
"AnimationFillMode",
|
|
642
|
+
"AnimationPlayState",
|
|
643
|
+
"BaselineSource",
|
|
644
|
+
"BreakBetween",
|
|
645
|
+
"BreakWithin",
|
|
646
|
+
"BackgroundRepeat",
|
|
647
|
+
"BorderImageRepeat",
|
|
648
|
+
"BorderStyle",
|
|
649
|
+
"table::CaptionSide",
|
|
650
|
+
"Clear",
|
|
651
|
+
"Contain",
|
|
652
|
+
"ContentVisibility",
|
|
653
|
+
"ContainerType",
|
|
654
|
+
"Display",
|
|
655
|
+
"DominantBaseline",
|
|
656
|
+
"FillRule",
|
|
657
|
+
"FlexWrap",
|
|
658
|
+
"Float",
|
|
659
|
+
"FontLanguageOverride",
|
|
660
|
+
"FontSynthesis",
|
|
661
|
+
"FontSynthesisStyle",
|
|
662
|
+
"FontVariantEastAsian",
|
|
663
|
+
"FontVariantLigatures",
|
|
664
|
+
"FontVariantNumeric",
|
|
665
|
+
"GridAutoFlow",
|
|
666
|
+
"ImageDecoding",
|
|
667
|
+
"ImageRendering",
|
|
668
|
+
"Inert",
|
|
669
|
+
"PositionArea",
|
|
670
|
+
"PositionAreaKeyword",
|
|
671
|
+
"PositionProperty",
|
|
672
|
+
"ContentDistribution",
|
|
673
|
+
"ItemPlacement",
|
|
674
|
+
"SelfAlignment",
|
|
675
|
+
"JustifyItems",
|
|
676
|
+
"LineBreak",
|
|
677
|
+
"MarginTrim",
|
|
678
|
+
"MasonryAutoFlow",
|
|
679
|
+
"MozTheme",
|
|
680
|
+
"BoolInteger",
|
|
681
|
+
"text::MozControlCharacterVisibility",
|
|
682
|
+
"MozScriptMinSize",
|
|
683
|
+
"MozScriptSizeMultiplier",
|
|
684
|
+
"TransformBox",
|
|
685
|
+
"TextDecorationSkipInk",
|
|
686
|
+
"OutlineStyle",
|
|
687
|
+
"Overflow",
|
|
688
|
+
"OverflowAnchor",
|
|
689
|
+
"OverflowWrap",
|
|
690
|
+
"OverscrollBehavior",
|
|
691
|
+
"PageOrientation",
|
|
692
|
+
"PointerEvents",
|
|
693
|
+
"PositionTryOrder",
|
|
694
|
+
"PositionVisibility",
|
|
695
|
+
"PrintColorAdjust",
|
|
696
|
+
"ForcedColorAdjust",
|
|
697
|
+
"Resize",
|
|
698
|
+
"RubyPosition",
|
|
699
|
+
"SVGPaintOrder",
|
|
700
|
+
"ScrollbarGutter",
|
|
701
|
+
"ScrollSnapAlign",
|
|
702
|
+
"ScrollSnapAxis",
|
|
703
|
+
"ScrollSnapStop",
|
|
704
|
+
"ScrollSnapStrictness",
|
|
705
|
+
"ScrollSnapType",
|
|
706
|
+
"TextAlign",
|
|
707
|
+
"TextAlignLast",
|
|
708
|
+
"TextAutospace",
|
|
709
|
+
"TextBoxEdge",
|
|
710
|
+
"TextBoxTrim",
|
|
711
|
+
"TextDecorationLine",
|
|
712
|
+
"TextEmphasisPosition",
|
|
713
|
+
"TextJustify",
|
|
714
|
+
"TextTransform",
|
|
715
|
+
"TextUnderlinePosition",
|
|
716
|
+
"TouchAction",
|
|
717
|
+
"TransformStyle",
|
|
718
|
+
"UserFocus",
|
|
719
|
+
"UserSelect",
|
|
720
|
+
"VectorEffect",
|
|
721
|
+
"WordBreak",
|
|
722
|
+
"WritingModeProperty",
|
|
723
|
+
"XSpan",
|
|
724
|
+
"XTextScale",
|
|
725
|
+
}
|
|
726
|
+
if self.name == "overflow-y":
|
|
727
|
+
return True
|
|
728
|
+
return bool(self.keyword)
|
|
729
|
+
|
|
730
|
+
def animated_type(self):
|
|
731
|
+
assert self.animatable
|
|
732
|
+
computed = "<{} as ToComputedValue>::ComputedValue".format(self.base_type())
|
|
733
|
+
if self.animation_type == "discrete":
|
|
734
|
+
return computed
|
|
735
|
+
return "<{} as ToAnimatedValue>::AnimatedValue".format(computed)
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
class Shorthand(Property):
|
|
739
|
+
def __init__(
|
|
740
|
+
self,
|
|
741
|
+
name,
|
|
742
|
+
sub_properties,
|
|
743
|
+
spec=None,
|
|
744
|
+
servo_pref=None,
|
|
745
|
+
gecko_pref=None,
|
|
746
|
+
kind=None,
|
|
747
|
+
allow_quirks=False,
|
|
748
|
+
derive_serialize=False,
|
|
749
|
+
derive_value_info=True,
|
|
750
|
+
enabled_in="content",
|
|
751
|
+
rule_types_allowed=None,
|
|
752
|
+
aliases=None,
|
|
753
|
+
extra_prefixes=None,
|
|
754
|
+
flags=None,
|
|
755
|
+
):
|
|
756
|
+
Property.__init__(
|
|
757
|
+
self,
|
|
758
|
+
name=name,
|
|
759
|
+
spec=spec,
|
|
760
|
+
servo_pref=servo_pref,
|
|
761
|
+
gecko_pref=gecko_pref,
|
|
762
|
+
enabled_in=enabled_in,
|
|
763
|
+
rule_types_allowed=rule_types_allowed,
|
|
764
|
+
aliases=aliases,
|
|
765
|
+
extra_prefixes=extra_prefixes,
|
|
766
|
+
flags=flags,
|
|
767
|
+
)
|
|
768
|
+
self.sub_properties = sub_properties
|
|
769
|
+
self.derive_serialize = derive_serialize
|
|
770
|
+
self.derive_value_info = derive_value_info
|
|
771
|
+
self.allow_quirks = allow_quirks
|
|
772
|
+
self.kind = kind
|
|
773
|
+
|
|
774
|
+
def get_animatable(self):
|
|
775
|
+
for sub in self.sub_properties:
|
|
776
|
+
if sub.animatable:
|
|
777
|
+
return True
|
|
778
|
+
return False
|
|
779
|
+
|
|
780
|
+
animatable = property(get_animatable)
|
|
781
|
+
|
|
782
|
+
@staticmethod
|
|
783
|
+
def type():
|
|
784
|
+
return "shorthand"
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
class Alias(object):
|
|
788
|
+
def __init__(self, name, original, gecko_pref):
|
|
789
|
+
self.name = name
|
|
790
|
+
self.ident = to_rust_ident(name)
|
|
791
|
+
self.camel_case = to_camel_case(self.ident)
|
|
792
|
+
self.idl_method = idl_method(name, self.camel_case)
|
|
793
|
+
self.original = original
|
|
794
|
+
self.enabled_in = original.enabled_in
|
|
795
|
+
self.animatable = original.animatable
|
|
796
|
+
self.servo_pref = original.servo_pref
|
|
797
|
+
self.gecko_pref = gecko_pref
|
|
798
|
+
self.rule_types_allowed = original.rule_types_allowed
|
|
799
|
+
self.flags = original.flags
|
|
800
|
+
|
|
801
|
+
@staticmethod
|
|
802
|
+
def type():
|
|
803
|
+
return "alias"
|
|
804
|
+
|
|
805
|
+
def rule_types_allowed_names(self):
|
|
806
|
+
for name in RULE_VALUES:
|
|
807
|
+
if self.rule_types_allowed & RULE_VALUES[name] != 0:
|
|
808
|
+
yield name
|
|
809
|
+
|
|
810
|
+
def experimental(self, engine):
|
|
811
|
+
if engine == "gecko":
|
|
812
|
+
return bool(self.gecko_pref)
|
|
813
|
+
elif engine == "servo":
|
|
814
|
+
return bool(self.servo_pref)
|
|
815
|
+
else:
|
|
816
|
+
raise Exception("Bad engine: " + engine)
|
|
817
|
+
|
|
818
|
+
def explicitly_enabled_in_ua_sheets(self):
|
|
819
|
+
return self.enabled_in in ["ua", "chrome"]
|
|
820
|
+
|
|
821
|
+
def explicitly_enabled_in_chrome(self):
|
|
822
|
+
return self.enabled_in == "chrome"
|
|
823
|
+
|
|
824
|
+
def enabled_in_content(self):
|
|
825
|
+
return self.enabled_in == "content"
|
|
826
|
+
|
|
827
|
+
def noncustomcsspropertyid(self):
|
|
828
|
+
return "NonCustomCSSPropertyId::eCSSPropertyAlias_%s" % self.ident
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
class Method(object):
|
|
832
|
+
def __init__(self, name, return_type=None, arg_types=None, is_mut=False):
|
|
833
|
+
self.name = name
|
|
834
|
+
self.return_type = return_type
|
|
835
|
+
self.arg_types = arg_types or []
|
|
836
|
+
self.is_mut = is_mut
|
|
837
|
+
|
|
838
|
+
def arg_list(self):
|
|
839
|
+
args = ["_: " + x for x in self.arg_types]
|
|
840
|
+
args = ["&mut self" if self.is_mut else "&self"] + args
|
|
841
|
+
return ", ".join(args)
|
|
842
|
+
|
|
843
|
+
def signature(self):
|
|
844
|
+
sig = "fn %s(%s)" % (self.name, self.arg_list())
|
|
845
|
+
if self.return_type:
|
|
846
|
+
sig = sig + " -> " + self.return_type
|
|
847
|
+
return sig
|
|
848
|
+
|
|
849
|
+
def declare(self):
|
|
850
|
+
return self.signature() + ";"
|
|
851
|
+
|
|
852
|
+
def stub(self):
|
|
853
|
+
return self.signature() + "{ unimplemented!() }"
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
class StyleStruct(object):
|
|
857
|
+
def __init__(self, name, inherited, gecko_name=None):
|
|
858
|
+
self.gecko_struct_name = "Gecko" + name
|
|
859
|
+
self.name = name
|
|
860
|
+
self.name_lower = to_snake_case(name)
|
|
861
|
+
self.ident = to_rust_ident(self.name_lower)
|
|
862
|
+
self.longhands = []
|
|
863
|
+
self.inherited = inherited
|
|
864
|
+
self.gecko_name = gecko_name or name
|
|
865
|
+
self.gecko_ffi_name = "nsStyle" + self.gecko_name
|
|
866
|
+
self.document_dependent = self.gecko_name in ["Font", "Visibility", "Text"]
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
class Descriptor(object):
|
|
870
|
+
def __init__(self, name, type, parser=None, gecko_pref=None, ignore_malloc_size_of=None, aliases=[]):
|
|
871
|
+
self.name = name
|
|
872
|
+
self.aliases = aliases
|
|
873
|
+
self.type = type
|
|
874
|
+
self.parser = parser
|
|
875
|
+
self.gecko_pref = gecko_pref
|
|
876
|
+
self.ignore_malloc_size_of = ignore_malloc_size_of
|
|
877
|
+
self.ident = to_rust_ident(name)
|
|
878
|
+
self.camel_case = to_camel_case(name)
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
class PropertiesData(object):
|
|
882
|
+
def __init__(self, engine):
|
|
883
|
+
self.engine = engine
|
|
884
|
+
self.longhands = []
|
|
885
|
+
self.longhands_by_name = {}
|
|
886
|
+
self.logical_groups = {}
|
|
887
|
+
self.longhand_aliases = []
|
|
888
|
+
self.shorthands = []
|
|
889
|
+
self.shorthands_by_name = {}
|
|
890
|
+
self.shorthand_aliases = []
|
|
891
|
+
self.counted_unknown_properties = [
|
|
892
|
+
CountedUnknownProperty(p) for p in COUNTED_UNKNOWN_PROPERTIES
|
|
893
|
+
]
|
|
894
|
+
|
|
895
|
+
self.style_structs = [
|
|
896
|
+
StyleStruct("Background", inherited=False),
|
|
897
|
+
StyleStruct("Border", inherited=False),
|
|
898
|
+
StyleStruct("Box", inherited=False, gecko_name="Display"),
|
|
899
|
+
StyleStruct("Column", inherited=False),
|
|
900
|
+
StyleStruct("Counters", inherited=False, gecko_name="Content"),
|
|
901
|
+
StyleStruct("Effects", inherited=False),
|
|
902
|
+
StyleStruct("Font", inherited=True),
|
|
903
|
+
StyleStruct("InheritedBox", inherited=True, gecko_name="Visibility"),
|
|
904
|
+
StyleStruct("InheritedSVG", inherited=True, gecko_name="SVG"),
|
|
905
|
+
StyleStruct("InheritedTable", inherited=True, gecko_name="TableBorder"),
|
|
906
|
+
StyleStruct("InheritedText", inherited=True, gecko_name="Text"),
|
|
907
|
+
StyleStruct("InheritedUI", inherited=True, gecko_name="UI"),
|
|
908
|
+
StyleStruct("List", inherited=True),
|
|
909
|
+
StyleStruct("Margin", inherited=False),
|
|
910
|
+
StyleStruct("Outline", inherited=False),
|
|
911
|
+
StyleStruct("Padding", inherited=False),
|
|
912
|
+
StyleStruct("Page", inherited=False),
|
|
913
|
+
StyleStruct("Position", inherited=False),
|
|
914
|
+
StyleStruct("SVG", inherited=False, gecko_name="SVGReset"),
|
|
915
|
+
StyleStruct("Table", inherited=False),
|
|
916
|
+
StyleStruct("Text", inherited=False, gecko_name="TextReset"),
|
|
917
|
+
StyleStruct("UI", inherited=False, gecko_name="UIReset"),
|
|
918
|
+
StyleStruct("XUL", inherited=False),
|
|
919
|
+
]
|
|
920
|
+
|
|
921
|
+
longhands_toml = toml.loads(open(os.path.join(os.path.dirname(__file__), "longhands.toml")).read())
|
|
922
|
+
for name, args in longhands_toml.items():
|
|
923
|
+
style_struct = self.style_struct_by_name_lower(args["struct"])
|
|
924
|
+
del args['struct']
|
|
925
|
+
|
|
926
|
+
# Handle keyword properties
|
|
927
|
+
if 'keyword' in args:
|
|
928
|
+
keyword_dict = args.pop('keyword')
|
|
929
|
+
if 'values' not in keyword_dict:
|
|
930
|
+
raise TypeError(f"{name}: keyword should have 'values'")
|
|
931
|
+
values = keyword_dict.pop('values')
|
|
932
|
+
keyword = Keyword(name, values, **keyword_dict)
|
|
933
|
+
self.declare_longhand(style_struct, name, keyword=keyword, **args)
|
|
934
|
+
else:
|
|
935
|
+
# Handle predefined_type properties
|
|
936
|
+
if 'type' not in args:
|
|
937
|
+
raise TypeError(f"{name} should have a type")
|
|
938
|
+
args['predefined_type'] = args.pop('type')
|
|
939
|
+
if 'initial' not in args and not args.get('vector'):
|
|
940
|
+
raise TypeError(f"{name} should have an initial value (only vector properties should lack one)")
|
|
941
|
+
args['initial_value'] = args.pop('initial', None)
|
|
942
|
+
self.declare_longhand(style_struct, name, **args)
|
|
943
|
+
|
|
944
|
+
for group, props in self.logical_groups.items():
|
|
945
|
+
logical_count = sum(1 for p in props if p.logical)
|
|
946
|
+
if logical_count * 2 != len(props):
|
|
947
|
+
raise RuntimeError(f"Logical group {group} has unbalanced logical / physical properties")
|
|
948
|
+
|
|
949
|
+
# After this code, `data.longhands` is sorted in the following order:
|
|
950
|
+
# - first all keyword variants and all variants known to be Copy,
|
|
951
|
+
# - second all the other variants, such as all variants with the same field
|
|
952
|
+
# have consecutive discriminants.
|
|
953
|
+
# The variable `variants` contain the same entries as `data.longhands` in
|
|
954
|
+
# the same order, but must exist separately to the data source, because
|
|
955
|
+
# we then need to add three additional variants `WideKeywordDeclaration`,
|
|
956
|
+
# `VariableDeclaration` and `CustomDeclaration`.
|
|
957
|
+
self.declaration_variants = []
|
|
958
|
+
for property in self.longhands:
|
|
959
|
+
self.declaration_variants.append({
|
|
960
|
+
"name": property.camel_case,
|
|
961
|
+
"type": property.specified_type(),
|
|
962
|
+
"doc": "`" + property.name + "`",
|
|
963
|
+
"copy": property.specified_is_copy(),
|
|
964
|
+
})
|
|
965
|
+
groups = {}
|
|
966
|
+
keyfunc = lambda x: x["type"]
|
|
967
|
+
sortkeys = {}
|
|
968
|
+
# WARNING: It is *really* important for the variants of `LonghandId`
|
|
969
|
+
# and `PropertyDeclaration` to be defined in the exact same order,
|
|
970
|
+
# with the exception of `CSSWideKeyword`, `WithVariables` and `Custom`,
|
|
971
|
+
# which don't exist in `LonghandId`.
|
|
972
|
+
for ty, group in groupby(sorted(self.declaration_variants, key=keyfunc), keyfunc):
|
|
973
|
+
group = list(group)
|
|
974
|
+
groups[ty] = group
|
|
975
|
+
for v in group:
|
|
976
|
+
if len(group) == 1:
|
|
977
|
+
sortkeys[v["name"]] = (not v["copy"], 1, v["name"], "")
|
|
978
|
+
else:
|
|
979
|
+
sortkeys[v["name"]] = (not v["copy"], len(group), ty, v["name"])
|
|
980
|
+
# It is extremely important to sort the `data.longhands` array here so
|
|
981
|
+
# that it is in the same order as `variants`, for `LonghandId` and
|
|
982
|
+
# `PropertyDeclarationId` to coincide.
|
|
983
|
+
self.longhands.sort(key=lambda x: sortkeys[x.camel_case])
|
|
984
|
+
self.declaration_variants.sort(key=lambda x: sortkeys[x["name"]])
|
|
985
|
+
self.declaration_extra_variants = [
|
|
986
|
+
{
|
|
987
|
+
"name": "CSSWideKeyword",
|
|
988
|
+
"type": "WideKeywordDeclaration",
|
|
989
|
+
"doc": "A CSS-wide keyword.",
|
|
990
|
+
"copy": False,
|
|
991
|
+
},
|
|
992
|
+
{
|
|
993
|
+
"name": "WithVariables",
|
|
994
|
+
"type": "VariableDeclaration",
|
|
995
|
+
"doc": "An unparsed declaration.",
|
|
996
|
+
"copy": False,
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
"name": "Custom",
|
|
1000
|
+
"type": "CustomDeclaration",
|
|
1001
|
+
"doc": "A custom property declaration.",
|
|
1002
|
+
"copy": False,
|
|
1003
|
+
},
|
|
1004
|
+
]
|
|
1005
|
+
for v in self.declaration_extra_variants:
|
|
1006
|
+
self.declaration_variants.append(v)
|
|
1007
|
+
groups[v["type"]] = [v]
|
|
1008
|
+
|
|
1009
|
+
shorthands_toml = toml.loads(open(os.path.join(os.path.dirname(__file__), "shorthands.toml")).read())
|
|
1010
|
+
for name, args in shorthands_toml.items():
|
|
1011
|
+
self.declare_shorthand(name, **args)
|
|
1012
|
+
self.declare_all_shorthand()
|
|
1013
|
+
|
|
1014
|
+
self.font_face_descriptors = self._load_descriptors("font_face_descriptors.toml")
|
|
1015
|
+
self.counter_style_descriptors = self._load_descriptors("counter_style_descriptors.toml")
|
|
1016
|
+
self.property_descriptors = self._load_descriptors("property_descriptors.toml")
|
|
1017
|
+
self.view_transition_descriptors = self._load_descriptors("view_transition_descriptors.toml")
|
|
1018
|
+
|
|
1019
|
+
|
|
1020
|
+
def declare_all_shorthand(self):
|
|
1021
|
+
# We don't define the 'all' shorthand using the regular helpers:shorthand
|
|
1022
|
+
# mechanism, since it causes some very large types to be generated.
|
|
1023
|
+
#
|
|
1024
|
+
# Make sure logical properties appear before its physical
|
|
1025
|
+
# counter-parts, in order to prevent bugs like:
|
|
1026
|
+
#
|
|
1027
|
+
# https://bugzilla.mozilla.org/show_bug.cgi?id=1410028
|
|
1028
|
+
#
|
|
1029
|
+
# FIXME(emilio): Adopt the resolution from:
|
|
1030
|
+
#
|
|
1031
|
+
# https://github.com/w3c/csswg-drafts/issues/1898
|
|
1032
|
+
#
|
|
1033
|
+
# when there is one, whatever that is.
|
|
1034
|
+
logical_longhands = []
|
|
1035
|
+
other_longhands = []
|
|
1036
|
+
for p in self.longhands:
|
|
1037
|
+
if p.name in ['direction', 'unicode-bidi']:
|
|
1038
|
+
continue;
|
|
1039
|
+
if not p.enabled_in_content() and not p.experimental(self.engine):
|
|
1040
|
+
continue;
|
|
1041
|
+
if "style" not in p.rule_types_allowed_names():
|
|
1042
|
+
continue;
|
|
1043
|
+
if p.logical:
|
|
1044
|
+
logical_longhands.append(p)
|
|
1045
|
+
else:
|
|
1046
|
+
other_longhands.append(p)
|
|
1047
|
+
|
|
1048
|
+
# Cache locality when iterating over the `all` shorthand is important
|
|
1049
|
+
# for transition handling, so we sort by style struct.
|
|
1050
|
+
# We technically don't care about the logical prop order (because those
|
|
1051
|
+
# are not animated themselves), but we sort them the same way for
|
|
1052
|
+
# consistency.
|
|
1053
|
+
logical_longhands.sort(key=lambda p: p.style_struct.name)
|
|
1054
|
+
other_longhands.sort(key=lambda p: p.style_struct.name)
|
|
1055
|
+
|
|
1056
|
+
all_names = list(map(lambda p: p.name, logical_longhands + other_longhands))
|
|
1057
|
+
|
|
1058
|
+
self.all_shorthand_length = len(all_names)
|
|
1059
|
+
self.declare_shorthand(
|
|
1060
|
+
"all",
|
|
1061
|
+
all_names,
|
|
1062
|
+
spec="https://drafts.csswg.org/css-cascade-3/#all-shorthand"
|
|
1063
|
+
)
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
def _load_descriptors(self, filename):
|
|
1067
|
+
path = os.path.join(os.path.dirname(__file__), filename)
|
|
1068
|
+
data = toml.loads(open(path).read())
|
|
1069
|
+
return [Descriptor(name, **args) for name, args in data.items()]
|
|
1070
|
+
|
|
1071
|
+
def style_struct_by_name_lower(self, name):
|
|
1072
|
+
for s in self.style_structs:
|
|
1073
|
+
if s.name_lower == name:
|
|
1074
|
+
return s
|
|
1075
|
+
raise TypeError(f"Unexpected struct name {name}")
|
|
1076
|
+
|
|
1077
|
+
def active_style_structs(self):
|
|
1078
|
+
return [s for s in self.style_structs if s.longhands]
|
|
1079
|
+
|
|
1080
|
+
def add_prefixed_aliases(self, property):
|
|
1081
|
+
for prefix, pref in property.extra_prefixes:
|
|
1082
|
+
property.aliases.append(("-%s-%s" % (prefix, property.name), pref))
|
|
1083
|
+
|
|
1084
|
+
def declare_longhand(self, style_struct, name, extra_gecko_aliases=None, engine=None, **kwargs):
|
|
1085
|
+
if engine and self.engine != engine:
|
|
1086
|
+
return
|
|
1087
|
+
if extra_gecko_aliases and self.engine == "gecko":
|
|
1088
|
+
kwargs.setdefault('aliases', []).extend(extra_gecko_aliases)
|
|
1089
|
+
longhand = Longhand(style_struct, name, **kwargs)
|
|
1090
|
+
self.add_prefixed_aliases(longhand)
|
|
1091
|
+
longhand.aliases = [Alias(xp[0], longhand, xp[1]) for xp in longhand.aliases]
|
|
1092
|
+
self.longhand_aliases += longhand.aliases
|
|
1093
|
+
style_struct.longhands.append(longhand)
|
|
1094
|
+
self.longhands.append(longhand)
|
|
1095
|
+
self.longhands_by_name[name] = longhand
|
|
1096
|
+
if longhand.logical_group:
|
|
1097
|
+
self.logical_groups.setdefault(
|
|
1098
|
+
longhand.logical_group, []
|
|
1099
|
+
).append(longhand)
|
|
1100
|
+
|
|
1101
|
+
return longhand
|
|
1102
|
+
|
|
1103
|
+
def declare_shorthand(self, name, sub_properties, extra_gecko_sub_properties=None, extra_gecko_aliases=None, engine=None, *args, **kwargs):
|
|
1104
|
+
if engine and self.engine != engine:
|
|
1105
|
+
return
|
|
1106
|
+
if self.engine == "gecko":
|
|
1107
|
+
if extra_gecko_sub_properties:
|
|
1108
|
+
sub_properties.extend(extra_gecko_sub_properties)
|
|
1109
|
+
if extra_gecko_aliases:
|
|
1110
|
+
kwargs.setdefault('aliases', []).extend(extra_gecko_aliases)
|
|
1111
|
+
sub_properties = [self.longhands_by_name[s] for s in sub_properties]
|
|
1112
|
+
shorthand = Shorthand(name, sub_properties, *args, **kwargs)
|
|
1113
|
+
self.add_prefixed_aliases(shorthand)
|
|
1114
|
+
shorthand.aliases = [Alias(xp[0], shorthand, xp[1]) for xp in shorthand.aliases]
|
|
1115
|
+
self.shorthand_aliases += shorthand.aliases
|
|
1116
|
+
self.shorthands.append(shorthand)
|
|
1117
|
+
self.shorthands_by_name[name] = shorthand
|
|
1118
|
+
return shorthand
|
|
1119
|
+
|
|
1120
|
+
def shorthands_except_all(self):
|
|
1121
|
+
return [s for s in self.shorthands if s.name != "all"]
|
|
1122
|
+
|
|
1123
|
+
def all_aliases(self):
|
|
1124
|
+
return self.longhand_aliases + self.shorthand_aliases
|
|
1125
|
+
|
|
1126
|
+
def all_properties_and_aliases(self):
|
|
1127
|
+
return self.longhands + self.shorthands + self.longhand_aliases + self.shorthand_aliases
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
def _add_logical_props(data, props):
|
|
1131
|
+
groups = set()
|
|
1132
|
+
for prop in props:
|
|
1133
|
+
if prop not in data.longhands_by_name:
|
|
1134
|
+
assert data.engine == "servo"
|
|
1135
|
+
continue
|
|
1136
|
+
prop = data.longhands_by_name[prop]
|
|
1137
|
+
if prop.logical_group:
|
|
1138
|
+
groups.add(prop.logical_group)
|
|
1139
|
+
for group in groups:
|
|
1140
|
+
for prop in data.logical_groups[group]:
|
|
1141
|
+
props.add(prop.name)
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
# These are probably Gecko bugs and should be supported per spec.
|
|
1145
|
+
def _remove_common_first_line_and_first_letter_properties(props, engine):
|
|
1146
|
+
if engine == "gecko":
|
|
1147
|
+
props.remove("tab-size")
|
|
1148
|
+
props.remove("hyphens")
|
|
1149
|
+
props.remove("line-break")
|
|
1150
|
+
props.remove("text-align-last")
|
|
1151
|
+
props.remove("text-emphasis-position")
|
|
1152
|
+
props.remove("text-emphasis-style")
|
|
1153
|
+
props.remove("text-emphasis-color")
|
|
1154
|
+
props.remove("text-wrap-style")
|
|
1155
|
+
|
|
1156
|
+
props.remove("overflow-wrap")
|
|
1157
|
+
props.remove("text-align")
|
|
1158
|
+
props.remove("text-justify")
|
|
1159
|
+
props.remove("white-space-collapse")
|
|
1160
|
+
props.remove("text-wrap-mode")
|
|
1161
|
+
props.remove("word-break")
|
|
1162
|
+
props.remove("text-indent")
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
class PropertyRestrictions:
|
|
1166
|
+
@staticmethod
|
|
1167
|
+
def logical_group(data, group):
|
|
1168
|
+
return [p.name for p in data.logical_groups[group]]
|
|
1169
|
+
|
|
1170
|
+
@staticmethod
|
|
1171
|
+
def shorthand(data, shorthand):
|
|
1172
|
+
if shorthand not in data.shorthands_by_name:
|
|
1173
|
+
return []
|
|
1174
|
+
return [p.name for p in data.shorthands_by_name[shorthand].sub_properties]
|
|
1175
|
+
|
|
1176
|
+
@staticmethod
|
|
1177
|
+
def spec(data, spec_path):
|
|
1178
|
+
return [p.name for p in data.longhands if spec_path in p.spec]
|
|
1179
|
+
|
|
1180
|
+
# https://svgwg.org/svg2-draft/propidx.html
|
|
1181
|
+
@staticmethod
|
|
1182
|
+
def svg_text_properties():
|
|
1183
|
+
props = set(
|
|
1184
|
+
[
|
|
1185
|
+
"fill",
|
|
1186
|
+
"fill-opacity",
|
|
1187
|
+
"fill-rule",
|
|
1188
|
+
"paint-order",
|
|
1189
|
+
"stroke",
|
|
1190
|
+
"stroke-dasharray",
|
|
1191
|
+
"stroke-dashoffset",
|
|
1192
|
+
"stroke-linecap",
|
|
1193
|
+
"stroke-linejoin",
|
|
1194
|
+
"stroke-miterlimit",
|
|
1195
|
+
"stroke-opacity",
|
|
1196
|
+
"stroke-width",
|
|
1197
|
+
"text-rendering",
|
|
1198
|
+
"vector-effect",
|
|
1199
|
+
]
|
|
1200
|
+
)
|
|
1201
|
+
return props
|
|
1202
|
+
|
|
1203
|
+
@staticmethod
|
|
1204
|
+
def webkit_text_properties():
|
|
1205
|
+
props = set(
|
|
1206
|
+
[
|
|
1207
|
+
# Kinda like css-text?
|
|
1208
|
+
"-webkit-text-stroke-width",
|
|
1209
|
+
"-webkit-text-fill-color",
|
|
1210
|
+
"-webkit-text-stroke-color",
|
|
1211
|
+
]
|
|
1212
|
+
)
|
|
1213
|
+
return props
|
|
1214
|
+
|
|
1215
|
+
# https://drafts.csswg.org/css-pseudo/#first-letter-styling
|
|
1216
|
+
@staticmethod
|
|
1217
|
+
def first_letter(data):
|
|
1218
|
+
props = set(
|
|
1219
|
+
[
|
|
1220
|
+
"color",
|
|
1221
|
+
"opacity",
|
|
1222
|
+
"float",
|
|
1223
|
+
"initial-letter",
|
|
1224
|
+
# Kinda like css-fonts?
|
|
1225
|
+
"-moz-osx-font-smoothing",
|
|
1226
|
+
"alignment-baseline",
|
|
1227
|
+
"baseline-shift",
|
|
1228
|
+
"baseline-source",
|
|
1229
|
+
"line-height",
|
|
1230
|
+
# Kinda like css-backgrounds?
|
|
1231
|
+
"background-blend-mode",
|
|
1232
|
+
]
|
|
1233
|
+
+ PropertyRestrictions.shorthand(data, "padding")
|
|
1234
|
+
+ PropertyRestrictions.shorthand(data, "margin")
|
|
1235
|
+
+ PropertyRestrictions.spec(data, "css-fonts")
|
|
1236
|
+
+ PropertyRestrictions.spec(data, "css-backgrounds")
|
|
1237
|
+
+ PropertyRestrictions.spec(data, "css-text")
|
|
1238
|
+
+ PropertyRestrictions.spec(data, "css-shapes")
|
|
1239
|
+
+ PropertyRestrictions.spec(data, "css-text-decor")
|
|
1240
|
+
)
|
|
1241
|
+
props = props.union(PropertyRestrictions.svg_text_properties())
|
|
1242
|
+
props = props.union(PropertyRestrictions.webkit_text_properties())
|
|
1243
|
+
|
|
1244
|
+
_add_logical_props(data, props)
|
|
1245
|
+
|
|
1246
|
+
_remove_common_first_line_and_first_letter_properties(props, data.engine)
|
|
1247
|
+
return props
|
|
1248
|
+
|
|
1249
|
+
# https://drafts.csswg.org/css-pseudo/#first-line-styling
|
|
1250
|
+
@staticmethod
|
|
1251
|
+
def first_line(data):
|
|
1252
|
+
props = set(
|
|
1253
|
+
[
|
|
1254
|
+
# Per spec.
|
|
1255
|
+
"color",
|
|
1256
|
+
"opacity",
|
|
1257
|
+
# Kinda like css-fonts?
|
|
1258
|
+
"-moz-osx-font-smoothing",
|
|
1259
|
+
"alignment-baseline",
|
|
1260
|
+
"baseline-shift",
|
|
1261
|
+
"baseline-source",
|
|
1262
|
+
"line-height",
|
|
1263
|
+
# Kinda like css-backgrounds?
|
|
1264
|
+
"background-blend-mode",
|
|
1265
|
+
]
|
|
1266
|
+
+ PropertyRestrictions.spec(data, "css-fonts")
|
|
1267
|
+
+ PropertyRestrictions.spec(data, "css-backgrounds")
|
|
1268
|
+
+ PropertyRestrictions.spec(data, "css-text")
|
|
1269
|
+
+ PropertyRestrictions.spec(data, "css-text-decor")
|
|
1270
|
+
)
|
|
1271
|
+
props = props.union(PropertyRestrictions.svg_text_properties())
|
|
1272
|
+
props = props.union(PropertyRestrictions.webkit_text_properties())
|
|
1273
|
+
|
|
1274
|
+
# These are probably Gecko bugs and should be supported per spec.
|
|
1275
|
+
for prop in PropertyRestrictions.shorthand(data, "border"):
|
|
1276
|
+
props.remove(prop)
|
|
1277
|
+
for prop in PropertyRestrictions.shorthand(data, "border-radius"):
|
|
1278
|
+
props.remove(prop)
|
|
1279
|
+
props.remove("box-shadow")
|
|
1280
|
+
|
|
1281
|
+
_remove_common_first_line_and_first_letter_properties(props, data.engine)
|
|
1282
|
+
return props
|
|
1283
|
+
|
|
1284
|
+
# https://drafts.csswg.org/css-pseudo/#placeholder
|
|
1285
|
+
#
|
|
1286
|
+
# The spec says that placeholder and first-line have the same restrictions,
|
|
1287
|
+
# except those defined in css-inline.
|
|
1288
|
+
# We also allow a handful other properties for ::placeholder, which is allowed by
|
|
1289
|
+
# the spec.
|
|
1290
|
+
@staticmethod
|
|
1291
|
+
def placeholder(data):
|
|
1292
|
+
props = PropertyRestrictions.first_line(data)
|
|
1293
|
+
for p in PropertyRestrictions.spec(data, "css-inline"):
|
|
1294
|
+
props.discard(p)
|
|
1295
|
+
props.add("opacity")
|
|
1296
|
+
props.add("text-overflow")
|
|
1297
|
+
props.add("text-align")
|
|
1298
|
+
props.add("text-justify")
|
|
1299
|
+
for p in PropertyRestrictions.shorthand(data, "text-wrap"):
|
|
1300
|
+
props.add(p)
|
|
1301
|
+
for p in PropertyRestrictions.shorthand(data, "white-space"):
|
|
1302
|
+
props.add(p)
|
|
1303
|
+
# ::placeholder can't be SVG text
|
|
1304
|
+
props -= PropertyRestrictions.svg_text_properties()
|
|
1305
|
+
# Historically ::placeholder's line-height was !important in the UA sheet.
|
|
1306
|
+
props.remove("line-height")
|
|
1307
|
+
|
|
1308
|
+
return props
|
|
1309
|
+
|
|
1310
|
+
# https://drafts.csswg.org/css-lists-3/#marker-properties
|
|
1311
|
+
@staticmethod
|
|
1312
|
+
def marker(data):
|
|
1313
|
+
return set(
|
|
1314
|
+
[
|
|
1315
|
+
"color",
|
|
1316
|
+
"content",
|
|
1317
|
+
"counter-increment",
|
|
1318
|
+
"counter-reset",
|
|
1319
|
+
"counter-set",
|
|
1320
|
+
"cursor",
|
|
1321
|
+
"direction",
|
|
1322
|
+
"hyphens",
|
|
1323
|
+
"line-height",
|
|
1324
|
+
"quotes",
|
|
1325
|
+
"text-combine-upright",
|
|
1326
|
+
"text-emphasis-color",
|
|
1327
|
+
"text-emphasis-position",
|
|
1328
|
+
"text-emphasis-style",
|
|
1329
|
+
"text-orientation",
|
|
1330
|
+
"text-shadow",
|
|
1331
|
+
"text-transform",
|
|
1332
|
+
"unicode-bidi",
|
|
1333
|
+
"-moz-osx-font-smoothing",
|
|
1334
|
+
]
|
|
1335
|
+
+ PropertyRestrictions.shorthand(data, "animation-range")
|
|
1336
|
+
+ PropertyRestrictions.shorthand(data, "text-wrap")
|
|
1337
|
+
+ PropertyRestrictions.shorthand(data, "white-space")
|
|
1338
|
+
+ PropertyRestrictions.spec(data, "css-fonts")
|
|
1339
|
+
+ PropertyRestrictions.spec(data, "css-animations")
|
|
1340
|
+
+ PropertyRestrictions.spec(data, "css-transitions")
|
|
1341
|
+
)
|
|
1342
|
+
|
|
1343
|
+
# https://www.w3.org/TR/webvtt1/#the-cue-pseudo-element
|
|
1344
|
+
@staticmethod
|
|
1345
|
+
def cue(data):
|
|
1346
|
+
return set(
|
|
1347
|
+
[
|
|
1348
|
+
"color",
|
|
1349
|
+
"opacity",
|
|
1350
|
+
"visibility",
|
|
1351
|
+
"text-shadow",
|
|
1352
|
+
"text-combine-upright",
|
|
1353
|
+
"ruby-position",
|
|
1354
|
+
# XXX Should these really apply to cue?
|
|
1355
|
+
"-moz-osx-font-smoothing",
|
|
1356
|
+
# FIXME(emilio): background-blend-mode should be part of the
|
|
1357
|
+
# background shorthand, and get reset, per
|
|
1358
|
+
# https://drafts.fxtf.org/compositing/#background-blend-mode
|
|
1359
|
+
"background-blend-mode",
|
|
1360
|
+
]
|
|
1361
|
+
+ PropertyRestrictions.shorthand(data, "text-decoration")
|
|
1362
|
+
+ PropertyRestrictions.shorthand(data, "text-wrap")
|
|
1363
|
+
+ PropertyRestrictions.shorthand(data, "white-space")
|
|
1364
|
+
+ PropertyRestrictions.shorthand(data, "background")
|
|
1365
|
+
+ PropertyRestrictions.shorthand(data, "outline")
|
|
1366
|
+
+ PropertyRestrictions.shorthand(data, "font")
|
|
1367
|
+
+ PropertyRestrictions.shorthand(data, "font-synthesis")
|
|
1368
|
+
)
|
|
1369
|
+
|
|
1370
|
+
|
|
1371
|
+
class CountedUnknownProperty:
|
|
1372
|
+
def __init__(self, name):
|
|
1373
|
+
self.name = name
|
|
1374
|
+
self.ident = to_rust_ident(name)
|
|
1375
|
+
self.camel_case = to_camel_case(self.ident)
|