srctree

Robin Linden parent 4908725b 65b70d09
style: Support the child combinator

inlinesplit
style/style.cpp added: 34, removed: 2, total 32
@@ -29,6 +29,26 @@ bool is_match(style::StyledNode const &node, std::string_view selector) {
// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes
auto [selector_, psuedo_class] = util::split_once(selector, ":");
 
// https://developer.mozilla.org/en-US/docs/Web/CSS/Child_combinator
if (selector_.contains('>')) {
// TODO(robinlinden): std::views::reverse and friends when we drop Clang 14 and 15.
auto parts = util::split(selector_, ">");
selector_ = util::trim(parts.back());
parts.pop_back();
std::ranges::reverse(parts);
 
// We only check the parent and up here, and if they all match, we fall
// through and check this node.
auto const *current = node.parent;
for (auto const &part : parts) {
if (current == nullptr || !is_match(*current, util::trim(part))) {
return false;
}
 
current = current->parent;
}
}
 
if (!psuedo_class.empty()) {
// https://developer.mozilla.org/en-US/docs/Web/CSS/:any-link
// https://developer.mozilla.org/en-US/docs/Web/CSS/:link
 
style/style_test.cpp added: 34, removed: 2, total 32
@@ -82,6 +82,18 @@ int main() {
});
}
 
etest::test("is_match: child", [] {
dom::Element dom = dom::Element{"div", {{"class", "logo"}}, {dom::Element{"span"}}};
style::StyledNode node{dom, {}, {style::StyledNode{dom.children[0]}}};
node.children[0].parent = &node;
expect(style::is_match(node.children[0], ".logo > span"sv));
expect(!style::is_match(node, ".logo > span"sv));
 
std::get<dom::Element>(dom.children[0]).attributes["class"] = "ohno";
expect(style::is_match(node.children[0], ".logo > .ohno"sv));
expect(style::is_match(node.children[0], ".logo > span"sv));
});
 
etest::test("matching_rules: simple names", [] {
std::vector<css::Rule> stylesheet;
expect(style::matching_rules(dom::Element{"div"}, stylesheet).empty());