Переглянути джерело

LibWeb: Implement the `:focus-visible` pseudo-class

This is very naive for now, and matches whenever `:focus` does.
Sam Atkins 1 рік тому
батько
коміт
14e6bae593

+ 2 - 0
Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp

@@ -485,6 +485,8 @@ Parser::ParseErrorOr<Selector::SimpleSelector> Parser::parse_pseudo_simple_selec
             return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::FirstOfType);
             return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::FirstOfType);
         if (pseudo_name.equals_ignoring_ascii_case("focus"sv))
         if (pseudo_name.equals_ignoring_ascii_case("focus"sv))
             return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::Focus);
             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))
         if (pseudo_name.equals_ignoring_ascii_case("focus-within"sv))
             return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::FocusWithin);
             return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::FocusWithin);
         if (pseudo_name.equals_ignoring_ascii_case("hover"sv))
         if (pseudo_name.equals_ignoring_ascii_case("hover"sv))

+ 1 - 0
Userland/Libraries/LibWeb/CSS/Selector.cpp

@@ -214,6 +214,7 @@ ErrorOr<String> Selector::SimpleSelector::serialize() const
         case Selector::SimpleSelector::PseudoClass::Type::Visited:
         case Selector::SimpleSelector::PseudoClass::Type::Visited:
         case Selector::SimpleSelector::PseudoClass::Type::Hover:
         case Selector::SimpleSelector::PseudoClass::Type::Hover:
         case Selector::SimpleSelector::PseudoClass::Type::Focus:
         case Selector::SimpleSelector::PseudoClass::Type::Focus:
+        case Selector::SimpleSelector::PseudoClass::Type::FocusVisible:
         case Selector::SimpleSelector::PseudoClass::Type::FocusWithin:
         case Selector::SimpleSelector::PseudoClass::Type::FocusWithin:
         case Selector::SimpleSelector::PseudoClass::Type::FirstChild:
         case Selector::SimpleSelector::PseudoClass::Type::FirstChild:
         case Selector::SimpleSelector::PseudoClass::Type::LastChild:
         case Selector::SimpleSelector::PseudoClass::Type::LastChild:

+ 3 - 0
Userland/Libraries/LibWeb/CSS/Selector.h

@@ -90,6 +90,7 @@ public:
                 Visited,
                 Visited,
                 Hover,
                 Hover,
                 Focus,
                 Focus,
+                FocusVisible,
                 FocusWithin,
                 FocusWithin,
                 FirstChild,
                 FirstChild,
                 LastChild,
                 LastChild,
@@ -261,6 +262,8 @@ constexpr StringView pseudo_class_name(Selector::SimpleSelector::PseudoClass::Ty
         return "hover"sv;
         return "hover"sv;
     case Selector::SimpleSelector::PseudoClass::Type::Focus:
     case Selector::SimpleSelector::PseudoClass::Type::Focus:
         return "focus"sv;
         return "focus"sv;
+    case Selector::SimpleSelector::PseudoClass::Type::FocusVisible:
+        return "focus-visible"sv;
     case Selector::SimpleSelector::PseudoClass::Type::FocusWithin:
     case Selector::SimpleSelector::PseudoClass::Type::FocusWithin:
         return "focus-within"sv;
         return "focus-within"sv;
     case Selector::SimpleSelector::PseudoClass::Type::FirstChild:
     case Selector::SimpleSelector::PseudoClass::Type::FirstChild:

+ 3 - 0
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);
         return matches_hover_pseudo_class(element);
     case CSS::Selector::SimpleSelector::PseudoClass::Type::Focus:
     case CSS::Selector::SimpleSelector::PseudoClass::Type::Focus:
         return element.is_focused();
         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: {
     case CSS::Selector::SimpleSelector::PseudoClass::Type::FocusWithin: {
         auto* focused_element = element.document().focused_element();
         auto* focused_element = element.document().focused_element();
         return focused_element && element.is_inclusive_ancestor_of(*focused_element);
         return focused_element && element.is_inclusive_ancestor_of(*focused_element);

+ 3 - 0
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:
                 case CSS::Selector::SimpleSelector::PseudoClass::Type::Focus:
                     pseudo_class_description = "Focus";
                     pseudo_class_description = "Focus";
                     break;
                     break;
+                case CSS::Selector::SimpleSelector::PseudoClass::Type::FocusVisible:
+                    pseudo_class_description = "FocusVisible";
+                    break;
                 case CSS::Selector::SimpleSelector::PseudoClass::Type::FocusWithin:
                 case CSS::Selector::SimpleSelector::PseudoClass::Type::FocusWithin:
                     pseudo_class_description = "FocusWithin";
                     pseudo_class_description = "FocusWithin";
                     break;
                     break;