diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPseudoClass.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPseudoClass.cpp index 06e06ab38d..910aca738e 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPseudoClass.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPseudoClass.cpp @@ -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 == ""sv) { parameter_type = "ForgivingSelectorList"_string; + } else if (argument_string == ""sv) { + parameter_type = "Ident"_string; } else if (argument_string == ""sv) { parameter_type = "LanguageRanges"_string; } else if (argument_string == ""sv) { diff --git a/Userland/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp b/Userland/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp index 1a5c8b297d..8bdc3c096c 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp @@ -512,6 +512,29 @@ Parser::ParseErrorOr 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 languages; auto function_token_stream = TokenStream(pseudo_function.values()); diff --git a/Userland/Libraries/LibWeb/CSS/Selector.h b/Userland/Libraries/LibWeb/CSS/Selector.h index 532c2396ae..97f99985bb 100644 --- a/Userland/Libraries/LibWeb/CSS/Selector.h +++ b/Userland/Libraries/LibWeb/CSS/Selector.h @@ -12,6 +12,7 @@ #include #include #include +#include namespace Web::CSS { @@ -96,6 +97,9 @@ public: // Used for :lang(en-gb,dk) Vector languages {}; + + // Used by :dir() + Optional identifier {}; }; struct Name { diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index af6e9bef35..d646df8523 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -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);