diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 76716bf3d1..59d1a7f173 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -447,6 +447,8 @@ Parser::ParseErrorOr Parser::parse_pseudo_simple_selec return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::Active); if (pseudo_name.equals_ignoring_ascii_case("checked"sv)) return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::Checked); + if (pseudo_name.equals_ignoring_ascii_case("indeterminate"sv)) + return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::Indeterminate); if (pseudo_name.equals_ignoring_ascii_case("disabled"sv)) return make_pseudo_class_selector(Selector::SimpleSelector::PseudoClass::Type::Disabled); if (pseudo_name.equals_ignoring_ascii_case("empty"sv)) diff --git a/Userland/Libraries/LibWeb/CSS/Selector.h b/Userland/Libraries/LibWeb/CSS/Selector.h index 87d269f54a..dd1da6cdbd 100644 --- a/Userland/Libraries/LibWeb/CSS/Selector.h +++ b/Userland/Libraries/LibWeb/CSS/Selector.h @@ -105,6 +105,7 @@ public: Disabled, Enabled, Checked, + Indeterminate, Is, Not, Where, @@ -275,6 +276,8 @@ constexpr StringView pseudo_class_name(Selector::SimpleSelector::PseudoClass::Ty return "enabled"sv; case Selector::SimpleSelector::PseudoClass::Type::Checked: return "checked"sv; + case Selector::SimpleSelector::PseudoClass::Type::Indeterminate: + return "indeterminate"sv; case Selector::SimpleSelector::PseudoClass::Type::Active: return "active"sv; case Selector::SimpleSelector::PseudoClass::Type::NthChild: diff --git a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp index 7ad6d480be..92e8c1313f 100644 --- a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp +++ b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -96,6 +97,28 @@ static inline bool matches_checked_pseudo_class(DOM::Element const& element) return false; } +// https://html.spec.whatwg.org/multipage/semantics-other.html#selector-indeterminate +static inline bool matches_indeterminate_pseudo_class(DOM::Element const& element) +{ + // The :indeterminate pseudo-class must match any element falling into one of the following categories: + // - input elements whose type attribute is in the Checkbox state and whose indeterminate IDL attribute is set to true + // FIXME: - input elements whose type attribute is in the Radio Button state and whose radio button group contains no input elements whose checkedness state is true. + if (is(element)) { + auto const& input_element = static_cast(element); + switch (input_element.type_state()) { + case HTML::HTMLInputElement::TypeAttributeState::Checkbox: + return input_element.indeterminate(); + default: + return false; + } + } + // - progress elements with no value content attribute + if (is(element)) { + return !element.has_attribute(HTML::AttributeNames::value); + } + return false; +} + static inline bool matches_attribute(CSS::Selector::SimpleSelector::Attribute const& attribute, DOM::Element const& element) { if (attribute.match_type == CSS::Selector::SimpleSelector::Attribute::MatchType::HasAttribute) { @@ -241,6 +264,8 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla && !element.is_actually_disabled(); case CSS::Selector::SimpleSelector::PseudoClass::Type::Checked: return matches_checked_pseudo_class(element); + case CSS::Selector::SimpleSelector::PseudoClass::Type::Indeterminate: + return matches_indeterminate_pseudo_class(element); case CSS::Selector::SimpleSelector::PseudoClass::Type::Is: case CSS::Selector::SimpleSelector::PseudoClass::Type::Where: for (auto& selector : pseudo_class.argument_selector_list) { diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index ee6de8ae3b..666924b989 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -441,6 +441,9 @@ void dump_selector(StringBuilder& builder, CSS::Selector const& selector) case CSS::Selector::SimpleSelector::PseudoClass::Type::Checked: pseudo_class_description = "Checked"; break; + case CSS::Selector::SimpleSelector::PseudoClass::Type::Indeterminate: + pseudo_class_description = "Indeterminate"; + break; case CSS::Selector::SimpleSelector::PseudoClass::Type::Not: pseudo_class_description = "Not"; break;