mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-25 17:25:08 +02:00
LibWeb/CSS: Add flags for element-backed & tree-abiding pseudo-elements
Generate a couple of functions for checking if a pseudo-element fits these categories.
This commit is contained in:
Notes:
github-actions[bot]
2026-04-08 09:38:21 +00:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/LadybirdBrowser/ladybird/commit/492cfc58d9e Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/8728
@@ -262,7 +262,9 @@ Each entry has the following properties:
|
||||
| `alias-for` | No | Nothing | Use to specify that this should be treated as an alias for the named pseudo-element. |
|
||||
| `function-syntax` | No | Nothing | Syntax for the function arguments if this is a function-type pseudo-element. Copied directly from the spec. |
|
||||
| `is-allowed-in-has` | No | `false` | Whether this is a [`:has`-allowed pseudo-element](https://drafts.csswg.org/selectors/#has-allowed-pseudo-element). |
|
||||
| `is-element-backed` | No | `false` | Whether this is an [element-backed pseudo-element](https://drafts.csswg.org/css-pseudo-4/#element-backed). |
|
||||
| `is-pseudo-root` | No | `false` | Whether this is a [pseudo-element root](https://drafts.csswg.org/css-view-transitions/#pseudo-element-root). |
|
||||
| `is-tree-abiding` | No | `false` | Whether this is a [tree-abiding pseudo-element](https://drafts.csswg.org/css-pseudo-4/#tree-abiding). |
|
||||
| `property-whitelist` | No | Nothing | Some pseudo-elements only permit certain properties. If so, name them in an array here. Some special values are allowed here for categories of properties - see below. |
|
||||
| `spec` | No | Nothing | Link to the spec definition, for reference. Not used in generated code. |
|
||||
| `type` | No | `"identifier"` | What type of pseudo-element is this. Either "identifier", "function", or "both". |
|
||||
@@ -273,6 +275,8 @@ The generated code provides:
|
||||
- `Optional<PseudoElement> aliased_pseudo_element_from_string(StringView)` is similar, but returns the `PseudoElement` this name is an alias for
|
||||
- `StringView pseudo_element_name(PseudoElement)` to convert a `PseudoElement` back into a string
|
||||
- `bool is_has_allowed_pseudo_element(PseudoElement)` returns whether the pseudo-element is valid inside `:has()`
|
||||
- `bool is_element_backed_pseudo_element(PseudoElement)` returns whether the pseudo-element is element-backed
|
||||
- `bool is_tree_abiding_pseudo_element(PseudoElement)` returns whether the pseudo-element is tree-abiding
|
||||
- `bool is_pseudo_element_root(PseudoElement)` returns whether the pseudo-element is a [pseudo-element root](https://drafts.csswg.org/css-view-transitions/#pseudo-element-root)
|
||||
- `bool pseudo_element_supports_property(PseudoElement, PropertyID)` returns whether the property can be applied to this pseudo-element
|
||||
|
||||
|
||||
@@ -36,19 +36,23 @@
|
||||
"alias-for": "slider-thumb"
|
||||
},
|
||||
"after": {
|
||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-after"
|
||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-after",
|
||||
"is-tree-abiding": true
|
||||
},
|
||||
"backdrop": {
|
||||
"spec": "https://drafts.csswg.org/css-position-4/#selectordef-backdrop"
|
||||
},
|
||||
"before": {
|
||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-before"
|
||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-before",
|
||||
"is-tree-abiding": true
|
||||
},
|
||||
"details-content": {
|
||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-details-content"
|
||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-details-content",
|
||||
"is-element-backed": true
|
||||
},
|
||||
"file-selector-button": {
|
||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-file-selector-button"
|
||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-file-selector-button",
|
||||
"is-element-backed": true
|
||||
},
|
||||
"first-letter": {
|
||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-first-letter",
|
||||
@@ -82,15 +86,18 @@
|
||||
]
|
||||
},
|
||||
"marker": {
|
||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-marker"
|
||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-marker",
|
||||
"is-tree-abiding": true
|
||||
},
|
||||
"part": {
|
||||
"spec": "https://drafts.csswg.org/css-shadow-1/#selectordef-part",
|
||||
"type": "function",
|
||||
"function-syntax": "<ident>+"
|
||||
"function-syntax": "<ident>+",
|
||||
"is-element-backed": true
|
||||
},
|
||||
"placeholder": {
|
||||
"spec": "https://drafts.csswg.org/css-pseudo-4/#selectordef-placeholder",
|
||||
"is-tree-abiding": true,
|
||||
"property-whitelist": [
|
||||
"#font-properties",
|
||||
"color",
|
||||
@@ -127,7 +134,8 @@
|
||||
"slotted": {
|
||||
"spec": "https://drafts.csswg.org/css-shadow-1/#slotted-pseudo",
|
||||
"type": "function",
|
||||
"function-syntax": "<compound-selector>"
|
||||
"function-syntax": "<compound-selector>",
|
||||
"is-element-backed": true
|
||||
},
|
||||
"view-transition": {
|
||||
"spec": "https://drafts.csswg.org/css-view-transitions-1/#selectordef-view-transition",
|
||||
|
||||
@@ -87,6 +87,8 @@ Optional<PseudoElement> aliased_pseudo_element_from_string(StringView);
|
||||
WEB_API StringView pseudo_element_name(PseudoElement);
|
||||
|
||||
bool is_has_allowed_pseudo_element(PseudoElement);
|
||||
bool is_tree_abiding_pseudo_element(PseudoElement);
|
||||
bool is_element_backed_pseudo_element(PseudoElement);
|
||||
bool is_pseudo_element_root(PseudoElement);
|
||||
bool pseudo_element_supports_property(PseudoElement, PropertyID);
|
||||
|
||||
@@ -222,6 +224,65 @@ bool is_has_allowed_pseudo_element(PseudoElement pseudo_element)
|
||||
}
|
||||
}
|
||||
|
||||
bool is_tree_abiding_pseudo_element(PseudoElement pseudo_element)
|
||||
{
|
||||
// Element-backed pseudo-elements are always tree-abiding.
|
||||
// https://drafts.csswg.org/css-pseudo-4/#element-backed
|
||||
if (is_element_backed_pseudo_element(pseudo_element))
|
||||
return true;
|
||||
|
||||
switch (pseudo_element) {
|
||||
)~~~");
|
||||
|
||||
pseudo_elements_data.for_each_member([&](auto& name, JsonValue const& value) {
|
||||
auto& pseudo_element = value.as_object();
|
||||
if (pseudo_element.has("alias-for"sv))
|
||||
return;
|
||||
if (!pseudo_element.get_bool("is-tree-abiding"sv).value_or(false))
|
||||
return;
|
||||
|
||||
auto member_generator = generator.fork();
|
||||
member_generator.set("name:titlecase", title_casify(name));
|
||||
|
||||
member_generator.append(R"~~~(
|
||||
case PseudoElement::@name:titlecase@:
|
||||
return true;
|
||||
)~~~");
|
||||
});
|
||||
|
||||
generator.append(R"~~~(
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_element_backed_pseudo_element(PseudoElement pseudo_element)
|
||||
{
|
||||
switch (pseudo_element) {
|
||||
)~~~");
|
||||
|
||||
pseudo_elements_data.for_each_member([&](auto& name, JsonValue const& value) {
|
||||
auto& pseudo_element = value.as_object();
|
||||
if (pseudo_element.has("alias-for"sv))
|
||||
return;
|
||||
if (!pseudo_element.get_bool("is-element-backed"sv).value_or(false))
|
||||
return;
|
||||
|
||||
auto member_generator = generator.fork();
|
||||
member_generator.set("name:titlecase", title_casify(name));
|
||||
|
||||
member_generator.append(R"~~~(
|
||||
case PseudoElement::@name:titlecase@:
|
||||
return true;
|
||||
)~~~");
|
||||
});
|
||||
|
||||
generator.append(R"~~~(
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_pseudo_element_root(PseudoElement pseudo_element)
|
||||
{
|
||||
switch (pseudo_element) {
|
||||
|
||||
Reference in New Issue
Block a user