diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 7fa23e73ff..e874ed3028 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -506,6 +506,8 @@ Result Parser::parse_simple_sel simple_selector.pseudo_class.type = Selector::SimpleSelector::PseudoClass::Type::FirstOfType; } else if (pseudo_name.equals_ignoring_case("focus")) { simple_selector.pseudo_class.type = Selector::SimpleSelector::PseudoClass::Type::Focus; + } else if (pseudo_name.equals_ignoring_case("focus-within")) { + simple_selector.pseudo_class.type = Selector::SimpleSelector::PseudoClass::Type::FocusWithin; } else if (pseudo_name.equals_ignoring_case("hover")) { simple_selector.pseudo_class.type = Selector::SimpleSelector::PseudoClass::Type::Hover; } else if (pseudo_name.equals_ignoring_case("last-child")) { diff --git a/Userland/Libraries/LibWeb/CSS/Selector.h b/Userland/Libraries/LibWeb/CSS/Selector.h index 7e4d8a5878..a2c435ce44 100644 --- a/Userland/Libraries/LibWeb/CSS/Selector.h +++ b/Userland/Libraries/LibWeb/CSS/Selector.h @@ -60,6 +60,7 @@ public: Visited, Hover, Focus, + FocusWithin, FirstChild, LastChild, OnlyChild, @@ -185,6 +186,8 @@ constexpr StringView pseudo_class_name(Selector::SimpleSelector::PseudoClass::Ty return "hover"sv; case Selector::SimpleSelector::PseudoClass::Type::Focus: return "focus"sv; + case Selector::SimpleSelector::PseudoClass::Type::FocusWithin: + return "focus-within"sv; case Selector::SimpleSelector::PseudoClass::Type::FirstChild: return "first-child"sv; case Selector::SimpleSelector::PseudoClass::Type::LastChild: diff --git a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp index 7bad2280a2..bd065fe514 100644 --- a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp +++ b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp @@ -137,6 +137,10 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla return matches_hover_pseudo_class(element); case CSS::Selector::SimpleSelector::PseudoClass::Type::Focus: return element.is_focused(); + case CSS::Selector::SimpleSelector::PseudoClass::Type::FocusWithin: { + auto* focused_element = element.document().focused_element(); + return focused_element && element.is_inclusive_ancestor_of(*focused_element); + } case CSS::Selector::SimpleSelector::PseudoClass::Type::FirstChild: return !element.previous_element_sibling(); case CSS::Selector::SimpleSelector::PseudoClass::Type::LastChild: diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index 89b6126cbb..c6cb37472e 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -405,6 +405,9 @@ void dump_selector(StringBuilder& builder, CSS::Selector const& selector) case CSS::Selector::SimpleSelector::PseudoClass::Type::Focus: pseudo_class_description = "Focus"; break; + case CSS::Selector::SimpleSelector::PseudoClass::Type::FocusWithin: + pseudo_class_description = "FocusWithin"; + break; case CSS::Selector::SimpleSelector::PseudoClass::Type::Empty: pseudo_class_description = "Empty"; break;