mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-20 00:08:55 +00:00
LibWeb/CSS: Add support for pseudo-classes taking <an+b>#
This commit is contained in:
parent
fbae3b824a
commit
e7890429aa
Notes:
github-actions[bot]
2025-08-13 08:48:47 +00:00
Author: https://github.com/AtkinsSJ
Commit: e7890429aa
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5830
4 changed files with 51 additions and 0 deletions
|
@ -710,6 +710,37 @@ Parser::ParseErrorOr<Selector::SimpleSelector> Parser::parse_pseudo_simple_selec
|
|||
};
|
||||
};
|
||||
|
||||
auto parse_an_plus_b_list_selector = [this](auto pseudo_class, Vector<ComponentValue> const& function_values) -> ParseErrorOr<Selector::SimpleSelector> {
|
||||
TokenStream tokens { function_values };
|
||||
auto list = parse_a_comma_separated_list_of_component_values(tokens);
|
||||
Vector<Selector::SimpleSelector::ANPlusBPattern> an_plus_b_patterns;
|
||||
|
||||
for (auto const& values : list) {
|
||||
TokenStream pattern_tokens { values };
|
||||
auto an_plus_b_pattern = parse_a_n_plus_b_pattern(pattern_tokens);
|
||||
if (!an_plus_b_pattern.has_value()) {
|
||||
ErrorReporter::the().report(InvalidPseudoClassOrElementError {
|
||||
.name = MUST(String::formatted(":{}", pseudo_class_name(pseudo_class))),
|
||||
.value_string = pattern_tokens.dump_string(),
|
||||
.description = "Invalid An+B format."_string,
|
||||
});
|
||||
return ParseError::SyntaxError;
|
||||
}
|
||||
an_plus_b_patterns.append(an_plus_b_pattern.release_value());
|
||||
}
|
||||
|
||||
tokens.discard_whitespace();
|
||||
if (tokens.has_next_token())
|
||||
return ParseError::SyntaxError;
|
||||
|
||||
return Selector::SimpleSelector {
|
||||
.type = Selector::SimpleSelector::Type::PseudoClass,
|
||||
.value = Selector::SimpleSelector::PseudoClassSelector {
|
||||
.type = pseudo_class,
|
||||
.an_plus_b_patterns = move(an_plus_b_patterns) }
|
||||
};
|
||||
};
|
||||
|
||||
auto const& pseudo_function = pseudo_class_token.function();
|
||||
auto maybe_pseudo_class = pseudo_class_from_string(pseudo_function.name);
|
||||
if (!maybe_pseudo_class.has_value()) {
|
||||
|
@ -756,6 +787,8 @@ Parser::ParseErrorOr<Selector::SimpleSelector> Parser::parse_pseudo_simple_selec
|
|||
switch (metadata.parameter_type) {
|
||||
case PseudoClassMetadata::ParameterType::ANPlusB:
|
||||
return parse_an_plus_b_selector(pseudo_class, pseudo_function.value, false);
|
||||
case PseudoClassMetadata::ParameterType::ANPlusBList:
|
||||
return parse_an_plus_b_list_selector(pseudo_class, pseudo_function.value);
|
||||
case PseudoClassMetadata::ParameterType::ANPlusBOf:
|
||||
return parse_an_plus_b_selector(pseudo_class, pseudo_function.value, true);
|
||||
case PseudoClassMetadata::ParameterType::CompoundSelector: {
|
||||
|
|
|
@ -462,6 +462,11 @@ String Selector::SimpleSelector::serialize() const
|
|||
// The result of serializing the value using the rules to serialize an <an+b> value.
|
||||
s.append(pseudo_class.an_plus_b_patterns.first().serialize());
|
||||
break;
|
||||
case PseudoClassMetadata::ParameterType::ANPlusBList:
|
||||
serialize_a_comma_separated_list(s, pseudo_class.an_plus_b_patterns, [](auto& builder, ANPlusBPattern const& an_plus_b) {
|
||||
builder.append(an_plus_b.serialize());
|
||||
});
|
||||
break;
|
||||
case PseudoClassMetadata::ParameterType::CompoundSelector:
|
||||
case PseudoClassMetadata::ParameterType::ForgivingSelectorList:
|
||||
case PseudoClassMetadata::ParameterType::ForgivingRelativeSelectorList:
|
||||
|
|
|
@ -575,6 +575,16 @@ void dump_selector(StringBuilder& builder, CSS::Selector const& selector, int in
|
|||
builder.append(")"sv);
|
||||
break;
|
||||
}
|
||||
case CSS::PseudoClassMetadata::ParameterType::ANPlusBList: {
|
||||
builder.append("([\n"sv);
|
||||
for (auto& an_plus_b : pseudo_class.an_plus_b_patterns) {
|
||||
indent(builder, indent_levels + 2);
|
||||
builder.appendff("(step={}, offset={})\n", an_plus_b.step_size, an_plus_b.offset);
|
||||
}
|
||||
indent(builder, indent_levels + 1);
|
||||
builder.append("])"sv);
|
||||
break;
|
||||
}
|
||||
case CSS::PseudoClassMetadata::ParameterType::CompoundSelector:
|
||||
case CSS::PseudoClassMetadata::ParameterType::ForgivingSelectorList:
|
||||
case CSS::PseudoClassMetadata::ParameterType::ForgivingRelativeSelectorList:
|
||||
|
|
|
@ -70,6 +70,7 @@ struct PseudoClassMetadata {
|
|||
enum class ParameterType {
|
||||
None,
|
||||
ANPlusB,
|
||||
ANPlusBList,
|
||||
ANPlusBOf,
|
||||
CompoundSelector,
|
||||
ForgivingSelectorList,
|
||||
|
@ -168,6 +169,8 @@ PseudoClassMetadata pseudo_class_metadata(PseudoClass pseudo_class)
|
|||
if (is_valid_as_function) {
|
||||
if (argument_string == "<an+b>"sv) {
|
||||
parameter_type = "ANPlusB"_string;
|
||||
} else if (argument_string == "<an+b>#"sv) {
|
||||
parameter_type = "ANPlusBList"_string;
|
||||
} else if (argument_string == "<an+b-of>"sv) {
|
||||
parameter_type = "ANPlusBOf"_string;
|
||||
} else if (argument_string == "<compound-selector>"sv) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue