diff options
author | Andreas Kling <kling@serenityos.org> | 2022-02-25 17:14:14 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-02-25 19:38:31 +0100 |
commit | 31508b2788af7ccc30c0b992f4fd8e854371bf1e (patch) | |
tree | dd5509a52a9f9ed643f46ae7e1e70cfe551ffbe4 /Userland | |
parent | 29144f92383f4e52a311b7e5a902860520bf1ef2 (diff) | |
download | serenity-31508b2788af7ccc30c0b992f4fd8e854371bf1e.zip |
LibWeb: Make CSS :empty selector match empty text nodes as well
Previously we were only matching elements with *no* text children.
With this patch, we now also allow any number of empty text children to
be present as well.
1% progression on ACID3. :^)
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp index 267b719467..ddbd02cd25 100644 --- a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp +++ b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp @@ -93,8 +93,23 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla return !element.next_element_sibling(); case CSS::Selector::SimpleSelector::PseudoClass::Type::OnlyChild: return !(element.previous_element_sibling() || element.next_element_sibling()); - case CSS::Selector::SimpleSelector::PseudoClass::Type::Empty: - return !(element.first_child_of_type<DOM::Element>() || element.first_child_of_type<DOM::Text>()); + case CSS::Selector::SimpleSelector::PseudoClass::Type::Empty: { + if (!element.has_children()) + return true; + if (element.first_child_of_type<DOM::Element>()) + return false; + // NOTE: CSS Selectors level 4 changed ":empty" to also match whitespace-only text nodes. + // However, none of the major browser supports this yet, so let's just hang back until they do. + bool has_nonempty_text_child = false; + element.for_each_child_of_type<DOM::Text>([&](auto const& text_child) { + if (!text_child.data().is_empty()) { + has_nonempty_text_child = true; + return IterationDecision::Break; + } + return IterationDecision::Continue; + }); + return !has_nonempty_text_child; + } case CSS::Selector::SimpleSelector::PseudoClass::Type::Root: return is<HTML::HTMLHtmlElement>(element); case CSS::Selector::SimpleSelector::PseudoClass::Type::FirstOfType: |