srctree

Robin Linden parent 61d9efc5 f677fb8b
style: Add support for applying a stylesheet to the dom

inlinesplit
dom/dom.h added: 139, removed: 7, total 132
@@ -40,6 +40,22 @@ inline Node create_element_node(std::string_view name, AttrMap attrs, std::vecto
 
std::string to_string(Node const &node);
 
inline bool operator==(dom::Doctype const &a, dom::Doctype const &b) noexcept {
return a.doctype == b.doctype;
}
 
inline bool operator==(dom::Text const &a, dom::Text const &b) noexcept {
return a.text == b.text;
}
 
inline bool operator==(dom::Element const &a, dom::Element const &b) noexcept {
return a.name == b.name && a.attributes == b.attributes;
}
 
inline bool operator==(dom::Node const &a, dom::Node const &b) noexcept {
return a.children == b.children && a.data == b.data;
}
 
} // namespace dom
 
#endif
 
style/BUILD added: 139, removed: 7, total 132
@@ -3,7 +3,10 @@ load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
cc_library(
name = "style",
srcs = ["style.cpp"],
hdrs = ["style.h"],
hdrs = [
"style.h",
"styled_node.h",
],
visibility = ["//visibility:public"],
deps = [
"//css",
 
style/style.cpp added: 139, removed: 7, total 132
@@ -2,6 +2,7 @@
 
#include <algorithm>
#include <iterator>
#include <utility>
 
namespace style {
 
@@ -30,4 +31,21 @@ std::vector<std::pair<std::string, std::string>> matching_rules(
return matched_rules;
}
 
StyledNode style_tree(dom::Node const &root, std::vector<css::Rule> const &stylesheet) {
std::vector<StyledNode> children{};
for (auto const &child : root.children) {
children.push_back(style_tree(child, stylesheet));
}
 
auto properties = std::holds_alternative<dom::Element>(root.data)
? matching_rules(std::get<dom::Element>(root.data), stylesheet)
: std::vector<std::pair<std::string, std::string>>{};
 
return {
.node = root,
.properties = std::move(properties),
.children = std::move(children),
};
}
 
} // namespace style
 
style/style.h added: 139, removed: 7, total 132
@@ -3,6 +3,7 @@
 
#include "css/rule.h"
#include "dom/dom.h"
#include "style/styled_node.h"
 
#include <string_view>
#include <string>
@@ -17,6 +18,8 @@ std::vector<std::pair<std::string, std::string>> matching_rules(
dom::Element const &element,
std::vector<css::Rule> const &stylesheet);
 
StyledNode style_tree(dom::Node const &root, std::vector<css::Rule> const &stylesheet);
 
} // namespace style
 
#endif
 
style/style_test.cpp added: 139, removed: 7, total 132
@@ -1,4 +1,5 @@
#include "style/style.h"
#include "style/styled_node.h"
 
#include "css/rule.h"
#include "etest/etest.h"
@@ -67,5 +68,72 @@ int main() {
}
});
 
etest::test("style_tree: structure", [] {
dom::Node root = dom::create_element_node(
"html",
{},
{
dom::create_element_node("head", {}, {}),
dom::create_element_node("body", {}, {
dom::create_element_node("p", {}, {}),
}),
}
);
 
style::StyledNode expected{
.node = root,
.properties = {},
.children = {
{root.children[0], {}, {}},
{root.children[1], {}, {
{root.children[1].children[0], {}, {}},
}},
},
};
 
expect(style::style_tree(root, {}) == expected);
});
 
etest::test("style_tree: style is applied", [] {
dom::Node root = dom::create_element_node(
"html",
{},
{
dom::create_element_node("head", {}, {}),
dom::create_element_node("body", {}, {
dom::create_element_node("p", {}, {}),
}),
}
);
 
std::vector<css::Rule> stylesheet{
{
.selectors = {"p"},
.declarations = {
{"height", "100px"},
}
},
{
.selectors = {"body"},
.declarations = {
{"text-size", "500em"},
}
},
};
 
style::StyledNode expected{
.node = root,
.properties = {},
.children = {
{root.children[0], {}, {}},
{root.children[1], {{"text-size", "500em"}}, {
{root.children[1].children[0], {{"height", "100px"}}, {}},
}},
},
};
 
expect(style::style_tree(root, stylesheet) == expected);
});
 
return etest::run_all_tests();
}
 
filename was Deleted added: 139, removed: 7, total 132
@@ -0,0 +1,24 @@
#ifndef STYLE_STYLED_NODE_H_
#define STYLE_STYLED_NODE_H_
 
#include "dom/dom.h"
 
#include <string>
#include <utility>
#include <vector>
 
namespace style {
 
struct StyledNode {
dom::Node const &node;
std::vector<std::pair<std::string, std::string>> properties;
std::vector<StyledNode> children;
};
 
inline bool operator==(style::StyledNode const &a, style::StyledNode const &b) noexcept {
return a.node == b.node && a.properties == b.properties && a.children == b.children;
}
 
} // namespace style
 
#endif