LibWeb/CSS: Implement the :state(foo) pseudo-class

This matches custom elements that have `foo` in their custom states set.

The 2 test failures here are because we don't support `::part()` yet.
This commit is contained in:
Sam Atkins 2025-07-04 15:18:08 +01:00 committed by Tim Ledbetter
commit 202c55bf28
Notes: github-actions[bot] 2025-07-04 17:11:37 +00:00
12 changed files with 503 additions and 2 deletions

View file

@ -155,6 +155,9 @@
"stalled": {
"argument": ""
},
"state": {
"argument": "<ident>"
},
"suboptimal-value": {
"argument": ""
},

View file

@ -61,6 +61,7 @@ static bool can_selector_use_fast_matches(Selector const& selector)
PseudoClass::LocalLink,
PseudoClass::OnlyChild,
PseudoClass::Root,
PseudoClass::State,
PseudoClass::Visited))
return false;
} else if (!first_is_one_of(simple_selector.type,

View file

@ -15,6 +15,7 @@
#include <LibWeb/DOM/NamedNodeMap.h>
#include <LibWeb/DOM/Text.h>
#include <LibWeb/HTML/AttributeNames.h>
#include <LibWeb/HTML/CustomElements/CustomStateSet.h>
#include <LibWeb/HTML/HTMLAnchorElement.h>
#include <LibWeb/HTML/HTMLDetailsElement.h>
#include <LibWeb/HTML/HTMLDialogElement.h>
@ -1059,6 +1060,15 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla
return false;
}
case CSS::PseudoClass::State: {
// https://html.spec.whatwg.org/multipage/semantics-other.html#selector-custom
// The :state(identifier) pseudo-class must match all custom elements whose states set's set entries contains identifier.
if (!element.is_custom())
return false;
if (auto* custom_state_set = element.custom_state_set())
return custom_state_set->has_state(pseudo_class.ident->string_value);
return false;
}
}
return false;