summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@serenityos.org>2022-02-26 13:53:13 +0000
committerAndreas Kling <kling@serenityos.org>2022-02-26 15:30:24 +0100
commita57128467a2f11fb61cb4efe9b0fa3e3e6d51540 (patch)
treee9c86712ddbacb1d2b622153e7b18e6545354ad9 /Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp
parent2e23cce557d3aed29fb36383d0a448c6f0175881 (diff)
downloadserenity-a57128467a2f11fb61cb4efe9b0fa3e3e6d51540.zip
LibWeb: Implement :nth-of-type and :nth-last-of-type selectors :^)
Diffstat (limited to 'Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp')
-rw-r--r--Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp23
1 files changed, 21 insertions, 2 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp
index ddbd02cd25..52b4965ab9 100644
--- a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp
+++ b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp
@@ -142,6 +142,8 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla
return true;
case CSS::Selector::SimpleSelector::PseudoClass::Type::NthChild:
case CSS::Selector::SimpleSelector::PseudoClass::Type::NthLastChild:
+ case CSS::Selector::SimpleSelector::PseudoClass::Type::NthOfType:
+ case CSS::Selector::SimpleSelector::PseudoClass::Type::NthLastOfType:
auto const step_size = pseudo_class.nth_child_pattern.step_size;
auto const offset = pseudo_class.nth_child_pattern.offset;
if (step_size == 0 && offset == 0)
@@ -152,12 +154,29 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla
return false;
int index = 1;
- if (pseudo_class.type == CSS::Selector::SimpleSelector::PseudoClass::Type::NthChild) {
+ switch (pseudo_class.type) {
+ case CSS::Selector::SimpleSelector::PseudoClass::Type::NthChild: {
for (auto* child = parent->first_child_of_type<DOM::Element>(); child && child != &element; child = child->next_element_sibling())
++index;
- } else {
+ break;
+ }
+ case CSS::Selector::SimpleSelector::PseudoClass::Type::NthLastChild: {
for (auto* child = parent->last_child_of_type<DOM::Element>(); child && child != &element; child = child->previous_element_sibling())
++index;
+ break;
+ }
+ case CSS::Selector::SimpleSelector::PseudoClass::Type::NthOfType: {
+ for (auto* child = previous_sibling_with_same_tag_name(element); child; child = previous_sibling_with_same_tag_name(*child))
+ ++index;
+ break;
+ }
+ case CSS::Selector::SimpleSelector::PseudoClass::Type::NthLastOfType: {
+ for (auto* child = next_sibling_with_same_tag_name(element); child; child = next_sibling_with_same_tag_name(*child))
+ ++index;
+ break;
+ }
+ default:
+ VERIFY_NOT_REACHED();
}
if (step_size < 0) {