From 14e6bae5931ad5b6209707c7593b3c38e9efaaf5 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Wed, 2 Aug 2023 14:17:04 +0100 Subject: [PATCH] LibWeb: Implement the `:focus-visible` pseudo-class This is very naive for now, and matches whenever `:focus` does. --- Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp | 2 ++ Userland/Libraries/LibWeb/CSS/Selector.cpp | 1 + Userland/Libraries/LibWeb/CSS/Selector.h | 3 +++ Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp | 3 +++ Userland/Libraries/LibWeb/Dump.cpp | 3 +++ 5 files changed, 12 insertions(+) diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 9b781fdf23..93750ffac3 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -485,6 +485,8 @@ Parser::ParseErrorOr Parser::parse_pseudo_simple_selec return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::FirstOfType); if (pseudo_name.equals_ignoring_ascii_case("focus"sv)) return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::Focus); + if (pseudo_name.equals_ignoring_ascii_case("focus-visible"sv)) + return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::FocusVisible); if (pseudo_name.equals_ignoring_ascii_case("focus-within"sv)) return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::FocusWithin); if (pseudo_name.equals_ignoring_ascii_case("hover"sv)) diff --git a/Userland/Libraries/LibWeb/CSS/Selector.cpp b/Userland/Libraries/LibWeb/CSS/Selector.cpp index 53234e3728..d82f422e7d 100644 --- a/Userland/Libraries/LibWeb/CSS/Selector.cpp +++ b/Userland/Libraries/LibWeb/CSS/Selector.cpp @@ -214,6 +214,7 @@ ErrorOr Selector::SimpleSelector::serialize() const case Selector::SimpleSelector::PseudoClass::Type::Visited: case Selector::SimpleSelector::PseudoClass::Type::Hover: case Selector::SimpleSelector::PseudoClass::Type::Focus: + case Selector::SimpleSelector::PseudoClass::Type::FocusVisible: case Selector::SimpleSelector::PseudoClass::Type::FocusWithin: case Selector::SimpleSelector::PseudoClass::Type::FirstChild: case Selector::SimpleSelector::PseudoClass::Type::LastChild: diff --git a/Userland/Libraries/LibWeb/CSS/Selector.h b/Userland/Libraries/LibWeb/CSS/Selector.h index 6b360074df..7db68beda9 100644 --- a/Userland/Libraries/LibWeb/CSS/Selector.h +++ b/Userland/Libraries/LibWeb/CSS/Selector.h @@ -90,6 +90,7 @@ public: Visited, Hover, Focus, + FocusVisible, FocusWithin, FirstChild, LastChild, @@ -261,6 +262,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::FocusVisible: + return "focus-visible"sv; case Selector::SimpleSelector::PseudoClass::Type::FocusWithin: return "focus-within"sv; case Selector::SimpleSelector::PseudoClass::Type::FirstChild: diff --git a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp index 46e2f4360f..48a8065dd9 100644 --- a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp +++ b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp @@ -217,6 +217,9 @@ 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::FocusVisible: + // FIXME: We should only apply this when a visible focus is useful. Decide when that is! + 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); diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index 4ebacdb343..cf9053b925 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -494,6 +494,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::FocusVisible: + pseudo_class_description = "FocusVisible"; + break; case CSS::Selector::SimpleSelector::PseudoClass::Type::FocusWithin: pseudo_class_description = "FocusWithin"; break;