From 391ebf2b2699db51b325b370ef9b5e2b085a41e2 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Thu, 6 Aug 2026 23:59:39 +0100 Subject: [PATCH 1/2] LibWeb: Declare each style group in `Properties.json` Declare the group for every physical longhand in `Properties.json` and generate a dependency mask function and a per group longhand list from the declarations. The generator rejects a longhand without a declaration and a shorthand or alias with one. A logical alias derives its mask from the target property's group and the inherited box group that stores the mapping context. --- Documentation/CSSGeneratedFiles.md | 11 + Libraries/LibWeb/CSS/ComputedValues.cpp | 16 + Libraries/LibWeb/CSS/Properties.json | 301 +++++++++++++++++- .../generate_libweb_css_property_id.py | 129 ++++++++ 4 files changed, 448 insertions(+), 9 deletions(-) diff --git a/Documentation/CSSGeneratedFiles.md b/Documentation/CSSGeneratedFiles.md index 1dd7b56dbaa16..9dce708b8c7c3 100644 --- a/Documentation/CSSGeneratedFiles.md +++ b/Documentation/CSSGeneratedFiles.md @@ -35,6 +35,7 @@ Each property will have some set of these fields on it: | `positional-value-list-shorthand` | No | `false` | Boolean. Whether this property is a "positional value list shorthand". See below. | `bool property_is_positional_value_list_shorthand(PropertyID)` | | `quirks` | No | `[]` | Array of strings. Some properties have special behavior in "quirks mode", which are listed here. See below. | `bool property_has_quirk(PropertyID, Quirk)` | | `requires-computation` | Yes | | String. When a property's value needs to be run through the computation process. See below. | `bool property_requires_computation_with_inherited_value(PropertyID)`
`bool property_requires_computation_with_initial_value(PropertyID)`
`bool property_requires_computation_with_cascaded_value(PropertyID)` | +| `style-group` | Yes | | String or array of strings. Which style group stores the longhand's computed value. See below. | `u32 style_group_dependency_mask(PropertyID)`
`ReadonlySpan longhands_in_style_group(StyleGroupIndex)` | | `valid-identifiers` | No | `[]` | Array of strings. Which keywords the property accepts. See below. | `bool property_accepts_keyword(PropertyID, Keyword)`
`Optional resolve_legacy_value_alias(PropertyID, Keyword)` | | `valid-types` | No | `[]` | Array of strings. Which value types the property accepts. See below. | `bool property_accepts_type(PropertyID, ValueType)` | | `needs-layout-for-getcomputedstyle` | No | `false` | Boolean. Whether this property requires up-to-date layout before it could be queried by getComputedStyle() | `bool property_needs_layout_for_getcomputedstyle(PropertyID)` | @@ -121,6 +122,16 @@ required. | `cascaded-value` | Only run the computation process if the specified value was determined based on a cascaded value | | `never` | Always skip the computation process | +### `style-group` + +`ComputedValues` stores computed values in groups of related properties, which elements share with each other wherever +possible. When two styles use the same group payload, every property in that group is known to be equal, which saves +memory and allows style diffing to skip work. + +Each longhand names the group that stores its value, Shorthands and aliases take their values from their longhands, so +they must not declare a group. If producing a property's computed style value also reads from other groups, you should +list all of the relevant groups. + ### `valid-identifiers` A list of CSS keyword names, that the property accepts. Consider defining an enum instead and putting its name in the diff --git a/Libraries/LibWeb/CSS/ComputedValues.cpp b/Libraries/LibWeb/CSS/ComputedValues.cpp index 1b8b75267eed8..67109639bb09a 100644 --- a/Libraries/LibWeb/CSS/ComputedValues.cpp +++ b/Libraries/LibWeb/CSS/ComputedValues.cpp @@ -455,6 +455,7 @@ static void register_style_group_field_descriptors() Vector descriptors; auto add = [&](size_t group_index, PropertyID property, u32 offset, u8 kind, u16 keyword, Array const* keyword_table, double required_px = 0) { + VERIFY((style_group_dependency_mask(property) & (1u << group_index)) != 0); descriptors.append({ .group_index = static_cast(group_index), .property_id = static_cast(to_underlying(property)), @@ -674,6 +675,21 @@ static void register_style_group_field_descriptors() PropertyID::BackgroundRepeat, PropertyID::BackgroundSize, PropertyID::BackgroundBlendMode }) add(background, property, 0, GROUP_FIELD_REQUIRE_INITIAL_VALUE, 0, nullptr); + u32 generically_built_group_mask = 0; + Array longhand_has_descriptor {}; + for (auto const& descriptor : descriptors) { + generically_built_group_mask |= 1u << descriptor.group_index; + longhand_has_descriptor[descriptor.property_id - to_underlying(first_longhand_property_id)] = true; + } + + for (auto i = to_underlying(first_longhand_property_id); i <= to_underlying(last_longhand_property_id); ++i) { + auto property_id = static_cast(i); + if (property_is_logical_alias(property_id)) + continue; + if ((style_group_dependency_mask(property_id) & generically_built_group_mask) != 0) + VERIFY(longhand_has_descriptor[i - to_underlying(first_longhand_property_id)]); + } + rust_style_group_register_field_descriptors(descriptors.data(), descriptors.size()); } diff --git a/Libraries/LibWeb/CSS/Properties.json b/Libraries/LibWeb/CSS/Properties.json index 5aba44ac694ef..7963a580d9ddb 100644 --- a/Libraries/LibWeb/CSS/Properties.json +++ b/Libraries/LibWeb/CSS/Properties.json @@ -153,6 +153,7 @@ "initial": "currentColor", "needs-layout-node-for-resolved-value": true, "requires-computation": "cascaded-value", + "style-group": "inherited-text", "valid-types": [ "color" ] @@ -190,6 +191,7 @@ "inherited": true, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "inherited-ui", "valid-types": [ "color" ], @@ -202,6 +204,7 @@ "inherited": false, "initial": "normal", "requires-computation": "never", + "style-group": "alignment", "valid-types": [ "align-content" ] @@ -211,6 +214,7 @@ "inherited": false, "initial": "normal", "requires-computation": "never", + "style-group": "alignment", "valid-types": [ "align-items" ] @@ -220,6 +224,7 @@ "inherited": false, "initial": "auto", "requires-computation": "never", + "style-group": "alignment", "valid-types": [ "align-self" ] @@ -236,6 +241,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "anchor", "valid-types": [ "dashed-ident" ], @@ -249,6 +255,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "anchor", "valid-types": [ "dashed-ident" ], @@ -279,6 +286,7 @@ "inherited": false, "initial": "replace", "requires-computation": "never", + "style-group": "animation", "valid-types": [ "animation-composition" ], @@ -291,6 +299,7 @@ "initial": "0s", "requires-computation": "cascaded-value", "multiplicity": "coordinating-list", + "style-group": "animation", "valid-types": [ "time [-∞,∞]" ] @@ -302,6 +311,7 @@ "initial": "normal", "multiplicity": "coordinating-list", "requires-computation": "never", + "style-group": "animation", "valid-identifiers": [ "normal", "reverse", @@ -317,6 +327,7 @@ "multiplicity": "coordinating-list", "needs-layout-node-for-resolved-value": true, "requires-computation": "cascaded-value", + "style-group": "animation", "valid-types": [ "time [0,∞]" ], @@ -331,6 +342,7 @@ "initial": "none", "multiplicity": "coordinating-list", "requires-computation": "never", + "style-group": "animation", "valid-identifiers": [ "none", "forwards", @@ -345,6 +357,7 @@ "initial": "1", "multiplicity": "coordinating-list", "requires-computation": "cascaded-value", + "style-group": "animation", "valid-types": [ "number [0,∞]" ], @@ -359,6 +372,7 @@ "initial": "none", "multiplicity": "coordinating-list", "requires-computation": "cascaded-value", + "style-group": "animation", "valid-types": [ "string", "custom-ident ![none]" @@ -374,6 +388,7 @@ "initial": "running", "multiplicity": "coordinating-list", "requires-computation": "never", + "style-group": "animation", "valid-identifiers": [ "running", "paused" @@ -385,6 +400,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "animation", "valid-types": [ "dashed-ident", "scroll-function", @@ -403,6 +419,7 @@ "initial": "ease", "multiplicity": "coordinating-list", "requires-computation": "cascaded-value", + "style-group": "animation", "valid-types": [ "easing-function", "easing-keyword" @@ -413,6 +430,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "misc-reset", "valid-types": [ "appearance" ] @@ -423,6 +441,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "box", "valid-types": [ "ratio" ], @@ -441,6 +460,7 @@ "__comment": "FIXME: List `filter-value-list` as a valid-type once it's generically supported.", "multiplicity": "list", "requires-computation": "cascaded-value", + "style-group": [ "effects", "inherited-text" ], "valid-identifiers": [ "none" ] @@ -452,6 +472,7 @@ "inherited": false, "initial": "visible", "requires-computation": "never", + "style-group": "transform", "valid-types": [ "backface-visibility" ] @@ -479,6 +500,7 @@ "initial": "scroll", "multiplicity": "coordinating-list", "requires-computation": "always", + "style-group": "background", "valid-types": [ "background-attachment" ] @@ -490,6 +512,7 @@ "initial": "normal", "multiplicity": "coordinating-list", "requires-computation": "always", + "style-group": "background", "valid-types": [ "mix-blend-mode" ] @@ -502,6 +525,7 @@ "multiplicity": "coordinating-list", "__comment": "FIXME: Support `border-area`", "requires-computation": "always", + "style-group": "background", "valid-types": [ "background-box" ] @@ -513,6 +537,7 @@ "initial": "transparent", "needs-layout-node-for-resolved-value": true, "requires-computation": "non-inherited-value", + "style-group": "background", "valid-types": [ "color" ], @@ -527,6 +552,7 @@ "initial": "none", "multiplicity": "coordinating-list", "requires-computation": "cascaded-value", + "style-group": "background", "valid-types": [ "image" ], @@ -542,6 +568,7 @@ "multiplicity": "coordinating-list", "__comment": "FIXME: This shouldn't allow `text`", "requires-computation": "always", + "style-group": "background", "valid-types": [ "background-box" ] @@ -570,6 +597,7 @@ "initial": "0%", "multiplicity": "coordinating-list", "requires-computation": "always", + "style-group": "background", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -588,6 +616,7 @@ "initial": "0%", "multiplicity": "coordinating-list", "requires-computation": "always", + "style-group": "background", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -607,6 +636,7 @@ "multiplicity": "coordinating-list", "max-values": 2, "requires-computation": "always", + "style-group": "background", "valid-types": [ "repetition" ], @@ -623,6 +653,7 @@ "multiplicity": "coordinating-list", "max-values": 2, "requires-computation": "always", + "style-group": "background", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -776,6 +807,7 @@ "inherited": false, "needs-layout-node-for-resolved-value": true, "requires-computation": "cascaded-value", + "style-group": "border", "valid-types": [ "color" ], @@ -790,6 +822,7 @@ "inherited": false, "max-values": 2, "requires-computation": "cascaded-value", + "style-group": "border", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -803,6 +836,7 @@ "inherited": false, "max-values": 2, "requires-computation": "cascaded-value", + "style-group": "border", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -814,6 +848,7 @@ "initial": "none", "inherited": false, "requires-computation": "never", + "style-group": "border", "valid-types": [ "line-style" ] @@ -823,6 +858,7 @@ "initial": "medium", "inherited": false, "requires-computation": "non-inherited-value", + "style-group": "border", "valid-types": [ "length [0,∞]", "line-width" @@ -838,6 +874,7 @@ "inherited": true, "initial": "separate", "requires-computation": "never", + "style-group": "inherited-table", "valid-types": [ "border-collapse" ] @@ -890,6 +927,7 @@ "initial": "0", "max-values": 4, "requires-computation": "cascaded-value", + "style-group": "border", "valid-types": [ "length [0,∞]", "number [0,∞]" @@ -902,6 +940,7 @@ "initial": "stretch", "max-values": 2, "requires-computation": "never", + "style-group": "border", "valid-types": [ "border-image-repeat" ] @@ -912,6 +951,7 @@ "inherited": false, "initial": "100%", "requires-computation": "cascaded-value", + "style-group": "border", "valid-identifiers": [ "fill" ], @@ -927,6 +967,7 @@ "inherited": false, "initial": "none", "requires-computation": "cascaded-value", + "style-group": "border", "valid-types": [ "image" ], @@ -941,6 +982,7 @@ "initial": "1", "max-values": 4, "requires-computation": "cascaded-value", + "style-group": "border", "valid-types": [ "length [0,∞]", "percentage [0,∞]", @@ -1070,6 +1112,7 @@ "inherited": false, "needs-layout-node-for-resolved-value": true, "requires-computation": "cascaded-value", + "style-group": "border", "valid-types": [ "color" ], @@ -1082,6 +1125,7 @@ "initial": "none", "inherited": false, "requires-computation": "never", + "style-group": "border", "valid-types": [ "line-style" ] @@ -1091,6 +1135,7 @@ "initial": "medium", "inherited": false, "requires-computation": "non-inherited-value", + "style-group": "border", "valid-types": [ "length [0,∞]", "line-width" @@ -1130,6 +1175,7 @@ "inherited": false, "needs-layout-node-for-resolved-value": true, "requires-computation": "cascaded-value", + "style-group": "border", "valid-types": [ "color" ], @@ -1142,6 +1188,7 @@ "initial": "none", "inherited": false, "requires-computation": "never", + "style-group": "border", "valid-types": [ "line-style" ] @@ -1151,6 +1198,7 @@ "initial": "medium", "inherited": false, "requires-computation": "non-inherited-value", + "style-group": "border", "valid-types": [ "length [0,∞]", "line-width" @@ -1167,6 +1215,7 @@ "initial": "0", "max-values": 2, "requires-computation": "cascaded-value", + "style-group": "inherited-table", "valid-types": [ "length [0,∞]" ], @@ -1216,6 +1265,7 @@ "inherited": false, "needs-layout-node-for-resolved-value": true, "requires-computation": "cascaded-value", + "style-group": "border", "valid-types": [ "color" ], @@ -1230,6 +1280,7 @@ "inherited": false, "max-values": 2, "requires-computation": "cascaded-value", + "style-group": "border", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -1243,6 +1294,7 @@ "inherited": false, "max-values": 2, "requires-computation": "cascaded-value", + "style-group": "border", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -1254,6 +1306,7 @@ "initial": "none", "inherited": false, "requires-computation": "never", + "style-group": "border", "valid-types": [ "line-style" ] @@ -1263,6 +1316,7 @@ "initial": "medium", "inherited": false, "requires-computation": "non-inherited-value", + "style-group": "border", "valid-types": [ "length [0,∞]", "line-width" @@ -1294,6 +1348,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "surround", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]", @@ -1316,6 +1371,7 @@ "needs-layout-node-for-resolved-value": true, "requires-computation": "cascaded-value", "multiplicity": "list", + "style-group": "effects", "valid-identifiers": [ "none" ] @@ -1325,6 +1381,7 @@ "inherited": false, "initial": "content-box", "requires-computation": "never", + "style-group": "box", "valid-types": [ "box-sizing" ] @@ -1334,6 +1391,7 @@ "inherited": true, "initial": "top", "requires-computation": "never", + "style-group": "inherited-table", "valid-types": [ "caption-side" ] @@ -1345,6 +1403,7 @@ "initial": "auto", "needs-layout-node-for-resolved-value": true, "requires-computation": "cascaded-value", + "style-group": "inherited-ui", "valid-identifiers": [ "auto" ], @@ -1357,6 +1416,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "box", "valid-types": [ "clear" ] @@ -1368,6 +1428,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "effects", "valid-identifiers": [ "auto" ], @@ -1385,6 +1446,7 @@ "affects-stacking-context": true, "inherited": false, "requires-computation": "cascaded-value", + "style-group": "mask", "valid-identifiers": [ "none" ], @@ -1401,6 +1463,7 @@ "inherited": true, "initial": "nonzero", "requires-computation": "never", + "style-group": "inherited-svg", "valid-types": [ "fill-rule" ] @@ -1412,6 +1475,7 @@ "initial": "canvastext", "needs-layout-node-for-resolved-value": true, "requires-computation": "non-inherited-value", + "style-group": "inherited-text", "valid-types": [ "color" ], @@ -1425,6 +1489,7 @@ "inherited": true, "initial": "srgb", "requires-computation": "never", + "style-group": "inherited-svg", "valid-types": [ "color-interpolation" ] @@ -1435,6 +1500,7 @@ "inherited": true, "initial": "linearrgb", "requires-computation": "never", + "style-group": "inherited-svg", "valid-types": [ "color-interpolation" ] @@ -1445,6 +1511,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "inherited-ui", "valid-types": [ "custom-ident ![normal,light,dark,only]" ], @@ -1459,6 +1526,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "box", "valid-types": [ "integer [1,∞]" ], @@ -1471,6 +1539,7 @@ "inherited": false, "initial": "normal", "requires-computation": "cascaded-value", + "style-group": "alignment", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -1485,6 +1554,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "length [0,∞]" ], @@ -1497,6 +1567,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "misc-reset", "valid-types": [ "column-span" ] @@ -1506,6 +1577,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "box", "valid-types": [ "length [0,∞]" ], @@ -1528,6 +1600,7 @@ "initial": "none", "needs-layout-node-for-resolved-value": true, "requires-computation": "never", + "style-group": "box", "valid-types": [ "contain" ] @@ -1546,6 +1619,7 @@ "initial": "none", "multiplicity": "list", "requires-computation": "never", + "style-group": "box", "valid-types": [ "custom-ident ![none,and,not,or]" ], @@ -1559,6 +1633,7 @@ "inherited": false, "initial": "normal", "requires-computation": "never", + "style-group": "box", "valid-identifiers": [ "normal", "size", @@ -1572,6 +1647,7 @@ "initial": "normal", "__comment": "FIXME: This accepts a whole lot of other types and identifiers!", "requires-computation": "cascaded-value", + "style-group": "content", "valid-types": [ "counter", "image", @@ -1591,6 +1667,7 @@ "inherited": false, "initial": "visible", "requires-computation": "never", + "style-group": "inherited-box", "valid-types": [ "content-visibility" ] @@ -1622,6 +1699,7 @@ "inherited": false, "initial": "round", "requires-computation": "non-inherited-value", + "style-group": "border", "valid-types": [ "corner-shape" ] @@ -1631,6 +1709,7 @@ "inherited": false, "initial": "round", "requires-computation": "non-inherited-value", + "style-group": "border", "valid-types": [ "corner-shape" ] @@ -1732,6 +1811,7 @@ "inherited": false, "initial": "round", "requires-computation": "non-inherited-value", + "style-group": "border", "valid-types": [ "corner-shape" ] @@ -1741,6 +1821,7 @@ "inherited": false, "initial": "round", "requires-computation": "non-inherited-value", + "style-group": "border", "valid-types": [ "corner-shape" ] @@ -1762,6 +1843,7 @@ "initial": "none", "multiplicity": "list", "requires-computation": "cascaded-value", + "style-group": "content", "valid-types": [ "custom-ident ![none]", "integer [-∞,∞]" @@ -1776,6 +1858,7 @@ "initial": "none", "multiplicity": "list", "requires-computation": "cascaded-value", + "style-group": "content", "valid-types": [ "custom-ident ![none]", "integer [-∞,∞]" @@ -1790,6 +1873,7 @@ "initial": "none", "multiplicity": "list", "requires-computation": "cascaded-value", + "style-group": "content", "valid-types": [ "custom-ident ![none]", "integer [-∞,∞]" @@ -1804,6 +1888,7 @@ "inherited": true, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "inherited-ui", "valid-types": [ "url", "cursor-predefined", @@ -1816,6 +1901,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "svg-reset", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -1831,6 +1917,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "svg-reset", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -1844,13 +1931,15 @@ "animation-type": "by-computed-value", "inherited": false, "initial": "none", - "requires-computation": "never" + "requires-computation": "never", + "style-group": "svg-reset" }, "direction": { "animation-type": "none", "inherited": true, "initial": "ltr", "requires-computation": "never", + "style-group": "inherited-box", "valid-types": [ "direction" ] @@ -1861,6 +1950,7 @@ "initial": "inline", "requires-computation": "never", "max-values": 3, + "style-group": "box", "valid-identifiers": [ "list-item" ], @@ -1877,6 +1967,7 @@ "inherited": true, "initial": "auto", "requires-computation": "never", + "style-group": "inherited-svg", "valid-types": [ "baseline-metric" ], @@ -1889,6 +1980,7 @@ "inherited": true, "initial": "show", "requires-computation": "never", + "style-group": "inherited-table", "valid-types": [ "empty-cells" ] @@ -1899,6 +1991,7 @@ "inherited": true, "initial": "black", "requires-computation": "non-inherited-value", + "style-group": "inherited-svg", "valid-types": [ "paint" ] @@ -1909,6 +2002,7 @@ "inherited": true, "initial": "1", "requires-computation": "cascaded-value", + "style-group": "inherited-svg", "valid-types": [ "opacity-value" ] @@ -1919,6 +2013,7 @@ "inherited": true, "initial": "nonzero", "requires-computation": "never", + "style-group": "inherited-svg", "valid-types": [ "fill-rule" ] @@ -1934,6 +2029,7 @@ "__comment": "FIXME: List `filter-value-list` as a valid-type once it's generically supported.", "multiplicity": "list", "requires-computation": "cascaded-value", + "style-group": [ "effects", "inherited-text" ], "valid-identifiers": [ "none" ] @@ -1954,6 +2050,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "alignment", "valid-types": [ "fit-content", "length [0,∞]", @@ -1972,6 +2069,7 @@ "inherited": false, "initial": "row", "requires-computation": "never", + "style-group": "alignment", "valid-types": [ "flex-direction" ] @@ -1988,6 +2086,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "alignment", "valid-types": [ "number [0,∞]" ] @@ -1997,6 +2096,7 @@ "inherited": false, "initial": "1", "requires-computation": "cascaded-value", + "style-group": "alignment", "valid-types": [ "number [0,∞]" ] @@ -2006,6 +2106,7 @@ "inherited": false, "initial": "nowrap", "requires-computation": "never", + "style-group": "alignment", "valid-types": [ "flex-wrap" ] @@ -2015,6 +2116,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "box", "valid-types": [ "float" ] @@ -2025,6 +2127,7 @@ "inherited": false, "initial": "black", "requires-computation": "non-inherited-value", + "style-group": "svg-reset", "valid-types": [ "color" ] @@ -2035,6 +2138,7 @@ "inherited": false, "initial": "1", "requires-computation": "cascaded-value", + "style-group": "svg-reset", "valid-types": [ "opacity-value" ] @@ -2063,6 +2167,7 @@ "initial": "serif", "multiplicity": "list", "requires-computation": "never", + "style-group": "font", "valid-types": [ "custom-ident", "string" @@ -2074,6 +2179,7 @@ "initial": "normal", "multiplicity": "list", "requires-computation": "cascaded-value", + "style-group": "font", "valid-types": [ "integer [0,∞]", "opentype-tag" @@ -2089,6 +2195,7 @@ "inherited": true, "initial": "auto", "requires-computation": "never", + "style-group": "font", "valid-types": [ "font-kerning" ] @@ -2098,6 +2205,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "font", "valid-types": [ "string" ], @@ -2110,6 +2218,7 @@ "inherited": true, "initial": "auto", "requires-computation": "never", + "style-group": "font", "valid-types": [ "font-optical-sizing" ] @@ -2119,6 +2228,7 @@ "inherited": true, "initial": "medium", "requires-computation": "non-inherited-value", + "style-group": "font", "valid-types": [ "length [0,∞]", "percentage [0,∞]", @@ -2141,6 +2251,7 @@ "inherited": true, "initial": "normal", "requires-computation": "cascaded-value", + "style-group": "font", "valid-types": [ "font-style" ] @@ -2165,6 +2276,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "font", "valid-identifiers": [ "normal" ], @@ -2177,6 +2289,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "font", "valid-types": [ "font-variant-caps" ] @@ -2186,6 +2299,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "font", "valid-identifiers": [ "normal" ], @@ -2198,6 +2312,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "font", "valid-types": [ "font-variant-emoji" ] @@ -2207,6 +2322,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "font", "valid-identifiers": [ "normal", "none" @@ -2220,6 +2336,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "font", "valid-identifiers": [ "normal" ], @@ -2232,6 +2349,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "font", "valid-types": [ "font-variant-position" ] @@ -2242,6 +2360,7 @@ "initial": "normal", "multiplicity": "list", "requires-computation": "cascaded-value", + "style-group": "font", "valid-types": [ "number [-∞,∞]", "opentype-tag" @@ -2256,6 +2375,7 @@ "initial": "normal", "needs-layout-node-for-resolved-value": true, "requires-computation": "non-inherited-value", + "style-group": "font", "valid-types": [ "number [1,1000]" ], @@ -2272,6 +2392,7 @@ "initial": "normal", "needs-layout-node-for-resolved-value": true, "requires-computation": "non-inherited-value", + "style-group": "font", "valid-types": [ "percentage [0,∞]", "font-width" @@ -2333,6 +2454,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "grid", "valid-identifiers": [ "auto" ], @@ -2347,13 +2469,15 @@ "animation-type": "discrete", "inherited": false, "initial": "row", - "requires-computation": "never" + "requires-computation": "never", + "style-group": "box" }, "grid-auto-rows": { "animation-type": "by-computed-value", "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "grid", "valid-identifiers": [ "auto" ], @@ -2382,6 +2506,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "grid", "valid-identifiers": [ "auto" ], @@ -2397,6 +2522,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "grid", "valid-identifiers": [ "auto" ], @@ -2425,6 +2551,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "grid", "valid-identifiers": [ "auto" ], @@ -2440,6 +2567,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "grid", "valid-identifiers": [ "auto" ], @@ -2470,6 +2598,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "grid", "valid-identifiers": [ "none" ], @@ -2483,6 +2612,7 @@ "initial": "none", "max-values": 4, "requires-computation": "cascaded-value", + "style-group": "grid", "valid-identifiers": [ "auto" ], @@ -2500,6 +2630,7 @@ "initial": "none", "max-values": 4, "requires-computation": "cascaded-value", + "style-group": "grid", "valid-identifiers": [ "auto" ], @@ -2516,6 +2647,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "sizing", "valid-types": [ "fit-content", "length [0,∞]", @@ -2538,6 +2670,7 @@ "inherited": true, "initial": "auto", "requires-computation": "never", + "style-group": "inherited-box", "valid-types": [ "image-rendering" ] @@ -2641,6 +2774,7 @@ "inherited": false, "initial": "auto", "requires-computation": "never", + "style-group": "effects", "valid-types": [ "isolation" ] @@ -2650,6 +2784,7 @@ "inherited": false, "initial": "normal", "requires-computation": "never", + "style-group": "alignment", "valid-types": [ "justify-content" ] @@ -2659,6 +2794,7 @@ "inherited": false, "initial": "legacy", "requires-computation": "never", + "style-group": "alignment", "valid-types": [ "justify-items" ] @@ -2668,6 +2804,7 @@ "inherited": false, "initial": "auto", "requires-computation": "never", + "style-group": "alignment", "valid-types": [ "justify-self" ] @@ -2677,6 +2814,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "surround", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]", @@ -2697,6 +2835,7 @@ "initial": "normal", "needs-layout-node-for-resolved-value": true, "requires-computation": "non-inherited-value", + "style-group": "inherited-text", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -2715,6 +2854,7 @@ "initial": "normal", "needs-layout-node-for-resolved-value": true, "requires-computation": "cascaded-value", + "style-group": "font", "valid-types": [ "length [0,∞]", "number [0,∞]", @@ -2739,6 +2879,7 @@ "inherited": true, "initial": "none", "requires-computation": "cascaded-value", + "style-group": "inherited-list", "valid-types": [ "image" ], @@ -2751,6 +2892,7 @@ "inherited": true, "initial": "outside", "requires-computation": "never", + "style-group": "inherited-list", "valid-types": [ "list-style-position" ] @@ -2760,6 +2902,7 @@ "inherited": true, "initial": "disc", "requires-computation": "never", + "style-group": "inherited-list", "valid-types": [ "counter-style", "string" @@ -2826,6 +2969,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "surround", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -2875,6 +3019,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "surround", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -2893,6 +3038,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "surround", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -2911,6 +3057,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "surround", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -2946,6 +3093,7 @@ "affects-layout": false, "multiplicity": "coordinating-list", "requires-computation": "never", + "style-group": "mask", "valid-types": [ "coord-box" ], @@ -2960,6 +3108,7 @@ "affects-layout": false, "multiplicity": "coordinating-list", "requires-computation": "never", + "style-group": "mask", "valid-types": [ "compositing-operator" ], @@ -2973,6 +3122,7 @@ "affects-stacking-context": true, "multiplicity": "coordinating-list", "requires-computation": "cascaded-value", + "style-group": "mask", "valid-types": [ "image", "url" @@ -2988,6 +3138,7 @@ "affects-layout": false, "multiplicity": "coordinating-list", "requires-computation": "never", + "style-group": "mask", "valid-types": [ "masking-mode" ], @@ -2999,6 +3150,7 @@ "affects-layout": false, "multiplicity": "coordinating-list", "requires-computation": "never", + "style-group": "mask", "valid-types": [ "coord-box" ], @@ -3011,6 +3163,7 @@ "initial": "0% 0%", "multiplicity": "coordinating-list", "requires-computation": "cascaded-value", + "style-group": "mask", "valid-types": [ "position" ], @@ -3024,6 +3177,7 @@ "multiplicity": "coordinating-list", "max-values": 2, "requires-computation": "never", + "style-group": "mask", "valid-types": [ "repetition" ], @@ -3040,6 +3194,7 @@ "multiplicity": "coordinating-list", "max-values": 2, "requires-computation": "cascaded-value", + "style-group": "mask", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -3058,6 +3213,7 @@ "affects-layout": false, "multiplicity": "single", "requires-computation": "never", + "style-group": "mask", "valid-types": [ "mask-type" ], @@ -3070,6 +3226,7 @@ "needs-layout-node-for-resolved-value": true, "__comment": "FIXME: `add()` is also valid but we can't represent that here yet.", "requires-computation": "cascaded-value", + "style-group": "font", "valid-types": [ "integer [-∞,∞]" ], @@ -3082,6 +3239,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "font", "valid-types": [ "math-shift" ] @@ -3091,6 +3249,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "font", "valid-types": [ "math-style" ] @@ -3107,6 +3266,7 @@ "inherited": false, "initial": "none", "requires-computation": "cascaded-value", + "style-group": "sizing", "valid-types": [ "fit-content", "length [0,∞]", @@ -3134,6 +3294,7 @@ "inherited": false, "initial": "none", "requires-computation": "cascaded-value", + "style-group": "sizing", "valid-types": [ "fit-content", "length [0,∞]", @@ -3161,6 +3322,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "sizing", "valid-types": [ "fit-content", "length [0,∞]", @@ -3188,6 +3350,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "sizing", "valid-types": [ "fit-content", "length [0,∞]", @@ -3210,6 +3373,7 @@ "inherited": false, "initial": "normal", "requires-computation": "never", + "style-group": "effects", "valid-types": [ "mix-blend-mode" ] @@ -3220,6 +3384,7 @@ "inherited": false, "initial": "fill", "requires-computation": "never", + "style-group": "misc-reset", "valid-types": [ "object-fit" ] @@ -3231,6 +3396,7 @@ "inherited": false, "initial": "50% 50%", "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "position" ], @@ -3244,6 +3410,7 @@ "inherited": false, "initial": "1", "requires-computation": "cascaded-value", + "style-group": "effects", "valid-types": [ "opacity-value" ] @@ -3253,6 +3420,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "alignment", "valid-types": [ "integer [-∞,∞]" ] @@ -3262,6 +3430,7 @@ "inherited": true, "initial": "2", "requires-computation": "cascaded-value", + "style-group": "inherited-text", "valid-types": [ "integer [1,∞]" ], @@ -3284,6 +3453,7 @@ "initial": "currentColor", "needs-layout-node-for-resolved-value": true, "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "color" ] @@ -3294,6 +3464,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "length [-∞,∞]" ] @@ -3304,6 +3475,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "misc-reset", "valid-types": [ "outline-style" ] @@ -3314,6 +3486,7 @@ "inherited": false, "initial": "medium", "requires-computation": "non-inherited-value", + "style-group": "misc-reset", "valid-types": [ "length [0,∞]", "line-width" @@ -3377,6 +3550,7 @@ "animation-type": "by-computed-value", "inherited": false, "initial": "0px", + "style-group": "misc-reset", "valid-types": [ "length [0,∞]" ], @@ -3408,6 +3582,7 @@ "animation-type": "by-computed-value", "inherited": false, "initial": "0px", + "style-group": "misc-reset", "valid-types": [ "length [0,∞]" ], @@ -3417,6 +3592,7 @@ "animation-type": "by-computed-value", "inherited": false, "initial": "0px", + "style-group": "misc-reset", "valid-types": [ "length [0,∞]" ], @@ -3426,6 +3602,7 @@ "animation-type": "by-computed-value", "inherited": false, "initial": "0px", + "style-group": "misc-reset", "valid-types": [ "length [0,∞]" ], @@ -3442,6 +3619,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "inherited-text", "valid-identifiers": [ "anywhere", "break-word", @@ -3453,6 +3631,7 @@ "inherited": false, "initial": "visible", "requires-computation": "never", + "style-group": "box", "valid-types": [ "overflow" ], @@ -3465,6 +3644,7 @@ "inherited": false, "initial": "visible", "requires-computation": "never", + "style-group": "box", "valid-types": [ "overflow" ], @@ -3524,6 +3704,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "surround", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -3566,6 +3747,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "surround", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -3581,6 +3763,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "surround", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -3596,6 +3779,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "surround", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -3611,6 +3795,7 @@ "inherited": true, "initial": "normal", "requires-computation": "never", + "style-group": "inherited-svg", "valid-identifiers": [ "normal" ], @@ -3624,6 +3809,7 @@ "inherited": false, "initial": "none", "requires-computation": "cascaded-value", + "style-group": "transform", "valid-identifiers": [ "none" ], @@ -3638,6 +3824,7 @@ "inherited": false, "initial": "50% 50%", "requires-computation": "cascaded-value", + "style-group": "transform", "valid-types": [ "position" ], @@ -3670,6 +3857,7 @@ "inherited": true, "initial": "auto", "requires-computation": "never", + "style-group": "inherited-ui", "valid-types": [ "pointer-events" ] @@ -3679,6 +3867,7 @@ "inherited": false, "initial": "static", "requires-computation": "never", + "style-group": "box", "valid-types": [ "positioning" ] @@ -3688,6 +3877,7 @@ "inherited": false, "initial": "normal", "requires-computation": "never", + "style-group": "anchor", "valid-types": [ "dashed-ident" ], @@ -3703,6 +3893,7 @@ "inherited": false, "initial": "none", "requires-computation": "cascaded-value", + "style-group": "anchor", "valid-types": [ "position-area" ], @@ -3715,6 +3906,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "anchor", "valid-types": [ "dashed-ident", "try-tactic" @@ -3728,6 +3920,7 @@ "inherited": false, "initial": "normal", "requires-computation": "never", + "style-group": "anchor", "valid-types": [ "try-order" ], @@ -3740,6 +3933,7 @@ "inherited": false, "initial": "anchors-visible", "requires-computation": "never", + "style-group": "anchor", "valid-identifiers": [ "always", "anchors-valid", @@ -3753,6 +3947,7 @@ "initial": "auto", "multiplicity": "list", "requires-computation": "never", + "style-group": "inherited-list", "valid-types": [ "string" ], @@ -3767,6 +3962,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "svg-reset", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -3782,6 +3978,7 @@ "affects-layout": false, "initial": "none", "requires-computation": "never", + "style-group": "box", "valid-types": [ "resize" ] @@ -3791,6 +3988,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "surround", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]", @@ -3813,13 +4011,15 @@ "affects-layout": false, "affects-scrollable-overflow": true, "affects-stacking-context": true, - "requires-computation": "cascaded-value" + "requires-computation": "cascaded-value", + "style-group": "transform" }, "row-gap": { "animation-type": "by-computed-value", "inherited": false, "initial": "normal", "requires-computation": "cascaded-value", + "style-group": "alignment", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -3835,6 +4035,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "svg-reset", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -3853,6 +4054,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "svg-reset", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -3873,7 +4075,8 @@ "affects-layout": false, "affects-scrollable-overflow": true, "affects-stacking-context": true, - "requires-computation": "cascaded-value" + "requires-computation": "cascaded-value", + "style-group": "transform" }, "scroll-behavior": { "initial": "auto", @@ -3881,6 +4084,7 @@ "affects-layout": false, "animation-type": "none", "requires-computation": "never", + "style-group": "misc-reset", "valid-identifiers": [ "auto", "smooth" @@ -3927,6 +4131,7 @@ "initial": "0", "inherited": false, "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "length [-∞,∞]" ] @@ -3959,6 +4164,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "length [-∞,∞]" ] @@ -3968,6 +4174,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "length [-∞,∞]" ] @@ -3977,6 +4184,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "length [-∞,∞]" ] @@ -4032,6 +4240,7 @@ "initial": "auto", "inherited": false, "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -4074,6 +4283,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -4088,6 +4298,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -4102,6 +4313,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -4126,6 +4338,7 @@ "inherited": false, "initial": "block", "requires-computation": "never", + "style-group": "animation", "valid-types": [ "axis" ], @@ -4137,6 +4350,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "animation", "valid-identifiers": [ "none" ], @@ -4150,7 +4364,8 @@ "animation-type": "by-computed-value", "inherited": true, "initial": "auto", - "requires-computation": "cascaded-value" + "requires-computation": "cascaded-value", + "style-group": "inherited-ui" }, "scrollbar-gutter": { "affects-layout": false, @@ -4158,7 +4373,8 @@ "__comment": "This property should affect layout per-spec, but ladybird always uses overlay scrollbars so it doesn't in practice.", "inherited": false, "initial": "auto", - "requires-computation": "never" + "requires-computation": "never", + "style-group": "misc-reset" }, "scrollbar-width": { "affects-layout": false, @@ -4166,6 +4382,7 @@ "inherited": false, "initial": "auto", "requires-computation": "never", + "style-group": "misc-reset", "valid-types": [ "scrollbar-width" ], @@ -4181,6 +4398,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "opacity-value" ] @@ -4190,6 +4408,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "misc-reset", "valid-types": [ "length [0,∞]", "percentage [0,∞]" @@ -4201,7 +4420,8 @@ "animation-type": "by-computed-value", "inherited": false, "initial": "none", - "requires-computation": "cascaded-value" + "requires-computation": "cascaded-value", + "style-group": "misc-reset" }, "shape-rendering": { "affects-layout": true, @@ -4209,6 +4429,7 @@ "inherited": true, "initial": "auto", "requires-computation": "never", + "style-group": "svg-reset", "valid-types": [ "shape-rendering" ] @@ -4219,6 +4440,7 @@ "inherited": false, "initial": "black", "requires-computation": "non-inherited-value", + "style-group": "svg-reset", "valid-types": [ "color" ] @@ -4229,6 +4451,7 @@ "inherited": false, "initial": "1", "requires-computation": "cascaded-value", + "style-group": "svg-reset", "valid-types": [ "opacity-value" ] @@ -4239,6 +4462,7 @@ "inherited": true, "initial": "none", "requires-computation": "cascaded-value", + "style-group": "inherited-svg", "valid-types": [ "paint" ] @@ -4249,7 +4473,8 @@ "initial": "none", "affects-layout": false, "percentages-resolve-to": "length", - "requires-computation": "cascaded-value" + "requires-computation": "cascaded-value", + "style-group": "inherited-svg" }, "stroke-dashoffset": { "affects-layout": false, @@ -4257,6 +4482,7 @@ "inherited": true, "initial": "0px", "requires-computation": "cascaded-value", + "style-group": "inherited-svg", "valid-types": [ "length [0,∞]", "number [0,∞]", @@ -4270,6 +4496,7 @@ "inherited": true, "initial": "butt", "requires-computation": "never", + "style-group": "inherited-svg", "valid-types": [ "stroke-linecap" ] @@ -4280,6 +4507,7 @@ "inherited": true, "initial": "miter", "requires-computation": "never", + "style-group": "inherited-svg", "valid-types": [ "stroke-linejoin" ] @@ -4290,6 +4518,7 @@ "inherited": true, "initial": "4", "requires-computation": "cascaded-value", + "style-group": "inherited-svg", "valid-types": [ "number [0,∞]" ] @@ -4300,6 +4529,7 @@ "inherited": true, "initial": "1", "requires-computation": "cascaded-value", + "style-group": "inherited-svg", "valid-types": [ "opacity-value" ] @@ -4310,6 +4540,7 @@ "inherited": true, "initial": "1px", "requires-computation": "cascaded-value", + "style-group": "inherited-svg", "valid-types": [ "length [0,∞]", "number [0,∞]", @@ -4322,6 +4553,7 @@ "inherited": true, "initial": "8", "requires-computation": "cascaded-value", + "style-group": "inherited-text", "valid-types": [ "length [0,∞]", "number [0,∞]" @@ -4332,6 +4564,7 @@ "inherited": false, "initial": "auto", "requires-computation": "never", + "style-group": "box", "valid-types": [ "table-layout" ] @@ -4341,6 +4574,7 @@ "inherited": true, "initial": "start", "requires-computation": "never", + "style-group": "inherited-text", "valid-types": [ "text-align" ] @@ -4350,6 +4584,7 @@ "inherited": true, "initial": "start", "requires-computation": "never", + "style-group": "inherited-svg", "valid-types": [ "text-anchor" ] @@ -4371,6 +4606,7 @@ "initial": "currentcolor", "needs-layout-node-for-resolved-value": true, "requires-computation": "cascaded-value", + "style-group": "text-reset", "valid-types": [ "color" ] @@ -4382,6 +4618,7 @@ "inherited": true, "initial": "none", "requires-computation": "never", + "style-group": "text-reset", "valid-types": [ "text-decoration-line" ] @@ -4392,6 +4629,7 @@ "inherited": true, "initial": "auto", "requires-computation": "never", + "style-group": "inherited-text", "valid-types": [ "text-decoration-skip-ink" ] @@ -4402,6 +4640,7 @@ "inherited": false, "initial": "solid", "requires-computation": "never", + "style-group": "text-reset", "valid-types": [ "text-decoration-style" ] @@ -4412,6 +4651,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "text-reset", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -4427,6 +4667,7 @@ "inherited": true, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "inherited-text", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -4445,6 +4686,7 @@ "inherited": true, "initial": "auto", "requires-computation": "never", + "style-group": "inherited-text", "valid-types": [ "text-justify" ], @@ -4458,6 +4700,7 @@ "inherited": false, "initial": "clip", "requires-computation": "never", + "style-group": "box", "valid-types": [ "text-overflow" ] @@ -4468,6 +4711,7 @@ "inherited": true, "initial": "auto", "requires-computation": "never", + "style-group": "font", "valid-types": [ "text-rendering" ] @@ -4479,6 +4723,7 @@ "initial": "none", "needs-layout-node-for-resolved-value": true, "requires-computation": "cascaded-value", + "style-group": "inherited-text", "valid-identifiers": [ "none" ] @@ -4489,6 +4734,7 @@ "inherited": true, "initial": "none", "requires-computation": "never", + "style-group": "inherited-text", "valid-types": [ "text-transform" ] @@ -4498,6 +4744,7 @@ "inherited": true, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "inherited-text", "valid-identifiers": [ "auto" ], @@ -4512,6 +4759,7 @@ "inherited": true, "initial": "auto", "requires-computation": "never", + "style-group": "inherited-text", "valid-types": [ "text-underline-position-horizontal", "text-underline-position-vertical" @@ -4529,6 +4777,7 @@ "inherited": true, "initial": "wrap", "requires-computation": "never", + "style-group": "inherited-text", "valid-types": [ "text-wrap-mode" ] @@ -4538,6 +4787,7 @@ "inherited": true, "initial": "auto", "requires-computation": "never", + "style-group": "inherited-text", "valid-types": [ "text-wrap-style" ] @@ -4547,13 +4797,15 @@ "animation-type": "none", "inherited": false, "initial": "none", - "requires-computation": "never" + "requires-computation": "never", + "style-group": "animation" }, "top": { "animation-type": "by-computed-value", "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "surround", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]", @@ -4575,6 +4827,7 @@ "initial": "auto", "max-values": 3, "requires-computation": "never", + "style-group": "misc-reset", "valid-types": [ "touch-action" ] @@ -4590,6 +4843,7 @@ "needs-layout-node-for-resolved-value": true, "percentages-resolve-to": "length", "requires-computation": "cascaded-value", + "style-group": "transform", "valid-types": [ "transform-list" ], @@ -4605,6 +4859,7 @@ "affects-layout": false, "affects-scrollable-overflow": true, "requires-computation": "never", + "style-group": "transform", "valid-types": [ "transform-box" ] @@ -4618,6 +4873,7 @@ "initial": "50% 50%", "max-values": 3, "requires-computation": "cascaded-value", + "style-group": "transform", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -4637,6 +4893,7 @@ "inherited": false, "initial": "flat", "requires-computation": "never", + "style-group": "transform", "valid-identifiers": [ "flat", "preserve-3d" @@ -4661,6 +4918,7 @@ "initial": "normal", "multiplicity": "coordinating-list", "requires-computation": "never", + "style-group": "animation", "valid-types": [ "transition-behavior" ] @@ -4672,6 +4930,7 @@ "initial": "0s", "multiplicity": "coordinating-list", "requires-computation": "cascaded-value", + "style-group": "animation", "valid-types": [ "time [-∞,∞]" ] @@ -4683,6 +4942,7 @@ "initial": "0s", "multiplicity": "coordinating-list", "requires-computation": "cascaded-value", + "style-group": "animation", "valid-types": [ "time [0,∞]" ] @@ -4694,6 +4954,7 @@ "initial": "all", "multiplicity": "coordinating-list", "requires-computation": "never", + "style-group": "animation", "valid-types": [ "custom-ident ![none]" ], @@ -4708,6 +4969,7 @@ "initial": "ease", "multiplicity": "coordinating-list", "requires-computation": "cascaded-value", + "style-group": "animation", "valid-types": [ "easing-function", "easing-keyword" @@ -4722,6 +4984,7 @@ "affects-scrollable-overflow": true, "affects-stacking-context": true, "requires-computation": "cascaded-value", + "style-group": "transform", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -4733,6 +4996,7 @@ "inherited": false, "initial": "normal", "requires-computation": "never", + "style-group": "box", "valid-types": [ "unicode-bidi" ] @@ -4743,6 +5007,7 @@ "inherited": false, "initial": "auto", "requires-computation": "never", + "style-group": "misc-reset", "valid-types": [ "user-select" ] @@ -4753,6 +5018,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "svg-reset", "valid-types": [ "vector-effect" ] @@ -4762,6 +5028,7 @@ "inherited": false, "initial": "baseline", "requires-computation": "cascaded-value", + "style-group": "box", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]", @@ -4788,6 +5055,7 @@ "inherited": false, "initial": "block", "requires-computation": "never", + "style-group": "animation", "valid-types": [ "axis" ], @@ -4799,6 +5067,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "animation", "valid-types": [ "view-timeline-inset" ], @@ -4811,6 +5080,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "animation", "valid-identifiers": [ "none" ], @@ -4826,6 +5096,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "misc-reset", "valid-types": [ "custom-ident ![auto,none]" ], @@ -4838,6 +5109,7 @@ "inherited": true, "initial": "visible", "requires-computation": "never", + "style-group": "inherited-box", "valid-types": [ "visibility" ] @@ -4858,6 +5130,7 @@ "inherited": true, "initial": "collapse", "requires-computation": "never", + "style-group": "inherited-text", "valid-types": [ "white-space-collapse" ] @@ -4867,6 +5140,7 @@ "inherited": false, "initial": "none", "requires-computation": "never", + "style-group": "text-reset", "valid-identifiers": [ "none", "discard-before", @@ -4879,6 +5153,7 @@ "inherited": true, "initial": "2", "requires-computation": "cascaded-value", + "style-group": "inherited-text", "valid-types": [ "integer [1,∞]" ], @@ -4889,6 +5164,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "sizing", "valid-types": [ "fit-content", "length [0,∞]", @@ -4913,6 +5189,7 @@ "initial": "auto", "multiplicity": "list", "requires-computation": "never", + "style-group": "misc-reset", "valid-types": [ "custom-ident ![all,auto,contents,none,scroll-position,will-change]" ], @@ -4927,6 +5204,7 @@ "initial": "normal", "inherited": true, "requires-computation": "never", + "style-group": "inherited-text", "valid-identifiers": [ "normal", "keep-all", @@ -4939,6 +5217,7 @@ "inherited": true, "initial": "normal", "requires-computation": "non-inherited-value", + "style-group": "inherited-text", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -4959,6 +5238,7 @@ "inherited": true, "initial": "horizontal-tb", "requires-computation": "never", + "style-group": "inherited-box", "valid-types": [ "writing-mode" ] @@ -4969,6 +5249,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "svg-reset", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -4984,6 +5265,7 @@ "inherited": false, "initial": "0", "requires-computation": "cascaded-value", + "style-group": "svg-reset", "valid-types": [ "length [-∞,∞]", "percentage [-∞,∞]" @@ -5000,6 +5282,7 @@ "inherited": false, "initial": "auto", "requires-computation": "cascaded-value", + "style-group": "box", "valid-types": [ "integer [-∞,∞]" ], diff --git a/Meta/Generators/generate_libweb_css_property_id.py b/Meta/Generators/generate_libweb_css_property_id.py index 025a44af22916..e8b8ae8f7f222 100644 --- a/Meta/Generators/generate_libweb_css_property_id.py +++ b/Meta/Generators/generate_libweb_css_property_id.py @@ -26,6 +26,69 @@ def is_legacy_alias(prop: dict) -> bool: return "legacy-alias-for" in prop +STYLE_GROUP_ENUMERATORS = { + "alignment": "AlignmentValues", + "anchor": "AnchorValues", + "animation": "AnimationValues", + "background": "BackgroundValues", + "border": "BorderValues", + "box": "BoxValues", + "content": "ContentValues", + "effects": "EffectsValues", + "font": "FontValues", + "grid": "GridValues", + "inherited-box": "InheritedBoxValues", + "inherited-list": "InheritedListValues", + "inherited-svg": "InheritedSVGValues", + "inherited-table": "InheritedTableValues", + "inherited-text": "InheritedTextValues", + "inherited-ui": "InheritedUIValues", + "mask": "MaskValues", + "misc-reset": "MiscResetValues", + "sizing": "SizingValues", + "surround": "SurroundValues", + "svg-reset": "SVGResetValues", + "text-reset": "TextResetValues", + "transform": "TransformValues", +} + + +def style_groups_of(prop: dict) -> list: + groups = prop.get("style-group") + if groups is None: + return [] + if isinstance(groups, str): + return [groups] + return groups + + +def verify_style_groups(properties: dict, logical_property_groups: dict) -> None: + for name, value in properties.items(): + groups = style_groups_of(value) + is_physical_longhand = ( + not is_legacy_alias(value) and "longhands" not in value and "logical-alias-for" not in value + ) + if is_physical_longhand: + if not groups: + print(f"Longhand property '{name}' is missing its style-group", file=sys.stderr) + sys.exit(1) + for group in groups: + if group not in STYLE_GROUP_ENUMERATORS: + print(f"Property '{name}' has unknown style-group '{group}'", file=sys.stderr) + sys.exit(1) + elif groups: + print(f"Property '{name}' must not declare a style-group", file=sys.stderr) + sys.exit(1) + + # A logical alias inherits the style-group of its group's first physical member, so every + # member must agree on it. + for group_name, group in logical_property_groups.items(): + member_groups = {tuple(style_groups_of(properties[member])) for member in group["physical"].values()} + if len(member_groups) > 1: + print(f"Logical property group '{group_name}' spans multiple style-groups", file=sys.stderr) + sys.exit(1) + + def verify_alphabetical(data: dict, path: str) -> None: most_recent_name = "" for name in data: @@ -176,6 +239,7 @@ def write_header_file(out: TextIO, properties: dict, logical_property_groups: di #pragma once #include +#include #include #include #include @@ -188,6 +252,8 @@ def write_header_file(out: TextIO, properties: dict, logical_property_groups: di namespace Web::CSS {{ +enum class StyleGroupIndex : size_t; + enum class PropertyID : {property_id_underlying_type} {{ Custom, """) @@ -293,6 +359,8 @@ def write_header_file(out: TextIO, properties: dict, logical_property_groups: di size_t property_maximum_value_count(PropertyID); bool property_affects_layout(PropertyID); +u32 style_group_dependency_mask(PropertyID); +ReadonlySpan longhands_in_style_group(StyleGroupIndex); bool property_affects_stacking_context(PropertyID); bool property_affects_accumulated_visual_contexts(PropertyID); bool property_affects_scrollable_overflow(PropertyID); @@ -356,6 +424,7 @@ def write_implementation_file(out: TextIO, properties: dict, logical_property_gr out.write(""" #include #include +#include #include #include #include @@ -561,6 +630,65 @@ def write_implementation_file(out: TextIO, properties: dict, logical_property_gr } } +u32 style_group_dependency_mask(PropertyID property_id) +{ + switch (property_id) { +""") + + dependency_mask_clusters: dict = {} + for name, value in properties.items(): + if is_legacy_alias(value): + continue + groups = style_groups_of(value) + if not groups: + continue + if "logical-alias-for" in value and "inherited-box" not in groups: + # The mapping context stored in the inherited box group selects the physical + # longhand a logical alias follows. + groups = groups + ["inherited-box"] + expression = " | ".join( + f"1u << to_underlying(StyleGroupIndex::{STYLE_GROUP_ENUMERATORS[group]})" for group in groups + ) + dependency_mask_clusters.setdefault(expression, []).append(name) + + for expression, names in dependency_mask_clusters.items(): + for name in names: + out.write(f" case PropertyID::{title_casify(name)}:\n") + out.write(f" return {expression};\n") + + out.write(""" default: + VERIFY_NOT_REACHED(); + } +} + +ReadonlySpan longhands_in_style_group(StyleGroupIndex group) +{ + switch (group) { +""") + + style_group_members: dict = {group: [] for group in STYLE_GROUP_ENUMERATORS} + for name, value in properties.items(): + if is_legacy_alias(value) or "logical-alias-for" in value: + continue + groups = style_groups_of(value) + if groups: + style_group_members[groups[0]].append(name) + + for group, enumerator in STYLE_GROUP_ENUMERATORS.items(): + out.write(f" case StyleGroupIndex::{enumerator}: {{\n") + out.write(" static constexpr Array longhands {\n") + for name in style_group_members[group]: + out.write(f" PropertyID::{title_casify(name)},\n") + out.write(""" }; + return longhands.span(); + } +""") + + out.write(""" default: + VERIFY_NOT_REACHED(); + } +} + bool property_affects_stacking_context(PropertyID property_id) { switch (property_id) { @@ -1659,6 +1787,7 @@ def main(): verify_alphabetical(properties, args.properties_json) verify_alphabetical(logical_property_groups, args.groups_json) verify_alphabetical(enums, args.enums_json) + verify_style_groups(properties, logical_property_groups) enum_names = list(enums.keys()) From 97a6e2fa5cb9229813b71edff53ed3756d3da8be Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Fri, 7 Aug 2026 00:00:16 +0100 Subject: [PATCH 2/2] LibWeb: Derive style group property lists from `Properties.json` data --- Libraries/LibWeb/CSS/ComputedValues.cpp | 359 +++--------------------- 1 file changed, 45 insertions(+), 314 deletions(-) diff --git a/Libraries/LibWeb/CSS/ComputedValues.cpp b/Libraries/LibWeb/CSS/ComputedValues.cpp index 67109639bb09a..d6036cb5ad15c 100644 --- a/Libraries/LibWeb/CSS/ComputedValues.cpp +++ b/Libraries/LibWeb/CSS/ComputedValues.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -127,28 +128,6 @@ static Array const& keyword_code_table() return table; } -// The properties feeding the text reset group's descriptors, in registration -// order. -static constexpr Array text_reset_group_properties { - PropertyID::TextDecorationLine, - PropertyID::TextDecorationThickness, - PropertyID::TextDecorationStyle, - PropertyID::TextDecorationColor, - PropertyID::WhiteSpaceTrim, -}; - -// The properties feeding the effects group's descriptors, in registration -// order. -static constexpr Array effects_group_properties { - PropertyID::Opacity, - PropertyID::Filter, - PropertyID::BackdropFilter, - PropertyID::MixBlendMode, - PropertyID::Isolation, - PropertyID::BoxShadow, - PropertyID::Clip, -}; - // The appearance keyword mapping with the compatibility keywords excluded: // they normalize to auto for the appearance field but stay raw for // computed_appearance, so their pages take the C++ population path. @@ -176,43 +155,6 @@ static Optional appearance_without_compat_from_keyword(Keyword keywo } } -// The properties feeding the misc reset group's descriptors, in registration -// order; Appearance appears twice, once per derived field. -static constexpr Array misc_reset_group_properties { - PropertyID::ScrollMarginTop, - PropertyID::ScrollMarginRight, - PropertyID::ScrollMarginBottom, - PropertyID::ScrollMarginLeft, - PropertyID::ScrollPaddingTop, - PropertyID::ScrollPaddingRight, - PropertyID::ScrollPaddingBottom, - PropertyID::ScrollPaddingLeft, - PropertyID::OverflowClipMarginTop, - PropertyID::OverflowClipMarginRight, - PropertyID::OverflowClipMarginBottom, - PropertyID::OverflowClipMarginLeft, - PropertyID::ColumnSpan, - PropertyID::Appearance, - PropertyID::Appearance, - PropertyID::OutlineStyle, - PropertyID::ObjectFit, - PropertyID::ColumnHeight, - PropertyID::OutlineColor, - PropertyID::OutlineOffset, - PropertyID::OutlineWidth, - PropertyID::UserSelect, - PropertyID::ObjectPosition, - PropertyID::ViewTransitionName, - PropertyID::TouchAction, - PropertyID::ScrollBehavior, - PropertyID::ScrollbarGutter, - PropertyID::ScrollbarWidth, - PropertyID::ShapeImageThreshold, - PropertyID::ShapeMargin, - PropertyID::ShapeOutside, - PropertyID::WillChange, -}; - // overflow-wrap has no generated keyword converter; the mapping matches the // switch in create(). static Optional overflow_wrap_from_keyword(Keyword keyword) @@ -229,222 +171,14 @@ static Optional overflow_wrap_from_keyword(Keyword keyword) } } -// The properties feeding the inherited text group's descriptors, in -// registration order; the doubled properties feed two fields each. -static constexpr Array inherited_text_group_properties { - PropertyID::Color, - PropertyID::Color, - PropertyID::WebkitTextFillColor, - PropertyID::WebkitTextFillColor, - PropertyID::TextShadow, - PropertyID::TextAlign, - PropertyID::TextJustify, - PropertyID::TextTransform, - PropertyID::TextWrapMode, - PropertyID::TextWrapStyle, - PropertyID::TextDecorationSkipInk, - PropertyID::TextUnderlinePosition, - PropertyID::TextUnderlineOffset, - PropertyID::TextIndent, - PropertyID::TabSize, - PropertyID::WhiteSpaceCollapse, - PropertyID::WordBreak, - PropertyID::OverflowWrap, - PropertyID::WordSpacing, - PropertyID::WordSpacing, - PropertyID::LetterSpacing, - PropertyID::LetterSpacing, - PropertyID::Orphans, - PropertyID::Widows, -}; - -// The properties feeding the inherited UI group's descriptors, in -// registration order; the doubled properties feed two fields each. -static constexpr Array inherited_ui_group_properties { - PropertyID::CaretColor, - PropertyID::CaretColor, - PropertyID::AccentColor, - PropertyID::AccentColor, - PropertyID::Cursor, - PropertyID::PointerEvents, - PropertyID::ScrollbarColor, - PropertyID::ColorScheme, - PropertyID::ColorScheme, -}; - -// The properties feeding the transform group's descriptors, in registration -// order. -static constexpr Array transform_group_properties { - PropertyID::Transform, - PropertyID::TransformBox, - PropertyID::TransformOrigin, - PropertyID::TransformStyle, - PropertyID::BackfaceVisibility, - PropertyID::Rotate, - PropertyID::Translate, - PropertyID::Scale, - PropertyID::Perspective, - PropertyID::PerspectiveOrigin, -}; - -// The properties feeding the mask group's descriptors, in registration -// order. -static constexpr Array mask_group_properties { - PropertyID::MaskImage, - PropertyID::MaskType, - PropertyID::ClipPath, - PropertyID::MaskMode, - PropertyID::MaskRepeat, - PropertyID::MaskPosition, - PropertyID::MaskClip, - PropertyID::MaskOrigin, - PropertyID::MaskSize, - PropertyID::MaskComposite, -}; - -// The properties feeding the grid group's descriptors, in registration -// order. Every field registers as an initial-value constraint until the -// core learns the grid representations. -static constexpr Array grid_group_properties { - PropertyID::GridAutoColumns, - PropertyID::GridAutoRows, - PropertyID::GridTemplateColumns, - PropertyID::GridTemplateRows, - PropertyID::GridColumnEnd, - PropertyID::GridColumnStart, - PropertyID::GridRowEnd, - PropertyID::GridRowStart, - PropertyID::GridTemplateAreas, -}; - -// The properties feeding the animation group's descriptors, in registration -// order. Every field registers as an initial-value constraint: elements -// without animations, timelines or transitions adopt a shared payload. -static constexpr Array animation_group_properties { - PropertyID::AnimationName, - PropertyID::AnimationComposition, - PropertyID::AnimationDelay, - PropertyID::AnimationDirection, - PropertyID::AnimationDuration, - PropertyID::AnimationFillMode, - PropertyID::AnimationIterationCount, - PropertyID::AnimationPlayState, - PropertyID::AnimationTimeline, - PropertyID::AnimationTimingFunction, - PropertyID::ScrollTimelineName, - PropertyID::ScrollTimelineAxis, - PropertyID::TimelineScope, - PropertyID::ViewTimelineName, - PropertyID::ViewTimelineAxis, - PropertyID::ViewTimelineInset, - PropertyID::TransitionProperty, - PropertyID::TransitionDuration, - PropertyID::TransitionTimingFunction, - PropertyID::TransitionDelay, - PropertyID::TransitionBehavior, -}; +static NeverDestroyed, to_underlying(StyleGroupIndex::Count)>> s_style_group_gather_properties; +static bool s_style_group_gather_properties_populated { false }; -// The properties feeding the inherited SVG group's descriptors, in -// registration order. -static constexpr Array inherited_svg_group_properties { - PropertyID::Fill, - PropertyID::Stroke, - PropertyID::FillRule, - PropertyID::ClipRule, - PropertyID::FillOpacity, - PropertyID::StrokeOpacity, - PropertyID::StrokeLinecap, - PropertyID::StrokeLinejoin, - PropertyID::StrokeDasharray, - PropertyID::StrokeDashoffset, - PropertyID::StrokeMiterlimit, - PropertyID::StrokeWidth, - PropertyID::ColorInterpolation, - PropertyID::ColorInterpolationFilters, - PropertyID::PaintOrder, - PropertyID::TextAnchor, - PropertyID::DominantBaseline, -}; - -// The properties feeding the inherited list group's descriptors, in -// registration order. -static constexpr Array inherited_list_group_properties { - PropertyID::ListStyleType, - PropertyID::ListStylePosition, - PropertyID::ListStyleImage, - PropertyID::Quotes, -}; - -// The properties feeding the content and anchor groups' descriptors, in -// registration order. Everything registers as constraints: both groups adopt -// shared payloads unless their properties are actually used. -static constexpr Array content_group_properties { - PropertyID::Content, - PropertyID::CounterIncrement, - PropertyID::CounterReset, - PropertyID::CounterSet, -}; - -static constexpr Array anchor_group_properties { - PropertyID::AnchorName, - PropertyID::AnchorScope, - PropertyID::PositionAnchor, - PropertyID::PositionArea, - PropertyID::PositionTryFallbacks, - PropertyID::PositionTryOrder, - PropertyID::PositionVisibility, -}; - -// The properties feeding the border group's descriptors, in registration -// order; each side's color feeds both the resolved color and the retained -// shell. -static constexpr Array border_group_properties { - PropertyID::BorderLeftColor, - PropertyID::BorderLeftColor, - PropertyID::BorderLeftStyle, - PropertyID::BorderLeftWidth, - PropertyID::BorderTopColor, - PropertyID::BorderTopColor, - PropertyID::BorderTopStyle, - PropertyID::BorderTopWidth, - PropertyID::BorderRightColor, - PropertyID::BorderRightColor, - PropertyID::BorderRightStyle, - PropertyID::BorderRightWidth, - PropertyID::BorderBottomColor, - PropertyID::BorderBottomColor, - PropertyID::BorderBottomStyle, - PropertyID::BorderBottomWidth, - PropertyID::BorderBottomLeftRadius, - PropertyID::BorderBottomRightRadius, - PropertyID::BorderTopLeftRadius, - PropertyID::BorderTopRightRadius, - PropertyID::CornerBottomLeftShape, - PropertyID::CornerBottomRightShape, - PropertyID::CornerTopLeftShape, - PropertyID::CornerTopRightShape, - PropertyID::BorderImageSource, - PropertyID::BorderImageOutset, - PropertyID::BorderImageRepeat, - PropertyID::BorderImageSlice, - PropertyID::BorderImageWidth, -}; - -// The properties feeding the background group's descriptors, in registration -// order; the color feeds both the resolved color and the retained shell. -static constexpr Array background_group_properties { - PropertyID::BackgroundColor, - PropertyID::BackgroundColor, - PropertyID::BackgroundImage, - PropertyID::BackgroundClip, - PropertyID::BackgroundAttachment, - PropertyID::BackgroundOrigin, - PropertyID::BackgroundPositionX, - PropertyID::BackgroundPositionY, - PropertyID::BackgroundRepeat, - PropertyID::BackgroundSize, - PropertyID::BackgroundBlendMode, -}; +static ReadonlySpan style_group_gather_properties(StyleGroupIndex group_index) +{ + VERIFY(s_style_group_gather_properties_populated); + return (*s_style_group_gather_properties)[to_underlying(group_index)]; +} static void register_style_group_field_descriptors() { @@ -582,11 +316,11 @@ static void register_style_group_field_descriptors() add(mask, PropertyID::MaskComposite, 0, GROUP_FIELD_REQUIRE_INITIAL_VALUE, 0, nullptr); constexpr auto grid = to_underlying(StyleGroupIndex::GridValues); - for (auto property : grid_group_properties) + for (auto property : longhands_in_style_group(StyleGroupIndex::GridValues)) add(grid, property, 0, GROUP_FIELD_REQUIRE_INITIAL_VALUE, 0, nullptr); constexpr auto animation = to_underlying(StyleGroupIndex::AnimationValues); - for (auto property : animation_group_properties) + for (auto property : longhands_in_style_group(StyleGroupIndex::AnimationValues)) add(animation, property, 0, GROUP_FIELD_REQUIRE_INITIAL_VALUE, 0, nullptr); using InheritedSVG = ComputedValues::InheritedSVGValues; @@ -670,18 +404,21 @@ static void register_style_group_field_descriptors() constexpr auto background = to_underlying(StyleGroupIndex::BackgroundValues); add(background, PropertyID::BackgroundColor, offsetof(Background, background_color), GROUP_FIELD_COLOR, 0, nullptr); add(background, PropertyID::BackgroundColor, offsetof(Background, background_color_style_value), GROUP_FIELD_RETAINED_DATA, 0, nullptr); - for (auto property : { PropertyID::BackgroundImage, PropertyID::BackgroundClip, PropertyID::BackgroundAttachment, - PropertyID::BackgroundOrigin, PropertyID::BackgroundPositionX, PropertyID::BackgroundPositionY, - PropertyID::BackgroundRepeat, PropertyID::BackgroundSize, PropertyID::BackgroundBlendMode }) + for (auto property : longhands_in_style_group(StyleGroupIndex::BackgroundValues)) { + if (property == PropertyID::BackgroundColor) + continue; add(background, property, 0, GROUP_FIELD_REQUIRE_INITIAL_VALUE, 0, nullptr); + } u32 generically_built_group_mask = 0; Array longhand_has_descriptor {}; for (auto const& descriptor : descriptors) { generically_built_group_mask |= 1u << descriptor.group_index; longhand_has_descriptor[descriptor.property_id - to_underlying(first_longhand_property_id)] = true; + (*s_style_group_gather_properties)[descriptor.group_index].append(static_cast(descriptor.property_id)); } + s_style_group_gather_properties_populated = true; for (auto i = to_underlying(first_longhand_property_id); i <= to_underlying(last_longhand_property_id); ++i) { auto property_id = static_cast(i); if (property_is_logical_alias(property_id)) @@ -1257,15 +994,15 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co if (inherited_table_adopted) computed_values.adopt_inherited_table_group(const_cast(inherited_table_payload)); - auto gather_group_values = [&](Array const& properties, Array& entries) { - for (size_t i = 0; i < N; ++i) { - auto const& value = computed_style.property(properties[i]); - entries[i] = { value.rust_style_value_data(), 0, false, 0, false }; - } + auto gather_group_values = [&](ReadonlySpan properties) { + Vector entries; + entries.ensure_capacity(properties.size()); + for (auto property : properties) + entries.unchecked_append({ computed_style.property(property).rust_style_value_data(), 0, false, 0, false }); + return entries; }; - Array content_group_values; - gather_group_values(content_group_properties, content_group_values); + auto content_group_values = gather_group_values(style_group_gather_properties(StyleGroupIndex::ContentValues)); auto* content_payload = ComputedValuesFFI::rust_build_style_group( ContentValues::style_group_index, content_group_values.data(), @@ -1275,8 +1012,7 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co if (content_adopted) computed_values.adopt_content_group(const_cast(content_payload)); - Array anchor_group_values; - gather_group_values(anchor_group_properties, anchor_group_values); + auto anchor_group_values = gather_group_values(style_group_gather_properties(StyleGroupIndex::AnchorValues)); auto* anchor_payload = ComputedValuesFFI::rust_build_style_group( AnchorValues::style_group_index, anchor_group_values.data(), @@ -1407,8 +1143,7 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co inherit_parent ? static_cast(inherit_parent->m_noninherited.sizing.operator->()) : nullptr); computed_values.adopt_sizing_group(const_cast(sizing_payload)); - Array grid_group_values; - gather_group_values(grid_group_properties, grid_group_values); + auto grid_group_values = gather_group_values(style_group_gather_properties(StyleGroupIndex::GridValues)); auto* grid_payload = ComputedValuesFFI::rust_build_style_group( GridValues::style_group_index, grid_group_values.data(), @@ -1418,8 +1153,7 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co if (grid_adopted) computed_values.adopt_grid_group(const_cast(grid_payload)); - Array mask_group_values; - gather_group_values(mask_group_properties, mask_group_values); + auto mask_group_values = gather_group_values(style_group_gather_properties(StyleGroupIndex::MaskValues)); auto* mask_payload = ComputedValuesFFI::rust_build_style_group( MaskValues::style_group_index, mask_group_values.data(), @@ -1429,8 +1163,7 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co if (mask_adopted) computed_values.adopt_mask_group(const_cast(mask_payload)); - Array transform_group_values; - gather_group_values(transform_group_properties, transform_group_values); + auto transform_group_values = gather_group_values(style_group_gather_properties(StyleGroupIndex::TransformValues)); auto* transform_payload = ComputedValuesFFI::rust_build_style_group( TransformValues::style_group_index, transform_group_values.data(), @@ -1440,8 +1173,8 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co if (transform_adopted) computed_values.adopt_transform_group(const_cast(transform_payload)); - Array effects_group_values; - gather_group_values(effects_group_properties, effects_group_values); + auto effects_group_properties = style_group_gather_properties(StyleGroupIndex::EffectsValues); + auto effects_group_values = gather_group_values(effects_group_properties); for (size_t i = 0; i < effects_group_properties.size(); ++i) { if (effects_group_properties[i] == PropertyID::Opacity) { effects_group_values[i].resolved_number = computed_style.opacity(); @@ -1530,8 +1263,7 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co computed_values.set_line_height(computed_style.line_height_data(), computed_style.line_height(document.font_computer())); computed_values.set_font_variant_emoji(computed_style.font_variant_emoji()); - Array animation_group_values; - gather_group_values(animation_group_properties, animation_group_values); + auto animation_group_values = gather_group_values(style_group_gather_properties(StyleGroupIndex::AnimationValues)); auto* animation_payload = ComputedValuesFFI::rust_build_style_group( AnimationValues::style_group_index, animation_group_values.data(), @@ -1644,8 +1376,8 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co // own color, which reaches the shared resolution context only further down. auto own_color_resolution_context = color_resolution_context; own_color_resolution_context.current_color = color; - Array inherited_text_group_values; - gather_group_values(inherited_text_group_properties, inherited_text_group_values); + auto inherited_text_group_properties = style_group_gather_properties(StyleGroupIndex::InheritedTextValues); + auto inherited_text_group_values = gather_group_values(inherited_text_group_properties); for (size_t i = 0; i < inherited_text_group_properties.size(); ++i) { auto gather_property_id = inherited_text_group_properties[i]; if (gather_property_id == PropertyID::Color) { @@ -1658,8 +1390,8 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co } } } - Array inherited_ui_group_values; - gather_group_values(inherited_ui_group_properties, inherited_ui_group_values); + auto inherited_ui_group_properties = style_group_gather_properties(StyleGroupIndex::InheritedUIValues); + auto inherited_ui_group_values = gather_group_values(inherited_ui_group_properties); for (size_t i = 0; i < inherited_ui_group_properties.size(); ++i) { auto ui_property_id = inherited_ui_group_properties[i]; if (ui_property_id == PropertyID::CaretColor) { @@ -1674,8 +1406,7 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co } } - Array inherited_list_group_values; - gather_group_values(inherited_list_group_properties, inherited_list_group_values); + auto inherited_list_group_values = gather_group_values(style_group_gather_properties(StyleGroupIndex::InheritedListValues)); auto* inherited_list_payload = ComputedValuesFFI::rust_build_style_group( InheritedListValues::style_group_index, inherited_list_group_values.data(), @@ -1685,8 +1416,8 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co if (inherited_list_adopted) computed_values.adopt_inherited_list_group(const_cast(inherited_list_payload)); - Array inherited_svg_group_values; - gather_group_values(inherited_svg_group_properties, inherited_svg_group_values); + auto inherited_svg_group_properties = style_group_gather_properties(StyleGroupIndex::InheritedSVGValues); + auto inherited_svg_group_values = gather_group_values(inherited_svg_group_properties); for (size_t i = 0; i < inherited_svg_group_properties.size(); ++i) { auto svg_property_id = inherited_svg_group_properties[i]; if (svg_property_id == PropertyID::FillOpacity) { @@ -1726,8 +1457,8 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co VERIFY(svg_reset_payload); computed_values.adopt_svg_reset_group(const_cast(svg_reset_payload)); - Array border_group_values; - gather_group_values(border_group_properties, border_group_values); + auto border_group_properties = style_group_gather_properties(StyleGroupIndex::BorderValues); + auto border_group_values = gather_group_values(border_group_properties); for (size_t i = 0; i < border_group_properties.size(); ++i) { auto border_property_id = border_group_properties[i]; switch (border_property_id) { @@ -1749,8 +1480,8 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co break; } } - Array background_group_values; - gather_group_values(background_group_properties, background_group_values); + auto background_group_properties = style_group_gather_properties(StyleGroupIndex::BackgroundValues); + auto background_group_values = gather_group_values(background_group_properties); for (size_t i = 0; i < background_group_properties.size(); ++i) { if (background_group_properties[i] == PropertyID::BackgroundColor) { background_group_values[i].resolved_color = computed_style.color(PropertyID::BackgroundColor, own_color_resolution_context).value(); @@ -1811,8 +1542,8 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co // NB: The text reset group builds only after the element's color lands in the // resolution context above, since text-decoration-color may be currentcolor. - Array text_reset_group_values; - gather_group_values(text_reset_group_properties, text_reset_group_values); + auto text_reset_group_properties = style_group_gather_properties(StyleGroupIndex::TextResetValues); + auto text_reset_group_values = gather_group_values(text_reset_group_properties); for (size_t i = 0; i < text_reset_group_properties.size(); ++i) { if (text_reset_group_properties[i] == PropertyID::TextDecorationColor) { text_reset_group_values[i].resolved_color = computed_style.color(PropertyID::TextDecorationColor, color_resolution_context).value(); @@ -1828,8 +1559,8 @@ NonnullRefPtr ComputedValues::create(ComputedProperties co if (text_reset_adopted) computed_values.adopt_text_reset_group(const_cast(text_reset_payload)); - Array misc_reset_group_values; - gather_group_values(misc_reset_group_properties, misc_reset_group_values); + auto misc_reset_group_properties = style_group_gather_properties(StyleGroupIndex::MiscResetValues); + auto misc_reset_group_values = gather_group_values(misc_reset_group_properties); for (size_t i = 0; i < misc_reset_group_properties.size(); ++i) { if (misc_reset_group_properties[i] == PropertyID::OutlineColor) { if (auto const& outline_color = computed_style.property(PropertyID::OutlineColor); outline_color.has_color()) {