mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:37:44 +00:00
LibWeb: Implement :nth-[last-]child(n of foo)
syntax
In Selectors level 4, `:nth-child()` and `:nth-last-child()` can both optionally take a selector-list argument. This selector-list acts as a filter, so that only elements matching the list are counted. For example, this means that the following are equivalent: ```css :nth-child(2n+1 of p) {} p:nth-of-type(2n+1) {} ```
This commit is contained in:
parent
0e4c35b4b2
commit
5b0187477b
5 changed files with 92 additions and 25 deletions
|
@ -180,16 +180,35 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla
|
|||
if (!parent)
|
||||
return false;
|
||||
|
||||
auto matches_selector_list = [](CSS::SelectorList const& list, DOM::Element const& element) {
|
||||
if (list.is_empty())
|
||||
return true;
|
||||
for (auto const& child_selector : list) {
|
||||
if (matches(child_selector, element)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
int index = 1;
|
||||
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;
|
||||
if (!matches_selector_list(pseudo_class.argument_selector_list, element))
|
||||
return false;
|
||||
for (auto* child = parent->first_child_of_type<DOM::Element>(); child && child != &element; child = child->next_element_sibling()) {
|
||||
if (matches_selector_list(pseudo_class.argument_selector_list, *child))
|
||||
++index;
|
||||
}
|
||||
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;
|
||||
if (!matches_selector_list(pseudo_class.argument_selector_list, element))
|
||||
return false;
|
||||
for (auto* child = parent->last_child_of_type<DOM::Element>(); child && child != &element; child = child->previous_element_sibling()) {
|
||||
if (matches_selector_list(pseudo_class.argument_selector_list, *child))
|
||||
++index;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CSS::Selector::SimpleSelector::PseudoClass::Type::NthOfType: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue