LibWeb: Add support for pseudo-class functions that take an ident param

This is prep work for `:dir()`, though other pseudo-classes may well use
it in the future too.
This commit is contained in:
Sam Atkins 2023-08-12 18:11:50 +01:00 committed by Andreas Kling
parent 9522f761a3
commit 5b125811f1
Notes: sideshowbarker 2024-07-17 07:48:42 +09:00
4 changed files with 33 additions and 0 deletions

View file

@ -73,6 +73,7 @@ struct PseudoClassMetadata {
ANPlusBOf,
CompoundSelector,
ForgivingSelectorList,
Ident,
LanguageRanges,
SelectorList,
} parameter_type;
@ -169,6 +170,8 @@ PseudoClassMetadata pseudo_class_metadata(PseudoClass pseudo_class)
parameter_type = "CompoundSelector"_string;
} else if (argument_string == "<forgiving-selector-list>"sv) {
parameter_type = "ForgivingSelectorList"_string;
} else if (argument_string == "<ident>"sv) {
parameter_type = "Ident"_string;
} else if (argument_string == "<language-ranges>"sv) {
parameter_type = "LanguageRanges"_string;
} else if (argument_string == "<selector-list>"sv) {

View file

@ -512,6 +512,29 @@ Parser::ParseErrorOr<Selector::SimpleSelector> Parser::parse_pseudo_simple_selec
.argument_selector_list = move(argument_selector_list) }
};
}
case PseudoClassMetadata::ParameterType::Ident: {
auto function_token_stream = TokenStream(pseudo_function.values());
function_token_stream.skip_whitespace();
auto maybe_ident_token = function_token_stream.next_token();
function_token_stream.skip_whitespace();
if (!maybe_ident_token.is(Token::Type::Ident) || function_token_stream.has_next_token()) {
dbgln_if(CSS_PARSER_DEBUG, "Failed to parse :{}() parameter as an ident: not an ident", pseudo_function.name());
return ParseError::SyntaxError;
}
auto maybe_ident = value_id_from_string(maybe_ident_token.token().ident());
if (!maybe_ident.has_value()) {
dbgln_if(CSS_PARSER_DEBUG, "Failed to parse :{}() parameter as an ident: unrecognized ident", pseudo_function.name());
return ParseError::SyntaxError;
}
return Selector::SimpleSelector {
.type = Selector::SimpleSelector::Type::PseudoClass,
.value = Selector::SimpleSelector::PseudoClassSelector {
.type = pseudo_class,
.identifier = maybe_ident.value() }
};
}
case PseudoClassMetadata::ParameterType::LanguageRanges: {
Vector<FlyString> languages;
auto function_token_stream = TokenStream(pseudo_function.values());

View file

@ -12,6 +12,7 @@
#include <AK/String.h>
#include <AK/Vector.h>
#include <LibWeb/CSS/PseudoClass.h>
#include <LibWeb/CSS/ValueID.h>
namespace Web::CSS {
@ -96,6 +97,9 @@ public:
// Used for :lang(en-gb,dk)
Vector<FlyString> languages {};
// Used by :dir()
Optional<ValueID> identifier {};
};
struct Name {

View file

@ -505,6 +505,9 @@ void dump_selector(StringBuilder& builder, CSS::Selector const& selector)
builder.append("])"sv);
break;
}
case CSS::PseudoClassMetadata::ParameterType::Ident:
builder.appendff("(ident={})", string_from_value_id(pseudo_class.identifier.value()));
break;
case CSS::PseudoClassMetadata::ParameterType::LanguageRanges: {
builder.append('(');
builder.join(',', pseudo_class.languages);