diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Helpers.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Helpers.cpp index f1697adfa9c..523643c302e 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Helpers.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Helpers.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2018-2022, Andreas Kling * Copyright (c) 2020-2023, the SerenityOS developers. - * Copyright (c) 2021-2023, Sam Atkins + * Copyright (c) 2021-2024, Sam Atkins * Copyright (c) 2021, Tobias Christiansen * Copyright (c) 2022, MacDue * @@ -49,6 +49,11 @@ Optional parse_selector(CSS::Parser::ParsingContext const& co return CSS::Parser::Parser::create(context, selector_text).parse_as_selector(); } +Optional parse_pseudo_element_selector(CSS::Parser::ParsingContext const& context, StringView selector_text) +{ + return CSS::Parser::Parser::create(context, selector_text).parse_as_pseudo_element_selector(); +} + RefPtr parse_media_query(CSS::Parser::ParsingContext const& context, StringView string) { return CSS::Parser::Parser::create(context, string).parse_as_media_query(); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 7fa229fa276..390fcdc382a 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -60,6 +60,8 @@ public: Optional parse_as_selector(SelectorParsingMode = SelectorParsingMode::Standard); Optional parse_as_relative_selector(SelectorParsingMode = SelectorParsingMode::Standard); + Optional parse_as_pseudo_element_selector(); + Vector> parse_as_media_query_list(); RefPtr parse_as_media_query(); @@ -412,6 +414,7 @@ CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const&, Str CSS::ElementInlineCSSStyleDeclaration* parse_css_style_attribute(CSS::Parser::ParsingContext const&, StringView, DOM::Element&); RefPtr parse_css_value(CSS::Parser::ParsingContext const&, StringView, CSS::PropertyID property_id = CSS::PropertyID::Invalid); Optional parse_selector(CSS::Parser::ParsingContext const&, StringView); +Optional parse_pseudo_element_selector(CSS::Parser::ParsingContext const&, StringView); CSS::CSSRule* parse_css_rule(CSS::Parser::ParsingContext const&, StringView); RefPtr parse_media_query(CSS::Parser::ParsingContext const&, StringView); Vector> parse_media_query_list(CSS::Parser::ParsingContext const&, StringView); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp b/Userland/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp index 676257fd5c5..e4be646ef41 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp @@ -32,6 +32,34 @@ Optional Parser::parse_as_relative_selector(SelectorParsingMode pa return {}; } +Optional Parser::parse_as_pseudo_element_selector() +{ + // FIXME: This is quite janky. Selector parsing is not at all designed to allow parsing just a single part of a selector. + // So, this code parses a whole selector, then rejects it if it's not a single pseudo-element simple selector. + // Come back and fix this, future Sam! + auto maybe_selector_list = parse_a_selector_list(m_token_stream, SelectorType::Standalone, SelectorParsingMode::Standard); + if (maybe_selector_list.is_error()) + return {}; + auto& selector_list = maybe_selector_list.value(); + + if (selector_list.size() != 1) + return {}; + auto& selector = selector_list.first(); + + if (selector->compound_selectors().size() != 1) + return {}; + auto& first_compound_selector = selector->compound_selectors().first(); + + if (first_compound_selector.simple_selectors.size() != 1) + return {}; + auto& simple_selector = first_compound_selector.simple_selectors.first(); + + if (simple_selector.type != Selector::SimpleSelector::Type::PseudoElement) + return {}; + + return simple_selector.pseudo_element(); +} + template Parser::ParseErrorOr Parser::parse_a_selector_list(TokenStream& tokens, SelectorType mode, SelectorParsingMode parsing_mode) {