LibWeb: Bucket :host selectors by subject pseudo-class

Only shadow hosts can match :host selectors, so route them through the
subject pseudo-class bucket instead of the generic other bucket. Full
selector matching still validates the shadow-root context and any
arguments.
This commit is contained in:
Andreas Kling 2026-06-18 21:39:33 +02:00 committed by Andreas Kling
parent 8e473cb703
commit 14fc971035

View file

@ -3113,6 +3113,7 @@ static bool subject_pseudo_class_is_bucketable(PseudoClass pseudo_class)
case PseudoClass::FocusWithin:
case PseudoClass::Fullscreen:
case PseudoClass::Heading:
case PseudoClass::Host:
case PseudoClass::Hover:
case PseudoClass::Link:
case PseudoClass::LocalLink:
@ -3129,6 +3130,8 @@ static bool subject_pseudo_class_is_bucketable(PseudoClass pseudo_class)
static u8 subject_pseudo_class_bucket_priority(PseudoClass pseudo_class)
{
switch (pseudo_class) {
case PseudoClass::Host:
return 110;
case PseudoClass::FocusVisible:
return 100;
case PseudoClass::Focus:
@ -3346,6 +3349,8 @@ static bool matches_subject_pseudo_class_bucket(PseudoClass pseudo_class, DOM::E
return element.is_fullscreen_element();
case PseudoClass::Heading:
return element.is_html_heading_element();
case PseudoClass::Host:
return element.is_shadow_host();
case PseudoClass::Hover:
return matches_hover_pseudo_class_for_rule_bucket(element);
case PseudoClass::LocalLink:
@ -4275,7 +4280,8 @@ static IterationDecision for_each_matching_rule_bucket(DOM::AbstractElement abst
if (decision == IterationDecision::Break)
return IterationDecision::Break;
static constexpr Array<PseudoClass, 17> subject_pseudo_classes {
static constexpr Array<PseudoClass, 18> subject_pseudo_classes {
PseudoClass::Host,
PseudoClass::FocusVisible,
PseudoClass::Focus,
PseudoClass::Active,