mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-09 17:44:56 +09:00
LibWeb/CSS: Automatically serialize functional pseudo-class arguments
The spec gives us a hard-coded list of functional pseudo-classes and how to serialize them - but this list is incomplete and likely to always be outdated compared to the list of pseudo-classes that exist. So instead, use the generated metadata we already have to serialize their arguments based on their type. This fixes :dir() and :has(), which previously did not serialize their arguments. Gets us 26 passes (including 6 from that as-yet-unmerged :dir() test).
This commit is contained in:
parent
5f144f366d
commit
7aed541ed0
Notes:
github-actions[bot]
2025-05-16 22:32:00 +00:00
Author: https://github.com/AtkinsSJ
Commit: 7aed541ed0
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4780
3 changed files with 49 additions and 39 deletions
|
@ -444,21 +444,31 @@ String Selector::SimpleSelector::serialize() const
|
|||
s.append(':');
|
||||
s.append(pseudo_class_name(pseudo_class.type));
|
||||
s.append('(');
|
||||
if (pseudo_class.type == PseudoClass::NthChild
|
||||
|| pseudo_class.type == PseudoClass::NthLastChild
|
||||
|| pseudo_class.type == PseudoClass::NthOfType
|
||||
|| pseudo_class.type == PseudoClass::NthLastOfType) {
|
||||
// NB: The spec list is incomplete. For ease of maintenance, we use the data from PseudoClasses.json for
|
||||
// this instead of a hard-coded list.
|
||||
switch (metadata.parameter_type) {
|
||||
case PseudoClassMetadata::ParameterType::None:
|
||||
break;
|
||||
case PseudoClassMetadata::ParameterType::ANPlusB:
|
||||
case PseudoClassMetadata::ParameterType::ANPlusBOf:
|
||||
// The result of serializing the value using the rules to serialize an <an+b> value.
|
||||
s.append(pseudo_class.nth_child_pattern.serialize());
|
||||
} else if (pseudo_class.type == PseudoClass::Not
|
||||
|| pseudo_class.type == PseudoClass::Is
|
||||
|| pseudo_class.type == PseudoClass::Where) {
|
||||
break;
|
||||
case PseudoClassMetadata::ParameterType::CompoundSelector:
|
||||
case PseudoClassMetadata::ParameterType::ForgivingSelectorList:
|
||||
case PseudoClassMetadata::ParameterType::ForgivingRelativeSelectorList:
|
||||
case PseudoClassMetadata::ParameterType::RelativeSelectorList:
|
||||
case PseudoClassMetadata::ParameterType::SelectorList:
|
||||
// The result of serializing the value using the rules for serializing a group of selectors.
|
||||
// NOTE: `:is()` and `:where()` aren't in the spec for this yet, but it should be!
|
||||
s.append(serialize_a_group_of_selectors(pseudo_class.argument_selector_list));
|
||||
} else if (pseudo_class.type == PseudoClass::Lang) {
|
||||
break;
|
||||
case PseudoClassMetadata::ParameterType::Ident:
|
||||
s.append(string_from_keyword(pseudo_class.keyword.value()));
|
||||
break;
|
||||
case PseudoClassMetadata::ParameterType::LanguageRanges:
|
||||
// The serialization of a comma-separated list of each argument’s serialization as a string, preserving relative order.
|
||||
s.join(", "sv, pseudo_class.languages);
|
||||
break;
|
||||
}
|
||||
s.append(')');
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@ Harness status: OK
|
|||
|
||||
Found 10 tests
|
||||
|
||||
3 Pass
|
||||
7 Fail
|
||||
Fail ":dir(rtl)" should be a valid selector
|
||||
Fail ":dir( rtl )" should be a valid selector
|
||||
Fail ":dir(ltr):dir(rtl)" should be a valid selector
|
||||
Fail "foo:dir(RTL)" should be a valid selector
|
||||
Fail ":dir(auto)" should be a valid selector
|
||||
Fail ":dir(none)" should be a valid selector
|
||||
9 Pass
|
||||
1 Fail
|
||||
Pass ":dir(rtl)" should be a valid selector
|
||||
Pass ":dir( rtl )" should be a valid selector
|
||||
Pass ":dir(ltr):dir(rtl)" should be a valid selector
|
||||
Pass "foo:dir(RTL)" should be a valid selector
|
||||
Pass ":dir(auto)" should be a valid selector
|
||||
Pass ":dir(none)" should be a valid selector
|
||||
Fail ":dir(something-made-up)" should be a valid selector
|
||||
Pass ":dir()" should be an invalid selector
|
||||
Pass ":dir(\"ltr\")" should be an invalid selector
|
||||
|
|
|
@ -2,31 +2,31 @@ Harness status: OK
|
|||
|
||||
Found 29 tests
|
||||
|
||||
6 Pass
|
||||
23 Fail
|
||||
Fail ":has(a)" should be a valid selector
|
||||
Fail ":has(#a)" should be a valid selector
|
||||
Fail ":has(.a)" should be a valid selector
|
||||
Fail ":has([a])" should be a valid selector
|
||||
Fail ":has([a=\"b\"])" should be a valid selector
|
||||
Fail ":has([a|=\"b\"])" should be a valid selector
|
||||
Fail ":has(:hover)" should be a valid selector
|
||||
Fail "*:has(.a)" should be a valid selector
|
||||
Fail ".a:has(.b)" should be a valid selector
|
||||
26 Pass
|
||||
3 Fail
|
||||
Pass ":has(a)" should be a valid selector
|
||||
Pass ":has(#a)" should be a valid selector
|
||||
Pass ":has(.a)" should be a valid selector
|
||||
Pass ":has([a])" should be a valid selector
|
||||
Pass ":has([a=\"b\"])" should be a valid selector
|
||||
Pass ":has([a|=\"b\"])" should be a valid selector
|
||||
Pass ":has(:hover)" should be a valid selector
|
||||
Pass "*:has(.a)" should be a valid selector
|
||||
Pass ".a:has(.b)" should be a valid selector
|
||||
Fail ".a:has(> .b)" should be a valid selector
|
||||
Fail ".a:has(~ .b)" should be a valid selector
|
||||
Fail ".a:has(+ .b)" should be a valid selector
|
||||
Fail ".a:has(.b) .c" should be a valid selector
|
||||
Fail ".a .b:has(.c)" should be a valid selector
|
||||
Fail ".a .b:has(.c .d)" should be a valid selector
|
||||
Fail ".a .b:has(.c .d) .e" should be a valid selector
|
||||
Fail ".a:has(.b:is(.c .d))" should be a valid selector
|
||||
Fail ".a:is(.b:has(.c) .d)" should be a valid selector
|
||||
Fail ".a:not(:has(.b))" should be a valid selector
|
||||
Fail ".a:has(:not(.b))" should be a valid selector
|
||||
Fail ".a:has(.b):has(.c)" should be a valid selector
|
||||
Fail "*|*:has(*)" should be a valid selector
|
||||
Fail ":has(*|*)" should be a valid selector
|
||||
Pass ".a:has(.b) .c" should be a valid selector
|
||||
Pass ".a .b:has(.c)" should be a valid selector
|
||||
Pass ".a .b:has(.c .d)" should be a valid selector
|
||||
Pass ".a .b:has(.c .d) .e" should be a valid selector
|
||||
Pass ".a:has(.b:is(.c .d))" should be a valid selector
|
||||
Pass ".a:is(.b:has(.c) .d)" should be a valid selector
|
||||
Pass ".a:not(:has(.b))" should be a valid selector
|
||||
Pass ".a:has(:not(.b))" should be a valid selector
|
||||
Pass ".a:has(.b):has(.c)" should be a valid selector
|
||||
Pass "*|*:has(*)" should be a valid selector
|
||||
Pass ":has(*|*)" should be a valid selector
|
||||
Pass ":has" should be an invalid selector
|
||||
Pass ".a:has" should be an invalid selector
|
||||
Pass ".a:has b" should be an invalid selector
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue