summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-02-25 17:14:14 +0100
committerAndreas Kling <kling@serenityos.org>2022-02-25 19:38:31 +0100
commit31508b2788af7ccc30c0b992f4fd8e854371bf1e (patch)
treedd5509a52a9f9ed643f46ae7e1e70cfe551ffbe4 /Userland
parent29144f92383f4e52a311b7e5a902860520bf1ef2 (diff)
downloadserenity-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.cpp19
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: